vendor: 4,985 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.11.3 27 * https://greensock.com 28 * 29 * @license Copyright 2008-2022, GreenSock. All rights reserved. 30 * Subject to the terms at https://greensock.com/standard-license or for 31 * Club GreenSock 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: 7,375 bytes, lines 162-396
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 && _lazyRender(); 201 animation.render(time, suppressEvents, force || _reverting && time < 0 && (animation._initted || animation._startAt)); 202 _lazyTweens.length && _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); 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); 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._initted && !child._dur
vendor: 11,458 bytes, lines 396-708
396) { 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
vendor: 3,154 bytes, lines 708-798
708--; 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
vendor: 4,891 bytes, lines 798-960
798-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(value) { 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); 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 },
vendor: 7,656 bytes, lines 961-1246
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 _createPlugin = function _createPlugin(config) { 970 config = !config.name && config["default"] || config; 971 972 var name = config.name, 973 isFunc = _isFunction(config), 974 Plugin = name && !isFunc && config.init ? function () { 975 this._props = []; 976 } : config, 977 instanceDefaults = { 978 init: _emptyFunc, 979 render: _renderPropTweens, 980 add: _addPropTween, 981 kill: _killPropTweensOf, 982 modifier: _addPluginModifier, 983 rawVars: 0 984 }, 985 statics = { 986 targetTest: 0, 987 get: 0, 988 getSetter: _getSetter, 989 aliases: {}, 990 register: 0 991 }; 992 993 _wake(); 994 995 if (config !== Plugin) { 996 if (_plugins[name]) { 997 return; 998 } 999 1000 _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics)); 1001 1002 _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics))); 1003 1004 _plugins[Plugin.prop = name] = Plugin; 1005 1006 if (config.targetTest) { 1007 _harnessPlugins.push(Plugin); 1008 1009 _reservedProps[name] = 1; 1010 } 1011 1012 name = (name === "css" ? "CSS" : name.charAt(0).toUpperCase() + name.substr(1)) + "Plugin"; 1013 } 1014 1015 _addGlobal(name, Plugin); 1016 1017 config.register && config.register(gsap, Plugin, PropTween); 1018 }, 1019 _255 = 255, 1020 _colorLookup = { 1021 aqua: [0, _255, _255], 1022 lime: [0, _255, 0], 1023 silver: [192, 192, 192], 1024 black: [0, 0, 0], 1025 maroon: [128, 0, 0], 1026 teal: [0, 128, 128], 1027 blue: [0, 0, _255], 1028 navy: [0, 0, 128], 1029 white: [_255, _255, _255], 1030 olive: [128, 128, 0], 1031 yellow: [_255, _255, 0], 1032 orange: [_255, 165, 0], 1033 gray: [128, 128, 128], 1034 purple: [128, 0, 128], 1035 green: [0, 128, 0], 1036 red: [_255, 0, 0], 1037 pink: [_255, 192, 203], 1038 cyan: [0, _255, _255], 1039 transparent: [_255, _255, _255, 0] 1040 }, 1041 _hue = function _hue(h, m1, m2) { 1042 h += h < 0 ? 1 : h > 1 ? -1 : 0; 1043 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; 1044 }, 1045 splitColor = function splitColor(v, toHSL, forceAlpha) { 1046 var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0, 1047 r, 1048 g, 1049 b, 1050 h, 1051 s, 1052 l, 1053 max, 1054 min, 1055 d, 1056 wasHSL; 1057 1058 if (!a) { 1059 if (v.substr(-1) === ",") { 1060 v = v.substr(0, v.length - 1); 1061 } 1062 1063 if (_colorLookup[v]) { 1064 a = _colorLookup[v]; 1065 } else if (v.charAt(0) === "#") { 1066 if (v.length < 6) { 1067 r = v.charAt(1); 1068 g = v.charAt(2); 1069 b = v.charAt(3); 1070 v = "#" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : ""); 1071 } 1072 1073 if (v.length === 9) { 1074 a = parseInt(v.substr(1, 6), 16); 1075 return [a >> 16, a >> 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255]; 1076 } 1077 1078 v = parseInt(v.substr(1), 16); 1079 a = [v >> 16, v >> 8 & _255, v & _255]; 1080 } else if (v.substr(0, 3) === "hsl") { 1081 a = wasHSL = v.match(_strictNumExp); 1082 1083 if (!toHSL) { 1084 h = +a[0] % 360 / 360; 1085 s = +a[1] / 100; 1086 l = +a[2] / 100; 1087 g = l <= .5 ? l * (s + 1) : l + s - l * s; 1088 r = l * 2 - g; 1089 a.length > 3 && (a[3] *= 1); 1090 a[0] = _hue(h + 1 / 3, r, g); 1091 a[1] = _hue(h, r, g); 1092 a[2] = _hue(h - 1 / 3, r, g); 1093 } else if (~v.indexOf("=")) { 1094 a = v.match(_numExp); 1095 forceAlpha && a.length < 4 && (a[3] = 1); 1096 return a; 1097 } 1098 } else { 1099 a = v.match(_strictNumExp) || _colorLookup.transparent; 1100 } 1101 1102 a = a.map(Number); 1103 } 1104 1105 if (toHSL && !wasHSL) { 1106 r = a[0] / _255; 1107 g = a[1] / _255; 1108 b = a[2] / _255; 1109 max = Math.max(r, g, b); 1110 min = Math.min(r, g, b); 1111 l = (max + min) / 2; 1112 1113 if (max === min) { 1114 h = s = 0; 1115 } else { 1116 d = max - min; 1117 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 1118 h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4; 1119 h *= 60; 1120 } 1121 1122 a[0] = ~~(h + .5); 1123 a[1] = ~~(s * 100 + .5); 1124 a[2] = ~~(l * 100 + .5); 1125 } 1126 1127 forceAlpha && a.length < 4 && (a[3] = 1); 1128 return a; 1129 }, 1130 _colorOrderData = function _colorOrderData(v) { 1131 var values = [], 1132 c = [], 1133 i = -1; 1134 v.split(_colorExp).forEach(function (v) { 1135 var a = v.match(_numWithUnitExp) || []; 1136 values.push.apply(values, a); 1137 c.push(i += a.length + 1); 1138 }); 1139 values.c = c; 1140 return values; 1141 }, 1142 _formatColors = function _formatColors(s, toHSL, orderMatchData) { 1143 var result = "", 1144 colors = (s + result).match(_colorExp), 1145 type = toHSL ? "hsla(" : "rgba(", 1146 i = 0, 1147 c, 1148 shell, 1149 d, 1150 l; 1151 1152 if (!colors) { 1153 return s; 1154 } 1155 1156 colors = colors.map(function (color) { 1157 return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : color.join(",")) + ")"; 1158 }); 1159 1160 if (orderMatchData) { 1161 d = _colorOrderData(s); 1162 c = orderMatchData.c; 1163 1164 if (c.join(result) !== d.c.join(result)) { 1165 shell = s.replace(_colorExp, "1").split(_numWithUnitExp); 1166 l = shell.length - 1; 1167 1168 for (; i < l; i++) { 1169 result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + "0,0,0,0)" : (d.length ? d : colors.length ? colors : orderMatchData).shift()); 1170 } 1171 } 1172 } 1173 1174 if (!shell) { 1175 shell = s.split(_colorExp); 1176 l = shell.length - 1; 1177 1178 for (; i < l; i++) { 1179 result += shell[i] + colors[i]; 1180 } 1181 } 1182 1183 return result + shell[l]; 1184 }, 1185 _colorExp = function () { 1186 var s = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b", 1187 p; 1188 1189 for (p in _colorLookup) { 1190 s += "|" + p + "\\b"; 1191 } 1192 1193 return new RegExp(s + ")", "gi"); 1194 }(), 1195 _hslExp = /hsl[a]?\(/, 1196 _colorStringFilter = function _colorStringFilter(a) { 1197 var combined = a.join(" "), 1198 toHSL; 1199 _colorExp.lastIndex = 0; 1200 1201 if (_colorExp.test(combined)) { 1202 toHSL = _hslExp.test(combined); 1203 a[1] = _formatColors(a[1], toHSL); 1204 a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1])); 1205 return true; 1206 } 1207 }, 1208 _tickerActive, 1209 _ticker = function () { 1210 var _getTime = Date.now, 1211 _lagThreshold = 500, 1212 _adjustedLag = 33, 1213 _startTime = _getTime(), 1214 _lastUpdate = _startTime, 1215 _gap = 1000 / 240, 1216 _nextTime = _gap, 1217 _listeners = [], 1218 _id, 1219 _req, 1220 _raf, 1221 _self, 1222 _delta, 1223 _i, 1224 _tick = function _tick(v) { 1225 var elapsed = _getTime() - _lastUpdate, 1226 manual = v === true, 1227 overlap, 1228 dispatch, 1229 time, 1230 frame; 1231 1232 elapsed > _lagThreshold && (_startTime += elapsed - _adjustedLag); 1233 _lastUpdate += elapsed; 1234 time = _lastUpdate - _startTime; 1235 overlap = time - _nextTime; 1236 1237 if (overlap > 0 || manual) { 1238 frame = ++_self.frame; 1239 _delta = time - _self.time * 1000; 1240 _self.time = time = time / 1000; 1241 _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap); 1242 dispatch = 1; 1243 } 1244 1245 manual || (_id = _req(_tick)); 1246
vendor: 4,239 bytes, lines 1247-1383
1247 if (dispatch) { 1248 for (_i = 0; _i < _listeners.length; _i++) { 1249 _listeners[_i](time, _delta, frame, v); 1250 } 1251 } 1252 }; 1253 1254 _self = { 1255 time: 0, 1256 frame: 0, 1257 tick: function tick() { 1258 _tick(true); 1259 }, 1260 deltaRatio: function deltaRatio(fps) { 1261 return _delta / (1000 / (fps || 60)); 1262 }, 1263 wake: function wake() { 1264 if (_coreReady) { 1265 if (!_coreInitted && _windowExists()) { 1266 _win = _coreInitted = window; 1267 _doc = _win.document || {}; 1268 _globals.gsap = gsap; 1269 (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version); 1270 1271 _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {}); 1272 1273 _raf = _win.requestAnimationFrame; 1274 } 1275 1276 _id && _self.sleep(); 1277 1278 _req = _raf || function (f) { 1279 return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0); 1280 }; 1281 1282 _tickerActive = 1; 1283 1284 _tick(2); 1285 } 1286 }, 1287 sleep: function sleep() { 1288 (_raf ? _win.cancelAnimationFrame : clearTimeout)(_id); 1289 _tickerActive = 0; 1290 _req = _emptyFunc; 1291 }, 1292 lagSmoothing: function lagSmoothing(threshold, adjustedLag) { 1293 _lagThreshold = threshold || 1 / _tinyNum; 1294 _adjustedLag = Math.min(adjustedLag, _lagThreshold, 0); 1295 }, 1296 fps: function fps(_fps) { 1297 _gap = 1000 / (_fps || 240); 1298 _nextTime = _self.time * 1000 + _gap; 1299 }, 1300 add: function add(callback, once, prioritize) { 1301 var func = once ? function (t, d, f, v) { 1302 callback(t, d, f, v); 1303 1304 _self.remove(func); 1305 } : callback; 1306 1307 _self.remove(callback); 1308 1309 _listeners[prioritize ? "unshift" : "push"](func); 1310 1311 _wake(); 1312 1313 return func; 1314 }, 1315 remove: function remove(callback, i) { 1316 ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--; 1317 }, 1318 _listeners: _listeners 1319 }; 1320 return _self; 1321 }(), 1322 _wake = function _wake() { 1323 return !_tickerActive && _ticker.wake(); 1324 }, 1325 _easeMap = {}, 1326 _customEaseExp = /^[\d.\-M][\d.\-,\s]/, 1327 _quotesExp = /["']/g, 1328 _parseObjectInString = function _parseObjectInString(value) { 1329 var obj = {}, 1330 split = value.substr(1, value.length - 3).split(":"), 1331 key = split[0], 1332 i = 1, 1333 l = split.length, 1334 index, 1335 val, 1336 parsedVal; 1337 1338 for (; i < l; i++) { 1339 val = split[i]; 1340 index = i !== l - 1 ? val.lastIndexOf(",") : val.length; 1341 parsedVal = val.substr(0, index); 1342 obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, "").trim() : +parsedVal; 1343 key = val.substr(index + 1).trim(); 1344 } 1345 1346 return obj; 1347 }, 1348 _valueInParentheses = function _valueInParentheses(value) { 1349 var open = value.indexOf("(") + 1, 1350 close = value.indexOf(")"), 1351 nested = value.indexOf("(", open); 1352 return value.substring(open, ~nested && nested < close ? value.indexOf(")", close + 1) : close); 1353 }, 1354 _configEaseFromString = function _configEaseFromString(name) { 1355 var split = (name + "").split("("), 1356 ease = _easeMap[split[0]]; 1357 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; 1358 }, 1359 _invertEase = function _invertEase(ease) { 1360 return function (p) { 1361 return 1 - ease(1 - p); 1362 }; 1363 }, 1364 _propagateYoyoEase = function _propagateYoyoEase(timeline, isYoyo) { 1365 var child = timeline._first, 1366 ease; 1367 1368 while (child) { 1369 if (child instanceof Timeline) { 1370 _propagateYoyoEase(child, isYoyo); 1371 } else if (child.vars.yoyoEase && (!child._yoyo || !child._repeat) && child._yoyo !== isYoyo) { 1372 if (child.timeline) { 1373 _propagateYoyoEase(child.timeline, isYoyo); 1374 } else { 1375 ease = child._ease; 1376 child._ease = child._yEase; 1377 child._yEase = ease; 1378 child._yoyo = isYoyo; 1379 } 1380 } 1381 1382 child = child._next; 1383 }
vendor: 3,445 bytes, lines 1383-1494
1383 1384 }, 1385 _parseEase = function _parseEase(ease, defaultEase) { 1386 return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase; 1387 }, 1388 _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) { 1389 if (easeOut === void 0) { 1390 easeOut = function easeOut(p) { 1391 return 1 - easeIn(1 - p); 1392 }; 1393 } 1394 1395 if (easeInOut === void 0) { 1396 easeInOut = function easeInOut(p) { 1397 return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2; 1398 }; 1399 } 1400 1401 var ease = { 1402 easeIn: easeIn, 1403 easeOut: easeOut, 1404 easeInOut: easeInOut 1405 }, 1406 lowercaseName; 1407 1408 _forEachName(names, function (name) { 1409 _easeMap[name] = _globals[name] = ease; 1410 _easeMap[lowercaseName = name.toLowerCase()] = easeOut; 1411 1412 for (var p in ease) { 1413 _easeMap[lowercaseName + (p === "easeIn" ? ".in" : p === "easeOut" ? ".out" : ".inOut")] = _easeMap[name + "." + p] = ease[p]; 1414 } 1415 }); 1416 1417 return ease; 1418 }, 1419 _easeInOutFromOut = function _easeInOutFromOut(easeOut) { 1420 return function (p) { 1421 return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2; 1422 }; 1423 }, 1424 _configElastic = function _configElastic(type, amplitude, period) { 1425 var p1 = amplitude >= 1 ? amplitude : 1, 1426 p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1), 1427 p3 = p2 / _2PI * (Math.asin(1 / p1) || 0), 1428 easeOut = function easeOut(p) { 1429 return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1; 1430 }, 1431 ease = type === "out" ? easeOut : type === "in" ? function (p) { 1432 return 1 - easeOut(1 - p); 1433 } : _easeInOutFromOut(easeOut); 1434 1435 p2 = _2PI / p2; 1436 1437 ease.config = function (amplitude, period) { 1438 return _configElastic(type, amplitude, period); 1439 }; 1440 1441 return ease; 1442 }, 1443 _configBack = function _configBack(type, overshoot) { 1444 if (overshoot === void 0) { 1445 overshoot = 1.70158; 1446 } 1447 1448 var easeOut = function easeOut(p) { 1449 return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0; 1450 }, 1451 ease = type === "out" ? easeOut : type === "in" ? function (p) { 1452 return 1 - easeOut(1 - p); 1453 } : _easeInOutFromOut(easeOut); 1454 1455 ease.config = function (overshoot) { 1456 return _configBack(type, overshoot); 1457 }; 1458 1459 return ease; 1460 }; 1461 1462 _forEachName("Linear,Quad,Cubic,Quart,Quint,Strong", function (name, i) { 1463 var power = i < 5 ? i + 1 : i; 1464 1465 _insertEase(name + ",Power" + (power - 1), i ? function (p) { 1466 return Math.pow(p, power); 1467 } : function (p) { 1468 return p; 1469 }, function (p) { 1470 return 1 - Math.pow(1 - p, power); 1471 }, function (p) { 1472 return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2; 1473 }); 1474 }); 1475 1476 _easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn; 1477 1478 _insertEase("Elastic", _configElastic("in"), _configElastic("out"), _configElastic()); 1479 1480 (function (n, c) { 1481 var n1 = 1 / c, 1482 n2 = 2 * n1, 1483 n3 = 2.5 * n1, 1484 easeOut = function easeOut(p) { 1485 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; 1486 }; 1487 1488 _insertEase("Bounce", function (p) { 1489 return 1 - easeOut(1 - p); 1490 }, easeOut); 1491 })(7.5625, 2.75); 1492 1493 _insertEase("Expo", function (p) { 1494 return
vendor: 6,314 bytes, lines 1494-1684
1494p ? Math.pow(2, 10 * (p - 1)) : 0; 1495 }); 1496 1497 _insertEase("Circ", function (p) { 1498 return -(_sqrt(1 - p * p) - 1); 1499 }); 1500 1501 _insertEase("Sine", function (p) { 1502 return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1; 1503 }); 1504 1505 _insertEase("Back", _configBack("in"), _configBack("out"), _configBack()); 1506 1507 _easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = { 1508 config: function config(steps, immediateStart) { 1509 if (steps === void 0) { 1510 steps = 1; 1511 } 1512 1513 var p1 = 1 / steps, 1514 p2 = steps + (immediateStart ? 0 : 1), 1515 p3 = immediateStart ? 1 : 0, 1516 max = 1 - _tinyNum; 1517 return function (p) { 1518 return ((p2 * _clamp(0, max, p) | 0) + p3) * p1; 1519 }; 1520 } 1521 }; 1522 _defaults.ease = _easeMap["quad.out"]; 1523 1524 _forEachName("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt", function (name) { 1525 return _callbackNames += name + "," + name + "Params,"; 1526 }); 1527 1528 var GSCache = function GSCache(target, harness) { 1529 this.id = _gsID++; 1530 target._gsap = this; 1531 this.target = target; 1532 this.harness = harness; 1533 this.get = harness ? harness.get : _getProperty; 1534 this.set = harness ? harness.getSetter : _getSetter; 1535 }; 1536 var Animation = function () { 1537 function Animation(vars) { 1538 this.vars = vars; 1539 this._delay = +vars.delay || 0; 1540 1541 if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) { 1542 this._rDelay = vars.repeatDelay || 0; 1543 this._yoyo = !!vars.yoyo || !!vars.yoyoEase; 1544 } 1545 1546 this._ts = 1; 1547 1548 _setDuration(this, +vars.duration, 1, 1); 1549 1550 this.data = vars.data; 1551 1552 if (_context) { 1553 this._ctx = _context; 1554 1555 _context.data.push(this); 1556 } 1557 1558 _tickerActive || _ticker.wake(); 1559 } 1560 1561 var _proto = Animation.prototype; 1562 1563 _proto.delay = function delay(value) { 1564 if (value || value === 0) { 1565 this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay); 1566 this._delay = value; 1567 return this; 1568 } 1569 1570 return this._delay; 1571 }; 1572 1573 _proto.duration = function duration(value) { 1574 return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur; 1575 }; 1576 1577 _proto.totalDuration = function totalDuration(value) { 1578 if (!arguments.length) { 1579 return this._tDur; 1580 } 1581 1582 this._dirty = 0; 1583 return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1)); 1584 }; 1585 1586 _proto.totalTime = function totalTime(_totalTime, suppressEvents) { 1587 _wake(); 1588 1589 if (!arguments.length) { 1590 return this._tTime; 1591 } 1592 1593 var parent = this._dp; 1594 1595 if (parent && parent.smoothChildTiming && this._ts) { 1596 _alignPlayhead(this, _totalTime); 1597 1598 !parent._dp || parent.parent || _postAddChecks(parent, this); 1599 1600 while (parent && parent.parent) { 1601 if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) { 1602 parent.totalTime(parent._tTime, true); 1603 } 1604 1605 parent = parent.parent; 1606 } 1607 1608 if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) { 1609 _addToTimeline(this._dp, this, this._start - this._delay); 1610 } 1611 } 1612 1613 if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !_totalTime && !this._initted && (this.add || this._ptLookup)) { 1614 this._ts || (this._pTime = _totalTime); 1615 1616 _lazySafeRender(this, _totalTime, suppressEvents); 1617 } 1618 1619 return this; 1620 }; 1621 1622 _proto.time = function time(value, suppressEvents) { 1623 return arguments.length ? this.totalTime(Math.min(this.totalDuration(), value + _elapsedCycleDuration(this)) % (this._dur + this._rDelay) || (value ? this._dur : 0), suppressEvents) : this._time; 1624 }; 1625 1626 _proto.totalProgress = function totalProgress(value, suppressEvents) { 1627 return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.ratio; 1628 }; 1629 1630 _proto.progress = function progress(value, suppressEvents) { 1631 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.ratio; 1632 }; 1633 1634 _proto.iteration = function iteration(value, suppressEvents) { 1635 var cycleDuration = this.duration() + this._rDelay; 1636 1637 return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1; 1638 }; 1639 1640 _proto.timeScale = function timeScale(value) { 1641 if (!arguments.length) { 1642 return this._rts === -_tinyNum ? 0 : this._rts; 1643 } 1644 1645 if (this._rts === value) { 1646 return this; 1647 } 1648 1649 var tTime = this.parent && this._ts ? _parentToChildTotalTime(this.parent._time, this) : this._tTime; 1650 this._rts = +value || 0; 1651 this._ts = this._ps || value === -_tinyNum ? 0 : this._rts; 1652 this.totalTime(_clamp(-this._delay, this._tDur, tTime), true); 1653 1654 _setEnd(this); 1655 1656 return _recacheAncestors(this); 1657 }; 1658 1659 _proto.paused = function paused(value) { 1660 if (!arguments.length) { 1661 return this._ps; 1662 } 1663 1664 if (this._ps !== value) { 1665 this._ps = value; 1666 1667 if (value) { 1668 this._pTime = this._tTime || Math.max(-this._delay, this.rawTime()); 1669 this._ts = this._act = 0; 1670 } else { 1671 _wake(); 1672 1673 this._ts = this._rts; 1674 this.totalTime(this.parent && !this.parent.smoothChildTiming ? this.rawTime() : this._tTime || this._pTime, this.progress() === 1 && Math.abs(this._zTime) !== _tinyNum && (this._tTime -= _tinyNum)); 1675 } 1676 } 1677 1678 return this; 1679 }; 1680 1681 _proto.startTime = function startTime(value) { 1682 if (arguments.length) { 1683 this._start = value; 1684 var parent = this.parent || this._dp;
vendor: 3,424 bytes, lines 1685-1797
1685 parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, value - this._delay); 1686 return this; 1687 } 1688 1689 return this._start; 1690 }; 1691 1692 _proto.endTime = function endTime(includeRepeats) { 1693 return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts || 1); 1694 }; 1695 1696 _proto.rawTime = function rawTime(wrapRepeats) { 1697 var parent = this.parent || this._dp; 1698 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); 1699 }; 1700 1701 _proto.revert = function revert(config) { 1702 if (config === void 0) { 1703 config = _revertConfig; 1704 } 1705 1706 var prevIsReverting = _reverting; 1707 _reverting = config; 1708 1709 if (this._initted || this._startAt) { 1710 this.timeline && this.timeline.revert(config); 1711 this.totalTime(-0.01, config.suppressEvents); 1712 } 1713 1714 this.data !== "nested" && config.kill !== false && this.kill(); 1715 _reverting = prevIsReverting; 1716 return this; 1717 }; 1718 1719 _proto.globalTime = function globalTime(rawTime) { 1720 var animation = this, 1721 time = arguments.length ? rawTime : animation.rawTime(); 1722 1723 while (animation) { 1724 time = animation._start + time / (animation._ts || 1); 1725 animation = animation._dp; 1726 } 1727 1728 return !this.parent && this.vars.immediateRender ? -1 : time; 1729 }; 1730 1731 _proto.repeat = function repeat(value) { 1732 if (arguments.length) { 1733 this._repeat = value === Infinity ? -2 : value; 1734 return _onUpdateTotalDuration(this); 1735 } 1736 1737 return this._repeat === -2 ? Infinity : this._repeat; 1738 }; 1739 1740 _proto.repeatDelay = function repeatDelay(value) { 1741 if (arguments.length) { 1742 var time = this._time; 1743 this._rDelay = value; 1744 1745 _onUpdateTotalDuration(this); 1746 1747 return time ? this.time(time) : this; 1748 } 1749 1750 return this._rDelay; 1751 }; 1752 1753 _proto.yoyo = function yoyo(value) { 1754 if (arguments.length) { 1755 this._yoyo = value; 1756 return this; 1757 } 1758 1759 return this._yoyo; 1760 }; 1761 1762 _proto.seek = function seek(position, suppressEvents) { 1763 return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents)); 1764 }; 1765 1766 _proto.restart = function restart(includeDelay, suppressEvents) { 1767 return this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents)); 1768 }; 1769 1770 _proto.play = function play(from, suppressEvents) { 1771 from != null && this.seek(from, suppressEvents); 1772 return this.reversed(false).paused(false); 1773 }; 1774 1775 _proto.reverse = function reverse(from, suppressEvents) { 1776 from != null && this.seek(from || this.totalDuration(), suppressEvents); 1777 return this.reversed(true).paused(false); 1778 }; 1779 1780 _proto.pause = function pause(atTime, suppressEvents) { 1781 atTime != null && this.seek(atTime, suppressEvents); 1782 return this.paused(true); 1783 }; 1784 1785 _proto.resume = function resume() { 1786 return this.paused(false); 1787 }; 1788 1789 _proto.reversed = function reversed(value) { 1790 if (arguments.length) { 1791 !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0)); 1792 return this; 1793 } 1794 1795 return this._rts < 0; 1796 }; 1797
vendor: 8,586 bytes, lines 1798-2069
1798 _proto.invalidate = function invalidate() { 1799 this._initted = this._act = 0; 1800 this._zTime = -_tinyNum; 1801 return this; 1802 }; 1803 1804 _proto.isActive = function isActive() { 1805 var parent = this.parent || this._dp, 1806 start = this._start, 1807 rawTime; 1808 return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum); 1809 }; 1810 1811 _proto.eventCallback = function eventCallback(type, callback, params) { 1812 var vars = this.vars; 1813 1814 if (arguments.length > 1) { 1815 if (!callback) { 1816 delete vars[type]; 1817 } else { 1818 vars[type] = callback; 1819 params && (vars[type + "Params"] = params); 1820 type === "onUpdate" && (this._onUpdate = callback); 1821 } 1822 1823 return this; 1824 } 1825 1826 return vars[type]; 1827 }; 1828 1829 _proto.then = function then(onFulfilled) { 1830 var self = this; 1831 return new Promise(function (resolve) { 1832 var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough, 1833 _resolve = function _resolve() { 1834 var _then = self.then; 1835 self.then = null; 1836 _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then); 1837 resolve(f); 1838 self.then = _then; 1839 }; 1840 1841 if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) { 1842 _resolve(); 1843 } else { 1844 self._prom = _resolve; 1845 } 1846 }); 1847 }; 1848 1849 _proto.kill = function kill() { 1850 _interrupt(this); 1851 }; 1852 1853 return Animation; 1854 }(); 1855 1856 _setDefaults(Animation.prototype, { 1857 _time: 0, 1858 _start: 0, 1859 _end: 0, 1860 _tTime: 0, 1861 _tDur: 0, 1862 _dirty: 0, 1863 _repeat: 0, 1864 _yoyo: false, 1865 parent: null, 1866 _initted: false, 1867 _rDelay: 0, 1868 _ts: 1, 1869 _dp: 0, 1870 ratio: 0, 1871 _zTime: -_tinyNum, 1872 _prom: 0, 1873 _ps: false, 1874 _rts: 1 1875 }); 1876 1877 var Timeline = function (_Animation) { 1878 _inheritsLoose(Timeline, _Animation); 1879 1880 function Timeline(vars, position) { 1881 var _this; 1882 1883 if (vars === void 0) { 1884 vars = {}; 1885 } 1886 1887 _this = _Animation.call(this, vars) || this; 1888 _this.labels = {}; 1889 _this.smoothChildTiming = !!vars.smoothChildTiming; 1890 _this.autoRemoveChildren = !!vars.autoRemoveChildren; 1891 _this._sort = _isNotFalse(vars.sortChildren); 1892 _globalTimeline && _addToTimeline(vars.parent || _globalTimeline, _assertThisInitialized(_this), position); 1893 vars.reversed && _this.reverse(); 1894 vars.paused && _this.paused(true); 1895 vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger); 1896 return _this; 1897 } 1898 1899 var _proto2 = Timeline.prototype; 1900 1901 _proto2.to = function to(targets, vars, position) { 1902 _createTweenType(0, arguments, this); 1903 1904 return this; 1905 }; 1906 1907 _proto2.from = function from(targets, vars, position) { 1908 _createTweenType(1, arguments, this); 1909 1910 return this; 1911 }; 1912 1913 _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) { 1914 _createTweenType(2, arguments, this); 1915 1916 return this; 1917 }; 1918 1919 _proto2.set = function set(targets, vars, position) { 1920 vars.duration = 0; 1921 vars.parent = this; 1922 _inheritDefaults(vars).repeatDelay || (vars.repeat = 0); 1923 vars.immediateRender = !!vars.immediateRender; 1924 new Tween(targets, vars, _parsePosition(this, position), 1); 1925 return this; 1926 }; 1927 1928 _proto2.call = function call(callback, params, position) { 1929 return _addToTimeline(this, Tween.delayedCall(0, callback, params), position); 1930 }; 1931 1932 _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 1933 vars.duration = duration; 1934 vars.stagger = vars.stagger || stagger; 1935 vars.onComplete = onCompleteAll; 1936 vars.onCompleteParams = onCompleteAllParams; 1937 vars.parent = this; 1938 new Tween(targets, vars, _parsePosition(this, position)); 1939 return this; 1940 }; 1941 1942 _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 1943 vars.runBackwards = 1; 1944 _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender); 1945 return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams); 1946 }; 1947 1948 _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) { 1949 toVars.startAt = fromVars; 1950 _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender); 1951 return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams); 1952 }; 1953 1954 _proto2.render = function render(totalTime, suppressEvents, force) { 1955 var prevTime = this._time, 1956 tDur = this._dirty ? this.totalDuration() : this._tDur, 1957 dur = this._dur, 1958 tTime = totalTime <= 0 ? 0 : _roundPrecise(totalTime), 1959 crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur), 1960 time, 1961 child, 1962 next, 1963 iteration, 1964 cycleDuration, 1965 prevPaused, 1966 pauseTween, 1967 timeScale, 1968 prevStart, 1969 prevIteration, 1970 yoyo, 1971 isYoyo; 1972 this !== _globalTimeline && tTime > tDur && totalTime >= 0 && (tTime = tDur); 1973 1974 if (tTime !== this._tTime || force || crossingStart) { 1975 if (prevTime !== this._time && dur) { 1976 tTime += this._time - prevTime; 1977 totalTime += this._time - prevTime; 1978 } 1979 1980 time = tTime; 1981 prevStart = this._start; 1982 timeScale = this._ts; 1983 prevPaused = !timeScale; 1984 1985 if (crossingStart) { 1986 dur || (prevTime = this._zTime); 1987 (totalTime || !suppressEvents) && (this._zTime = totalTime); 1988 } 1989 1990 if (this._repeat) { 1991 yoyo = this._yoyo; 1992 cycleDuration = dur + this._rDelay; 1993 1994 if (this._repeat < -1 && totalTime < 0) { 1995 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 1996 } 1997 1998 time = _roundPrecise(tTime % cycleDuration); 1999 2000 if (tTime === tDur) { 2001 iteration = this._repeat; 2002 time = dur; 2003 } else { 2004 iteration = ~~(tTime / cycleDuration); 2005 2006 if (iteration && iteration === tTime / cycleDuration) { 2007 time = dur; 2008 iteration--; 2009 } 2010 2011 time > dur && (time = dur); 2012 } 2013 2014 prevIteration = _animationCycle(this._tTime, cycleDuration); 2015 !prevTime && this._tTime && prevIteration !== iteration && (prevIteration = iteration); 2016 2017 if (yoyo && iteration & 1) { 2018 time = dur - time; 2019 isYoyo = 1; 2020 } 2021 2022 if (iteration !== prevIteration && !this._lock) { 2023 var rewinding = yoyo && prevIteration & 1, 2024 doesWrap = rewinding === (yoyo && iteration & 1); 2025 iteration < prevIteration && (rewinding = !rewinding); 2026 prevTime = rewinding ? 0 : dur; 2027 this._lock = 1; 2028 this.render(prevTime || (isYoyo ? 0 : _roundPrecise(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0; 2029 this._tTime = tTime; 2030 !suppressEvents && this.parent && _callback(this, "onRepeat"); 2031 this.vars.repeatRefresh && !isYoyo && (this.invalidate()._lock = 1); 2032 2033 if (prevTime && prevTime !== this._time || prevPaused !== !this._ts || this.vars.onRepeat && !this.parent && !this._act) { 2034 return this; 2035 } 2036 2037 dur = this._dur; 2038 tDur = this._tDur; 2039 2040 if (doesWrap) { 2041 this._lock = 2; 2042 prevTime = rewinding ? dur : -0.0001; 2043 this.render(prevTime, true); 2044 this.vars.repeatRefresh && !isYoyo && this.invalidate(); 2045 } 2046 2047 this._lock = 0; 2048 2049 if (!this._ts && !prevPaused) { 2050 return this; 2051 } 2052 2053 _propagateYoyoEase(this, isYoyo); 2054 } 2055 } 2056 2057 if (this._hasPause && !this._forcing && this._lock < 2) { 2058 pauseTween = _findNextPauseTween(this, _roundPrecise(prevTime), _roundPrecise(time)); 2059 2060 if (pauseTween) { 2061 tTime -= time - (time = pauseTween._start); 2062 } 2063 } 2064 2065 this._tTime = tTime; 2066 this._time = time; 2067 this._act = !timeScale; 2068 2069 if (!this._initted) {
vendor: 15,188 bytes, lines 2070-2602
2070 this._onUpdate = this.vars.onUpdate; 2071 this._initted = 1; 2072 this._zTime = totalTime; 2073 prevTime = 0; 2074 } 2075 2076 if (!prevTime && time && !suppressEvents) { 2077 _callback(this, "onStart"); 2078 2079 if (this._tTime !== tTime) { 2080 return this; 2081 } 2082 } 2083 2084 if (time >= prevTime && totalTime >= 0) { 2085 child = this._first; 2086 2087 while (child) { 2088 next = child._next; 2089 2090 if ((child._act || time >= child._start) && child._ts && pauseTween !== child) { 2091 if (child.parent !== this) { 2092 return this.render(totalTime, suppressEvents, force); 2093 } 2094 2095 child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force); 2096 2097 if (time !== this._time || !this._ts && !prevPaused) { 2098 pauseTween = 0; 2099 next && (tTime += this._zTime = -_tinyNum); 2100 break; 2101 } 2102 } 2103 2104 child = next; 2105 } 2106 } else { 2107 child = this._last; 2108 var adjustedTime = totalTime < 0 ? totalTime : time; 2109 2110 while (child) { 2111 next = child._prev; 2112 2113 if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) { 2114 if (child.parent !== this) { 2115 return this.render(totalTime, suppressEvents, force); 2116 } 2117 2118 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)); 2119 2120 if (time !== this._time || !this._ts && !prevPaused) { 2121 pauseTween = 0; 2122 next && (tTime += this._zTime = adjustedTime ? -_tinyNum : _tinyNum); 2123 break; 2124 } 2125 } 2126 2127 child = next; 2128 } 2129 } 2130 2131 if (pauseTween && !suppressEvents) { 2132 this.pause(); 2133 pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1; 2134 2135 if (this._ts) { 2136 this._start = prevStart; 2137 2138 _setEnd(this); 2139 2140 return this.render(totalTime, suppressEvents, force); 2141 } 2142 } 2143 2144 this._onUpdate && !suppressEvents && _callback(this, "onUpdate", true); 2145 if (tTime === tDur && this._tTime >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) { 2146 (totalTime || !dur) && (tTime === tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); 2147 2148 if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime || !tDur)) { 2149 _callback(this, tTime === tDur && totalTime >= 0 ? "onComplete" : "onReverseComplete", true); 2150 2151 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 2152 } 2153 } 2154 } 2155 2156 return this; 2157 }; 2158 2159 _proto2.add = function add(child, position) { 2160 var _this2 = this; 2161 2162 _isNumber(position) || (position = _parsePosition(this, position, child)); 2163 2164 if (!(child instanceof Animation)) { 2165 if (_isArray(child)) { 2166 child.forEach(function (obj) { 2167 return _this2.add(obj, position); 2168 }); 2169 return this; 2170 } 2171 2172 if (_isString(child)) { 2173 return this.addLabel(child, position); 2174 } 2175 2176 if (_isFunction(child)) { 2177 child = Tween.delayedCall(0, child); 2178 } else { 2179 return this; 2180 } 2181 } 2182 2183 return this !== child ? _addToTimeline(this, child, position) : this; 2184 }; 2185 2186 _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) { 2187 if (nested === void 0) { 2188 nested = true; 2189 } 2190 2191 if (tweens === void 0) { 2192 tweens = true; 2193 } 2194 2195 if (timelines === void 0) { 2196 timelines = true; 2197 } 2198 2199 if (ignoreBeforeTime === void 0) { 2200 ignoreBeforeTime = -_bigNum; 2201 } 2202 2203 var a = [], 2204 child = this._first; 2205 2206 while (child) { 2207 if (child._start >= ignoreBeforeTime) { 2208 if (child instanceof Tween) { 2209 tweens && a.push(child); 2210 } else { 2211 timelines && a.push(child); 2212 nested && a.push.apply(a, child.getChildren(true, tweens, timelines)); 2213 } 2214 } 2215 2216 child = child._next; 2217 } 2218 2219 return a; 2220 }; 2221 2222 _proto2.getById = function getById(id) { 2223 var animations = this.getChildren(1, 1, 1), 2224 i = animations.length; 2225 2226 while (i--) { 2227 if (animations[i].vars.id === id) { 2228 return animations[i]; 2229 } 2230 } 2231 }; 2232 2233 _proto2.remove = function remove(child) { 2234 if (_isString(child)) { 2235 return this.removeLabel(child); 2236 } 2237 2238 if (_isFunction(child)) { 2239 return this.killTweensOf(child); 2240 } 2241 2242 _removeLinkedListItem(this, child); 2243 2244 if (child === this._recent) { 2245 this._recent = this._last; 2246 } 2247 2248 return _uncache(this); 2249 }; 2250 2251 _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) { 2252 if (!arguments.length) { 2253 return this._tTime; 2254 } 2255 2256 this._forcing = 1; 2257 2258 if (!this._dp && this._ts) { 2259 this._start = _roundPrecise(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts)); 2260 } 2261 2262 _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents); 2263 2264 this._forcing = 0; 2265 return this; 2266 }; 2267 2268 _proto2.addLabel = function addLabel(label, position) { 2269 this.labels[label] = _parsePosition(this, position); 2270 return this; 2271 }; 2272 2273 _proto2.removeLabel = function removeLabel(label) { 2274 delete this.labels[label]; 2275 return this; 2276 }; 2277 2278 _proto2.addPause = function addPause(position, callback, params) { 2279 var t = Tween.delayedCall(0, callback || _emptyFunc, params); 2280 t.data = "isPause"; 2281 this._hasPause = 1; 2282 return _addToTimeline(this, t, _parsePosition(this, position)); 2283 }; 2284 2285 _proto2.removePause = function removePause(position) { 2286 var child = this._first; 2287 position = _parsePosition(this, position); 2288 2289 while (child) { 2290 if (child._start === position && child.data === "isPause") { 2291 _removeFromParent(child); 2292 } 2293 2294 child = child._next; 2295 } 2296 }; 2297 2298 _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) { 2299 var tweens = this.getTweensOf(targets, onlyActive), 2300 i = tweens.length; 2301 2302 while (i--) { 2303 _overwritingTween !== tweens[i] && tweens[i].kill(targets, props); 2304 } 2305 2306 return this; 2307 }; 2308 2309 _proto2.getTweensOf = function getTweensOf(targets, onlyActive) { 2310 var a = [], 2311 parsedTargets = toArray(targets), 2312 child = this._first, 2313 isGlobalTime = _isNumber(onlyActive), 2314 children; 2315 2316 while (child) { 2317 if (child instanceof Tween) { 2318 if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) { 2319 a.push(child); 2320 } 2321 } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) { 2322 a.push.apply(a, children); 2323 } 2324 2325 child = child._next; 2326 } 2327 2328 return a; 2329 }; 2330 2331 _proto2.tweenTo = function tweenTo(position, vars) { 2332 vars = vars || {}; 2333 2334 var tl = this, 2335 endTime = _parsePosition(tl, position), 2336 _vars = vars, 2337 startAt = _vars.startAt, 2338 _onStart = _vars.onStart, 2339 onStartParams = _vars.onStartParams, 2340 immediateRender = _vars.immediateRender, 2341 initted, 2342 tween = Tween.to(tl, _setDefaults({ 2343 ease: vars.ease || "none", 2344 lazy: false, 2345 immediateRender: false, 2346 time: endTime, 2347 overwrite: "auto", 2348 duration: vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum, 2349 onStart: function onStart() { 2350 tl.pause(); 2351 2352 if (!initted) { 2353 var duration = vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()); 2354 tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true); 2355 initted = 1; 2356 } 2357 2358 _onStart && _onStart.apply(tween, onStartParams || []); 2359 } 2360 }, vars)); 2361 2362 return immediateRender ? tween.render(0) : tween; 2363 }; 2364 2365 _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) { 2366 return this.tweenTo(toPosition, _setDefaults({ 2367 startAt: { 2368 time: _parsePosition(this, fromPosition) 2369 } 2370 }, vars)); 2371 }; 2372 2373 _proto2.recent = function recent() { 2374 return this._recent; 2375 }; 2376 2377 _proto2.nextLabel = function nextLabel(afterTime) { 2378 if (afterTime === void 0) { 2379 afterTime = this._time; 2380 } 2381 2382 return _getLabelInDirection(this, _parsePosition(this, afterTime)); 2383 }; 2384 2385 _proto2.previousLabel = function previousLabel(beforeTime) { 2386 if (beforeTime === void 0) { 2387 beforeTime = this._time; 2388 } 2389 2390 return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1); 2391 }; 2392 2393 _proto2.currentLabel = function currentLabel(value) { 2394 return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum); 2395 }; 2396 2397 _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) { 2398 if (ignoreBeforeTime === void 0) { 2399 ignoreBeforeTime = 0; 2400 } 2401 2402 var child = this._first, 2403 labels = this.labels, 2404 p; 2405 2406 while (child) { 2407 if (child._start >= ignoreBeforeTime) { 2408 child._start += amount; 2409 child._end += amount; 2410 } 2411 2412 child = child._next; 2413 } 2414 2415 if (adjustLabels) { 2416 for (p in labels) { 2417 if (labels[p] >= ignoreBeforeTime) { 2418 labels[p] += amount; 2419 } 2420 } 2421 } 2422 2423 return _uncache(this); 2424 }; 2425 2426 _proto2.invalidate = function invalidate(soft) { 2427 var child = this._first; 2428 this._lock = 0; 2429 2430 while (child) { 2431 child.invalidate(soft); 2432 child = child._next; 2433 } 2434 2435 return _Animation.prototype.invalidate.call(this, soft); 2436 }; 2437 2438 _proto2.clear = function clear(includeLabels) { 2439 if (includeLabels === void 0) { 2440 includeLabels = true; 2441 } 2442 2443 var child = this._first, 2444 next; 2445 2446 while (child) { 2447 next = child._next; 2448 this.remove(child); 2449 child = next; 2450 } 2451 2452 this._dp && (this._time = this._tTime = this._pTime = 0); 2453 includeLabels && (this.labels = {}); 2454 return _uncache(this); 2455 }; 2456 2457 _proto2.totalDuration = function totalDuration(value) { 2458 var max = 0, 2459 self = this, 2460 child = self._last, 2461 prevStart = _bigNum, 2462 prev, 2463 start, 2464 parent; 2465 2466 if (arguments.length) { 2467 return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value)); 2468 } 2469 2470 if (self._dirty) { 2471 parent = self.parent; 2472 2473 while (child) { 2474 prev = child._prev; 2475 child._dirty && child.totalDuration(); 2476 start = child._start; 2477 2478 if (start > prevStart && self._sort && child._ts && !self._lock) { 2479 self._lock = 1; 2480 _addToTimeline(self, child, start - child._delay, 1)._lock = 0; 2481 } else { 2482 prevStart = start; 2483 } 2484 2485 if (start < 0 && child._ts) { 2486 max -= start; 2487 2488 if (!parent && !self._dp || parent && parent.smoothChildTiming) { 2489 self._start += start / self._ts; 2490 self._time -= start; 2491 self._tTime -= start; 2492 } 2493 2494 self.shiftChildren(-start, false, -1e999); 2495 prevStart = 0; 2496 } 2497 2498 child._end > max && child._ts && (max = child._end); 2499 child = prev; 2500 } 2501 2502 _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1); 2503 2504 self._dirty = 0; 2505 } 2506 2507 return self._tDur; 2508 }; 2509 2510 Timeline.updateRoot = function updateRoot(time) { 2511 if (_globalTimeline._ts) { 2512 _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline)); 2513 2514 _lastRenderedFrame = _ticker.frame; 2515 } 2516 2517 if (_ticker.frame >= _nextGCFrame) { 2518 _nextGCFrame += _config.autoSleep || 120; 2519 var child = _globalTimeline._first; 2520 if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) { 2521 while (child && !child._ts) { 2522 child = child._next; 2523 } 2524 2525 child || _ticker.sleep(); 2526 } 2527 } 2528 }; 2529 2530 return Timeline; 2531 }(Animation); 2532 2533 _setDefaults(Timeline.prototype, { 2534 _lock: 0, 2535 _hasPause: 0, 2536 _forcing: 0 2537 }); 2538 2539 var _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) { 2540 var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter), 2541 index = 0, 2542 matchIndex = 0, 2543 result, 2544 startNums, 2545 color, 2546 endNum, 2547 chunk, 2548 startNum, 2549 hasRandom, 2550 a; 2551 pt.b = start; 2552 pt.e = end; 2553 start += ""; 2554 end += ""; 2555 2556 if (hasRandom = ~end.indexOf("random(")) { 2557 end = _replaceRandom(end); 2558 } 2559 2560 if (stringFilter) { 2561 a = [start, end]; 2562 stringFilter(a, target, prop); 2563 start = a[0]; 2564 end = a[1]; 2565 } 2566 2567 startNums = start.match(_complexStringNumExp) || []; 2568 2569 while (result = _complexStringNumExp.exec(end)) { 2570 endNum = result[0]; 2571 chunk = end.substring(index, result.index); 2572 2573 if (color) { 2574 color = (color + 1) % 5; 2575 } else if (chunk.substr(-5) === "rgba(") { 2576 color = 1; 2577 } 2578 2579 if (endNum !== startNums[matchIndex++]) { 2580 startNum = parseFloat(startNums[matchIndex - 1]) || 0; 2581 pt._pt = { 2582 _next: pt._pt, 2583 p: chunk || matchIndex === 1 ? chunk : ",", 2584 s: startNum, 2585 c: endNum.charAt(1) === "=" ? _parseRelative(startNum, endNum) - startNum : parseFloat(endNum) - startNum, 2586 m: color && color < 4 ? Math.round : 0 2587 }; 2588 index = _complexStringNumExp.lastIndex; 2589 } 2590 } 2591 2592 pt.c = index < end.length ? end.substring(index, end.length) : ""; 2593 pt.fp = funcParam; 2594 2595 if (_relExp.test(end) || hasRandom) { 2596 pt.e = 0; 2597 } 2598 2599 this._pt = pt; 2600 return pt; 2601 }, 2602 _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam, optional) {
vendor: 9,749 bytes, lines 2603-2889
2603 _isFunction(end) && (end = end(index || 0, target, targets)); 2604 var currentValue = target[prop], 2605 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](), 2606 setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc, 2607 pt; 2608 2609 if (_isString(end)) { 2610 if (~end.indexOf("random(")) { 2611 end = _replaceRandom(end); 2612 } 2613 2614 if (end.charAt(1) === "=") { 2615 pt = _parseRelative(parsedStart, end) + (getUnit(parsedStart) || 0); 2616 2617 if (pt || pt === 0) { 2618 end = pt; 2619 } 2620 } 2621 } 2622 2623 if (!optional || parsedStart !== end || _forceAllPropTweens) { 2624 if (!isNaN(parsedStart * end) && end !== "") { 2625 pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === "boolean" ? _renderBoolean : _renderPlain, 0, setter); 2626 funcParam && (pt.fp = funcParam); 2627 modifier && pt.modifier(modifier, this, target); 2628 return this._pt = pt; 2629 } 2630 2631 !currentValue && !(prop in target) && _missingPlugin(prop, end); 2632 return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam); 2633 } 2634 }, 2635 _processVars = function _processVars(vars, index, target, targets, tween) { 2636 _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets)); 2637 2638 if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) { 2639 return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars; 2640 } 2641 2642 var copy = {}, 2643 p; 2644 2645 for (p in vars) { 2646 copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets); 2647 } 2648 2649 return copy; 2650 }, 2651 _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) { 2652 var plugin, pt, ptLookup, i; 2653 2654 if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) { 2655 tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority); 2656 2657 if (tween !== _quickTween) { 2658 ptLookup = tween._ptLookup[tween._targets.indexOf(target)]; 2659 i = plugin._props.length; 2660 2661 while (i--) { 2662 ptLookup[plugin._props[i]] = pt; 2663 } 2664 } 2665 } 2666 2667 return plugin; 2668 }, 2669 _overwritingTween, 2670 _forceAllPropTweens, 2671 _initTween = function _initTween(tween, time, tTime) { 2672 var vars = tween.vars, 2673 ease = vars.ease, 2674 startAt = vars.startAt, 2675 immediateRender = vars.immediateRender, 2676 lazy = vars.lazy, 2677 onUpdate = vars.onUpdate, 2678 onUpdateParams = vars.onUpdateParams, 2679 callbackScope = vars.callbackScope, 2680 runBackwards = vars.runBackwards, 2681 yoyoEase = vars.yoyoEase, 2682 keyframes = vars.keyframes, 2683 autoRevert = vars.autoRevert, 2684 dur = tween._dur, 2685 prevStartAt = tween._startAt, 2686 targets = tween._targets, 2687 parent = tween.parent, 2688 fullTargets = parent && parent.data === "nested" ? parent.vars.targets : targets, 2689 autoOverwrite = tween._overwrite === "auto" && !_suppressOverwrites, 2690 tl = tween.timeline, 2691 cleanVars, 2692 i, 2693 p, 2694 pt, 2695 target, 2696 hasPriority, 2697 gsData, 2698 harness, 2699 plugin, 2700 ptLookup, 2701 index, 2702 harnessVars, 2703 overwritten; 2704 tl && (!keyframes || !ease) && (ease = "none"); 2705 tween._ease = _parseEase(ease, _defaults.ease); 2706 tween._yEase = yoyoEase ? _invertEase(_parseEase(yoyoEase === true ? ease : yoyoEase, _defaults.ease)) : 0; 2707 2708 if (yoyoEase && tween._yoyo && !tween._repeat) { 2709 yoyoEase = tween._yEase; 2710 tween._yEase = tween._ease; 2711 tween._ease = yoyoEase; 2712 } 2713 2714 tween._from = !tl && !!vars.runBackwards; 2715 2716 if (!tl || keyframes && !vars.stagger) { 2717 harness = targets[0] ? _getCache(targets[0]).harness : 0; 2718 harnessVars = harness && vars[harness.prop]; 2719 cleanVars = _copyExcluding(vars, _reservedProps); 2720 2721 if (prevStartAt) { 2722 prevStartAt._zTime < 0 && prevStartAt.progress(1); 2723 time < 0 && runBackwards && immediateRender && !autoRevert ? prevStartAt.render(-1, true) : prevStartAt.revert(runBackwards && dur ? _revertConfigNoKill : _startAtRevertConfig); 2724 prevStartAt._lazy = 0; 2725 } 2726 2727 if (startAt) { 2728 _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({ 2729 data: "isStart", 2730 overwrite: false, 2731 parent: parent, 2732 immediateRender: true, 2733 lazy: _isNotFalse(lazy), 2734 startAt: null, 2735 delay: 0, 2736 onUpdate: onUpdate, 2737 onUpdateParams: onUpdateParams, 2738 callbackScope: callbackScope, 2739 stagger: 0 2740 }, startAt))); 2741 2742 tween._startAt._dp = 0; 2743 time < 0 && (_reverting || !immediateRender && !autoRevert) && tween._startAt.revert(_revertConfigNoKill); 2744 2745 if (immediateRender) { 2746 if (dur && time <= 0 && tTime <= 0) { 2747 time && (tween._zTime = time); 2748 return; 2749 } 2750 } 2751 } else if (runBackwards && dur) { 2752 if (!prevStartAt) { 2753 time && (immediateRender = false); 2754 p = _setDefaults({ 2755 overwrite: false, 2756 data: "isFromStart", 2757 lazy: immediateRender && _isNotFalse(lazy), 2758 immediateRender: immediateRender, 2759 stagger: 0, 2760 parent: parent 2761 }, cleanVars); 2762 harnessVars && (p[harness.prop] = harnessVars); 2763 2764 _removeFromParent(tween._startAt = Tween.set(targets, p)); 2765 2766 tween._startAt._dp = 0; 2767 time < 0 && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween._startAt.render(-1, true)); 2768 tween._zTime = time; 2769 2770 if (!immediateRender) { 2771 _initTween(tween._startAt, _tinyNum, _tinyNum); 2772 } else if (!time) { 2773 return; 2774 } 2775 } 2776 } 2777 2778 tween._pt = tween._ptCache = 0; 2779 lazy = dur && _isNotFalse(lazy) || lazy && !dur; 2780 2781 for (i = 0; i < targets.length; i++) { 2782 target = targets[i]; 2783 gsData = target._gsap || _harness(targets)[i]._gsap; 2784 tween._ptLookup[i] = ptLookup = {}; 2785 _lazyLookup[gsData.id] && _lazyTweens.length && _lazyRender(); 2786 index = fullTargets === targets ? i : fullTargets.indexOf(target); 2787 2788 if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) { 2789 tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority); 2790 2791 plugin._props.forEach(function (name) { 2792 ptLookup[name] = pt; 2793 }); 2794 2795 plugin.priority && (hasPriority = 1); 2796 } 2797 2798 if (!harness || harnessVars) { 2799 for (p in cleanVars) { 2800 if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) { 2801 plugin.priority && (hasPriority = 1); 2802 } else { 2803 ptLookup[p] = pt = _addPropTween.call(tween, target, p, "get", cleanVars[p], index, fullTargets, 0, vars.stringFilter); 2804 } 2805 } 2806 } 2807 2808 tween._op && tween._op[i] && tween.kill(target, tween._op[i]); 2809 2810 if (autoOverwrite && tween._pt) { 2811 _overwritingTween = tween; 2812 2813 _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(time)); 2814 2815 overwritten = !tween.parent; 2816 _overwritingTween = 0; 2817 } 2818 2819 tween._pt && lazy && (_lazyLookup[gsData.id] = 1); 2820 } 2821 2822 hasPriority && _sortPropTweensByPriority(tween); 2823 tween._onInit && tween._onInit(tween); 2824 } 2825 2826 tween._onUpdate = onUpdate; 2827 tween._initted = (!tween._op || tween._pt) && !overwritten; 2828 keyframes && time <= 0 && tl.render(_bigNum, true, true); 2829 }, 2830 _updatePropTweens = function _updatePropTweens(tween, property, value, start, startIsRelative, ratio, time) { 2831 var ptCache = (tween._pt && tween._ptCache || (tween._ptCache = {}))[property], 2832 pt, 2833 rootPT, 2834 lookup, 2835 i; 2836 2837 if (!ptCache) { 2838 ptCache = tween._ptCache[property] = []; 2839 lookup = tween._ptLookup; 2840 i = tween._targets.length; 2841 2842 while (i--) { 2843 pt = lookup[i][property]; 2844 2845 if (pt && pt.d && pt.d._pt) { 2846 pt = pt.d._pt; 2847 2848 while (pt && pt.p !== property && pt.fp !== property) { 2849 pt = pt._next; 2850 } 2851 } 2852 2853 if (!pt) { 2854 _forceAllPropTweens = 1; 2855 tween.vars[property] = "+=0"; 2856 2857 _initTween(tween, time); 2858 2859 _forceAllPropTweens = 0; 2860 return 1; 2861 } 2862 2863 ptCache.push(pt); 2864 } 2865 } 2866 2867 i = ptCache.length; 2868 2869 while (i--) { 2870 rootPT = ptCache[i]; 2871 pt = rootPT._pt || rootPT; 2872 pt.s = (start || start === 0) && !startIsRelative ? start : pt.s + (start || 0) + ratio * pt.c; 2873 pt.c = value - pt.s; 2874 rootPT.e && (rootPT.e = _round(value) + getUnit(rootPT.e)); 2875 rootPT.b && (rootPT.b = pt.s + getUnit(rootPT.b)); 2876 } 2877 }, 2878 _addAliasesToVars = function _addAliasesToVars(targets, vars) { 2879 var harness = targets[0] ? _getCache(targets[0]).harness : 0, 2880 propertyAliases = harness && harness.aliases, 2881 copy, 2882 p, 2883 i, 2884 aliases; 2885 2886 if (!propertyAliases) { 2887 return vars; 2888 } 2889
vendor: 4,989 bytes, lines 2890-3032
2890 copy = _merge({}, vars); 2891 2892 for (p in propertyAliases) { 2893 if (p in copy) { 2894 aliases = propertyAliases[p].split(","); 2895 i = aliases.length; 2896 2897 while (i--) { 2898 copy[aliases[i]] = copy[p]; 2899 } 2900 } 2901 } 2902 2903 return copy; 2904 }, 2905 _parseKeyframe = function _parseKeyframe(prop, obj, allProps, easeEach) { 2906 var ease = obj.ease || easeEach || "power1.inOut", 2907 p, 2908 a; 2909 2910 if (_isArray(obj)) { 2911 a = allProps[prop] || (allProps[prop] = []); 2912 obj.forEach(function (value, i) { 2913 return a.push({ 2914 t: i / (obj.length - 1) * 100, 2915 v: value, 2916 e: ease 2917 }); 2918 }); 2919 } else { 2920 for (p in obj) { 2921 a = allProps[p] || (allProps[p] = []); 2922 p === "ease" || a.push({ 2923 t: parseFloat(prop), 2924 v: obj[p], 2925 e: ease 2926 }); 2927 } 2928 } 2929 }, 2930 _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) { 2931 return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf("random(") ? _replaceRandom(value) : value; 2932 }, 2933 _staggerTweenProps = _callbackNames + "repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,autoRevert", 2934 _staggerPropsToSkip = {}; 2935 2936 _forEachName(_staggerTweenProps + ",id,stagger,delay,duration,paused,scrollTrigger", function (name) { 2937 return _staggerPropsToSkip[name] = 1; 2938 }); 2939 2940 var Tween = function (_Animation2) { 2941 _inheritsLoose(Tween, _Animation2); 2942 2943 function Tween(targets, vars, position, skipInherit) { 2944 var _this3; 2945 2946 if (typeof vars === "number") { 2947 position.duration = vars; 2948 vars = position; 2949 position = null; 2950 } 2951 2952 _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars)) || this; 2953 var _this3$vars = _this3.vars, 2954 duration = _this3$vars.duration, 2955 delay = _this3$vars.delay, 2956 immediateRender = _this3$vars.immediateRender, 2957 stagger = _this3$vars.stagger, 2958 overwrite = _this3$vars.overwrite, 2959 keyframes = _this3$vars.keyframes, 2960 defaults = _this3$vars.defaults, 2961 scrollTrigger = _this3$vars.scrollTrigger, 2962 yoyoEase = _this3$vars.yoyoEase, 2963 parent = vars.parent || _globalTimeline, 2964 parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : "length" in vars) ? [targets] : toArray(targets), 2965 tl, 2966 i, 2967 copy, 2968 l, 2969 p, 2970 curTarget, 2971 staggerFunc, 2972 staggerVarsToMerge; 2973 _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn("GSAP target " + targets + " not found. https://greensock.com", !_config.nullTargetWarn) || []; 2974 _this3._ptLookup = []; 2975 _this3._overwrite = overwrite; 2976 2977 if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) { 2978 vars = _this3.vars; 2979 tl = _this3.timeline = new Timeline({ 2980 data: "nested", 2981 defaults: defaults || {}, 2982 targets: parent && parent.data === "nested" ? parent.vars.targets : parsedTargets 2983 }); 2984 tl.kill(); 2985 tl.parent = tl._dp = _assertThisInitialized(_this3); 2986 tl._start = 0; 2987 2988 if (stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) { 2989 l = parsedTargets.length; 2990 staggerFunc = stagger && distribute(stagger); 2991 2992 if (_isObject(stagger)) { 2993 for (p in stagger) { 2994 if (~_staggerTweenProps.indexOf(p)) { 2995 staggerVarsToMerge || (staggerVarsToMerge = {}); 2996 staggerVarsToMerge[p] = stagger[p]; 2997 } 2998 } 2999 } 3000 3001 for (i = 0; i < l; i++) { 3002 copy = _copyExcluding(vars, _staggerPropsToSkip); 3003 copy.stagger = 0; 3004 yoyoEase && (copy.yoyoEase = yoyoEase); 3005 staggerVarsToMerge && _merge(copy, staggerVarsToMerge); 3006 curTarget = parsedTargets[i]; 3007 copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets); 3008 copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay; 3009 3010 if (!stagger && l === 1 && copy.delay) { 3011 _this3._delay = delay = copy.delay; 3012 _this3._start += delay; 3013 copy.delay = 0; 3014 } 3015 3016 tl.to(curTarget, copy, staggerFunc ? staggerFunc(i, curTarget, parsedTargets) : 0); 3017 tl._ease = _easeMap.none; 3018 } 3019 3020 tl.duration() ? duration = delay = 0 : _this3.timeline = 0; 3021 } else if (keyframes) { 3022 _inheritDefaults(_setDefaults(tl.vars.defaults, { 3023 ease: "none" 3024 })); 3025 3026 tl._ease = _parseEase(keyframes.ease || vars.ease || "none"); 3027 var time = 0, 3028 a, 3029 kf, 3030 v; 3031 3032 if (_isArray(keyframes)) {
vendor: 6,328 bytes, lines 3033-3239
3033 keyframes.forEach(function (frame) { 3034 return tl.to(parsedTargets, frame, ">"); 3035 }); 3036 tl.duration(); 3037 } else { 3038 copy = {}; 3039 3040 for (p in keyframes) { 3041 p === "ease" || p === "easeEach" || _parseKeyframe(p, keyframes[p], copy, keyframes.easeEach); 3042 } 3043 3044 for (p in copy) { 3045 a = copy[p].sort(function (a, b) { 3046 return a.t - b.t; 3047 }); 3048 time = 0; 3049 3050 for (i = 0; i < a.length; i++) { 3051 kf = a[i]; 3052 v = { 3053 ease: kf.e, 3054 duration: (kf.t - (i ? a[i - 1].t : 0)) / 100 * duration 3055 }; 3056 v[p] = kf.v; 3057 tl.to(parsedTargets, v, time); 3058 time += v.duration; 3059 } 3060 } 3061 3062 tl.duration() < duration && tl.to({}, { 3063 duration: duration - tl.duration() 3064 }); 3065 } 3066 } 3067 3068 duration || _this3.duration(duration = tl.duration()); 3069 } else { 3070 _this3.timeline = 0; 3071 } 3072 3073 if (overwrite === true && !_suppressOverwrites) { 3074 _overwritingTween = _assertThisInitialized(_this3); 3075 3076 _globalTimeline.killTweensOf(parsedTargets); 3077 3078 _overwritingTween = 0; 3079 } 3080 3081 _addToTimeline(parent, _assertThisInitialized(_this3), position); 3082 3083 vars.reversed && _this3.reverse(); 3084 vars.paused && _this3.paused(true); 3085 3086 if (immediateRender || !duration && !keyframes && _this3._start === _roundPrecise(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== "nested") { 3087 _this3._tTime = -_tinyNum; 3088 3089 _this3.render(Math.max(0, -delay) || 0); 3090 } 3091 3092 scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger); 3093 return _this3; 3094 } 3095 3096 var _proto3 = Tween.prototype; 3097 3098 _proto3.render = function render(totalTime, suppressEvents, force) { 3099 var prevTime = this._time, 3100 tDur = this._tDur, 3101 dur = this._dur, 3102 isNegative = totalTime < 0, 3103 tTime = totalTime > tDur - _tinyNum && !isNegative ? tDur : totalTime < _tinyNum ? 0 : totalTime, 3104 time, 3105 pt, 3106 iteration, 3107 cycleDuration, 3108 prevIteration, 3109 isYoyo, 3110 ratio, 3111 timeline, 3112 yoyoEase; 3113 3114 if (!dur) { 3115 _renderZeroDurationTween(this, totalTime, suppressEvents, force); 3116 } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== isNegative) { 3117 time = tTime; 3118 timeline = this.timeline; 3119 3120 if (this._repeat) { 3121 cycleDuration = dur + this._rDelay; 3122 3123 if (this._repeat < -1 && isNegative) { 3124 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 3125 } 3126 3127 time = _roundPrecise(tTime % cycleDuration); 3128 3129 if (tTime === tDur) { 3130 iteration = this._repeat; 3131 time = dur; 3132 } else { 3133 iteration = ~~(tTime / cycleDuration); 3134 3135 if (iteration && iteration === tTime / cycleDuration) { 3136 time = dur; 3137 iteration--; 3138 } 3139 3140 time > dur && (time = dur); 3141 } 3142 3143 isYoyo = this._yoyo && iteration & 1; 3144 3145 if (isYoyo) { 3146 yoyoEase = this._yEase; 3147 time = dur - time; 3148 } 3149 3150 prevIteration = _animationCycle(this._tTime, cycleDuration); 3151 3152 if (time === prevTime && !force && this._initted) { 3153 this._tTime = tTime; 3154 return this; 3155 } 3156 3157 if (iteration !== prevIteration) { 3158 timeline && this._yEase && _propagateYoyoEase(timeline, isYoyo); 3159 3160 if (this.vars.repeatRefresh && !isYoyo && !this._lock) { 3161 this._lock = force = 1; 3162 this.render(_roundPrecise(cycleDuration * iteration), true).invalidate()._lock = 0; 3163 } 3164 } 3165 } 3166 3167 if (!this._initted) { 3168 if (_attemptInitTween(this, isNegative ? totalTime : time, force, suppressEvents, tTime)) { 3169 this._tTime = 0; 3170 return this; 3171 } 3172 3173 if (prevTime !== this._time) { 3174 return this; 3175 } 3176 3177 if (dur !== this._dur) { 3178 return this.render(totalTime, suppressEvents, force); 3179 } 3180 } 3181 3182 this._tTime = tTime; 3183 this._time = time; 3184 3185 if (!this._act && this._ts) { 3186 this._act = 1; 3187 this._lazy = 0; 3188 } 3189 3190 this.ratio = ratio = (yoyoEase || this._ease)(time / dur); 3191 3192 if (this._from) { 3193 this.ratio = ratio = 1 - ratio; 3194 } 3195 3196 if (time && !prevTime && !suppressEvents) { 3197 _callback(this, "onStart"); 3198 3199 if (this._tTime !== tTime) { 3200 return this; 3201 } 3202 } 3203 3204 pt = this._pt; 3205 3206 while (pt) { 3207 pt.r(ratio, pt.d); 3208 pt = pt._next; 3209 } 3210 3211 timeline && timeline.render(totalTime < 0 ? totalTime : !time && isYoyo ? -_tinyNum : timeline._dur * timeline._ease(time / this._dur), suppressEvents, force) || this._startAt && (this._zTime = totalTime); 3212 3213 if (this._onUpdate && !suppressEvents) { 3214 isNegative && _rewindStartAt(this, totalTime, suppressEvents, force); 3215 3216 _callback(this, "onUpdate"); 3217 } 3218 3219 this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, "onRepeat"); 3220 3221 if ((tTime === this._tDur || !tTime) && this._tTime === tTime) { 3222 isNegative && !this._onUpdate && _rewindStartAt(this, totalTime, true, true); 3223 (totalTime || !dur) && (tTime === this._tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); 3224 3225 if (!suppressEvents && !(isNegative && !prevTime) && (tTime || prevTime || isYoyo)) { 3226 _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true); 3227 3228 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 3229 } 3230 } 3231 } 3232 3233 return this; 3234 }; 3235 3236 _proto3.targets = function targets() { 3237 return this._targets; 3238 }; 3239
vendor: 1,277 bytes, lines 3240-3273
3240 _proto3.invalidate = function invalidate(soft) { 3241 (!soft || !this.vars.runBackwards) && (this._startAt = 0); 3242 this._pt = this._op = this._onUpdate = this._lazy = this.ratio = 0; 3243 this._ptLookup = []; 3244 this.timeline && this.timeline.invalidate(soft); 3245 return _Animation2.prototype.invalidate.call(this, soft); 3246 }; 3247 3248 _proto3.resetTo = function resetTo(property, value, start, startIsRelative) { 3249 _tickerActive || _ticker.wake(); 3250 this._ts || this.play(); 3251 var time = Math.min(this._dur, (this._dp._time - this._start) * this._ts), 3252 ratio; 3253 this._initted || _initTween(this, time); 3254 ratio = this._ease(time / this._dur); 3255 3256 if (_updatePropTweens(this, property, value, start, startIsRelative, ratio, time)) { 3257 return this.resetTo(property, value, start, startIsRelative); 3258 } 3259 3260 _alignPlayhead(this, 0); 3261 3262 this.parent || _addLinkedListItem(this._dp, this, "_first", "_last", this._dp._sort ? "_start" : 0); 3263 return this.render(0); 3264 }; 3265 3266 _proto3.kill = function kill(targets, vars) { 3267 if (vars === void 0) { 3268 vars = "all"; 3269 } 3270 3271 if (!targets && (!vars || vars === "all")) { 3272 this._lazy = this._pt = 0; 3273 return this.parent ? _interrupt(this) :
vendor: 7,709 bytes, lines 3273-3553
3273 this; 3274 } 3275 3276 if (this.timeline) { 3277 var tDur = this.timeline.totalDuration(); 3278 this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this); 3279 this.parent && tDur !== this.timeline.totalDuration() && _setDuration(this, this._dur * this.timeline._tDur / tDur, 0, 1); 3280 return this; 3281 } 3282 3283 var parsedTargets = this._targets, 3284 killingTargets = targets ? toArray(targets) : parsedTargets, 3285 propTweenLookup = this._ptLookup, 3286 firstPT = this._pt, 3287 overwrittenProps, 3288 curLookup, 3289 curOverwriteProps, 3290 props, 3291 p, 3292 pt, 3293 i; 3294 3295 if ((!vars || vars === "all") && _arraysMatch(parsedTargets, killingTargets)) { 3296 vars === "all" && (this._pt = 0); 3297 return _interrupt(this); 3298 } 3299 3300 overwrittenProps = this._op = this._op || []; 3301 3302 if (vars !== "all") { 3303 if (_isString(vars)) { 3304 p = {}; 3305 3306 _forEachName(vars, function (name) { 3307 return p[name] = 1; 3308 }); 3309 3310 vars = p; 3311 } 3312 3313 vars = _addAliasesToVars(parsedTargets, vars); 3314 } 3315 3316 i = parsedTargets.length; 3317 3318 while (i--) { 3319 if (~killingTargets.indexOf(parsedTargets[i])) { 3320 curLookup = propTweenLookup[i]; 3321 3322 if (vars === "all") { 3323 overwrittenProps[i] = vars; 3324 props = curLookup; 3325 curOverwriteProps = {}; 3326 } else { 3327 curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {}; 3328 props = vars; 3329 } 3330 3331 for (p in props) { 3332 pt = curLookup && curLookup[p]; 3333 3334 if (pt) { 3335 if (!("kill" in pt.d) || pt.d.kill(p) === true) { 3336 _removeLinkedListItem(this, pt, "_pt"); 3337 } 3338 3339 delete curLookup[p]; 3340 } 3341 3342 if (curOverwriteProps !== "all") { 3343 curOverwriteProps[p] = 1; 3344 } 3345 } 3346 } 3347 } 3348 3349 this._initted && !this._pt && firstPT && _interrupt(this); 3350 return this; 3351 }; 3352 3353 Tween.to = function to(targets, vars) { 3354 return new Tween(targets, vars, arguments[2]); 3355 }; 3356 3357 Tween.from = function from(targets, vars) { 3358 return _createTweenType(1, arguments); 3359 }; 3360 3361 Tween.delayedCall = function delayedCall(delay, callback, params, scope) { 3362 return new Tween(callback, 0, { 3363 immediateRender: false, 3364 lazy: false, 3365 overwrite: false, 3366 delay: delay, 3367 onComplete: callback, 3368 onReverseComplete: callback, 3369 onCompleteParams: params, 3370 onReverseCompleteParams: params, 3371 callbackScope: scope 3372 }); 3373 }; 3374 3375 Tween.fromTo = function fromTo(targets, fromVars, toVars) { 3376 return _createTweenType(2, arguments); 3377 }; 3378 3379 Tween.set = function set(targets, vars) { 3380 vars.duration = 0; 3381 vars.repeatDelay || (vars.repeat = 0); 3382 return new Tween(targets, vars); 3383 }; 3384 3385 Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) { 3386 return _globalTimeline.killTweensOf(targets, props, onlyActive); 3387 }; 3388 3389 return Tween; 3390 }(Animation); 3391 3392 _setDefaults(Tween.prototype, { 3393 _targets: [], 3394 _lazy: 0, 3395 _startAt: 0, 3396 _op: 0, 3397 _onInit: 0 3398 }); 3399 3400 _forEachName("staggerTo,staggerFrom,staggerFromTo", function (name) { 3401 Tween[name] = function () { 3402 var tl = new Timeline(), 3403 params = _slice.call(arguments, 0); 3404 3405 params.splice(name === "staggerFromTo" ? 5 : 4, 0, 0); 3406 return tl[name].apply(tl, params); 3407 }; 3408 }); 3409 3410 var _setterPlain = function _setterPlain(target, property, value) { 3411 return target[property] = value; 3412 }, 3413 _setterFunc = function _setterFunc(target, property, value) { 3414 return target[property](value); 3415 }, 3416 _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) { 3417 return target[property](data.fp, value); 3418 }, 3419 _setterAttribute = function _setterAttribute(target, property, value) { 3420 return target.setAttribute(property, value); 3421 }, 3422 _getSetter = function _getSetter(target, property) { 3423 return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain; 3424 }, 3425 _renderPlain = function _renderPlain(ratio, data) { 3426 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 1000000) / 1000000, data); 3427 }, 3428 _renderBoolean = function _renderBoolean(ratio, data) { 3429 return data.set(data.t, data.p, !!(data.s + data.c * ratio), data); 3430 }, 3431 _renderComplexString = function _renderComplexString(ratio, data) { 3432 var pt = data._pt, 3433 s = ""; 3434 3435 if (!ratio && data.b) { 3436 s = data.b; 3437 } else if (ratio === 1 && data.e) { 3438 s = data.e; 3439 } else { 3440 while (pt) { 3441 s = pt.p + (pt.m ? pt.m(pt.s + pt.c * ratio) : Math.round((pt.s + pt.c * ratio) * 10000) / 10000) + s; 3442 pt = pt._next; 3443 } 3444 3445 s += data.c; 3446 } 3447 3448 data.set(data.t, data.p, s, data); 3449 }, 3450 _renderPropTweens = function _renderPropTweens(ratio, data) { 3451 var pt = data._pt; 3452 3453 while (pt) { 3454 pt.r(ratio, pt.d); 3455 pt = pt._next; 3456 } 3457 }, 3458 _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) { 3459 var pt = this._pt, 3460 next; 3461 3462 while (pt) { 3463 next = pt._next; 3464 pt.p === property && pt.modifier(modifier, tween, target); 3465 pt = next; 3466 } 3467 }, 3468 _killPropTweensOf = function _killPropTweensOf(property) { 3469 var pt = this._pt, 3470 hasNonDependentRemaining, 3471 next; 3472 3473 while (pt) { 3474 next = pt._next; 3475 3476 if (pt.p === property && !pt.op || pt.op === property) { 3477 _removeLinkedListItem(this, pt, "_pt"); 3478 } else if (!pt.dep) { 3479 hasNonDependentRemaining = 1; 3480 } 3481 3482 pt = next; 3483 } 3484 3485 return !hasNonDependentRemaining; 3486 }, 3487 _setterWithModifier = function _setterWithModifier(target, property, value, data) { 3488 data.mSet(target, property, data.m.call(data.tween, value, data.mt), data); 3489 }, 3490 _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) { 3491 var pt = parent._pt, 3492 next, 3493 pt2, 3494 first, 3495 last; 3496 3497 while (pt) { 3498 next = pt._next; 3499 pt2 = first; 3500 3501 while (pt2 && pt2.pr > pt.pr) { 3502 pt2 = pt2._next; 3503 } 3504 3505 if (pt._prev = pt2 ? pt2._prev : last) { 3506 pt._prev._next = pt; 3507 } else { 3508 first = pt; 3509 } 3510 3511 if (pt._next = pt2) { 3512 pt2._prev = pt; 3513 } else { 3514 last = pt; 3515 } 3516 3517 pt = next; 3518 } 3519 3520 parent._pt = first; 3521 }; 3522 3523 var PropTween = function () { 3524 function PropTween(next, target, prop, start, change, renderer, data, setter, priority) { 3525 this.t = target; 3526 this.s = start; 3527 this.c = change; 3528 this.p = prop; 3529 this.r = renderer || _renderPlain; 3530 this.d = data || this; 3531 this.set = setter || _setterPlain; 3532 this.pr = priority || 0; 3533 this._next = next; 3534 3535 if (next) { 3536 next._prev = this; 3537 } 3538 } 3539 3540 var _proto4 = PropTween.prototype; 3541 3542 _proto4.modifier = function modifier(func, tween, target) { 3543 this.mSet = this.mSet || this.set; 3544 this.set = _setterWithModifier; 3545 this.m = func; 3546 this.mt = target; 3547 this.tween = tween; 3548 }; 3549 3550 return PropTween; 3551 }(); 3552 3553 _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
vendor: 3,674 bytes, lines 3553-3696
3553", function (name) { 3554 return _reservedProps[name] = 1; 3555 }); 3556 3557 _globals.TweenMax = _globals.TweenLite = Tween; 3558 _globals.TimelineLite = _globals.TimelineMax = Timeline; 3559 _globalTimeline = new Timeline({ 3560 sortChildren: false, 3561 defaults: _defaults, 3562 autoRemoveChildren: true, 3563 id: "root", 3564 smoothChildTiming: true 3565 }); 3566 _config.stringFilter = _colorStringFilter; 3567 3568 var _media = [], 3569 _listeners = {}, 3570 _emptyArray = [], 3571 _lastMediaTime = 0, 3572 _dispatch = function _dispatch(type) { 3573 return (_listeners[type] || _emptyArray).map(function (f) { 3574 return f(); 3575 }); 3576 }, 3577 _onMediaChange = function _onMediaChange() { 3578 var time = Date.now(), 3579 matches = []; 3580 3581 if (time - _lastMediaTime > 2) { 3582 _dispatch("matchMediaInit"); 3583 3584 _media.forEach(function (c) { 3585 var queries = c.queries, 3586 conditions = c.conditions, 3587 match, 3588 p, 3589 anyMatch, 3590 toggled; 3591 3592 for (p in queries) { 3593 match = _win.matchMedia(queries[p]).matches; 3594 match && (anyMatch = 1); 3595 3596 if (match !== conditions[p]) { 3597 conditions[p] = match; 3598 toggled = 1; 3599 } 3600 } 3601 3602 if (toggled) { 3603 c.revert(); 3604 anyMatch && matches.push(c); 3605 } 3606 }); 3607 3608 _dispatch("matchMediaRevert"); 3609 3610 matches.forEach(function (c) { 3611 return c.onMatch(c); 3612 }); 3613 _lastMediaTime = time; 3614 3615 _dispatch("matchMedia"); 3616 } 3617 }; 3618 3619 var Context = function () { 3620 function Context(func, scope) { 3621 this.selector = scope && selector(scope); 3622 this.data = []; 3623 this._r = []; 3624 this.isReverted = false; 3625 func && this.add(func); 3626 } 3627 3628 var _proto5 = Context.prototype; 3629 3630 _proto5.add = function add(name, func, scope) { 3631 if (_isFunction(name)) { 3632 scope = func; 3633 func = name; 3634 name = _isFunction; 3635 } 3636 3637 var self = this, 3638 f = function f() { 3639 var prev = _context, 3640 prevSelector = self.selector, 3641 result; 3642 prev && prev !== self && prev.data.push(self); 3643 scope && (self.selector = selector(scope)); 3644 _context = self; 3645 result = func.apply(self, arguments); 3646 _isFunction(result) && self._r.push(result); 3647 _context = prev; 3648 self.selector = prevSelector; 3649 self.isReverted = false; 3650 return result; 3651 }; 3652 3653 self.last = f; 3654 return name === _isFunction ? f(self) : name ? self[name] = f : f; 3655 }; 3656 3657 _proto5.ignore = function ignore(func) { 3658 var prev = _context; 3659 _context = null; 3660 func(this); 3661 _context = prev; 3662 }; 3663 3664 _proto5.getTweens = function getTweens() { 3665 var a = []; 3666 this.data.forEach(function (e) { 3667 return e instanceof Context ? a.push.apply(a, e.getTweens()) : e instanceof Tween && !(e.parent && e.parent.data === "nested") && a.push(e); 3668 }); 3669 return a; 3670 }; 3671 3672 _proto5.clear = function clear() { 3673 this._r.length = this.data.length = 0; 3674 }; 3675 3676 _proto5.kill = function kill(revert, matchMedia) { 3677 var _this4 = this; 3678 3679 if (revert) { 3680 var tweens = this.getTweens(); 3681 this.data.forEach(function (t) { 3682 if (t.data === "isFlip") { 3683 t.revert(); 3684 t.getChildren(true, true, false).forEach(function (tween) { 3685 return tweens.splice(tweens.indexOf(tween), 1); 3686 }); 3687 } 3688 }); 3689 tweens.map(function (t) { 3690 return { 3691 g: t.globalTime(0), 3692 t: t 3693 }; 3694 }).sort(function (a, b) { 3695 return b.g - a.g || -1; 3696 }
3696).forEach(function (o) { 3697 return o.t.revert(revert); 3698 }); 3699 this.data.forEach(function (e) { 3700 return !(e instanceof Animation) && e.revert && e.revert(revert); 3701 }); 3702 3703 this._r.forEach(function (f) { 3704 return f(revert, _this4); 3705 }); 3706 3707 this.isReverted = true; 3708 } else { 3709 this.data.forEach(function (e) { 3710 return e.kill && e.kill(); 3711 }); 3712 } 3713 3714 this.clear(); 3715 3716 if (matchMedia) { 3717 var i = _media.indexOf(this); 3718 3719 !!~i && _media.splice(i, 1); 3720 } 3721 }; 3722 3723 _proto5.revert = function revert(config) { 3724 this.kill(config || {}); 3725 }; 3726 3727 return Context; 3728 }(); 3729 3730 var MatchMedia = function () { 3731 function MatchMedia(scope) { 3732 this.contexts = []; 3733 this.scope = scope; 3734 } 3735 3736 var _proto6 = MatchMedia.prototype; 3737 3738 _proto6.add = function add(conditions, func, scope) { 3739 _isObject(conditions) || (conditions = { 3740 matches: conditions 3741 }); 3742 var context = new Context(0, scope || this.scope), 3743 cond = context.conditions = {}, 3744 mq, 3745 p, 3746 active; 3747 this.contexts.push(context); 3748 func = context.add("onMatch", func); 3749 context.queries = conditions; 3750 3751 for (p in conditions) { 3752 if (p === "all") { 3753 active = 1; 3754 } else { 3755 mq = _win.matchMedia(conditions[p]); 3756 3757 if (mq) { 3758 _media.indexOf(context) < 0 && _media.push(context); 3759 (cond[p] = mq.matches) && (active = 1); 3760 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 3761 } 3762 } 3763 } 3764 3765 active && func(context); 3766 return this; 3767 }; 3768 3769 _proto6.revert = function revert(config) { 3770 this.kill(config || {}); 3771 }; 3772 3773 _proto6.kill = function kill(revert) {
vendor: 2,486 bytes, lines 3774-3846
3774 this.contexts.forEach(function (c) { 3775 return c.kill(revert, true); 3776 }); 3777 }; 3778 3779 return MatchMedia; 3780 }(); 3781 3782 var _gsap = { 3783 registerPlugin: function registerPlugin() { 3784 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 3785 args[_key2] = arguments[_key2]; 3786 } 3787 3788 args.forEach(function (config) { 3789 return _createPlugin(config); 3790 }); 3791 }, 3792 timeline: function timeline(vars) { 3793 return new Timeline(vars); 3794 }, 3795 getTweensOf: function getTweensOf(targets, onlyActive) { 3796 return _globalTimeline.getTweensOf(targets, onlyActive); 3797 }, 3798 getProperty: function getProperty(target, property, unit, uncache) { 3799 _isString(target) && (target = toArray(target)[0]); 3800 3801 var getter = _getCache(target || {}).get, 3802 format = unit ? _passThrough : _numericIfPossible; 3803 3804 unit === "native" && (unit = ""); 3805 return !target ? target : !property ? function (property, unit, uncache) { 3806 return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 3807 } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 3808 }, 3809 quickSetter: function quickSetter(target, property, unit) { 3810 target = toArray(target); 3811 3812 if (target.length > 1) { 3813 var setters = target.map(function (t) { 3814 return gsap.quickSetter(t, property, unit); 3815 }), 3816 l = setters.length; 3817 return function (value) { 3818 var i = l; 3819 3820 while (i--) { 3821 setters[i](value); 3822 } 3823 }; 3824 } 3825 3826 target = target[0] || {}; 3827 3828 var Plugin = _plugins[property], 3829 cache = _getCache(target), 3830 p = cache.harness && (cache.harness.aliases || {})[property] || property, 3831 setter = Plugin ? function (value) { 3832 var p = new Plugin(); 3833 _quickTween._pt = 0; 3834 p.init(target, unit ? value + unit : value, _quickTween, 0, [target]); 3835 p.render(1, p); 3836 _quickTween._pt && _renderPropTweens(1, _quickTween); 3837 } : cache.set(target, p); 3838 3839 return Plugin ? setter : function (value) { 3840 return setter(target, p, unit ? value + unit : value, cache, 1); 3841 }; 3842 }, 3843 quickTo: function quickTo(target, property, vars) { 3844 var _merge2; 3845 3846 var tween = gsap.to(target, _merge((_merge2 = {}, _merge2[property] = "+=0.1", _merge2.paused = true, _merge
vendor: 5,649 bytes, lines 3846-4048
38462), vars || {})), 3847 func = function func(value, start, startIsRelative) { 3848 return tween.resetTo(property, value, start, startIsRelative); 3849 }; 3850 3851 func.tween = tween; 3852 return func; 3853 }, 3854 isTweening: function isTweening(targets) { 3855 return _globalTimeline.getTweensOf(targets, true).length > 0; 3856 }, 3857 defaults: function defaults(value) { 3858 value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease)); 3859 return _mergeDeep(_defaults, value || {}); 3860 }, 3861 config: function config(value) { 3862 return _mergeDeep(_config, value || {}); 3863 }, 3864 registerEffect: function registerEffect(_ref3) { 3865 var name = _ref3.name, 3866 effect = _ref3.effect, 3867 plugins = _ref3.plugins, 3868 defaults = _ref3.defaults, 3869 extendTimeline = _ref3.extendTimeline; 3870 (plugins || "").split(",").forEach(function (pluginName) { 3871 return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + " effect requires " + pluginName + " plugin."); 3872 }); 3873 3874 _effects[name] = function (targets, vars, tl) { 3875 return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl); 3876 }; 3877 3878 if (extendTimeline) { 3879 Timeline.prototype[name] = function (targets, vars, position) { 3880 return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position); 3881 }; 3882 } 3883 }, 3884 registerEase: function registerEase(name, ease) { 3885 _easeMap[name] = _parseEase(ease); 3886 }, 3887 parseEase: function parseEase(ease, defaultEase) { 3888 return arguments.length ? _parseEase(ease, defaultEase) : _easeMap; 3889 }, 3890 getById: function getById(id) { 3891 return _globalTimeline.getById(id); 3892 }, 3893 exportRoot: function exportRoot(vars, includeDelayedCalls) { 3894 if (vars === void 0) { 3895 vars = {}; 3896 } 3897 3898 var tl = new Timeline(vars), 3899 child, 3900 next; 3901 tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming); 3902 3903 _globalTimeline.remove(tl); 3904 3905 tl._dp = 0; 3906 tl._time = tl._tTime = _globalTimeline._time; 3907 child = _globalTimeline._first; 3908 3909 while (child) { 3910 next = child._next; 3911 3912 if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) { 3913 _addToTimeline(tl, child, child._start - child._delay); 3914 } 3915 3916 child = next; 3917 } 3918 3919 _addToTimeline(_globalTimeline, tl, 0); 3920 3921 return tl; 3922 }, 3923 context: function context(func, scope) { 3924 return func ? new Context(func, scope) : _context; 3925 }, 3926 matchMedia: function matchMedia(scope) { 3927 return new MatchMedia(scope); 3928 }, 3929 matchMediaRefresh: function matchMediaRefresh() { 3930 return _media.forEach(function (c) { 3931 var cond = c.conditions, 3932 found, 3933 p; 3934 3935 for (p in cond) { 3936 if (cond[p]) { 3937 cond[p] = false; 3938 found = 1; 3939 } 3940 } 3941 3942 found && c.revert(); 3943 }) || _onMediaChange(); 3944 }, 3945 addEventListener: function addEventListener(type, callback) { 3946 var a = _listeners[type] || (_listeners[type] = []); 3947 ~a.indexOf(callback) || a.push(callback); 3948 }, 3949 removeEventListener: function removeEventListener(type, callback) { 3950 var a = _listeners[type], 3951 i = a && a.indexOf(callback); 3952 i >= 0 && a.splice(i, 1); 3953 }, 3954 utils: { 3955 wrap: wrap, 3956 wrapYoyo: wrapYoyo, 3957 distribute: distribute, 3958 random: random, 3959 snap: snap, 3960 normalize: normalize, 3961 getUnit: getUnit, 3962 clamp: clamp, 3963 splitColor: splitColor, 3964 toArray: toArray, 3965 selector: selector, 3966 mapRange: mapRange, 3967 pipe: pipe, 3968 unitize: unitize, 3969 interpolate: interpolate, 3970 shuffle: shuffle 3971 }, 3972 install: _install, 3973 effects: _effects, 3974 ticker: _ticker, 3975 updateRoot: Timeline.updateRoot, 3976 plugins: _plugins, 3977 globalTimeline: _globalTimeline, 3978 core: { 3979 PropTween: PropTween, 3980 globals: _addGlobal, 3981 Tween: Tween, 3982 Timeline: Timeline, 3983 Animation: Animation, 3984 getCache: _getCache, 3985 _removeLinkedListItem: _removeLinkedListItem, 3986 reverting: function reverting() { 3987 return _reverting; 3988 }, 3989 context: function context(toAdd) { 3990 if (toAdd && _context) { 3991 _context.data.push(toAdd); 3992 3993 toAdd._ctx = _context; 3994 } 3995 3996 return _context; 3997 }, 3998 suppressOverwrites: function suppressOverwrites(value) { 3999 return _suppressOverwrites = value; 4000 } 4001 } 4002 }; 4003 4004 _forEachName("to,from,fromTo,delayedCall,set,killTweensOf", function (name) { 4005 return _gsap[name] = Tween[name]; 4006 }); 4007 4008 _ticker.add(Timeline.updateRoot); 4009 4010 _quickTween = _gsap.to({}, { 4011 duration: 0 4012 }); 4013 4014 var _getPluginPropTween = function _getPluginPropTween(plugin, prop) { 4015 var pt = plugin._pt; 4016 4017 while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) { 4018 pt = pt._next; 4019 } 4020 4021 return pt; 4022 }, 4023 _addModifiers = function _addModifiers(tween, modifiers) { 4024 var targets = tween._targets, 4025 p, 4026 i, 4027 pt; 4028 4029 for (p in modifiers) { 4030 i = targets.length; 4031 4032 while (i--) { 4033 pt = tween._ptLookup[i][p]; 4034 4035 if (pt && (pt = pt.d)) { 4036 if (pt._pt) { 4037 pt = _getPluginPropTween(pt, p); 4038 } 4039 4040 pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p); 4041 } 4042 } 4043 } 4044 }, 4045 _buildModifierPlugin = function _buildModifierPlugin(name, modifier) { 4046 return { 4047 name: name, 4048
vendor: 20,072 bytes, lines 4048-4675
4048rawVars: 1, 4049 init: function init(target, vars, tween) { 4050 tween._onInit = function (tween) { 4051 var temp, p; 4052 4053 if (_isString(vars)) { 4054 temp = {}; 4055 4056 _forEachName(vars, function (name) { 4057 return temp[name] = 1; 4058 }); 4059 4060 vars = temp; 4061 } 4062 4063 if (modifier) { 4064 temp = {}; 4065 4066 for (p in vars) { 4067 temp[p] = modifier(vars[p]); 4068 } 4069 4070 vars = temp; 4071 } 4072 4073 _addModifiers(tween, vars); 4074 }; 4075 } 4076 }; 4077 }; 4078 4079 var gsap = _gsap.registerPlugin({ 4080 name: "attr", 4081 init: function init(target, vars, tween, index, targets) { 4082 var p, pt, v; 4083 this.tween = tween; 4084 4085 for (p in vars) { 4086 v = target.getAttribute(p) || ""; 4087 pt = this.add(target, "setAttribute", (v || 0) + "", vars[p], index, targets, 0, 0, p); 4088 pt.op = p; 4089 pt.b = v; 4090 4091 this._props.push(p); 4092 } 4093 }, 4094 render: function render(ratio, data) { 4095 var pt = data._pt; 4096 4097 while (pt) { 4098 _reverting ? pt.set(pt.t, pt.p, pt.b, pt) : pt.r(ratio, pt.d); 4099 pt = pt._next; 4100 } 4101 } 4102 }, { 4103 name: "endArray", 4104 init: function init(target, value) { 4105 var i = value.length; 4106 4107 while (i--) { 4108 this.add(target, i, target[i] || 0, value[i], 0, 0, 0, 0, 0, 1); 4109 } 4110 } 4111 }, _buildModifierPlugin("roundProps", _roundModifier), _buildModifierPlugin("modifiers"), _buildModifierPlugin("snap", snap)) || _gsap; 4112 Tween.version = Timeline.version = gsap.version = "3.11.3"; 4113 _coreReady = 1; 4114 _windowExists() && _wake(); 4115 var Power0 = _easeMap.Power0, 4116 Power1 = _easeMap.Power1, 4117 Power2 = _easeMap.Power2, 4118 Power3 = _easeMap.Power3, 4119 Power4 = _easeMap.Power4, 4120 Linear = _easeMap.Linear, 4121 Quad = _easeMap.Quad, 4122 Cubic = _easeMap.Cubic, 4123 Quart = _easeMap.Quart, 4124 Quint = _easeMap.Quint, 4125 Strong = _easeMap.Strong, 4126 Elastic = _easeMap.Elastic, 4127 Back = _easeMap.Back, 4128 SteppedEase = _easeMap.SteppedEase, 4129 Bounce = _easeMap.Bounce, 4130 Sine = _easeMap.Sine, 4131 Expo = _easeMap.Expo, 4132 Circ = _easeMap.Circ; 4133 4134 var _win$1, 4135 _doc$1, 4136 _docElement, 4137 _pluginInitted, 4138 _tempDiv, 4139 _tempDivStyler, 4140 _recentSetterPlugin, 4141 _reverting$1, 4142 _windowExists$1 = function _windowExists() { 4143 return typeof window !== "undefined"; 4144 }, 4145 _transformProps = {}, 4146 _RAD2DEG = 180 / Math.PI, 4147 _DEG2RAD = Math.PI / 180, 4148 _atan2 = Math.atan2, 4149 _bigNum$1 = 1e8, 4150 _capsExp = /([A-Z])/g, 4151 _horizontalExp = /(left|right|width|margin|padding|x)/i, 4152 _complexExp = /[\s,\(]\S/, 4153 _propertyAliases = { 4154 autoAlpha: "opacity,visibility", 4155 scale: "scaleX,scaleY", 4156 alpha: "opacity" 4157 }, 4158 _renderCSSProp = function _renderCSSProp(ratio, data) { 4159 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 4160 }, 4161 _renderPropWithEnd = function _renderPropWithEnd(ratio, data) { 4162 return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 4163 }, 4164 _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) { 4165 return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data); 4166 }, 4167 _renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) { 4168 var value = data.s + data.c * ratio; 4169 data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data); 4170 }, 4171 _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) { 4172 return data.set(data.t, data.p, ratio ? data.e : data.b, data); 4173 }, 4174 _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) { 4175 return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data); 4176 }, 4177 _setterCSSStyle = function _setterCSSStyle(target, property, value) { 4178 return target.style[property] = value; 4179 }, 4180 _setterCSSProp = function _setterCSSProp(target, property, value) { 4181 return target.style.setProperty(property, value); 4182 }, 4183 _setterTransform = function _setterTransform(target, property, value) { 4184 return target._gsap[property] = value; 4185 }, 4186 _setterScale = function _setterScale(target, property, value) { 4187 return target._gsap.scaleX = target._gsap.scaleY = value; 4188 }, 4189 _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) { 4190 var cache = target._gsap; 4191 cache.scaleX = cache.scaleY = value; 4192 cache.renderTransform(ratio, cache); 4193 }, 4194 _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) { 4195 var cache = target._gsap; 4196 cache[property] = value; 4197 cache.renderTransform(ratio, cache); 4198 }, 4199 _transformProp = "transform", 4200 _transformOriginProp = _transformProp + "Origin", 4201 _saveStyle = function _saveStyle(property, isNotCSS) { 4202 var _this = this; 4203 4204 var target = this.target, 4205 style = target.style; 4206 4207 if (property in _transformProps) { 4208 this.tfm = this.tfm || {}; 4209 4210 if (property !== "transform") { 4211 property = _propertyAliases[property] || property; 4212 ~property.indexOf(",") ? property.split(",").forEach(function (a) { 4213 return _this.tfm[a] = _get(target, a); 4214 }) : this.tfm[property] = target._gsap.x ? target._gsap[property] : _get(target, property); 4215 } 4216 4217 if (this.props.indexOf(_transformProp) >= 0) { 4218 return; 4219 } 4220 4221 if (target._gsap.svg) { 4222 this.svgo = target.getAttribute("data-svg-origin"); 4223 this.props.push(_transformOriginProp, isNotCSS, ""); 4224 } 4225 4226 property = _transformProp; 4227 } 4228 4229 (style || isNotCSS) && this.props.push(property, isNotCSS, style[property]); 4230 }, 4231 _removeIndependentTransforms = function _removeIndependentTransforms(style) { 4232 if (style.translate) { 4233 style.removeProperty("translate"); 4234 style.removeProperty("scale"); 4235 style.removeProperty("rotate"); 4236 } 4237 }, 4238 _revertStyle = function _revertStyle() { 4239 var props = this.props, 4240 target = this.target, 4241 style = target.style, 4242 cache = target._gsap, 4243 i, 4244 p; 4245 4246 for (i = 0; i < props.length; i += 3) { 4247 props[i + 1] ? target[props[i]] = props[i + 2] : props[i + 2] ? style[props[i]] = props[i + 2] : style.removeProperty(props[i].replace(_capsExp, "-$1").toLowerCase()); 4248 } 4249 4250 if (this.tfm) { 4251 for (p in this.tfm) { 4252 cache[p] = this.tfm[p]; 4253 } 4254 4255 if (cache.svg) { 4256 cache.renderTransform(); 4257 target.setAttribute("data-svg-origin", this.svgo || ""); 4258 } 4259 4260 i = _reverting$1(); 4261 4262 if (i && !i.isStart && !style[_transformProp]) { 4263 _removeIndependentTransforms(style); 4264 4265 cache.uncache = 1; 4266 } 4267 } 4268 }, 4269 _getStyleSaver = function _getStyleSaver(target, properties) { 4270 var saver = { 4271 target: target, 4272 props: [], 4273 revert: _revertStyle, 4274 save: _saveStyle 4275 }; 4276 properties && properties.split(",").forEach(function (p) { 4277 return saver.save(p); 4278 }); 4279 return saver; 4280 }, 4281 _supports3D, 4282 _createElement = function _createElement(type, ns) { 4283 var e = _doc$1.createElementNS ? _doc$1.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc$1.createElement(type); 4284 return e.style ? e : _doc$1.createElement(type); 4285 }, 4286 _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) { 4287 var cs = getComputedStyle(target); 4288 return cs[property] || cs.getPropertyValue(property.replace(_capsExp, "-$1").toLowerCase()) || cs.getPropertyValue(property) || !skipPrefixFallback && _getComputedProperty(target, _checkPropPrefix(property) || property, 1) || ""; 4289 }, 4290 _prefixes = "O,Moz,ms,Ms,Webkit".split(","), 4291 _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) { 4292 var e = element || _tempDiv, 4293 s = e.style, 4294 i = 5; 4295 4296 if (property in s && !preferPrefix) { 4297 return property; 4298 } 4299 4300 property = property.charAt(0).toUpperCase() + property.substr(1); 4301 4302 while (i-- && !(_prefixes[i] + property in s)) {} 4303 4304 return i < 0 ? null : (i === 3 ? "ms" : i >= 0 ? _prefixes[i] : "") + property; 4305 }, 4306 _initCore = function _initCore() { 4307 if (_windowExists$1() && window.document) { 4308 _win$1 = window; 4309 _doc$1 = _win$1.document; 4310 _docElement = _doc$1.documentElement; 4311 _tempDiv = _createElement("div") || { 4312 style: {} 4313 }; 4314 _tempDivStyler = _createElement("div"); 4315 _transformProp = _checkPropPrefix(_transformProp); 4316 _transformOriginProp = _transformProp + "Origin"; 4317 _tempDiv.style.cssText = "border-width:0;line-height:0;position:absolute;padding:0"; 4318 _supports3D = !!_checkPropPrefix("perspective"); 4319 _reverting$1 = gsap.core.reverting; 4320 _pluginInitted = 1; 4321 } 4322 }, 4323 _getBBoxHack = function _getBBoxHack(swapIfPossible) { 4324 var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"), 4325 oldParent = this.parentNode, 4326 oldSibling = this.nextSibling, 4327 oldCSS = this.style.cssText, 4328 bbox; 4329 4330 _docElement.appendChild(svg); 4331 4332 svg.appendChild(this); 4333 this.style.display = "block"; 4334 4335 if (swapIfPossible) { 4336 try { 4337 bbox = this.getBBox(); 4338 this._gsapBBox = this.getBBox; 4339 this.getBBox = _getBBoxHack; 4340 } catch (e) {} 4341 } else if (this._gsapBBox) { 4342 bbox = this._gsapBBox(); 4343 } 4344 4345 if (oldParent) { 4346 if (oldSibling) { 4347 oldParent.insertBefore(this, oldSibling); 4348 } else { 4349 oldParent.appendChild(this); 4350 } 4351 } 4352 4353 _docElement.removeChild(svg); 4354 4355 this.style.cssText = oldCSS; 4356 return bbox; 4357 }, 4358 _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) { 4359 var i = attributesArray.length; 4360 4361 while (i--) { 4362 if (target.hasAttribute(attributesArray[i])) { 4363 return target.getAttribute(attributesArray[i]); 4364 } 4365 } 4366 }, 4367 _getBBox = function _getBBox(target) { 4368 var bounds; 4369 4370 try { 4371 bounds = target.getBBox(); 4372 } catch (error) { 4373 bounds = _getBBoxHack.call(target, true); 4374 } 4375 4376 bounds && (bounds.width || bounds.height) || target.getBBox === _getBBoxHack || (bounds = _getBBoxHack.call(target, true)); 4377 return bounds && !bounds.width && !bounds.x && !bounds.y ? { 4378 x: +_getAttributeFallbacks(target, ["x", "cx", "x1"]) || 0, 4379 y: +_getAttributeFallbacks(target, ["y", "cy", "y1"]) || 0, 4380 width: 0, 4381 height: 0 4382 } : bounds; 4383 }, 4384 _isSVG = function _isSVG(e) { 4385 return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e)); 4386 }, 4387 _removeProperty = function _removeProperty(target, property) { 4388 if (property) { 4389 var style = target.style; 4390 4391 if (property in _transformProps && property !== _transformOriginProp) { 4392 property = _transformProp; 4393 } 4394 4395 if (style.removeProperty) { 4396 if (property.substr(0, 2) === "ms" || property.substr(0, 6) === "webkit") { 4397 property = "-" + property; 4398 } 4399 4400 style.removeProperty(property.replace(_capsExp, "-$1").toLowerCase()); 4401 } else { 4402 style.removeAttribute(property); 4403 } 4404 } 4405 }, 4406 _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) { 4407 var pt = new PropTween(plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue); 4408 plugin._pt = pt; 4409 pt.b = beginning; 4410 pt.e = end; 4411 4412 plugin._props.push(property); 4413 4414 return pt; 4415 }, 4416 _nonConvertibleUnits = { 4417 deg: 1, 4418 rad: 1, 4419 turn: 1 4420 }, 4421 _nonStandardLayouts = { 4422 grid: 1, 4423 flex: 1 4424 }, 4425 _convertToUnit = function _convertToUnit(target, property, value, unit) { 4426 var curValue = parseFloat(value) || 0, 4427 curUnit = (value + "").trim().substr((curValue + "").length) || "px", 4428 style = _tempDiv.style, 4429 horizontal = _horizontalExp.test(property), 4430 isRootSVG = target.tagName.toLowerCase() === "svg", 4431 measureProperty = (isRootSVG ? "client" : "offset") + (horizontal ? "Width" : "Height"), 4432 amount = 100, 4433 toPixels = unit === "px", 4434 toPercent = unit === "%", 4435 px, 4436 parent, 4437 cache, 4438 isSVG; 4439 4440 if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) { 4441 return curValue; 4442 } 4443 4444 curUnit !== "px" && !toPixels && (curValue = _convertToUnit(target, property, value, "px")); 4445 isSVG = target.getCTM && _isSVG(target); 4446 4447 if ((toPercent || curUnit === "%") && (_transformProps[property] || ~property.indexOf("adius"))) { 4448 px = isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty]; 4449 return _round(toPercent ? curValue / px * amount : curValue / 100 * px); 4450 } 4451 4452 style[horizontal ? "width" : "height"] = amount + (toPixels ? curUnit : unit); 4453 parent = ~property.indexOf("adius") || unit === "em" && target.appendChild && !isRootSVG ? target : target.parentNode; 4454 4455 if (isSVG) { 4456 parent = (target.ownerSVGElement || {}).parentNode; 4457 } 4458 4459 if (!parent || parent === _doc$1 || !parent.appendChild) { 4460 parent = _doc$1.body; 4461 } 4462 4463 cache = parent._gsap; 4464 4465 if (cache && toPercent && cache.width && horizontal && cache.time === _ticker.time && !cache.uncache) { 4466 return _round(curValue / cache.width * amount); 4467 } else { 4468 (toPercent || curUnit === "%") && !_nonStandardLayouts[_getComputedProperty(parent, "display")] && (style.position = _getComputedProperty(target, "position")); 4469 parent === target && (style.position = "static"); 4470 parent.appendChild(_tempDiv); 4471 px = _tempDiv[measureProperty]; 4472 parent.removeChild(_tempDiv); 4473 style.position = "absolute"; 4474 4475 if (horizontal && toPercent) { 4476 cache = _getCache(parent); 4477 cache.time = _ticker.time; 4478 cache.width = parent[measureProperty]; 4479 } 4480 } 4481 4482 return _round(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0); 4483 }, 4484 _get = function _get(target, property, unit, uncache) { 4485 var value; 4486 _pluginInitted || _initCore(); 4487 4488 if (property in _propertyAliases && property !== "transform") { 4489 property = _propertyAliases[property]; 4490 4491 if (~property.indexOf(",")) { 4492 property = property.split(",")[0]; 4493 } 4494 } 4495 4496 if (_transformProps[property] && property !== "transform") { 4497 value = _parseTransform(target, uncache); 4498 value = property !== "transformOrigin" ? value[property] : value.svg ? value.origin : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + " " + value.zOrigin + "px"; 4499 } else { 4500 value = target.style[property]; 4501 4502 if (!value || value === "auto" || uncache || ~(value + "").indexOf("calc(")) { 4503 value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || _getProperty(target, property) || (property === "opacity" ? 1 : 0); 4504 } 4505 } 4506 4507 return unit && !~(value + "").trim().indexOf(" ") ? _convertToUnit(target, property, value, unit) + unit : value; 4508 }, 4509 _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) { 4510 if (!start || start === "none") { 4511 var p = _checkPropPrefix(prop, target, 1), 4512 s = p && _getComputedProperty(target, p, 1); 4513 4514 if (s && s !== start) { 4515 prop = p; 4516 start = s; 4517 } else if (prop === "borderColor") { 4518 start = _getComputedProperty(target, "borderTopColor"); 4519 } 4520 } 4521 4522 var pt = new PropTween(this._pt, target.style, prop, 0, 1, _renderComplexString), 4523 index = 0, 4524 matchIndex = 0, 4525 a, 4526 result, 4527 startValues, 4528 startNum, 4529 color, 4530 startValue, 4531 endValue, 4532 endNum, 4533 chunk, 4534 endUnit, 4535 startUnit, 4536 endValues; 4537 pt.b = start; 4538 pt.e = end; 4539 start += ""; 4540 end += ""; 4541 4542 if (end === "auto") { 4543 target.style[prop] = end; 4544 end = _getComputedProperty(target, prop) || end; 4545 target.style[prop] = start; 4546 } 4547 4548 a = [start, end]; 4549 4550 _colorStringFilter(a); 4551 4552 start = a[0]; 4553 end = a[1]; 4554 startValues = start.match(_numWithUnitExp) || []; 4555 endValues = end.match(_numWithUnitExp) || []; 4556 4557 if (endValues.length) { 4558 while (result = _numWithUnitExp.exec(end)) { 4559 endValue = result[0]; 4560 chunk = end.substring(index, result.index); 4561 4562 if (color) { 4563 color = (color + 1) % 5; 4564 } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") { 4565 color = 1; 4566 } 4567 4568 if (endValue !== (startValue = startValues[matchIndex++] || "")) { 4569 startNum = parseFloat(startValue) || 0; 4570 startUnit = startValue.substr((startNum + "").length); 4571 endValue.charAt(1) === "=" && (endValue = _parseRelative(startNum, endValue) + startUnit); 4572 endNum = parseFloat(endValue); 4573 endUnit = endValue.substr((endNum + "").length); 4574 index = _numWithUnitExp.lastIndex - endUnit.length; 4575 4576 if (!endUnit) { 4577 endUnit = endUnit || _config.units[prop] || startUnit; 4578 4579 if (index === end.length) { 4580 end += endUnit; 4581 pt.e += endUnit; 4582 } 4583 } 4584 4585 if (startUnit !== endUnit) { 4586 startNum = _convertToUnit(target, prop, startValue, endUnit) || 0; 4587 } 4588 4589 pt._pt = { 4590 _next: pt._pt, 4591 p: chunk || matchIndex === 1 ? chunk : ",", 4592 s: startNum, 4593 c: endNum - startNum, 4594 m: color && color < 4 || prop === "zIndex" ? Math.round : 0 4595 }; 4596 } 4597 } 4598 4599 pt.c = index < end.length ? end.substring(index, end.length) : ""; 4600 } else { 4601 pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue; 4602 } 4603 4604 _relExp.test(end) && (pt.e = 0); 4605 this._pt = pt; 4606 return pt; 4607 }, 4608 _keywordToPercent = { 4609 top: "0%", 4610 bottom: "100%", 4611 left: "0%", 4612 right: "100%", 4613 center: "50%" 4614 }, 4615 _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) { 4616 var split = value.split(" "), 4617 x = split[0], 4618 y = split[1] || "50%"; 4619 4620 if (x === "top" || x === "bottom" || y === "left" || y === "right") { 4621 value = x; 4622 x = y; 4623 y = value; 4624 } 4625 4626 split[0] = _keywordToPercent[x] || x; 4627 split[1] = _keywordToPercent[y] || y; 4628 return split.join(" "); 4629 }, 4630 _renderClearProps = function _renderClearProps(ratio, data) { 4631 if (data.tween && data.tween._time === data.tween._dur) { 4632 var target = data.t, 4633 style = target.style, 4634 props = data.u, 4635 cache = target._gsap, 4636 prop, 4637 clearTransforms, 4638 i; 4639 4640 if (props === "all" || props === true) { 4641 style.cssText = ""; 4642 clearTransforms = 1; 4643 } else { 4644 props = props.split(","); 4645 i = props.length; 4646 4647 while (--i > -1) { 4648 prop = props[i]; 4649 4650 if (_transformProps[prop]) { 4651 clearTransforms = 1; 4652 prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp; 4653 } 4654 4655 _removeProperty(target, prop); 4656 } 4657 } 4658 4659 if (clearTransforms) { 4660 _removeProperty(target, _transformProp); 4661 4662 if (cache) { 4663 cache.svg && target.removeAttribute("transform"); 4664 4665 _parseTransform(target, 1); 4666 4667 cache.uncache = 1; 4668 4669 _removeIndependentTransforms(style); 4670 } 4671 } 4672 } 4673 }, 4674 _specialProps = { 4675 clearProps: function clearProps(plugin, target, property, endValue, tween) {
vendor: 1,580 bytes, lines 4676-4716
4676 if (tween.data !== "isFromStart") { 4677 var pt = plugin._pt = new PropTween(plugin._pt, target, property, 0, 0, _renderClearProps); 4678 pt.u = endValue; 4679 pt.pr = -10; 4680 pt.tween = tween; 4681 4682 plugin._props.push(property); 4683 4684 return 1; 4685 } 4686 } 4687 }, 4688 _identity2DMatrix = [1, 0, 0, 1, 0, 0], 4689 _rotationalProperties = {}, 4690 _isNullTransform = function _isNullTransform(value) { 4691 return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value; 4692 }, 4693 _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) { 4694 var matrixString = _getComputedProperty(target, _transformProp); 4695 4696 return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(_numExp).map(_round); 4697 }, 4698 _getMatrix = function _getMatrix(target, force2D) { 4699 var cache = target._gsap || _getCache(target), 4700 style = target.style, 4701 matrix = _getComputedTransformMatrixAsArray(target), 4702 parent, 4703 nextSibling, 4704 temp, 4705 addedToDOM; 4706 4707 if (cache.svg && target.getAttribute("transform")) { 4708 temp = target.transform.baseVal.consolidate().matrix; 4709 matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f]; 4710 return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix; 4711 } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) { 4712 temp = style.display; 4713 style.display = "block"; 4714 parent = target.parentNode; 4715 4716 if (!parent || !target.offsetParent
vendor: 18,897 bytes, lines 4716-5313
4716) { 4717 addedToDOM = 1; 4718 nextSibling = target.nextElementSibling; 4719 4720 _docElement.appendChild(target); 4721 } 4722 4723 matrix = _getComputedTransformMatrixAsArray(target); 4724 temp ? style.display = temp : _removeProperty(target, "display"); 4725 4726 if (addedToDOM) { 4727 nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target); 4728 } 4729 } 4730 4731 return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix; 4732 }, 4733 _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) { 4734 var cache = target._gsap, 4735 matrix = matrixArray || _getMatrix(target, true), 4736 xOriginOld = cache.xOrigin || 0, 4737 yOriginOld = cache.yOrigin || 0, 4738 xOffsetOld = cache.xOffset || 0, 4739 yOffsetOld = cache.yOffset || 0, 4740 a = matrix[0], 4741 b = matrix[1], 4742 c = matrix[2], 4743 d = matrix[3], 4744 tx = matrix[4], 4745 ty = matrix[5], 4746 originSplit = origin.split(" "), 4747 xOrigin = parseFloat(originSplit[0]) || 0, 4748 yOrigin = parseFloat(originSplit[1]) || 0, 4749 bounds, 4750 determinant, 4751 x, 4752 y; 4753 4754 if (!originIsAbsolute) { 4755 bounds = _getBBox(target); 4756 xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * bounds.width : xOrigin); 4757 yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf("%") ? yOrigin / 100 * bounds.height : yOrigin); 4758 } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) { 4759 x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant; 4760 y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant; 4761 xOrigin = x; 4762 yOrigin = y; 4763 } 4764 4765 if (smooth || smooth !== false && cache.smooth) { 4766 tx = xOrigin - xOriginOld; 4767 ty = yOrigin - yOriginOld; 4768 cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx; 4769 cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty; 4770 } else { 4771 cache.xOffset = cache.yOffset = 0; 4772 } 4773 4774 cache.xOrigin = xOrigin; 4775 cache.yOrigin = yOrigin; 4776 cache.smooth = !!smooth; 4777 cache.origin = origin; 4778 cache.originIsAbsolute = !!originIsAbsolute; 4779 target.style[_transformOriginProp] = "0px 0px"; 4780 4781 if (pluginToAddPropTweensTo) { 4782 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin); 4783 4784 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin); 4785 4786 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset); 4787 4788 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset); 4789 } 4790 4791 target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin); 4792 }, 4793 _parseTransform = function _parseTransform(target, uncache) { 4794 var cache = target._gsap || new GSCache(target); 4795 4796 if ("x" in cache && !uncache && !cache.uncache) { 4797 return cache; 4798 } 4799 4800 var style = target.style, 4801 invertedScaleX = cache.scaleX < 0, 4802 px = "px", 4803 deg = "deg", 4804 cs = getComputedStyle(target), 4805 origin = _getComputedProperty(target, _transformOriginProp) || "0", 4806 x, 4807 y, 4808 z, 4809 scaleX, 4810 scaleY, 4811 rotation, 4812 rotationX, 4813 rotationY, 4814 skewX, 4815 skewY, 4816 perspective, 4817 xOrigin, 4818 yOrigin, 4819 matrix, 4820 angle, 4821 cos, 4822 sin, 4823 a, 4824 b, 4825 c, 4826 d, 4827 a12, 4828 a22, 4829 t1, 4830 t2, 4831 t3, 4832 a13, 4833 a23, 4834 a33, 4835 a42, 4836 a43, 4837 a32; 4838 x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0; 4839 scaleX = scaleY = 1; 4840 cache.svg = !!(target.getCTM && _isSVG(target)); 4841 4842 if (cs.translate) { 4843 if (cs.translate !== "none" || cs.scale !== "none" || cs.rotate !== "none") { 4844 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] : ""); 4845 } 4846 4847 style.scale = style.rotate = style.translate = "none"; 4848 } 4849 4850 matrix = _getMatrix(target, cache.svg); 4851 4852 if (cache.svg) { 4853 if (cache.uncache) { 4854 t2 = target.getBBox(); 4855 origin = cache.xOrigin - t2.x + "px " + (cache.yOrigin - t2.y) + "px"; 4856 t1 = ""; 4857 } else { 4858 t1 = !uncache && target.getAttribute("data-svg-origin"); 4859 } 4860 4861 _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix); 4862 } 4863 4864 xOrigin = cache.xOrigin || 0; 4865 yOrigin = cache.yOrigin || 0; 4866 4867 if (matrix !== _identity2DMatrix) { 4868 a = matrix[0]; 4869 b = matrix[1]; 4870 c = matrix[2]; 4871 d = matrix[3]; 4872 x = a12 = matrix[4]; 4873 y = a22 = matrix[5]; 4874 4875 if (matrix.length === 6) { 4876 scaleX = Math.sqrt(a * a + b * b); 4877 scaleY = Math.sqrt(d * d + c * c); 4878 rotation = a || b ? _atan2(b, a) * _RAD2DEG : 0; 4879 skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0; 4880 skewX && (scaleY *= Math.abs(Math.cos(skewX * _DEG2RAD))); 4881 4882 if (cache.svg) { 4883 x -= xOrigin - (xOrigin * a + yOrigin * c); 4884 y -= yOrigin - (xOrigin * b + yOrigin * d); 4885 } 4886 } else { 4887 a32 = matrix[6]; 4888 a42 = matrix[7]; 4889 a13 = matrix[8]; 4890 a23 = matrix[9]; 4891 a33 = matrix[10]; 4892 a43 = matrix[11]; 4893 x = matrix[12]; 4894 y = matrix[13]; 4895 z = matrix[14]; 4896 angle = _atan2(a32, a33); 4897 rotationX = angle * _RAD2DEG; 4898 4899 if (angle) { 4900 cos = Math.cos(-angle); 4901 sin = Math.sin(-angle); 4902 t1 = a12 * cos + a13 * sin; 4903 t2 = a22 * cos + a23 * sin; 4904 t3 = a32 * cos + a33 * sin; 4905 a13 = a12 * -sin + a13 * cos; 4906 a23 = a22 * -sin + a23 * cos; 4907 a33 = a32 * -sin + a33 * cos; 4908 a43 = a42 * -sin + a43 * cos; 4909 a12 = t1; 4910 a22 = t2; 4911 a32 = t3; 4912 } 4913 4914 angle = _atan2(-c, a33); 4915 rotationY = angle * _RAD2DEG; 4916 4917 if (angle) { 4918 cos = Math.cos(-angle); 4919 sin = Math.sin(-angle); 4920 t1 = a * cos - a13 * sin; 4921 t2 = b * cos - a23 * sin; 4922 t3 = c * cos - a33 * sin; 4923 a43 = d * sin + a43 * cos; 4924 a = t1; 4925 b = t2; 4926 c = t3; 4927 } 4928 4929 angle = _atan2(b, a); 4930 rotation = angle * _RAD2DEG; 4931 4932 if (angle) { 4933 cos = Math.cos(angle); 4934 sin = Math.sin(angle); 4935 t1 = a * cos + b * sin; 4936 t2 = a12 * cos + a22 * sin; 4937 b = b * cos - a * sin; 4938 a22 = a22 * cos - a12 * sin; 4939 a = t1; 4940 a12 = t2; 4941 } 4942 4943 if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) { 4944 rotationX = rotation = 0; 4945 rotationY = 180 - rotationY; 4946 } 4947 4948 scaleX = _round(Math.sqrt(a * a + b * b + c * c)); 4949 scaleY = _round(Math.sqrt(a22 * a22 + a32 * a32)); 4950 angle = _atan2(a12, a22); 4951 skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0; 4952 perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0; 4953 } 4954 4955 if (cache.svg) { 4956 t1 = target.getAttribute("transform"); 4957 cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp)); 4958 t1 && target.setAttribute("transform", t1); 4959 } 4960 } 4961 4962 if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) { 4963 if (invertedScaleX) { 4964 scaleX *= -1; 4965 skewX += rotation <= 0 ? 180 : -180; 4966 rotation += rotation <= 0 ? 180 : -180; 4967 } else { 4968 scaleY *= -1; 4969 skewX += skewX <= 0 ? 180 : -180; 4970 } 4971 } 4972 4973 uncache = uncache || cache.uncache; 4974 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; 4975 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; 4976 cache.z = z + px; 4977 cache.scaleX = _round(scaleX); 4978 cache.scaleY = _round(scaleY); 4979 cache.rotation = _round(rotation) + deg; 4980 cache.rotationX = _round(rotationX) + deg; 4981 cache.rotationY = _round(rotationY) + deg; 4982 cache.skewX = skewX + deg; 4983 cache.skewY = skewY + deg; 4984 cache.transformPerspective = perspective + px; 4985 4986 if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || 0) { 4987 style[_transformOriginProp] = _firstTwoOnly(origin); 4988 } 4989 4990 cache.xOffset = cache.yOffset = 0; 4991 cache.force3D = _config.force3D; 4992 cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms; 4993 cache.uncache = 0; 4994 return cache; 4995 }, 4996 _firstTwoOnly = function _firstTwoOnly(value) { 4997 return (value = value.split(" "))[0] + " " + value[1]; 4998 }, 4999 _addPxTranslate = function _addPxTranslate(target, start, value) { 5000 var unit = getUnit(start); 5001 return _round(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit; 5002 }, 5003 _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) { 5004 cache.z = "0px"; 5005 cache.rotationY = cache.rotationX = "0deg"; 5006 cache.force3D = 0; 5007 5008 _renderCSSTransforms(ratio, cache); 5009 }, 5010 _zeroDeg = "0deg", 5011 _zeroPx = "0px", 5012 _endParenthesis = ") ", 5013 _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) { 5014 var _ref = cache || this, 5015 xPercent = _ref.xPercent, 5016 yPercent = _ref.yPercent, 5017 x = _ref.x, 5018 y = _ref.y, 5019 z = _ref.z, 5020 rotation = _ref.rotation, 5021 rotationY = _ref.rotationY, 5022 rotationX = _ref.rotationX, 5023 skewX = _ref.skewX, 5024 skewY = _ref.skewY, 5025 scaleX = _ref.scaleX, 5026 scaleY = _ref.scaleY, 5027 transformPerspective = _ref.transformPerspective, 5028 force3D = _ref.force3D, 5029 target = _ref.target, 5030 zOrigin = _ref.zOrigin, 5031 transforms = "", 5032 use3D = force3D === "auto" && ratio && ratio !== 1 || force3D === true; 5033 5034 if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) { 5035 var angle = parseFloat(rotationY) * _DEG2RAD, 5036 a13 = Math.sin(angle), 5037 a33 = Math.cos(angle), 5038 cos; 5039 5040 angle = parseFloat(rotationX) * _DEG2RAD; 5041 cos = Math.cos(angle); 5042 x = _addPxTranslate(target, x, a13 * cos * -zOrigin); 5043 y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin); 5044 z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin); 5045 } 5046 5047 if (transformPerspective !== _zeroPx) { 5048 transforms += "perspective(" + transformPerspective + _endParenthesis; 5049 } 5050 5051 if (xPercent || yPercent) { 5052 transforms += "translate(" + xPercent + "%, " + yPercent + "%) "; 5053 } 5054 5055 if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) { 5056 transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis; 5057 } 5058 5059 if (rotation !== _zeroDeg) { 5060 transforms += "rotate(" + rotation + _endParenthesis; 5061 } 5062 5063 if (rotationY !== _zeroDeg) { 5064 transforms += "rotateY(" + rotationY + _endParenthesis; 5065 } 5066 5067 if (rotationX !== _zeroDeg) { 5068 transforms += "rotateX(" + rotationX + _endParenthesis; 5069 } 5070 5071 if (skewX !== _zeroDeg || skewY !== _zeroDeg) { 5072 transforms += "skew(" + skewX + ", " + skewY + _endParenthesis; 5073 } 5074 5075 if (scaleX !== 1 || scaleY !== 1) { 5076 transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis; 5077 } 5078 5079 target.style[_transformProp] = transforms || "translate(0, 0)"; 5080 }, 5081 _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) { 5082 var _ref2 = cache || this, 5083 xPercent = _ref2.xPercent, 5084 yPercent = _ref2.yPercent, 5085 x = _ref2.x, 5086 y = _ref2.y, 5087 rotation = _ref2.rotation, 5088 skewX = _ref2.skewX, 5089 skewY = _ref2.skewY, 5090 scaleX = _ref2.scaleX, 5091 scaleY = _ref2.scaleY, 5092 target = _ref2.target, 5093 xOrigin = _ref2.xOrigin, 5094 yOrigin = _ref2.yOrigin, 5095 xOffset = _ref2.xOffset, 5096 yOffset = _ref2.yOffset, 5097 forceCSS = _ref2.forceCSS, 5098 tx = parseFloat(x), 5099 ty = parseFloat(y), 5100 a11, 5101 a21, 5102 a12, 5103 a22, 5104 temp; 5105 5106 rotation = parseFloat(rotation); 5107 skewX = parseFloat(skewX); 5108 skewY = parseFloat(skewY); 5109 5110 if (skewY) { 5111 skewY = parseFloat(skewY); 5112 skewX += skewY; 5113 rotation += skewY; 5114 } 5115 5116 if (rotation || skewX) { 5117 rotation *= _DEG2RAD; 5118 skewX *= _DEG2RAD; 5119 a11 = Math.cos(rotation) * scaleX; 5120 a21 = Math.sin(rotation) * scaleX; 5121 a12 = Math.sin(rotation - skewX) * -scaleY; 5122 a22 = Math.cos(rotation - skewX) * scaleY; 5123 5124 if (skewX) { 5125 skewY *= _DEG2RAD; 5126 temp = Math.tan(skewX - skewY); 5127 temp = Math.sqrt(1 + temp * temp); 5128 a12 *= temp; 5129 a22 *= temp; 5130 5131 if (skewY) { 5132 temp = Math.tan(skewY); 5133 temp = Math.sqrt(1 + temp * temp); 5134 a11 *= temp; 5135 a21 *= temp; 5136 } 5137 } 5138 5139 a11 = _round(a11); 5140 a21 = _round(a21); 5141 a12 = _round(a12); 5142 a22 = _round(a22); 5143 } else { 5144 a11 = scaleX; 5145 a22 = scaleY; 5146 a21 = a12 = 0; 5147 } 5148 5149 if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) { 5150 tx = _convertToUnit(target, "x", x, "px"); 5151 ty = _convertToUnit(target, "y", y, "px"); 5152 } 5153 5154 if (xOrigin || yOrigin || xOffset || yOffset) { 5155 tx = _round(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset); 5156 ty = _round(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset); 5157 } 5158 5159 if (xPercent || yPercent) { 5160 temp = target.getBBox(); 5161 tx = _round(tx + xPercent / 100 * temp.width); 5162 ty = _round(ty + yPercent / 100 * temp.height); 5163 } 5164 5165 temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")"; 5166 target.setAttribute("transform", temp); 5167 forceCSS && (target.style[_transformProp] = temp); 5168 }, 5169 _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue) { 5170 var cap = 360, 5171 isString = _isString(endValue), 5172 endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1), 5173 change = endNum - startNum, 5174 finalValue = startNum + change + "deg", 5175 direction, 5176 pt; 5177 5178 if (isString) { 5179 direction = endValue.split("_")[1]; 5180 5181 if (direction === "short") { 5182 change %= cap; 5183 5184 if (change !== change % (cap / 2)) { 5185 change += change < 0 ? cap : -cap; 5186 } 5187 } 5188 5189 if (direction === "cw" && change < 0) { 5190 change = (change + cap * _bigNum$1) % cap - ~~(change / cap) * cap; 5191 } else if (direction === "ccw" && change > 0) { 5192 change = (change - cap * _bigNum$1) % cap - ~~(change / cap) * cap; 5193 } 5194 } 5195 5196 plugin._pt = pt = new PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd); 5197 pt.e = finalValue; 5198 pt.u = "deg"; 5199 5200 plugin._props.push(property); 5201 5202 return pt; 5203 }, 5204 _assign = function _assign(target, source) { 5205 for (var p in source) { 5206 target[p] = source[p]; 5207 } 5208 5209 return target; 5210 }, 5211 _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) { 5212 var startCache = _assign({}, target._gsap), 5213 exclude = "perspective,force3D,transformOrigin,svgOrigin", 5214 style = target.style, 5215 endCache, 5216 p, 5217 startValue, 5218 endValue, 5219 startNum, 5220 endNum, 5221 startUnit, 5222 endUnit; 5223 5224 if (startCache.svg) { 5225 startValue = target.getAttribute("transform"); 5226 target.setAttribute("transform", ""); 5227 style[_transformProp] = transforms; 5228 endCache = _parseTransform(target, 1); 5229 5230 _removeProperty(target, _transformProp); 5231 5232 target.setAttribute("transform", startValue); 5233 } else { 5234 startValue = getComputedStyle(target)[_transformProp]; 5235 style[_transformProp] = transforms; 5236 endCache = _parseTransform(target, 1); 5237 style[_transformProp] = startValue; 5238 } 5239 5240 for (p in _transformProps) { 5241 startValue = startCache[p]; 5242 endValue = endCache[p]; 5243 5244 if (startValue !== endValue && exclude.indexOf(p) < 0) { 5245 startUnit = getUnit(startValue); 5246 endUnit = getUnit(endValue); 5247 startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue); 5248 endNum = parseFloat(endValue); 5249 plugin._pt = new PropTween(plugin._pt, endCache, p, startNum, endNum - startNum, _renderCSSProp); 5250 plugin._pt.u = endUnit || 0; 5251 5252 plugin._props.push(p); 5253 } 5254 } 5255 5256 _assign(endCache, startCache); 5257 }; 5258 5259 _forEachName("padding,margin,Width,Radius", function (name, index) { 5260 var t = "Top", 5261 r = "Right", 5262 b = "Bottom", 5263 l = "Left", 5264 props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) { 5265 return index < 2 ? name + side : "border" + side + name; 5266 }); 5267 5268 _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) { 5269 var a, vars; 5270 5271 if (arguments.length < 4) { 5272 a = props.map(function (prop) { 5273 return _get(plugin, prop, property); 5274 }); 5275 vars = a.join(" "); 5276 return vars.split(a[0]).length === 5 ? a[0] : vars; 5277 } 5278 5279 a = (endValue + "").split(" "); 5280 vars = {}; 5281 props.forEach(function (prop, i) { 5282 return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0]; 5283 }); 5284 plugin.init(target, vars, tween); 5285 }; 5286 }); 5287 5288 var CSSPlugin = { 5289 name: "css", 5290 register: _initCore, 5291 targetTest: function targetTest(target) { 5292 return target.style && target.nodeType; 5293 }, 5294 init: function init(target, vars, tween, index, targets) { 5295 var props = this._props, 5296 style = target.style, 5297 startAt = tween.vars.startAt, 5298 startValue, 5299 endValue, 5300 endNum, 5301 startNum, 5302 type, 5303 specialProp, 5304 p, 5305 startUnit, 5306 endUnit, 5307 relative, 5308 isTransformRelated, 5309 transformPropTween, 5310 cache, 5311 smooth, 5312 hasPriority, 5313 inlineProps
vendor: 7,960 bytes, lines 5313-5500
5313; 5314 _pluginInitted || _initCore(); 5315 this.styles = this.styles || _getStyleSaver(target); 5316 inlineProps = this.styles.props; 5317 this.tween = tween; 5318 5319 for (p in vars) { 5320 if (p === "autoRound") { 5321 continue; 5322 } 5323 5324 endValue = vars[p]; 5325 5326 if (_plugins[p] && _checkPlugin(p, vars, tween, index, target, targets)) { 5327 continue; 5328 } 5329 5330 type = typeof endValue; 5331 specialProp = _specialProps[p]; 5332 5333 if (type === "function") { 5334 endValue = endValue.call(tween, index, target, targets); 5335 type = typeof endValue; 5336 } 5337 5338 if (type === "string" && ~endValue.indexOf("random(")) { 5339 endValue = _replaceRandom(endValue); 5340 } 5341 5342 if (specialProp) { 5343 specialProp(this, target, p, endValue, tween) && (hasPriority = 1); 5344 } else if (p.substr(0, 2) === "--") { 5345 startValue = (getComputedStyle(target).getPropertyValue(p) + "").trim(); 5346 endValue += ""; 5347 _colorExp.lastIndex = 0; 5348 5349 if (!_colorExp.test(startValue)) { 5350 startUnit = getUnit(startValue); 5351 endUnit = getUnit(endValue); 5352 } 5353 5354 endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit); 5355 this.add(style, "setProperty", startValue, endValue, index, targets, 0, 0, p); 5356 props.push(p); 5357 inlineProps.push(p, 0, style[p]); 5358 } else if (type !== "undefined") { 5359 if (startAt && p in startAt) { 5360 startValue = typeof startAt[p] === "function" ? startAt[p].call(tween, index, target, targets) : startAt[p]; 5361 _isString(startValue) && ~startValue.indexOf("random(") && (startValue = _replaceRandom(startValue)); 5362 getUnit(startValue + "") || (startValue += _config.units[p] || getUnit(_get(target, p)) || ""); 5363 (startValue + "").charAt(1) === "=" && (startValue = _get(target, p)); 5364 } else { 5365 startValue = _get(target, p); 5366 } 5367 5368 startNum = parseFloat(startValue); 5369 relative = type === "string" && endValue.charAt(1) === "=" && endValue.substr(0, 2); 5370 relative && (endValue = endValue.substr(2)); 5371 endNum = parseFloat(endValue); 5372 5373 if (p in _propertyAliases) { 5374 if (p === "autoAlpha") { 5375 if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) { 5376 startNum = 0; 5377 } 5378 5379 inlineProps.push("visibility", 0, style.visibility); 5380 5381 _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum); 5382 } 5383 5384 if (p !== "scale" && p !== "transform") { 5385 p = _propertyAliases[p]; 5386 ~p.indexOf(",") && (p = p.split(",")[0]); 5387 } 5388 } 5389 5390 isTransformRelated = p in _transformProps; 5391 5392 if (isTransformRelated) { 5393 this.styles.save(p); 5394 5395 if (!transformPropTween) { 5396 cache = target._gsap; 5397 cache.renderTransform && !vars.parseTransform || _parseTransform(target, vars.parseTransform); 5398 smooth = vars.smoothOrigin !== false && cache.smooth; 5399 transformPropTween = this._pt = new PropTween(this._pt, style, _transformProp, 0, 1, cache.renderTransform, cache, 0, -1); 5400 transformPropTween.dep = 1; 5401 } 5402 5403 if (p === "scale") { 5404 this._pt = new PropTween(this._pt, cache, "scaleY", startNum, (relative ? _parseRelative(startNum, relative + endNum) : endNum) - startNum || 0, _renderCSSProp); 5405 this._pt.u = 0; 5406 props.push("scaleY", p); 5407 p += "X"; 5408 } else if (p === "transformOrigin") { 5409 inlineProps.push(_transformOriginProp, 0, style[_transformOriginProp]); 5410 endValue = _convertKeywordsToPercentages(endValue); 5411 5412 if (cache.svg) { 5413 _applySVGOrigin(target, endValue, 0, smooth, 0, this); 5414 } else { 5415 endUnit = parseFloat(endValue.split(" ")[2]) || 0; 5416 endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit); 5417 5418 _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue)); 5419 } 5420 5421 continue; 5422 } else if (p === "svgOrigin") { 5423 _applySVGOrigin(target, endValue, 1, smooth, 0, this); 5424 5425 continue; 5426 } else if (p in _rotationalProperties) { 5427 _addRotationalPropTween(this, cache, p, startNum, relative ? _parseRelative(startNum, relative + endValue) : endValue); 5428 5429 continue; 5430 } else if (p === "smoothOrigin") { 5431 _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue); 5432 5433 continue; 5434 } else if (p === "force3D") { 5435 cache[p] = endValue; 5436 continue; 5437 } else if (p === "transform") { 5438 _addRawTransformPTs(this, endValue, target); 5439 5440 continue; 5441 } 5442 } else if (!(p in style)) { 5443 p = _checkPropPrefix(p) || p; 5444 } 5445 5446 if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) { 5447 startUnit = (startValue + "").substr((startNum + "").length); 5448 endNum || (endNum = 0); 5449 endUnit = getUnit(endValue) || (p in _config.units ? _config.units[p] : startUnit); 5450 startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit)); 5451 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); 5452 this._pt.u = endUnit || 0; 5453 5454 if (startUnit !== endUnit && endUnit !== "%") { 5455 this._pt.b = startValue; 5456 this._pt.r = _renderCSSPropWithBeginning; 5457 } 5458 } else if (!(p in style)) { 5459 if (p in target) { 5460 this.add(target, p, startValue || target[p], relative ? relative + endValue : endValue, index, targets); 5461 } else { 5462 _missingPlugin(p, endValue); 5463 5464 continue; 5465 } 5466 } else { 5467 _tweenComplexCSSString.call(this, target, p, startValue, relative ? relative + endValue : endValue); 5468 } 5469 5470 isTransformRelated || (p in style ? inlineProps.push(p, 0, style[p]) : inlineProps.push(p, 1, startValue || target[p])); 5471 props.push(p); 5472 } 5473 } 5474 5475 hasPriority && _sortPropTweensByPriority(this); 5476 }, 5477 render: function render(ratio, data) { 5478 if (data.tween._time || !_reverting$1()) { 5479 var pt = data._pt; 5480 5481 while (pt) { 5482 pt.r(ratio, pt.d); 5483 pt = pt._next; 5484 } 5485 } else { 5486 data.styles.revert(); 5487 } 5488 }, 5489 get: _get, 5490 aliases: _propertyAliases, 5491 getSetter: function getSetter(target, property, plugin) { 5492 var p = _propertyAliases[property]; 5493 p && p.indexOf(",") < 0 && (property = p); 5494 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); 5495 }, 5496 core: { 5497 _removeProperty: _removeProperty, 5498 _getMatrix: _getMatrix 5499 } 5500 };
5501 gsap.utils.checkPrefix = _checkPropPrefix; 5502 gsap.core.getStyleSaver = _getStyleSaver; 5503 5504 (function (positionAndScale, rotation, others, aliases) { 5505 var all = _forEachName(positionAndScale + "," + rotation + "," + others, function (name) { 5506 _transformProps[name] = 1; 5507 }); 5508 5509 _forEachName(rotation, function (name) { 5510 _config.units[name] = "deg"; 5511 _rotationalProperties[name] = 1; 5512 }); 5513 5514 _propertyAliases[all[13]] = positionAndScale + "," + rotation; 5515 5516 _forEachName(aliases, function (name) { 5517 var split = name.split(":"); 5518 _propertyAliases[split[1]] = all[split[0]]; 5519 }); 5520 })("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"); 5521 5522 _forEachName("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) { 5523 _config.units[name] = "px"; 5524 }); 5525 5526 gsap.registerPlugin(CSSPlugin); 5527 5528 var gsapWithCSS = gsap.registerPlugin(CSSPlugin) || gsap, 5529 TweenMaxWithCSS = gsapWithCSS.core.Tween; 5530 5531 exports.Back = Back; 5532 exports.Bounce = Bounce; 5533 exports.CSSPlugin = CSSPlugin; 5534 exports.Circ = Circ; 5535 exports.Cubic = Cubic; 5536 exports.Elastic = Elastic; 5537 exports.Expo = Expo; 5538 exports.Linear = Linear; 5539 exports.Power0 = Power0; 5540 exports.Power1 = Power1; 5541 exports.Power2 = Power2; 5542 exports.Power3 = Power3; 5543 exports.Power4 = Power4; 5544 exports.Quad = Quad; 5545 exports.Quart = Quart; 5546 exports.Quint = Quint; 5547 exports.Sine = Sine; 5548 exports.SteppedEase = SteppedEase; 5549 exports.Strong = Strong; 5550 exports.TimelineLite = Timeline; 5551 exports.TimelineMax = Timeline; 5552 exports.TweenLite = Tween; 5553 exports.TweenMax = TweenMaxWithCSS; 5554 exports.default = gsapWithCSS; 5555 exports.gsap = gsapWithCSS; 5556 5557 if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;} 5558 5559}))); 5560 5561(function(window, $) { 5562 'use strict'; 5563 var counter = 0, 5564 $headCache = $('head'), 5565 oldBigText = window.BigText, 5566 oldjQueryMethod = $.fn.bigtext, 5567 BigText = { 5568 DEBUG_MODE: false, 5569 DEFAULT_MIN_FONT_SIZE_PX: null, 5570 DEFAULT_MAX_FONT_SIZE_PX: 528, 5571 GLOBAL_STYLE_ID: 'bigtext-style', 5572 STYLE_ID: 'bigtext-id', 5573 LINE_CLASS_PREFIX: 'bigtext-line', 5574 EXEMPT_CLASS: 'bigtext-exempt', 5575 noConflict: function(restore) 5576 { 5577 if(restore) { 5578 $.fn.bigtext = oldjQueryMethod; 5579 window.BigText = oldBigText; 5580 } 5581 return BigText; 5582 }, 5583 supports: { 5584 wholeNumberFontSizeOnly: (function() { 5585 if( !( 'getComputedStyle' in window ) ) { 5586 return true; 5587 } 5588 var test = $('<div/>').css({ 5589 position: 'absolute', 5590 'font-size': '14.1px' 5591 }).insertBefore( $('script').eq(0) ), 5592 computedStyle = window.getComputedStyle( test[0], null ); 5593 5594 var ret = computedStyle && computedStyle.getPropertyValue( 'font-size' ) === '14px'; 5595 test.remove(); 5596 return ret; 5597 })() 5598 }, 5599 init: function() { 5600 if(!$('#'+BigText.GLOBAL_STYLE_ID).length) { 5601 $headCache.append(BigText.generateStyleTag(BigText.GLOBAL_STYLE_ID, ['.bigtext * { white-space: nowrap; } .bigtext > * { display: block; }', 5602 '.bigtext .' + BigText.EXEMPT_CLASS + ', .bigtext .' + BigText.EXEMPT_CLASS + ' * { white-space: normal; }'])); 5603 } 5604 }, 5605 bindResize: function(eventName, resizeFunction) { 5606 var timeoutId; 5607 $(window).unbind(eventName).bind(eventName, function() { 5608 if( timeoutId ) { 5609 clearTimeout( timeoutId ); 5610 } 5611 timeoutId = setTimeout( resizeFunction, 300 ); 5612 }); 5613 }, 5614 getStyleId: function(id) 5615 { 5616 return BigText.STYLE_ID + '-' + id; 5617 }, 5618 generateStyleTag: function(id, css) 5619 { 5620 return $('<style>' + css.join('\n') + '</style>').attr('id', id); 5621 }, 5622 clearCss: function(id) 5623 { 5624 var styleId = BigText.getStyleId(id); 5625 $('#' + styleId).remove(); 5626 }, 5627 generateCss: function(id, linesFontSizes, lineWordSpacings, minFontSizes) 5628 { 5629 var css = []; 5630 5631 BigText.clearCss(id); 5632 5633 for(var j=0, k=linesFontSizes.length; j<k; j++) { 5634 css.push('#' + id + ' .' + BigText.LINE_CLASS_PREFIX + j + ' {' + 5635 (minFontSizes[j] ? ' white-space: normal;' : '') + 5636 (linesFontSizes[j] ? ' font-size: ' + linesFontSizes[j] + 'px;' : '') + 5637 (lineWordSpacings[j] ? ' word-spacing: ' + lineWordSpacings[j] + 'px;' : '') + 5638 '}'); 5639 } 5640 5641 return BigText.generateStyleTag(BigText.getStyleId(id), css); 5642 }, 5643 jQueryMethod: function(options) 5644 {
5645 BigText.init(); 5646 5647 options = $.extend({ 5648 minfontsize: BigText.DEFAULT_MIN_FONT_SIZE_PX, 5649 maxfontsize: BigText.DEFAULT_MAX_FONT_SIZE_PX, 5650 childSelector: '', 5651 resize: true 5652 }, options || {}); 5653 5654 this.each(function() 5655 { 5656 var $t = $(this).addClass('bigtext'), 5657 maxWidth = $t.width(), 5658 id = $t.attr('id'), 5659 $children = options.childSelector ? $t.find( options.childSelector ) : $t.children(); 5660 5661 if(!id) { 5662 id = 'bigtext-id' + (counter++); 5663 $t.attr('id', id); 5664 } 5665 5666 if(options.resize) { 5667 BigText.bindResize('resize.bigtext-event-' + id, function() 5668 { 5669 // TODO only call this if the width has changed. 5670 BigText.jQueryMethod.call($('#' + id), options); 5671 }); 5672 } 5673 5674 BigText.clearCss(id); 5675 5676 $children.addClass(function(lineNumber, className) 5677 { 5678 // remove existing line classes. 5679 return [className.replace(new RegExp('\\b' + BigText.LINE_CLASS_PREFIX + '\\d+\\b'), ''), 5680 BigText.LINE_CLASS_PREFIX + lineNumber].join(' '); 5681 }); 5682 5683 var sizes = calculateSizes($t, $children, maxWidth, options.maxfontsize, options.minfontsize); 5684 $headCache.append(BigText.generateCss(id, sizes.fontSizes, sizes.wordSpacings, sizes.minFontSizes)); 5685 }); 5686 5687 return this.trigger('bigtext:complete'); 5688 } 5689 }; 5690 5691 function testLineDimensions($line, maxWidth, property, size, interval, units, previousWidth) 5692 { 5693 var width; 5694 previousWidth = typeof previousWidth === 'number' ? previousWidth : 0; 5695 $line.css(property, size + units); 5696 5697 width = $line.width(); 5698 5699 if(width >= maxWidth) { 5700 5701 $line.css(property, ''); 5702 5703 if(width === maxWidth) { 5704 return { 5705 match: 'exact', 5706 size: parseFloat((parseFloat(size) - 0.1).toFixed(3)) 5707 }; 5708 } 5709 5710 // Since this is an estimate, we calculate how far over the width we went with the new value. 5711 // If this is word-spacing (our last resort guess) and the over is less than the under, we keep the higher value. 5712 // Otherwise, we revert to the underestimate. 5713 var under = maxWidth - previousWidth, 5714 over = width - maxWidth; 5715 5716 return { 5717 match: 'estimate', 5718 size: parseFloat((parseFloat(size) - (property === 'word-spacing' && previousWidth && ( over < under ) ? 0 : interval)).toFixed(3)) 5719 }; 5720 } 5721 5722 return width; 5723 } 5724 5725 function calculateSizes($t, $children, maxWidth, maxFontSize, minFontSize) 5726 { 5727 var $c = $t.clone(true) 5728 .addClass('bigtext-cloned') 5729 .css({ 5730 fontFamily: $t.css('font-family'), 5731 textTransform: $t.css('text-transform'), 5732 wordSpacing: $t.css('word-spacing'), 5733 letterSpacing: $t.css('letter-spacing'), 5734 position: 'absolute', 5735 left: BigText.DEBUG_MODE ? 0 : -9999, 5736 top: BigText.DEBUG_MODE ? 0 : -9999 5737 }) 5738 .appendTo(document.body); 5739 5740 // font-size isn't the only thing we can modify, we can also mess with: 5741 // word-spacing and letter-spacing. WebKit does not respect subpixel 5742 // letter-spacing, word-spacing, or font-size. 5743 // TODO try -webkit-transform: scale() as a workaround. 5744 var fontSizes = [], 5745 wordSpacings = [], 5746 minFontSizes = [], 5747 ratios = []; 5748 5749 $children.css('float', 'left').each(function() { 5750 var $line = $(this), 5751 // TODO replace 8, 4 with a proportional size to the calculated font-size. 5752 intervals = BigText.supports.wholeNumberFontSizeOnly ? [8, 4, 1] : [8, 4, 1, 0.1], 5753 lineMax, 5754 newFontSize; 5755 5756 if($line.hasClass(BigText.EXEMPT_CLASS)) { 5757 fontSizes.push(null); 5758 ratios.push(null); 5759 minFontSizes.push(false); 5760 return; 5761 } 5762 5763 // TODO we can cache this ratio? 5764 var autoGuessSubtraction = 32, // font size in px 5765 currentFontSize = parseFloat($line.css('font-size')), 5766 ratio = ( $line.width() / currentFontSize ).toFixed(6); 5767 5768 newFontSize = parseInt( maxWidth / ratio, 10 ) - autoGuessSubtraction; 5769 5770 outer: for(var m=0, n=intervals.length; m<n; m++) { 5771 inner: for(var j=1, k=10; j<=k; j++) { 5772 if(newFontSize + j*intervals[m] > maxFontSize) { 5773 newFontSize = maxFontSize; 5774 break outer; 5775 } 5776 5777 lineMax = testLineDimensions($line, maxWidth, 'font-size', newFontSize + j*intervals[m], intervals[m], 'px', lineMax); 5778 if(typeof lineMax !== 'number') { 5779 newFontSize = lineMax.size; 5780 5781 if(lineMax.match === 'exact') { 5782 break outer; 5783 } 5784 break inner; 5785 } 5786 } 5787 } 5788 5789 ratios.push(maxWidth / newFontSize); 5790 5791 if(newFontSize > maxFontSize) { 5792 fontSizes.push(maxFontSize); 5793 minFontSizes.push(false); 5794 } else if(!!minFontSize && newFontSize < minFontSize) { 5795 fontSizes.push(minFontSize); 5796 minFontSizes.push(true); 5797 } else { 5798 fontSizes.push(newFontSize); 5799 minFontSizes.push(false); 5800 } 5801 }).each(function(lineNumber) { 5802 var $line = $(this), 5803 wordSpacing = 0, 5804 interval = 1, 5805 maxWordSpacing; 5806 5807 if($line.hasClass(BigText.EXEMPT_CLASS)) { 5808 wordSpacings.push(null); 5809 return; 5810 } 5811 5812 // must re-use font-size, even though it was removed above. 5813 $line.css('font-size', fontSizes[lineNumber] + 'px'); 5814 5815 for(var m=1, n=3; m<n; m+=interval) { 5816 maxWordSpacing = testLineDimensions($line, maxWidth, 'word-spacing', m, interval, 'px', maxWordSpacing); 5817 if(typeof maxWordSpacing !== 'number') { 5818 wordSpacing = maxWordSpacing.size; 5819 break; 5820 } 5821 } 5822 5823 $line.css('font-size', ''); 5824 wordSpacings.push(wordSpacing); 5825 }).removeAttr('style'); 5826 5827 if( !BigText.DEBUG_MODE ) { 5828 $c.remove(); 5829 } else { 5830 $c.css({ 5831 'background-color': 'rgba(255,255,255,.4)' 5832 }); 5833 } 5834 5835 return { 5836 fontSizes: fontSizes, 5837 wordSpacings: wordSpacings, 5838 ratios: ratios, 5839 minFontSizes: minFontSizes 5840 }; 5841 } 5842 5843 $.fn.bigtext = BigText.jQueryMethod; 5844 window.BigText = BigText; 5845 5846})(this, jQuery); 5847/*! 5848 * Isotope PACKAGED v3.0.6 5849 * 5850 * Licensed GPLv3 for open source use 5851 * or Isotope Commercial License for commercial use 5852 * 5853 * https://isotope.metafizzy.co 5854 * Copyright 2010-2018 Metafizzy
vendor: 15,902 bytes, lines 5854-6504
5854 5855 */ 5856 5857/** 5858 * Bridget makes jQuery widgets 5859 * v2.0.1 5860 * MIT license 5861 */ 5862 5863/* jshint browser: true, strict: true, undef: true, unused: true */ 5864 5865( function( window, factory ) { 5866 // universal module definition 5867 /*jshint strict: false */ /* globals define, module, require */ 5868 if ( typeof define == 'function' && define.amd ) { 5869 // AMD 5870 define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) { 5871 return factory( window, jQuery ); 5872 }); 5873 } else if ( typeof module == 'object' && module.exports ) { 5874 // CommonJS 5875 module.exports = factory( 5876 window, 5877 require('jquery') 5878 ); 5879 } else { 5880 // browser global 5881 window.jQueryBridget = factory( 5882 window, 5883 window.jQuery 5884 ); 5885 } 5886 5887}( window, function factory( window, jQuery ) { 5888'use strict'; 5889 5890// ----- utils ----- // 5891 5892var arraySlice = Array.prototype.slice; 5893 5894// helper function for logging errors 5895// $.error breaks jQuery chaining 5896var console = window.console; 5897var logError = typeof console == 'undefined' ? function() {} : 5898 function( message ) { 5899 console.error( message ); 5900 }; 5901 5902// ----- jQueryBridget ----- // 5903 5904function jQueryBridget( namespace, PluginClass, $ ) { 5905 $ = $ || jQuery || window.jQuery; 5906 if ( !$ ) { 5907 return; 5908 } 5909 5910 // add option method -> $().plugin('option', {...}) 5911 if ( !PluginClass.prototype.option ) { 5912 // option setter 5913 PluginClass.prototype.option = function( opts ) { 5914 // bail out if not an object 5915 if ( !$.isPlainObject( opts ) ){ 5916 return; 5917 } 5918 this.options = $.extend( true, this.options, opts ); 5919 }; 5920 } 5921 5922 // make jQuery plugin 5923 $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { 5924 if ( typeof arg0 == 'string' ) { 5925 // method call $().plugin( 'methodName', { options } ) 5926 // shift arguments by 1 5927 var args = arraySlice.call( arguments, 1 ); 5928 return methodCall( this, arg0, args ); 5929 } 5930 // just $().plugin({ options }) 5931 plainCall( this, arg0 ); 5932 return this; 5933 }; 5934 5935 // $().plugin('methodName') 5936 function methodCall( $elems, methodName, args ) { 5937 var returnValue; 5938 var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; 5939 5940 $elems.each( function( i, elem ) { 5941 // get instance 5942 var instance = $.data( elem, namespace ); 5943 if ( !instance ) { 5944 logError( namespace + ' not initialized. Cannot call methods, i.e. ' + 5945 pluginMethodStr ); 5946 return; 5947 } 5948 5949 var method = instance[ methodName ]; 5950 if ( !method || methodName.charAt(0) == '_' ) { 5951 logError( pluginMethodStr + ' is not a valid method' ); 5952 return; 5953 } 5954 5955 // apply method, get return value 5956 var value = method.apply( instance, args ); 5957 // set return value if value is returned, use only first value 5958 returnValue = returnValue === undefined ? value : returnValue; 5959 }); 5960 5961 return returnValue !== undefined ? returnValue : $elems; 5962 } 5963 5964 function plainCall( $elems, options ) { 5965 $elems.each( function( i, elem ) { 5966 var instance = $.data( elem, namespace ); 5967 if ( instance ) { 5968 // set options & init 5969 instance.option( options ); 5970 instance._init(); 5971 } else { 5972 // initialize new instance 5973 instance = new PluginClass( elem, options ); 5974 $.data( elem, namespace, instance ); 5975 } 5976 }); 5977 } 5978 5979 updateJQuery( $ ); 5980 5981} 5982 5983// ----- updateJQuery ----- // 5984 5985// set $.bridget for v1 backwards compatibility 5986function updateJQuery( $ ) { 5987 if ( !$ || ( $ && $.bridget ) ) { 5988 return; 5989 } 5990 $.bridget = jQueryBridget; 5991} 5992 5993updateJQuery( jQuery || window.jQuery ); 5994 5995// ----- ----- // 5996 5997return jQueryBridget; 5998 5999})); 6000 6001/** 6002 * EvEmitter v1.1.0 6003 * Lil' event emitter 6004 * MIT License 6005 */ 6006 6007/* jshint unused: true, undef: true, strict: true */ 6008 6009( function( global, factory ) { 6010 // universal module definition 6011 /* jshint strict: false */ /* globals define, module, window */ 6012 if ( typeof define == 'function' && define.amd ) { 6013 // AMD - RequireJS 6014 define( 'ev-emitter/ev-emitter',factory ); 6015 } else if ( typeof module == 'object' && module.exports ) { 6016 // CommonJS - Browserify, Webpack 6017 module.exports = factory(); 6018 } else { 6019 // Browser globals 6020 global.EvEmitter = factory(); 6021 } 6022 6023}( typeof window != 'undefined' ? window : this, function() { 6024 6025 6026 6027function EvEmitter() {} 6028 6029var proto = EvEmitter.prototype; 6030 6031proto.on = function( eventName, listener ) { 6032 if ( !eventName || !listener ) { 6033 return; 6034 } 6035 // set events hash 6036 var events = this._events = this._events || {}; 6037 // set listeners array 6038 var listeners = events[ eventName ] = events[ eventName ] || []; 6039 // only add once 6040 if ( listeners.indexOf( listener ) == -1 ) { 6041 listeners.push( listener ); 6042 } 6043 6044 return this; 6045}; 6046 6047proto.once = function( eventName, listener ) { 6048 if ( !eventName || !listener ) { 6049 return; 6050 } 6051 // add event 6052 this.on( eventName, listener ); 6053 // set once flag 6054 // set onceEvents hash 6055 var onceEvents = this._onceEvents = this._onceEvents || {}; 6056 // set onceListeners object 6057 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 6058 // set flag 6059 onceListeners[ listener ] = true; 6060 6061 return this; 6062}; 6063 6064proto.off = function( eventName, listener ) { 6065 var listeners = this._events && this._events[ eventName ]; 6066 if ( !listeners || !listeners.length ) { 6067 return; 6068 } 6069 var index = listeners.indexOf( listener ); 6070 if ( index != -1 ) { 6071 listeners.splice( index, 1 ); 6072 } 6073 6074 return this; 6075}; 6076 6077proto.emitEvent = function( eventName, args ) { 6078 var listeners = this._events && this._events[ eventName ]; 6079 if ( !listeners || !listeners.length ) { 6080 return; 6081 } 6082 // copy over to avoid interference if .off() in listener 6083 listeners = listeners.slice(0); 6084 args = args || []; 6085 // once stuff 6086 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 6087 6088 for ( var i=0; i < listeners.length; i++ ) { 6089 var listener = listeners[i] 6090 var isOnce = onceListeners && onceListeners[ listener ]; 6091 if ( isOnce ) { 6092 // remove listener 6093 // remove before trigger to prevent recursion 6094 this.off( eventName, listener ); 6095 // unset once flag 6096 delete onceListeners[ listener ]; 6097 } 6098 // trigger listener 6099 listener.apply( this, args ); 6100 } 6101 6102 return this; 6103}; 6104 6105proto.allOff = function() { 6106 delete this._events; 6107 delete this._onceEvents; 6108}; 6109 6110return EvEmitter; 6111 6112})); 6113 6114/*! 6115 * getSize v2.0.3 6116 * measure size of elements 6117 * MIT license 6118 */ 6119 6120/* jshint browser: true, strict: true, undef: true, unused: true */ 6121/* globals console: false */ 6122 6123( function( window, factory ) { 6124 /* jshint strict: false */ /* globals define, module */ 6125 if ( typeof define == 'function' && define.amd ) { 6126 // AMD 6127 define( 'get-size/get-size',factory ); 6128 } else if ( typeof module == 'object' && module.exports ) { 6129 // CommonJS 6130 module.exports = factory(); 6131 } else { 6132 // browser global 6133 window.getSize = factory(); 6134 } 6135 6136})( window, function factory() { 6137'use strict'; 6138 6139// -------------------------- helpers -------------------------- // 6140 6141// get a number from a string, not a percentage 6142function getStyleSize( value ) { 6143 var num = parseFloat( value ); 6144 // not a percent like '100%', and a number 6145 var isValid = value.indexOf('%') == -1 && !isNaN( num ); 6146 return isValid && num; 6147} 6148 6149function noop() {} 6150 6151var logError = typeof console == 'undefined' ? noop : 6152 function( message ) { 6153 console.error( message ); 6154 }; 6155 6156// -------------------------- measurements -------------------------- // 6157 6158var measurements = [ 6159 'paddingLeft', 6160 'paddingRight', 6161 'paddingTop', 6162 'paddingBottom', 6163 'marginLeft', 6164 'marginRight', 6165 'marginTop', 6166 'marginBottom', 6167 'borderLeftWidth', 6168 'borderRightWidth', 6169 'borderTopWidth', 6170 'borderBottomWidth' 6171]; 6172 6173var measurementsLength = measurements.length; 6174 6175function getZeroSize() { 6176 var size = { 6177 width: 0, 6178 height: 0, 6179 innerWidth: 0, 6180 innerHeight: 0, 6181 outerWidth: 0, 6182 outerHeight: 0 6183 }; 6184 for ( var i=0; i < measurementsLength; i++ ) { 6185 var measurement = measurements[i]; 6186 size[ measurement ] = 0; 6187 } 6188 return size; 6189} 6190 6191// -------------------------- getStyle -------------------------- // 6192 6193/** 6194 * getStyle, get style of element, check for Firefox bug 6195 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 6196 */ 6197function getStyle( elem ) { 6198 var style = getComputedStyle( elem ); 6199 if ( !style ) { 6200 logError( 'Style returned ' + style + 6201 '. Are you running this code in a hidden iframe on Firefox? ' + 6202 'See https://bit.ly/getsizebug1' ); 6203 } 6204 return style; 6205} 6206 6207// -------------------------- setup -------------------------- // 6208 6209var isSetup = false; 6210 6211var isBoxSizeOuter; 6212 6213/** 6214 * setup 6215 * check isBoxSizerOuter 6216 * do on first getSize() rather than on page load for Firefox bug 6217 */ 6218function setup() { 6219 // setup once 6220 if ( isSetup ) { 6221 return; 6222 } 6223 isSetup = true; 6224 6225 // -------------------------- box sizing -------------------------- // 6226 6227 /** 6228 * Chrome & Safari measure the outer-width on style.width on border-box elems 6229 * IE11 & Firefox<29 measures the inner-width 6230 */ 6231 var div = document.createElement('div'); 6232 div.style.width = '200px'; 6233 div.style.padding = '1px 2px 3px 4px'; 6234 div.style.borderStyle = 'solid'; 6235 div.style.borderWidth = '1px 2px 3px 4px'; 6236 div.style.boxSizing = 'border-box'; 6237 6238 var body = document.body || document.documentElement; 6239 body.appendChild( div ); 6240 var style = getStyle( div ); 6241 // round value for browser zoom. desandro/masonry#928 6242 isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200; 6243 getSize.isBoxSizeOuter = isBoxSizeOuter; 6244 6245 body.removeChild( div ); 6246} 6247 6248// -------------------------- getSize -------------------------- // 6249 6250function getSize( elem ) { 6251 setup(); 6252 6253 // use querySeletor if elem is string 6254 if ( typeof elem == 'string' ) { 6255 elem = document.querySelector( elem ); 6256 } 6257 6258 // do not proceed on non-objects 6259 if ( !elem || typeof elem != 'object' || !elem.nodeType ) { 6260 return; 6261 } 6262 6263 var style = getStyle( elem ); 6264 6265 // if hidden, everything is 0 6266 if ( style.display == 'none' ) { 6267 return getZeroSize(); 6268 } 6269 6270 var size = {}; 6271 size.width = elem.offsetWidth; 6272 size.height = elem.offsetHeight; 6273 6274 var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 6275 6276 // get all measurements 6277 for ( var i=0; i < measurementsLength; i++ ) { 6278 var measurement = measurements[i]; 6279 var value = style[ measurement ]; 6280 var num = parseFloat( value ); 6281 // any 'auto', 'medium' value will be 0 6282 size[ measurement ] = !isNaN( num ) ? num : 0; 6283 } 6284 6285 var paddingWidth = size.paddingLeft + size.paddingRight; 6286 var paddingHeight = size.paddingTop + size.paddingBottom; 6287 var marginWidth = size.marginLeft + size.marginRight; 6288 var marginHeight = size.marginTop + size.marginBottom; 6289 var borderWidth = size.borderLeftWidth + size.borderRightWidth; 6290 var borderHeight = size.borderTopWidth + size.borderBottomWidth; 6291 6292 var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; 6293 6294 // overwrite width and height if we can get it from style 6295 var styleWidth = getStyleSize( style.width ); 6296 if ( styleWidth !== false ) { 6297 size.width = styleWidth + 6298 // add padding and border unless it's already including it 6299 ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); 6300 } 6301 6302 var styleHeight = getStyleSize( style.height ); 6303 if ( styleHeight !== false ) { 6304 size.height = styleHeight + 6305 // add padding and border unless it's already including it 6306 ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); 6307 } 6308 6309 size.innerWidth = size.width - ( paddingWidth + borderWidth ); 6310 size.innerHeight = size.height - ( paddingHeight + borderHeight ); 6311 6312 size.outerWidth = size.width + marginWidth; 6313 size.outerHeight = size.height + marginHeight; 6314 6315 return size; 6316} 6317 6318return getSize; 6319 6320}); 6321 6322/** 6323 * matchesSelector v2.0.2 6324 * matchesSelector( element, '.selector' ) 6325 * MIT license 6326 */ 6327 6328/*jshint browser: true, strict: true, undef: true, unused: true */ 6329 6330( function( window, factory ) { 6331 /*global define: false, module: false */ 6332 'use strict'; 6333 // universal module definition 6334 if ( typeof define == 'function' && define.amd ) { 6335 // AMD 6336 define( 'desandro-matches-selector/matches-selector',factory ); 6337 } else if ( typeof module == 'object' && module.exports ) { 6338 // CommonJS 6339 module.exports = factory(); 6340 } else { 6341 // browser global 6342 window.matchesSelector = factory(); 6343 } 6344 6345}( window, function factory() { 6346 'use strict'; 6347 6348 var matchesMethod = ( function() { 6349 var ElemProto = window.Element.prototype; 6350 // check for the standard method name first 6351 if ( ElemProto.matches ) { 6352 return 'matches'; 6353 } 6354 // check un-prefixed 6355 if ( ElemProto.matchesSelector ) { 6356 return 'matchesSelector'; 6357 } 6358 // check vendor prefixes 6359 var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; 6360 6361 for ( var i=0; i < prefixes.length; i++ ) { 6362 var prefix = prefixes[i]; 6363 var method = prefix + 'MatchesSelector'; 6364 if ( ElemProto[ method ] ) { 6365 return method; 6366 } 6367 } 6368 })(); 6369 6370 return function matchesSelector( elem, selector ) { 6371 return elem[ matchesMethod ]( selector ); 6372 }; 6373 6374})); 6375 6376/** 6377 * Fizzy UI utils v2.0.7 6378 * MIT license 6379 */ 6380 6381/*jshint browser: true, undef: true, unused: true, strict: true */ 6382 6383( function( window, factory ) { 6384 // universal module definition 6385 /*jshint strict: false */ /*globals define, module, require */ 6386 6387 if ( typeof define == 'function' && define.amd ) { 6388 // AMD 6389 define( 'fizzy-ui-utils/utils',[ 6390 'desandro-matches-selector/matches-selector' 6391 ], function( matchesSelector ) { 6392 return factory( window, matchesSelector ); 6393 }); 6394 } else if ( typeof module == 'object' && module.exports ) { 6395 // CommonJS 6396 module.exports = factory( 6397 window, 6398 require('desandro-matches-selector') 6399 ); 6400 } else { 6401 // browser global 6402 window.fizzyUIUtils = factory( 6403 window, 6404 window.matchesSelector 6405 ); 6406 } 6407 6408}( window, function factory( window, matchesSelector ) { 6409 6410 6411 6412var utils = {}; 6413 6414// ----- extend ----- // 6415 6416// extends objects 6417utils.extend = function( a, b ) { 6418 for ( var prop in b ) { 6419 a[ prop ] = b[ prop ]; 6420 } 6421 return a; 6422}; 6423 6424// ----- modulo ----- // 6425 6426utils.modulo = function( num, div ) { 6427 return ( ( num % div ) + div ) % div; 6428}; 6429 6430// ----- makeArray ----- // 6431 6432var arraySlice = Array.prototype.slice; 6433 6434// turn element or nodeList into an array 6435utils.makeArray = function( obj ) { 6436 if ( Array.isArray( obj ) ) { 6437 // use object if already an array 6438 return obj; 6439 } 6440 // return empty array if undefined or null. #6 6441 if ( obj === null || obj === undefined ) { 6442 return []; 6443 } 6444 6445 var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; 6446 if ( isArrayLike ) { 6447 // convert nodeList to array 6448 return arraySlice.call( obj ); 6449 } 6450 6451 // array of single index 6452 return [ obj ]; 6453}; 6454 6455// ----- removeFrom ----- // 6456 6457utils.removeFrom = function( ary, obj ) { 6458 var index = ary.indexOf( obj ); 6459 if ( index != -1 ) { 6460 ary.splice( index, 1 ); 6461 } 6462}; 6463 6464// ----- getParent ----- // 6465 6466utils.getParent = function( elem, selector ) { 6467 while ( elem.parentNode && elem != document.body ) { 6468 elem = elem.parentNode; 6469 if ( matchesSelector( elem, selector ) ) { 6470 return elem; 6471 } 6472 } 6473}; 6474 6475// ----- getQueryElement ----- // 6476 6477// use element as selector string 6478utils.getQueryElement = function( elem ) { 6479 if ( typeof elem == 'string' ) { 6480 return document.querySelector( elem ); 6481 } 6482 return elem; 6483}; 6484 6485// ----- handleEvent ----- // 6486 6487// enable .ontype to trigger from .addEventListener( elem, 'type' ) 6488utils.handleEvent = function( event ) { 6489 var method = 'on' + event.type; 6490 if ( this[ method ] ) { 6491 this[ method ]( event ); 6492 } 6493}; 6494 6495// ----- filterFindElements ----- // 6496 6497utils.filterFindElements = function( elems, selector ) { 6498 // make array of elems 6499 elems = utils.makeArray( elems ); 6500 var ffElems = []; 6501 6502 elems.forEach( function( elem ) { 6503 // check that elem is an actual element 6504
6504// START UNCODE EDIT 6505 // if ( !( elem instanceof HTMLElement ) ) { 6506 if ( !( elem instanceof HTMLElement ) && !SiteParameters.is_frontend_editor ) { 6507 // END UNCODE EDIT
vendor: 23,480 bytes, lines 6507-7419
6507 6508 return; 6509 } 6510 // add elem if no selector 6511 if ( !selector ) { 6512 ffElems.push( elem ); 6513 return; 6514 } 6515 // filter & find items if we have a selector 6516 // filter 6517 if ( matchesSelector( elem, selector ) ) { 6518 ffElems.push( elem ); 6519 } 6520 // find children 6521 var childElems = elem.querySelectorAll( selector ); 6522 // concat childElems to filterFound array 6523 for ( var i=0; i < childElems.length; i++ ) { 6524 ffElems.push( childElems[i] ); 6525 } 6526 }); 6527 6528 return ffElems; 6529}; 6530 6531// ----- debounceMethod ----- // 6532 6533utils.debounceMethod = function( _class, methodName, threshold ) { 6534 threshold = threshold || 100; 6535 // original method 6536 var method = _class.prototype[ methodName ]; 6537 var timeoutName = methodName + 'Timeout'; 6538 6539 _class.prototype[ methodName ] = function() { 6540 var timeout = this[ timeoutName ]; 6541 clearTimeout( timeout ); 6542 6543 var args = arguments; 6544 var _this = this; 6545 this[ timeoutName ] = setTimeout( function() { 6546 method.apply( _this, args ); 6547 delete _this[ timeoutName ]; 6548 }, threshold ); 6549 }; 6550}; 6551 6552// ----- docReady ----- // 6553 6554utils.docReady = function( callback ) { 6555 var readyState = document.readyState; 6556 if ( readyState == 'complete' || readyState == 'interactive' ) { 6557 // do async to allow for other scripts to run. metafizzy/flickity#441 6558 setTimeout( callback ); 6559 } else { 6560 document.addEventListener( 'DOMContentLoaded', callback ); 6561 } 6562}; 6563 6564// ----- htmlInit ----- // 6565 6566// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ 6567utils.toDashed = function( str ) { 6568 return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { 6569 return $1 + '-' + $2; 6570 }).toLowerCase(); 6571}; 6572 6573var console = window.console; 6574/** 6575 * allow user to initialize classes via [data-namespace] or .js-namespace class 6576 * htmlInit( Widget, 'widgetName' ) 6577 * options are parsed from data-namespace-options 6578 */ 6579utils.htmlInit = function( WidgetClass, namespace ) { 6580 utils.docReady( function() { 6581 var dashedNamespace = utils.toDashed( namespace ); 6582 var dataAttr = 'data-' + dashedNamespace; 6583 var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' ); 6584 var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace ); 6585 var elems = utils.makeArray( dataAttrElems ) 6586 .concat( utils.makeArray( jsDashElems ) ); 6587 var dataOptionsAttr = dataAttr + '-options'; 6588 var jQuery = window.jQuery; 6589 6590 elems.forEach( function( elem ) { 6591 var attr = elem.getAttribute( dataAttr ) || 6592 elem.getAttribute( dataOptionsAttr ); 6593 var options; 6594 try { 6595 options = attr && JSON.parse( attr ); 6596 } catch ( error ) { 6597 // log error, do not initialize 6598 if ( console ) { 6599 console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className + 6600 ': ' + error ); 6601 } 6602 return; 6603 } 6604 // initialize 6605 var instance = new WidgetClass( elem, options ); 6606 // make available via $().data('namespace') 6607 if ( jQuery ) { 6608 jQuery.data( elem, namespace, instance ); 6609 } 6610 }); 6611 6612 }); 6613}; 6614 6615// ----- ----- // 6616 6617return utils; 6618 6619})); 6620 6621/** 6622 * Outlayer Item 6623 */ 6624 6625( function( window, factory ) { 6626 // universal module definition 6627 /* jshint strict: false */ /* globals define, module, require */ 6628 if ( typeof define == 'function' && define.amd ) { 6629 // AMD - RequireJS 6630 define( 'outlayer/item',[ 6631 'ev-emitter/ev-emitter', 6632 'get-size/get-size' 6633 ], 6634 factory 6635 ); 6636 } else if ( typeof module == 'object' && module.exports ) { 6637 // CommonJS - Browserify, Webpack 6638 module.exports = factory( 6639 require('ev-emitter'), 6640 require('get-size') 6641 ); 6642 } else { 6643 // browser global 6644 window.Outlayer = {}; 6645 window.Outlayer.Item = factory( 6646 window.EvEmitter, 6647 window.getSize 6648 ); 6649 } 6650 6651}( window, function factory( EvEmitter, getSize ) { 6652'use strict'; 6653 6654// ----- helpers ----- // 6655 6656function isEmptyObj( obj ) { 6657 for ( var prop in obj ) { 6658 return false; 6659 } 6660 prop = null; 6661 return true; 6662} 6663 6664// -------------------------- CSS3 support -------------------------- // 6665 6666 6667var docElemStyle = document.documentElement.style; 6668 6669var transitionProperty = typeof docElemStyle.transition == 'string' ? 6670 'transition' : 'WebkitTransition'; 6671var transformProperty = typeof docElemStyle.transform == 'string' ? 6672 'transform' : 'WebkitTransform'; 6673 6674var transitionEndEvent = { 6675 WebkitTransition: 'webkitTransitionEnd', 6676 transition: 'transitionend' 6677}[ transitionProperty ]; 6678 6679// cache all vendor properties that could have vendor prefix 6680var vendorProperties = { 6681 transform: transformProperty, 6682 transition: transitionProperty, 6683 transitionDuration: transitionProperty + 'Duration', 6684 transitionProperty: transitionProperty + 'Property', 6685 transitionDelay: transitionProperty + 'Delay' 6686}; 6687 6688// -------------------------- Item -------------------------- // 6689 6690function Item( element, layout ) { 6691 if ( !element ) { 6692 return; 6693 } 6694 6695 this.element = element; 6696 // parent layout class, i.e. Masonry, Isotope, or Packery 6697 this.layout = layout; 6698 this.position = { 6699 x: 0, 6700 y: 0 6701 }; 6702 6703 this._create(); 6704} 6705 6706// inherit EvEmitter 6707var proto = Item.prototype = Object.create( EvEmitter.prototype ); 6708proto.constructor = Item; 6709 6710proto._create = function() { 6711 // transition objects 6712 this._transn = { 6713 ingProperties: {}, 6714 clean: {}, 6715 onEnd: {} 6716 }; 6717 6718 this.css({ 6719 position: 'absolute' 6720 }); 6721}; 6722 6723// trigger specified handler for event type 6724proto.handleEvent = function( event ) { 6725 var method = 'on' + event.type; 6726 if ( this[ method ] ) { 6727 this[ method ]( event ); 6728 } 6729}; 6730 6731proto.getSize = function() { 6732 this.size = getSize( this.element ); 6733}; 6734 6735/** 6736 * apply CSS styles to element 6737 * @param {Object} style 6738 */ 6739proto.css = function( style ) { 6740 var elemStyle = this.element.style; 6741 6742 for ( var prop in style ) { 6743 // use vendor property if available 6744 var supportedProp = vendorProperties[ prop ] || prop; 6745 elemStyle[ supportedProp ] = style[ prop ]; 6746 } 6747}; 6748 6749 // measure position, and sets it 6750proto.getPosition = function() { 6751 var style = getComputedStyle( this.element ); 6752 var isOriginLeft = this.layout._getOption('originLeft'); 6753 var isOriginTop = this.layout._getOption('originTop'); 6754 var xValue = style[ isOriginLeft ? 'left' : 'right' ]; 6755 var yValue = style[ isOriginTop ? 'top' : 'bottom' ]; 6756 var x = parseFloat( xValue ); 6757 var y = parseFloat( yValue ); 6758 // convert percent to pixels 6759 var layoutSize = this.layout.size; 6760 if ( xValue.indexOf('%') != -1 ) { 6761 x = ( x / 100 ) * layoutSize.width; 6762 } 6763 if ( yValue.indexOf('%') != -1 ) { 6764 y = ( y / 100 ) * layoutSize.height; 6765 } 6766 // clean up 'auto' or other non-integer values 6767 x = isNaN( x ) ? 0 : x; 6768 y = isNaN( y ) ? 0 : y; 6769 // remove padding from measurement 6770 x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight; 6771 y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom; 6772 6773 this.position.x = x; 6774 this.position.y = y; 6775}; 6776 6777// set settled position, apply padding 6778proto.layoutPosition = function() { 6779 var layoutSize = this.layout.size; 6780 var style = {}; 6781 var isOriginLeft = this.layout._getOption('originLeft'); 6782 var isOriginTop = this.layout._getOption('originTop'); 6783 6784 // x 6785 var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight'; 6786 var xProperty = isOriginLeft ? 'left' : 'right'; 6787 var xResetProperty = isOriginLeft ? 'right' : 'left'; 6788 6789 var x = this.position.x + layoutSize[ xPadding ]; 6790 // set in percentage or pixels 6791 style[ xProperty ] = this.getXValue( x ); 6792 // reset other property 6793 style[ xResetProperty ] = ''; 6794 6795 // y 6796 var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom'; 6797 var yProperty = isOriginTop ? 'top' : 'bottom'; 6798 var yResetProperty = isOriginTop ? 'bottom' : 'top'; 6799 6800 var y = this.position.y + layoutSize[ yPadding ]; 6801 // set in percentage or pixels 6802 style[ yProperty ] = this.getYValue( y ); 6803 // reset other property 6804 style[ yResetProperty ] = ''; 6805 6806 this.css( style ); 6807 this.emitEvent( 'layout', [ this ] ); 6808}; 6809 6810proto.getXValue = function( x ) { 6811 var isHorizontal = this.layout._getOption('horizontal'); 6812 return this.layout.options.percentPosition && !isHorizontal ? 6813 ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px'; 6814}; 6815 6816proto.getYValue = function( y ) { 6817 var isHorizontal = this.layout._getOption('horizontal'); 6818 return this.layout.options.percentPosition && isHorizontal ? 6819 ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px'; 6820}; 6821 6822proto._transitionTo = function( x, y ) { 6823 this.getPosition(); 6824 // get current x & y from top/left 6825 var curX = this.position.x; 6826 var curY = this.position.y; 6827 6828 var didNotMove = x == this.position.x && y == this.position.y; 6829 6830 // save end position 6831 this.setPosition( x, y ); 6832 6833 // if did not move and not transitioning, just go to layout 6834 if ( didNotMove && !this.isTransitioning ) { 6835 this.layoutPosition(); 6836 return; 6837 } 6838 6839 var transX = x - curX; 6840 var transY = y - curY; 6841 var transitionStyle = {}; 6842 transitionStyle.transform = this.getTranslate( transX, transY ); 6843 6844 this.transition({ 6845 to: transitionStyle, 6846 onTransitionEnd: { 6847 transform: this.layoutPosition 6848 }, 6849 isCleaning: true 6850 }); 6851}; 6852 6853proto.getTranslate = function( x, y ) { 6854 // flip cooridinates if origin on right or bottom 6855 var isOriginLeft = this.layout._getOption('originLeft'); 6856 var isOriginTop = this.layout._getOption('originTop'); 6857 x = isOriginLeft ? x : -x; 6858 y = isOriginTop ? y : -y; 6859 return 'translate3d(' + x + 'px, ' + y + 'px, 0)'; 6860}; 6861 6862// non transition + transform support 6863proto.goTo = function( x, y ) { 6864 this.setPosition( x, y ); 6865 this.layoutPosition(); 6866}; 6867 6868proto.moveTo = proto._transitionTo; 6869 6870proto.setPosition = function( x, y ) { 6871 this.position.x = parseFloat( x ); 6872 this.position.y = parseFloat( y ); 6873}; 6874 6875// ----- transition ----- // 6876 6877/** 6878 * @param {Object} style - CSS 6879 * @param {Function} onTransitionEnd 6880 */ 6881 6882// non transition, just trigger callback 6883proto._nonTransition = function( args ) { 6884 this.css( args.to ); 6885 if ( args.isCleaning ) { 6886 this._removeStyles( args.to ); 6887 } 6888 for ( var prop in args.onTransitionEnd ) { 6889 args.onTransitionEnd[ prop ].call( this ); 6890 } 6891}; 6892 6893/** 6894 * proper transition 6895 * @param {Object} args - arguments 6896 * @param {Object} to - style to transition to 6897 * @param {Object} from - style to start transition from 6898 * @param {Boolean} isCleaning - removes transition styles after transition 6899 * @param {Function} onTransitionEnd - callback 6900 */ 6901proto.transition = function( args ) { 6902 // redirect to nonTransition if no transition duration 6903 if ( !parseFloat( this.layout.options.transitionDuration ) ) { 6904 this._nonTransition( args ); 6905 return; 6906 } 6907 6908 var _transition = this._transn; 6909 // keep track of onTransitionEnd callback by css property 6910 for ( var prop in args.onTransitionEnd ) { 6911 _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ]; 6912 } 6913 // keep track of properties that are transitioning 6914 for ( prop in args.to ) { 6915 _transition.ingProperties[ prop ] = true; 6916 // keep track of properties to clean up when transition is done 6917 if ( args.isCleaning ) { 6918 _transition.clean[ prop ] = true; 6919 } 6920 } 6921 6922 // set from styles 6923 if ( args.from ) { 6924 this.css( args.from ); 6925 // force redraw. http://blog.alexmaccaw.com/css-transitions 6926 var h = this.element.offsetHeight; 6927 // hack for JSHint to hush about unused var 6928 h = null; 6929 } 6930 // enable transition 6931 this.enableTransition( args.to ); 6932 // set styles that are transitioning 6933 this.css( args.to ); 6934 6935 this.isTransitioning = true; 6936 6937}; 6938 6939// dash before all cap letters, including first for 6940// WebkitTransform => -webkit-transform 6941function toDashedAll( str ) { 6942 return str.replace( /([A-Z])/g, function( $1 ) { 6943 return '-' + $1.toLowerCase(); 6944 }); 6945} 6946 6947var transitionProps = 'opacity,' + toDashedAll( transformProperty ); 6948 6949proto.enableTransition = function(/* style */) { 6950 // HACK changing transitionProperty during a transition 6951 // will cause transition to jump 6952 if ( this.isTransitioning ) { 6953 return; 6954 } 6955 6956 // make `transition: foo, bar, baz` from style object 6957 // HACK un-comment this when enableTransition can work 6958 // while a transition is happening 6959 // var transitionValues = []; 6960 // for ( var prop in style ) { 6961 // // dash-ify camelCased properties like WebkitTransition 6962 // prop = vendorProperties[ prop ] || prop; 6963 // transitionValues.push( toDashedAll( prop ) ); 6964 // } 6965 // munge number to millisecond, to match stagger 6966 var duration = this.layout.options.transitionDuration; 6967 duration = typeof duration == 'number' ? duration + 'ms' : duration; 6968 // enable transition styles 6969 this.css({ 6970 transitionProperty: transitionProps, 6971 transitionDuration: duration, 6972 transitionDelay: this.staggerDelay || 0 6973 }); 6974 // listen for transition end event 6975 this.element.addEventListener( transitionEndEvent, this, false ); 6976}; 6977 6978// ----- events ----- // 6979 6980proto.onwebkitTransitionEnd = function( event ) { 6981 this.ontransitionend( event ); 6982}; 6983 6984proto.onotransitionend = function( event ) { 6985 this.ontransitionend( event ); 6986}; 6987 6988// properties that I munge to make my life easier 6989var dashedVendorProperties = { 6990 '-webkit-transform': 'transform' 6991}; 6992 6993proto.ontransitionend = function( event ) { 6994 // disregard bubbled events from children 6995 if ( event.target !== this.element ) { 6996 return; 6997 } 6998 var _transition = this._transn; 6999 // get property name of transitioned property, convert to prefix-free 7000 var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName; 7001 7002 // remove property that has completed transitioning 7003 delete _transition.ingProperties[ propertyName ]; 7004 // check if any properties are still transitioning 7005 if ( isEmptyObj( _transition.ingProperties ) ) { 7006 // all properties have completed transitioning 7007 this.disableTransition(); 7008 } 7009 // clean style 7010 if ( propertyName in _transition.clean ) { 7011 // clean up style 7012 this.element.style[ event.propertyName ] = ''; 7013 delete _transition.clean[ propertyName ]; 7014 } 7015 // trigger onTransitionEnd callback 7016 if ( propertyName in _transition.onEnd ) { 7017 var onTransitionEnd = _transition.onEnd[ propertyName ]; 7018 onTransitionEnd.call( this ); 7019 delete _transition.onEnd[ propertyName ]; 7020 } 7021 7022 this.emitEvent( 'transitionEnd', [ this ] ); 7023}; 7024 7025proto.disableTransition = function() { 7026 this.removeTransitionStyles(); 7027 this.element.removeEventListener( transitionEndEvent, this, false ); 7028 this.isTransitioning = false; 7029}; 7030 7031/** 7032 * removes style property from element 7033 * @param {Object} style 7034**/ 7035proto._removeStyles = function( style ) { 7036 // clean up transition styles 7037 var cleanStyle = {}; 7038 for ( var prop in style ) { 7039 cleanStyle[ prop ] = ''; 7040 } 7041 this.css( cleanStyle ); 7042}; 7043 7044var cleanTransitionStyle = { 7045 transitionProperty: '', 7046 transitionDuration: '', 7047 transitionDelay: '' 7048}; 7049 7050proto.removeTransitionStyles = function() { 7051 // remove transition 7052 this.css( cleanTransitionStyle ); 7053}; 7054 7055// ----- stagger ----- // 7056 7057proto.stagger = function( delay ) { 7058 delay = isNaN( delay ) ? 0 : delay; 7059 this.staggerDelay = delay + 'ms'; 7060}; 7061 7062// ----- show/hide/remove ----- // 7063 7064// remove element from DOM 7065proto.removeElem = function() { 7066 this.element.parentNode.removeChild( this.element ); 7067 // remove display: none 7068 this.css({ display: '' }); 7069 this.emitEvent( 'remove', [ this ] ); 7070}; 7071 7072proto.remove = function() { 7073 // just remove element if no transition support or no transition 7074 if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) { 7075 this.removeElem(); 7076 return; 7077 } 7078 7079 // start transition 7080 this.once( 'transitionEnd', function() { 7081 this.removeElem(); 7082 }); 7083 this.hide(); 7084}; 7085 7086proto.reveal = function() { 7087 delete this.isHidden; 7088 // remove display: none 7089 this.css({ display: '' }); 7090 7091 var options = this.layout.options; 7092 7093 var onTransitionEnd = {}; 7094 var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle'); 7095 onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd; 7096 7097 this.transition({ 7098 from: options.hiddenStyle, 7099 to: options.visibleStyle, 7100 isCleaning: true, 7101 onTransitionEnd: onTransitionEnd 7102 }); 7103}; 7104 7105proto.onRevealTransitionEnd = function() { 7106 // check if still visible 7107 // during transition, item may have been hidden 7108 if ( !this.isHidden ) { 7109 this.emitEvent('reveal'); 7110 } 7111}; 7112 7113/** 7114 * get style property use for hide/reveal transition end 7115 * @param {String} styleProperty - hiddenStyle/visibleStyle 7116 * @returns {String} 7117 */ 7118proto.getHideRevealTransitionEndProperty = function( styleProperty ) { 7119 var optionStyle = this.layout.options[ styleProperty ]; 7120 // use opacity 7121 if ( optionStyle.opacity ) { 7122 return 'opacity'; 7123 } 7124 // get first property 7125 for ( var prop in optionStyle ) { 7126 return prop; 7127 } 7128}; 7129 7130proto.hide = function() { 7131 // set flag 7132 this.isHidden = true; 7133 // remove display: none 7134 this.css({ display: '' }); 7135 7136 var options = this.layout.options; 7137 7138 var onTransitionEnd = {}; 7139 var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle'); 7140 onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd; 7141 7142 this.transition({ 7143 from: options.visibleStyle, 7144 to: options.hiddenStyle, 7145 // keep hidden stuff hidden 7146 isCleaning: true, 7147 onTransitionEnd: onTransitionEnd 7148 }); 7149}; 7150 7151proto.onHideTransitionEnd = function() { 7152 // check if still hidden 7153 // during transition, item may have been un-hidden 7154 if ( this.isHidden ) { 7155 this.css({ display: 'none' }); 7156 this.emitEvent('hide'); 7157 } 7158}; 7159 7160proto.destroy = function() { 7161 this.css({ 7162 position: '', 7163 left: '', 7164 right: '', 7165 top: '', 7166 bottom: '', 7167 transition: '', 7168 transform: '' 7169 }); 7170}; 7171 7172return Item; 7173 7174})); 7175 7176/*! 7177 * Outlayer v2.1.1 7178 * the brains and guts of a layout library 7179 * MIT license 7180 */ 7181 7182( function( window, factory ) { 7183 'use strict'; 7184 // universal module definition 7185 /* jshint strict: false */ /* globals define, module, require */ 7186 if ( typeof define == 'function' && define.amd ) { 7187 // AMD - RequireJS 7188 define( 'outlayer/outlayer',[ 7189 'ev-emitter/ev-emitter', 7190 'get-size/get-size', 7191 'fizzy-ui-utils/utils', 7192 './item' 7193 ], 7194 function( EvEmitter, getSize, utils, Item ) { 7195 return factory( window, EvEmitter, getSize, utils, Item); 7196 } 7197 ); 7198 } else if ( typeof module == 'object' && module.exports ) { 7199 // CommonJS - Browserify, Webpack 7200 module.exports = factory( 7201 window, 7202 require('ev-emitter'), 7203 require('get-size'), 7204 require('fizzy-ui-utils'), 7205 require('./item') 7206 ); 7207 } else { 7208 // browser global 7209 window.Outlayer = factory( 7210 window, 7211 window.EvEmitter, 7212 window.getSize, 7213 window.fizzyUIUtils, 7214 window.Outlayer.Item 7215 ); 7216 } 7217 7218}( window, function factory( window, EvEmitter, getSize, utils, Item ) { 7219'use strict'; 7220 7221// ----- vars ----- // 7222 7223var console = window.console; 7224var jQuery = window.jQuery; 7225var noop = function() {}; 7226 7227// -------------------------- Outlayer -------------------------- // 7228 7229// globally unique identifiers 7230var GUID = 0; 7231// internal store of all Outlayer intances 7232var instances = {}; 7233 7234 7235/** 7236 * @param {Element, String} element 7237 * @param {Object} options 7238 * @constructor 7239 */ 7240function Outlayer( element, options ) { 7241 var queryElement = utils.getQueryElement( element ); 7242 if ( !queryElement ) { 7243 if ( console ) { 7244 console.error( 'Bad element for ' + this.constructor.namespace + 7245 ': ' + ( queryElement || element ) ); 7246 } 7247 return; 7248 } 7249 this.element = queryElement; 7250 // add jQuery 7251 if ( jQuery ) { 7252 this.$element = jQuery( this.element ); 7253 } 7254 7255 // options 7256 this.options = utils.extend( {}, this.constructor.defaults ); 7257 this.option( options ); 7258 7259 // add id for Outlayer.getFromElement 7260 var id = ++GUID; 7261 this.element.outlayerGUID = id; // expando 7262 instances[ id ] = this; // associate via id 7263 7264 // kick it off 7265 this._create(); 7266 7267 var isInitLayout = this._getOption('initLayout'); 7268 if ( isInitLayout ) { 7269 this.layout(); 7270 } 7271} 7272 7273// settings are for internal use only 7274Outlayer.namespace = 'outlayer'; 7275Outlayer.Item = Item; 7276 7277// default options 7278Outlayer.defaults = { 7279 containerStyle: { 7280 position: 'relative' 7281 }, 7282 initLayout: true, 7283 originLeft: true, 7284 originTop: true, 7285 resize: true, 7286 resizeContainer: true, 7287 // item options 7288 transitionDuration: '0.4s', 7289 hiddenStyle: { 7290 opacity: 0, 7291 transform: 'scale(0.001)' 7292 }, 7293 visibleStyle: { 7294 opacity: 1, 7295 transform: 'scale(1)' 7296 } 7297}; 7298 7299var proto = Outlayer.prototype; 7300// inherit EvEmitter 7301utils.extend( proto, EvEmitter.prototype ); 7302 7303/** 7304 * set options 7305 * @param {Object} opts 7306 */ 7307proto.option = function( opts ) { 7308 utils.extend( this.options, opts ); 7309}; 7310 7311/** 7312 * get backwards compatible option value, check old name 7313 */ 7314proto._getOption = function( option ) { 7315 var oldOption = this.constructor.compatOptions[ option ]; 7316 return oldOption && this.options[ oldOption ] !== undefined ? 7317 this.options[ oldOption ] : this.options[ option ]; 7318}; 7319 7320Outlayer.compatOptions = { 7321 // currentName: oldName 7322 initLayout: 'isInitLayout', 7323 horizontal: 'isHorizontal', 7324 layoutInstant: 'isLayoutInstant', 7325 originLeft: 'isOriginLeft', 7326 originTop: 'isOriginTop', 7327 resize: 'isResizeBound', 7328 resizeContainer: 'isResizingContainer' 7329}; 7330 7331proto._create = function() { 7332 // get items from children 7333 this.reloadItems(); 7334 // elements that affect layout, but are not laid out 7335 this.stamps = []; 7336 this.stamp( this.options.stamp ); 7337 // set container style 7338 utils.extend( this.element.style, this.options.containerStyle ); 7339 7340 // bind resize method 7341 var canBindResize = this._getOption('resize'); 7342 if ( canBindResize ) { 7343 this.bindResize(); 7344 } 7345}; 7346 7347// goes through all children again and gets bricks in proper order 7348proto.reloadItems = function() { 7349 // collection of item elements 7350 this.items = this._itemize( this.element.children ); 7351}; 7352 7353 7354/** 7355 * turn elements into Outlayer.Items to be used in layout 7356 * @param {Array or NodeList or HTMLElement} elems 7357 * @returns {Array} items - collection of new Outlayer Items 7358 */ 7359proto._itemize = function( elems ) { 7360 7361 var itemElems = this._filterFindItemElements( elems ); 7362 var Item = this.constructor.Item; 7363 7364 // create new Outlayer Items for collection 7365 var items = []; 7366 for ( var i=0; i < itemElems.length; i++ ) { 7367 var elem = itemElems[i]; 7368 var item = new Item( elem, this ); 7369 items.push( item ); 7370 } 7371 7372 return items; 7373}; 7374 7375/** 7376 * get item elements to be used in layout 7377 * @param {Array or NodeList or HTMLElement} elems 7378 * @returns {Array} items - item elements 7379 */ 7380proto._filterFindItemElements = function( elems ) { 7381 return utils.filterFindElements( elems, this.options.itemSelector ); 7382}; 7383 7384/** 7385 * getter method for getting item elements 7386 * @returns {Array} elems - collection of item elements 7387 */ 7388proto.getItemElements = function() { 7389 return this.items.map( function( item ) { 7390 return item.element; 7391 }); 7392}; 7393 7394// ----- init & layout ----- // 7395 7396/** 7397 * lays out all items 7398 */ 7399proto.layout = function() { 7400 this._resetLayout(); 7401 this._manageStamps(); 7402 7403 // don't animate first layout 7404 var layoutInstant = this._getOption('layoutInstant'); 7405 var isInstant = layoutInstant !== undefined ? 7406 layoutInstant : !this._isLayoutInited; 7407 this.layoutItems( this.items, isInstant ); 7408 7409 // flag for initalized 7410 this._isLayoutInited = true; 7411}; 7412 7413// _init is alias for layout 7414proto._init = proto.layout; 7415 7416/** 7417 * logic before any new layout 7418 */ 7419proto._resetLayout = function() {
vendor: 13,499 bytes, lines 7420-7988
7420 this.getSize(); 7421}; 7422 7423 7424proto.getSize = function() { 7425 this.size = getSize( this.element ); 7426}; 7427 7428/** 7429 * get measurement from option, for columnWidth, rowHeight, gutter 7430 * if option is String -> get element from selector string, & get size of element 7431 * if option is Element -> get size of element 7432 * else use option as a number 7433 * 7434 * @param {String} measurement 7435 * @param {String} size - width or height 7436 * @private 7437 */ 7438proto._getMeasurement = function( measurement, size ) { 7439 var option = this.options[ measurement ]; 7440 var elem; 7441 if ( !option ) { 7442 // default to 0 7443 this[ measurement ] = 0; 7444 } else { 7445 // use option as an element 7446 if ( typeof option == 'string' ) { 7447 elem = this.element.querySelector( option ); 7448 } else if ( option instanceof HTMLElement ) { 7449 elem = option; 7450 } 7451 // use size of element, if element 7452 this[ measurement ] = elem ? getSize( elem )[ size ] : option; 7453 } 7454}; 7455 7456/** 7457 * layout a collection of item elements 7458 * @api public 7459 */ 7460proto.layoutItems = function( items, isInstant ) { 7461 items = this._getItemsForLayout( items ); 7462 7463 this._layoutItems( items, isInstant ); 7464 7465 this._postLayout(); 7466}; 7467 7468/** 7469 * get the items to be laid out 7470 * you may want to skip over some items 7471 * @param {Array} items 7472 * @returns {Array} items 7473 */ 7474proto._getItemsForLayout = function( items ) { 7475 return items.filter( function( item ) { 7476 return !item.isIgnored; 7477 }); 7478}; 7479 7480/** 7481 * layout items 7482 * @param {Array} items 7483 * @param {Boolean} isInstant 7484 */ 7485proto._layoutItems = function( items, isInstant ) { 7486 this._emitCompleteOnItems( 'layout', items ); 7487 7488 if ( !items || !items.length ) { 7489 // no items, emit event with empty array 7490 return; 7491 } 7492 7493 var queue = []; 7494 7495 items.forEach( function( item ) { 7496 // get x/y object from method 7497 var position = this._getItemLayoutPosition( item ); 7498 // enqueue 7499 position.item = item; 7500 position.isInstant = isInstant || item.isLayoutInstant; 7501 queue.push( position ); 7502 }, this ); 7503 7504 this._processLayoutQueue( queue ); 7505}; 7506 7507/** 7508 * get item layout position 7509 * @param {Outlayer.Item} item 7510 * @returns {Object} x and y position 7511 */ 7512proto._getItemLayoutPosition = function( /* item */ ) { 7513 return { 7514 x: 0, 7515 y: 0 7516 }; 7517}; 7518 7519/** 7520 * iterate over array and position each item 7521 * Reason being - separating this logic prevents 'layout invalidation' 7522 * thx @paul_irish 7523 * @param {Array} queue 7524 */ 7525proto._processLayoutQueue = function( queue ) { 7526 this.updateStagger(); 7527 queue.forEach( function( obj, i ) { 7528 this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i ); 7529 }, this ); 7530}; 7531 7532// set stagger from option in milliseconds number 7533proto.updateStagger = function() { 7534 var stagger = this.options.stagger; 7535 if ( stagger === null || stagger === undefined ) { 7536 this.stagger = 0; 7537 return; 7538 } 7539 this.stagger = getMilliseconds( stagger ); 7540 return this.stagger; 7541}; 7542 7543/** 7544 * Sets position of item in DOM 7545 * @param {Outlayer.Item} item 7546 * @param {Number} x - horizontal position 7547 * @param {Number} y - vertical position 7548 * @param {Boolean} isInstant - disables transitions 7549 */ 7550proto._positionItem = function( item, x, y, isInstant, i ) { 7551 if ( isInstant ) { 7552 // if not transition, just set CSS 7553 item.goTo( x, y ); 7554 } else { 7555 item.stagger( i * this.stagger ); 7556 item.moveTo( x, y ); 7557 } 7558}; 7559 7560/** 7561 * Any logic you want to do after each layout, 7562 * i.e. size the container 7563 */ 7564proto._postLayout = function() { 7565 this.resizeContainer(); 7566}; 7567 7568proto.resizeContainer = function() { 7569 var isResizingContainer = this._getOption('resizeContainer'); 7570 if ( !isResizingContainer ) { 7571 return; 7572 } 7573 var size = this._getContainerSize(); 7574 if ( size ) { 7575 this._setContainerMeasure( size.width, true ); 7576 this._setContainerMeasure( size.height, false ); 7577 } 7578}; 7579 7580/** 7581 * Sets width or height of container if returned 7582 * @returns {Object} size 7583 * @param {Number} width 7584 * @param {Number} height 7585 */ 7586proto._getContainerSize = noop; 7587 7588/** 7589 * @param {Number} measure - size of width or height 7590 * @param {Boolean} isWidth 7591 */ 7592proto._setContainerMeasure = function( measure, isWidth ) { 7593 if ( measure === undefined ) { 7594 return; 7595 } 7596 7597 var elemSize = this.size; 7598 // add padding and border width if border box 7599 if ( elemSize.isBorderBox ) { 7600 measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + 7601 elemSize.borderLeftWidth + elemSize.borderRightWidth : 7602 elemSize.paddingBottom + elemSize.paddingTop + 7603 elemSize.borderTopWidth + elemSize.borderBottomWidth; 7604 } 7605 7606 measure = Math.max( measure, 0 ); 7607 this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; 7608}; 7609 7610/** 7611 * emit eventComplete on a collection of items events 7612 * @param {String} eventName 7613 * @param {Array} items - Outlayer.Items 7614 */ 7615proto._emitCompleteOnItems = function( eventName, items ) { 7616 var _this = this; 7617 function onComplete() { 7618 _this.dispatchEvent( eventName + 'Complete', null, [ items ] ); 7619 } 7620 7621 var count = items.length; 7622 if ( !items || !count ) { 7623 onComplete(); 7624 return; 7625 } 7626 7627 var doneCount = 0; 7628 function tick() { 7629 doneCount++; 7630 if ( doneCount == count ) { 7631 onComplete(); 7632 } 7633 } 7634 7635 // bind callback 7636 items.forEach( function( item ) { 7637 item.once( eventName, tick ); 7638 }); 7639}; 7640 7641/** 7642 * emits events via EvEmitter and jQuery events 7643 * @param {String} type - name of event 7644 * @param {Event} event - original event 7645 * @param {Array} args - extra arguments 7646 */ 7647proto.dispatchEvent = function( type, event, args ) { 7648 // add original event to arguments 7649 var emitArgs = event ? [ event ].concat( args ) : args; 7650 this.emitEvent( type, emitArgs ); 7651 7652 if ( jQuery ) { 7653 // set this.$element 7654 this.$element = this.$element || jQuery( this.element ); 7655 if ( event ) { 7656 // create jQuery event 7657 var $event = jQuery.Event( event ); 7658 $event.type = type; 7659 this.$element.trigger( $event, args ); 7660 } else { 7661 // just trigger with type if no event available 7662 this.$element.trigger( type, args ); 7663 } 7664 } 7665}; 7666 7667// -------------------------- ignore & stamps -------------------------- // 7668 7669 7670/** 7671 * keep item in collection, but do not lay it out 7672 * ignored items do not get skipped in layout 7673 * @param {Element} elem 7674 */ 7675proto.ignore = function( elem ) { 7676 var item = this.getItem( elem ); 7677 if ( item ) { 7678 item.isIgnored = true; 7679 } 7680}; 7681 7682/** 7683 * return item to layout collection 7684 * @param {Element} elem 7685 */ 7686proto.unignore = function( elem ) { 7687 var item = this.getItem( elem ); 7688 if ( item ) { 7689 delete item.isIgnored; 7690 } 7691}; 7692 7693/** 7694 * adds elements to stamps 7695 * @param {NodeList, Array, Element, or String} elems 7696 */ 7697proto.stamp = function( elems ) { 7698 elems = this._find( elems ); 7699 if ( !elems ) { 7700 return; 7701 } 7702 7703 this.stamps = this.stamps.concat( elems ); 7704 // ignore 7705 elems.forEach( this.ignore, this ); 7706}; 7707 7708/** 7709 * removes elements to stamps 7710 * @param {NodeList, Array, or Element} elems 7711 */ 7712proto.unstamp = function( elems ) { 7713 elems = this._find( elems ); 7714 if ( !elems ){ 7715 return; 7716 } 7717 7718 elems.forEach( function( elem ) { 7719 // filter out removed stamp elements 7720 utils.removeFrom( this.stamps, elem ); 7721 this.unignore( elem ); 7722 }, this ); 7723}; 7724 7725/** 7726 * finds child elements 7727 * @param {NodeList, Array, Element, or String} elems 7728 * @returns {Array} elems 7729 */ 7730proto._find = function( elems ) { 7731 if ( !elems ) { 7732 return; 7733 } 7734 // if string, use argument as selector string 7735 if ( typeof elems == 'string' ) { 7736 elems = this.element.querySelectorAll( elems ); 7737 } 7738 elems = utils.makeArray( elems ); 7739 return elems; 7740}; 7741 7742proto._manageStamps = function() { 7743 if ( !this.stamps || !this.stamps.length ) { 7744 return; 7745 } 7746 7747 this._getBoundingRect(); 7748 7749 this.stamps.forEach( this._manageStamp, this ); 7750}; 7751 7752// update boundingLeft / Top 7753proto._getBoundingRect = function() { 7754 // get bounding rect for container element 7755 var boundingRect = this.element.getBoundingClientRect(); 7756 var size = this.size; 7757 this._boundingRect = { 7758 left: boundingRect.left + size.paddingLeft + size.borderLeftWidth, 7759 top: boundingRect.top + size.paddingTop + size.borderTopWidth, 7760 right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ), 7761 bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth ) 7762 }; 7763}; 7764 7765/** 7766 * @param {Element} stamp 7767**/ 7768proto._manageStamp = noop; 7769 7770/** 7771 * get x/y position of element relative to container element 7772 * @param {Element} elem 7773 * @returns {Object} offset - has left, top, right, bottom 7774 */ 7775proto._getElementOffset = function( elem ) { 7776 var boundingRect = elem.getBoundingClientRect(); 7777 var thisRect = this._boundingRect; 7778 var size = getSize( elem ); 7779 var offset = { 7780 left: boundingRect.left - thisRect.left - size.marginLeft, 7781 top: boundingRect.top - thisRect.top - size.marginTop, 7782 right: thisRect.right - boundingRect.right - size.marginRight, 7783 bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom 7784 }; 7785 return offset; 7786}; 7787 7788// -------------------------- resize -------------------------- // 7789 7790// enable event handlers for listeners 7791// i.e. resize -> onresize 7792proto.handleEvent = utils.handleEvent; 7793 7794/** 7795 * Bind layout to window resizing 7796 */ 7797proto.bindResize = function() { 7798 window.addEventListener( 'resize', this ); 7799 this.isResizeBound = true; 7800}; 7801 7802/** 7803 * Unbind layout to window resizing 7804 */ 7805proto.unbindResize = function() { 7806 window.removeEventListener( 'resize', this ); 7807 this.isResizeBound = false; 7808}; 7809 7810proto.onresize = function() { 7811 this.resize(); 7812}; 7813 7814utils.debounceMethod( Outlayer, 'onresize', 100 ); 7815 7816proto.resize = function() { 7817 // don't trigger if size did not change 7818 // or if resize was unbound. See #9 7819 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 7820 return; 7821 } 7822 7823 this.layout(); 7824}; 7825 7826/** 7827 * check if layout is needed post layout 7828 * @returns Boolean 7829 */ 7830proto.needsResizeLayout = function() { 7831 var size = getSize( this.element ); 7832 // check that this.size and size are there 7833 // IE8 triggers resize on body size change, so they might not be 7834 var hasSizes = this.size && size; 7835 return hasSizes && size.innerWidth !== this.size.innerWidth; 7836}; 7837 7838// -------------------------- methods -------------------------- // 7839 7840/** 7841 * add items to Outlayer instance 7842 * @param {Array or NodeList or Element} elems 7843 * @returns {Array} items - Outlayer.Items 7844**/ 7845proto.addItems = function( elems ) { 7846 var items = this._itemize( elems ); 7847 // add items to collection 7848 if ( items.length ) { 7849 this.items = this.items.concat( items ); 7850 } 7851 return items; 7852}; 7853 7854/** 7855 * Layout newly-appended item elements 7856 * @param {Array or NodeList or Element} elems 7857 */ 7858proto.appended = function( elems ) { 7859 var items = this.addItems( elems ); 7860 if ( !items.length ) { 7861 return; 7862 } 7863 // layout and reveal just the new items 7864 this.layoutItems( items, true ); 7865 this.reveal( items ); 7866}; 7867 7868/** 7869 * Layout prepended elements 7870 * @param {Array or NodeList or Element} elems 7871 */ 7872proto.prepended = function( elems ) { 7873 var items = this._itemize( elems ); 7874 if ( !items.length ) { 7875 return; 7876 } 7877 // add items to beginning of collection 7878 var previousItems = this.items.slice(0); 7879 this.items = items.concat( previousItems ); 7880 // start new layout 7881 this._resetLayout(); 7882 this._manageStamps(); 7883 // layout new stuff without transition 7884 this.layoutItems( items, true ); 7885 this.reveal( items ); 7886 // layout previous items 7887 this.layoutItems( previousItems ); 7888}; 7889 7890/** 7891 * reveal a collection of items 7892 * @param {Array of Outlayer.Items} items 7893 */ 7894proto.reveal = function( items ) { 7895 this._emitCompleteOnItems( 'reveal', items ); 7896 if ( !items || !items.length ) { 7897 return; 7898 } 7899 var stagger = this.updateStagger(); 7900 items.forEach( function( item, i ) { 7901 item.stagger( i * stagger ); 7902 item.reveal(); 7903 }); 7904}; 7905 7906/** 7907 * hide a collection of items 7908 * @param {Array of Outlayer.Items} items 7909 */ 7910proto.hide = function( items ) { 7911 this._emitCompleteOnItems( 'hide', items ); 7912 if ( !items || !items.length ) { 7913 return; 7914 } 7915 var stagger = this.updateStagger(); 7916 items.forEach( function( item, i ) { 7917 item.stagger( i * stagger ); 7918 item.hide(); 7919 }); 7920}; 7921 7922/** 7923 * reveal item elements 7924 * @param {Array}, {Element}, {NodeList} items 7925 */ 7926proto.revealItemElements = function( elems ) { 7927 var items = this.getItems( elems ); 7928 this.reveal( items ); 7929}; 7930 7931/** 7932 * hide item elements 7933 * @param {Array}, {Element}, {NodeList} items 7934 */ 7935proto.hideItemElements = function( elems ) { 7936 var items = this.getItems( elems ); 7937 this.hide( items ); 7938}; 7939 7940/** 7941 * get Outlayer.Item, given an Element 7942 * @param {Element} elem 7943 * @param {Function} callback 7944 * @returns {Outlayer.Item} item 7945 */ 7946proto.getItem = function( elem ) { 7947 // loop through items to get the one that matches 7948 for ( var i=0; i < this.items.length; i++ ) { 7949 var item = this.items[i]; 7950 if ( item.element == elem ) { 7951 // return item 7952 return item; 7953 } 7954 } 7955}; 7956 7957/** 7958 * get collection of Outlayer.Items, given Elements 7959 * @param {Array} elems 7960 * @returns {Array} items - Outlayer.Items 7961 */ 7962proto.getItems = function( elems ) { 7963 elems = utils.makeArray( elems ); 7964 var items = []; 7965 elems.forEach( function( elem ) { 7966 var item = this.getItem( elem ); 7967 if ( item ) { 7968 items.push( item ); 7969 } 7970 }, this ); 7971 7972 return items; 7973}; 7974 7975/** 7976 * remove element(s) from instance and DOM 7977 * @param {Array or NodeList or Element} elems 7978 */ 7979proto.remove = function( elems ) { 7980 var removeItems = this.getItems( elems ); 7981 7982 this._emitCompleteOnItems( 'remove', removeItems ); 7983 7984 // bail if no items to remove 7985 if ( !removeItems || !removeItems.length ) { 7986 return; 7987 } 7988
vendor: 38,285 bytes, lines 7989-9412
7989 removeItems.forEach( function( item ) { 7990 item.remove(); 7991 // remove item from collection 7992 utils.removeFrom( this.items, item ); 7993 }, this ); 7994}; 7995 7996// ----- destroy ----- // 7997 7998// remove and disable Outlayer instance 7999proto.destroy = function() { 8000 // clean up dynamic styles 8001 var style = this.element.style; 8002 style.height = ''; 8003 style.position = ''; 8004 style.width = ''; 8005 // destroy items 8006 this.items.forEach( function( item ) { 8007 item.destroy(); 8008 }); 8009 8010 this.unbindResize(); 8011 8012 var id = this.element.outlayerGUID; 8013 delete instances[ id ]; // remove reference to instance by id 8014 delete this.element.outlayerGUID; 8015 // remove data for jQuery 8016 if ( jQuery ) { 8017 jQuery.removeData( this.element, this.constructor.namespace ); 8018 } 8019 8020}; 8021 8022// -------------------------- data -------------------------- // 8023 8024/** 8025 * get Outlayer instance from element 8026 * @param {Element} elem 8027 * @returns {Outlayer} 8028 */ 8029Outlayer.data = function( elem ) { 8030 elem = utils.getQueryElement( elem ); 8031 var id = elem && elem.outlayerGUID; 8032 return id && instances[ id ]; 8033}; 8034 8035 8036// -------------------------- create Outlayer class -------------------------- // 8037 8038/** 8039 * create a layout class 8040 * @param {String} namespace 8041 */ 8042Outlayer.create = function( namespace, options ) { 8043 // sub-class Outlayer 8044 var Layout = subclass( Outlayer ); 8045 // apply new options and compatOptions 8046 Layout.defaults = utils.extend( {}, Outlayer.defaults ); 8047 utils.extend( Layout.defaults, options ); 8048 Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions ); 8049 8050 Layout.namespace = namespace; 8051 8052 Layout.data = Outlayer.data; 8053 8054 // sub-class Item 8055 Layout.Item = subclass( Item ); 8056 8057 // -------------------------- declarative -------------------------- // 8058 8059 utils.htmlInit( Layout, namespace ); 8060 8061 // -------------------------- jQuery bridge -------------------------- // 8062 8063 // make into jQuery plugin 8064 if ( jQuery && jQuery.bridget ) { 8065 jQuery.bridget( namespace, Layout ); 8066 } 8067 8068 return Layout; 8069}; 8070 8071function subclass( Parent ) { 8072 function SubClass() { 8073 Parent.apply( this, arguments ); 8074 } 8075 8076 SubClass.prototype = Object.create( Parent.prototype ); 8077 SubClass.prototype.constructor = SubClass; 8078 8079 return SubClass; 8080} 8081 8082// ----- helpers ----- // 8083 8084// how many milliseconds are in each unit 8085var msUnits = { 8086 ms: 1, 8087 s: 1000 8088}; 8089 8090// munge time-like parameter into millisecond number 8091// '0.4s' -> 40 8092function getMilliseconds( time ) { 8093 if ( typeof time == 'number' ) { 8094 return time; 8095 } 8096 var matches = time.match( /(^\d*\.?\d*)(\w*)/ ); 8097 var num = matches && matches[1]; 8098 var unit = matches && matches[2]; 8099 if ( !num.length ) { 8100 return 0; 8101 } 8102 num = parseFloat( num ); 8103 var mult = msUnits[ unit ] || 1; 8104 return num * mult; 8105} 8106 8107// ----- fin ----- // 8108 8109// back in global 8110Outlayer.Item = Item; 8111 8112return Outlayer; 8113 8114})); 8115 8116/** 8117 * Isotope Item 8118**/ 8119 8120( function( window, factory ) { 8121 // universal module definition 8122 /* jshint strict: false */ /*globals define, module, require */ 8123 if ( typeof define == 'function' && define.amd ) { 8124 // AMD 8125 define( 'isotope-layout/js/item',[ 8126 'outlayer/outlayer' 8127 ], 8128 factory ); 8129 } else if ( typeof module == 'object' && module.exports ) { 8130 // CommonJS 8131 module.exports = factory( 8132 require('outlayer') 8133 ); 8134 } else { 8135 // browser global 8136 window.Isotope = window.Isotope || {}; 8137 window.Isotope.Item = factory( 8138 window.Outlayer 8139 ); 8140 } 8141 8142}( window, function factory( Outlayer ) { 8143'use strict'; 8144 8145// -------------------------- Item -------------------------- // 8146 8147// sub-class Outlayer Item 8148function Item() { 8149 Outlayer.Item.apply( this, arguments ); 8150} 8151 8152var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 8153 8154var _create = proto._create; 8155proto._create = function() { 8156 // assign id, used for original-order sorting 8157 this.id = this.layout.itemGUID++; 8158 _create.call( this ); 8159 this.sortData = {}; 8160}; 8161 8162proto.updateSortData = function() { 8163 if ( this.isIgnored ) { 8164 return; 8165 } 8166 // default sorters 8167 this.sortData.id = this.id; 8168 // for backward compatibility 8169 this.sortData['original-order'] = this.id; 8170 this.sortData.random = Math.random(); 8171 // go thru getSortData obj and apply the sorters 8172 var getSortData = this.layout.options.getSortData; 8173 var sorters = this.layout._sorters; 8174 for ( var key in getSortData ) { 8175 var sorter = sorters[ key ]; 8176 this.sortData[ key ] = sorter( this.element, this ); 8177 } 8178}; 8179 8180var _destroy = proto.destroy; 8181proto.destroy = function() { 8182 // call super 8183 _destroy.apply( this, arguments ); 8184 // reset display, #741 8185 this.css({ 8186 display: '' 8187 }); 8188}; 8189 8190return Item; 8191 8192})); 8193 8194/** 8195 * Isotope LayoutMode 8196 */ 8197 8198( function( window, factory ) { 8199 // universal module definition 8200 /* jshint strict: false */ /*globals define, module, require */ 8201 if ( typeof define == 'function' && define.amd ) { 8202 // AMD 8203 define( 'isotope-layout/js/layout-mode',[ 8204 'get-size/get-size', 8205 'outlayer/outlayer' 8206 ], 8207 factory ); 8208 } else if ( typeof module == 'object' && module.exports ) { 8209 // CommonJS 8210 module.exports = factory( 8211 require('get-size'), 8212 require('outlayer') 8213 ); 8214 } else { 8215 // browser global 8216 window.Isotope = window.Isotope || {}; 8217 window.Isotope.LayoutMode = factory( 8218 window.getSize, 8219 window.Outlayer 8220 ); 8221 } 8222 8223}( window, function factory( getSize, Outlayer ) { 8224 'use strict'; 8225 8226 // layout mode class 8227 function LayoutMode( isotope ) { 8228 this.isotope = isotope; 8229 // link properties 8230 if ( isotope ) { 8231 this.options = isotope.options[ this.namespace ]; 8232 this.element = isotope.element; 8233 this.items = isotope.filteredItems; 8234 this.size = isotope.size; 8235 } 8236 } 8237 8238 var proto = LayoutMode.prototype; 8239 8240 /** 8241 * some methods should just defer to default Outlayer method 8242 * and reference the Isotope instance as `this` 8243 **/ 8244 var facadeMethods = [ 8245 '_resetLayout', 8246 '_getItemLayoutPosition', 8247 '_manageStamp', 8248 '_getContainerSize', 8249 '_getElementOffset', 8250 'needsResizeLayout', 8251 '_getOption' 8252 ]; 8253 8254 facadeMethods.forEach( function( methodName ) { 8255 proto[ methodName ] = function() { 8256 return Outlayer.prototype[ methodName ].apply( this.isotope, arguments ); 8257 }; 8258 }); 8259 8260 // ----- ----- // 8261 8262 // for horizontal layout modes, check vertical size 8263 proto.needsVerticalResizeLayout = function() { 8264 // don't trigger if size did not change 8265 var size = getSize( this.isotope.element ); 8266 // check that this.size and size are there 8267 // IE8 triggers resize on body size change, so they might not be 8268 var hasSizes = this.isotope.size && size; 8269 return hasSizes && size.innerHeight != this.isotope.size.innerHeight; 8270 }; 8271 8272 // ----- measurements ----- // 8273 8274 proto._getMeasurement = function() { 8275 this.isotope._getMeasurement.apply( this, arguments ); 8276 }; 8277 8278 proto.getColumnWidth = function() { 8279 this.getSegmentSize( 'column', 'Width' ); 8280 }; 8281 8282 proto.getRowHeight = function() { 8283 this.getSegmentSize( 'row', 'Height' ); 8284 }; 8285 8286 /** 8287 * get columnWidth or rowHeight 8288 * segment: 'column' or 'row' 8289 * size 'Width' or 'Height' 8290 **/ 8291 proto.getSegmentSize = function( segment, size ) { 8292 var segmentName = segment + size; 8293 var outerSize = 'outer' + size; 8294 // columnWidth / outerWidth // rowHeight / outerHeight 8295 this._getMeasurement( segmentName, outerSize ); 8296 // got rowHeight or columnWidth, we can chill 8297 if ( this[ segmentName ] ) { 8298 return; 8299 } 8300 // fall back to item of first element 8301 var firstItemSize = this.getFirstItemSize(); 8302 this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] || 8303 // or size of container 8304 this.isotope.size[ 'inner' + size ]; 8305 }; 8306 8307 proto.getFirstItemSize = function() { 8308 var firstItem = this.isotope.filteredItems[0]; 8309 return firstItem && firstItem.element && getSize( firstItem.element ); 8310 }; 8311 8312 // ----- methods that should reference isotope ----- // 8313 8314 proto.layout = function() { 8315 this.isotope.layout.apply( this.isotope, arguments ); 8316 }; 8317 8318 proto.getSize = function() { 8319 this.isotope.getSize(); 8320 this.size = this.isotope.size; 8321 }; 8322 8323 // -------------------------- create -------------------------- // 8324 8325 LayoutMode.modes = {}; 8326 8327 LayoutMode.create = function( namespace, options ) { 8328 8329 function Mode() { 8330 LayoutMode.apply( this, arguments ); 8331 } 8332 8333 Mode.prototype = Object.create( proto ); 8334 Mode.prototype.constructor = Mode; 8335 8336 // default options 8337 if ( options ) { 8338 Mode.options = options; 8339 } 8340 8341 Mode.prototype.namespace = namespace; 8342 // register in Isotope 8343 LayoutMode.modes[ namespace ] = Mode; 8344 8345 return Mode; 8346 }; 8347 8348 return LayoutMode; 8349 8350})); 8351 8352/*! 8353 * Masonry v4.2.1 8354 * Cascading grid layout library 8355 * https://masonry.desandro.com 8356 * MIT License 8357 * by David DeSandro 8358 */ 8359 8360( function( window, factory ) { 8361 // universal module definition 8362 /* jshint strict: false */ /*globals define, module, require */ 8363 if ( typeof define == 'function' && define.amd ) { 8364 // AMD 8365 define( 'masonry-layout/masonry',[ 8366 'outlayer/outlayer', 8367 'get-size/get-size' 8368 ], 8369 factory ); 8370 } else if ( typeof module == 'object' && module.exports ) { 8371 // CommonJS 8372 module.exports = factory( 8373 require('outlayer'), 8374 require('get-size') 8375 ); 8376 } else { 8377 // browser global 8378 window.Masonry = factory( 8379 window.Outlayer, 8380 window.getSize 8381 ); 8382 } 8383 8384}( window, function factory( Outlayer, getSize ) { 8385 8386 8387 8388// -------------------------- masonryDefinition -------------------------- // 8389 8390 // create an Outlayer layout class 8391 var Masonry = Outlayer.create('masonry'); 8392 // isFitWidth -> fitWidth 8393 Masonry.compatOptions.fitWidth = 'isFitWidth'; 8394 8395 var proto = Masonry.prototype; 8396 8397 proto._resetLayout = function() { 8398 this.getSize(); 8399 this._getMeasurement( 'columnWidth', 'outerWidth' ); 8400 this._getMeasurement( 'gutter', 'outerWidth' ); 8401 this.measureColumns(); 8402 8403 // reset column Y 8404 this.colYs = []; 8405 for ( var i=0; i < this.cols; i++ ) { 8406 this.colYs.push( 0 ); 8407 } 8408 8409 this.maxY = 0; 8410 this.horizontalColIndex = 0; 8411 }; 8412 8413 proto.measureColumns = function() { 8414 this.getContainerWidth(); 8415 // if columnWidth is 0, default to outerWidth of first item 8416 if ( !this.columnWidth ) { 8417 var firstItem = this.items[0]; 8418 var firstItemElem = firstItem && firstItem.element; 8419 // columnWidth fall back to item of first element 8420 this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth || 8421 // if first elem has no width, default to size of container 8422 this.containerWidth; 8423 } 8424 8425 var columnWidth = this.columnWidth += this.gutter; 8426 8427 // calculate columns 8428 var containerWidth = this.containerWidth + this.gutter; 8429 var cols = containerWidth / columnWidth; 8430 // fix rounding errors, typically with gutters 8431 var excess = columnWidth - containerWidth % columnWidth; 8432 // if overshoot is less than a pixel, round up, otherwise floor it 8433 var mathMethod = excess && excess < 1 ? 'round' : 'floor'; 8434 cols = Math[ mathMethod ]( cols ); 8435 this.cols = Math.max( cols, 1 ); 8436 }; 8437 8438 proto.getContainerWidth = function() { 8439 // container is parent if fit width 8440 var isFitWidth = this._getOption('fitWidth'); 8441 var container = isFitWidth ? this.element.parentNode : this.element; 8442 // check that this.size and size are there 8443 // IE8 triggers resize on body size change, so they might not be 8444 var size = getSize( container ); 8445 this.containerWidth = size && size.innerWidth; 8446 }; 8447 8448 proto._getItemLayoutPosition = function( item ) { 8449 item.getSize(); 8450 // how many columns does this brick span 8451 var remainder = item.size.outerWidth % this.columnWidth; 8452 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 8453 // round if off by 1 pixel, otherwise use ceil 8454 var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth ); 8455 colSpan = Math.min( colSpan, this.cols ); 8456 // use horizontal or top column position 8457 var colPosMethod = this.options.horizontalOrder ? 8458 '_getHorizontalColPosition' : '_getTopColPosition'; 8459 var colPosition = this[ colPosMethod ]( colSpan, item ); 8460 // position the brick 8461 var position = { 8462 x: this.columnWidth * colPosition.col, 8463 y: colPosition.y 8464 }; 8465 // apply setHeight to necessary columns 8466 var setHeight = colPosition.y + item.size.outerHeight; 8467 var setMax = colSpan + colPosition.col; 8468 for ( var i = colPosition.col; i < setMax; i++ ) { 8469 this.colYs[i] = setHeight; 8470 } 8471 8472 return position; 8473 }; 8474 8475 proto._getTopColPosition = function( colSpan ) { 8476 var colGroup = this._getTopColGroup( colSpan ); 8477 // get the minimum Y value from the columns 8478 var minimumY = Math.min.apply( Math, colGroup ); 8479 8480 return { 8481 col: colGroup.indexOf( minimumY ), 8482 y: minimumY, 8483 }; 8484 }; 8485 8486 /** 8487 * @param {Number} colSpan - number of columns the element spans 8488 * @returns {Array} colGroup 8489 */ 8490 proto._getTopColGroup = function( colSpan ) { 8491 if ( colSpan < 2 ) { 8492 // if brick spans only one column, use all the column Ys 8493 return this.colYs; 8494 } 8495 8496 var colGroup = []; 8497 // how many different places could this brick fit horizontally 8498 var groupCount = this.cols + 1 - colSpan; 8499 // for each group potential horizontal position 8500 for ( var i = 0; i < groupCount; i++ ) { 8501 colGroup[i] = this._getColGroupY( i, colSpan ); 8502 } 8503 return colGroup; 8504 }; 8505 8506 proto._getColGroupY = function( col, colSpan ) { 8507 if ( colSpan < 2 ) { 8508 return this.colYs[ col ]; 8509 } 8510 // make an array of colY values for that one group 8511 var groupColYs = this.colYs.slice( col, col + colSpan ); 8512 // and get the max value of the array 8513 return Math.max.apply( Math, groupColYs ); 8514 }; 8515 8516 // get column position based on horizontal index. #873 8517 proto._getHorizontalColPosition = function( colSpan, item ) { 8518 var col = this.horizontalColIndex % this.cols; 8519 var isOver = colSpan > 1 && col + colSpan > this.cols; 8520 // shift to next row if item can't fit on current row 8521 col = isOver ? 0 : col; 8522 // don't let zero-size items take up space 8523 var hasSize = item.size.outerWidth && item.size.outerHeight; 8524 this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex; 8525 8526 return { 8527 col: col, 8528 y: this._getColGroupY( col, colSpan ), 8529 }; 8530 }; 8531 8532 proto._manageStamp = function( stamp ) { 8533 var stampSize = getSize( stamp ); 8534 var offset = this._getElementOffset( stamp ); 8535 // get the columns that this stamp affects 8536 var isOriginLeft = this._getOption('originLeft'); 8537 var firstX = isOriginLeft ? offset.left : offset.right; 8538 var lastX = firstX + stampSize.outerWidth; 8539 var firstCol = Math.floor( firstX / this.columnWidth ); 8540 firstCol = Math.max( 0, firstCol ); 8541 var lastCol = Math.floor( lastX / this.columnWidth ); 8542 // lastCol should not go over if multiple of columnWidth #425 8543 lastCol -= lastX % this.columnWidth ? 0 : 1; 8544 lastCol = Math.min( this.cols - 1, lastCol ); 8545 // set colYs to bottom of the stamp 8546 8547 var isOriginTop = this._getOption('originTop'); 8548 var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) + 8549 stampSize.outerHeight; 8550 for ( var i = firstCol; i <= lastCol; i++ ) { 8551 this.colYs[i] = Math.max( stampMaxY, this.colYs[i] ); 8552 } 8553 }; 8554 8555 proto._getContainerSize = function() { 8556 this.maxY = Math.max.apply( Math, this.colYs ); 8557 var size = { 8558 height: this.maxY 8559 }; 8560 8561 if ( this._getOption('fitWidth') ) { 8562 size.width = this._getContainerFitWidth(); 8563 } 8564 8565 return size; 8566 }; 8567 8568 proto._getContainerFitWidth = function() { 8569 var unusedCols = 0; 8570 // count unused columns 8571 var i = this.cols; 8572 while ( --i ) { 8573 if ( this.colYs[i] !== 0 ) { 8574 break; 8575 } 8576 unusedCols++; 8577 } 8578 // fit container to columns that have been used 8579 return ( this.cols - unusedCols ) * this.columnWidth - this.gutter; 8580 }; 8581 8582 proto.needsResizeLayout = function() { 8583 var previousWidth = this.containerWidth; 8584 this.getContainerWidth(); 8585 return previousWidth != this.containerWidth; 8586 }; 8587 8588 return Masonry; 8589 8590})); 8591 8592/*! 8593 * Masonry layout mode 8594 * sub-classes Masonry 8595 * https://masonry.desandro.com 8596 */ 8597 8598( function( window, factory ) { 8599 // universal module definition 8600 /* jshint strict: false */ /*globals define, module, require */ 8601 if ( typeof define == 'function' && define.amd ) { 8602 // AMD 8603 define( 'isotope-layout/js/layout-modes/masonry',[ 8604 '../layout-mode', 8605 'masonry-layout/masonry' 8606 ], 8607 factory ); 8608 } else if ( typeof module == 'object' && module.exports ) { 8609 // CommonJS 8610 module.exports = factory( 8611 require('../layout-mode'), 8612 require('masonry-layout') 8613 ); 8614 } else { 8615 // browser global 8616 factory( 8617 window.Isotope.LayoutMode, 8618 window.Masonry 8619 ); 8620 } 8621 8622}( window, function factory( LayoutMode, Masonry ) { 8623'use strict'; 8624 8625// -------------------------- masonryDefinition -------------------------- // 8626 8627 // create an Outlayer layout class 8628 var MasonryMode = LayoutMode.create('masonry'); 8629 8630 var proto = MasonryMode.prototype; 8631 8632 var keepModeMethods = { 8633 _getElementOffset: true, 8634 layout: true, 8635 _getMeasurement: true 8636 }; 8637 8638 // inherit Masonry prototype 8639 for ( var method in Masonry.prototype ) { 8640 // do not inherit mode methods 8641 if ( !keepModeMethods[ method ] ) { 8642 proto[ method ] = Masonry.prototype[ method ]; 8643 } 8644 } 8645 8646 var measureColumns = proto.measureColumns; 8647 proto.measureColumns = function() { 8648 // set items, used if measuring first item 8649 this.items = this.isotope.filteredItems; 8650 measureColumns.call( this ); 8651 }; 8652 8653 // point to mode options for fitWidth 8654 var _getOption = proto._getOption; 8655 proto._getOption = function( option ) { 8656 if ( option == 'fitWidth' ) { 8657 return this.options.isFitWidth !== undefined ? 8658 this.options.isFitWidth : this.options.fitWidth; 8659 } 8660 return _getOption.apply( this.isotope, arguments ); 8661 }; 8662 8663 return MasonryMode; 8664 8665})); 8666 8667/** 8668 * fitRows layout mode 8669 */ 8670 8671( function( window, factory ) { 8672 // universal module definition 8673 /* jshint strict: false */ /*globals define, module, require */ 8674 if ( typeof define == 'function' && define.amd ) { 8675 // AMD 8676 define( 'isotope-layout/js/layout-modes/fit-rows',[ 8677 '../layout-mode' 8678 ], 8679 factory ); 8680 } else if ( typeof exports == 'object' ) { 8681 // CommonJS 8682 module.exports = factory( 8683 require('../layout-mode') 8684 ); 8685 } else { 8686 // browser global 8687 factory( 8688 window.Isotope.LayoutMode 8689 ); 8690 } 8691 8692}( window, function factory( LayoutMode ) { 8693'use strict'; 8694 8695var FitRows = LayoutMode.create('fitRows'); 8696 8697var proto = FitRows.prototype; 8698 8699proto._resetLayout = function() { 8700 this.x = 0; 8701 this.y = 0; 8702 this.maxY = 0; 8703 this._getMeasurement( 'gutter', 'outerWidth' ); 8704}; 8705 8706proto._getItemLayoutPosition = function( item ) { 8707 item.getSize(); 8708 8709 var itemWidth = item.size.outerWidth + this.gutter; 8710 // if this element cannot fit in the current row 8711 var containerWidth = this.isotope.size.innerWidth + this.gutter; 8712 if ( this.x !== 0 && itemWidth + this.x > containerWidth ) { 8713 this.x = 0; 8714 this.y = this.maxY; 8715 } 8716 8717 var position = { 8718 x: this.x, 8719 y: this.y 8720 }; 8721 8722 this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight ); 8723 this.x += itemWidth; 8724 8725 return position; 8726}; 8727 8728proto._getContainerSize = function() { 8729 return { height: this.maxY }; 8730}; 8731 8732return FitRows; 8733 8734})); 8735 8736/** 8737 * vertical layout mode 8738 */ 8739 8740( function( window, factory ) { 8741 // universal module definition 8742 /* jshint strict: false */ /*globals define, module, require */ 8743 if ( typeof define == 'function' && define.amd ) { 8744 // AMD 8745 define( 'isotope-layout/js/layout-modes/vertical',[ 8746 '../layout-mode' 8747 ], 8748 factory ); 8749 } else if ( typeof module == 'object' && module.exports ) { 8750 // CommonJS 8751 module.exports = factory( 8752 require('../layout-mode') 8753 ); 8754 } else { 8755 // browser global 8756 factory( 8757 window.Isotope.LayoutMode 8758 ); 8759 } 8760 8761}( window, function factory( LayoutMode ) { 8762'use strict'; 8763 8764var Vertical = LayoutMode.create( 'vertical', { 8765 horizontalAlignment: 0 8766}); 8767 8768var proto = Vertical.prototype; 8769 8770proto._resetLayout = function() { 8771 this.y = 0; 8772}; 8773 8774proto._getItemLayoutPosition = function( item ) { 8775 item.getSize(); 8776 var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) * 8777 this.options.horizontalAlignment; 8778 var y = this.y; 8779 this.y += item.size.outerHeight; 8780 return { x: x, y: y }; 8781}; 8782 8783proto._getContainerSize = function() { 8784 return { height: this.y }; 8785}; 8786 8787return Vertical; 8788 8789})); 8790 8791/*! 8792 * Isotope v3.0.6 8793 * 8794 * Licensed GPLv3 for open source use 8795 * or Isotope Commercial License for commercial use 8796 * 8797 * https://isotope.metafizzy.co 8798 * Copyright 2010-2018 Metafizzy 8799 */ 8800 8801( function( window, factory ) { 8802 // universal module definition 8803 /* jshint strict: false */ /*globals define, module, require */ 8804 if ( typeof define == 'function' && define.amd ) { 8805 // AMD 8806 define( [ 8807 'outlayer/outlayer', 8808 'get-size/get-size', 8809 'desandro-matches-selector/matches-selector', 8810 'fizzy-ui-utils/utils', 8811 'isotope-layout/js/item', 8812 'isotope-layout/js/layout-mode', 8813 // include default layout modes 8814 'isotope-layout/js/layout-modes/masonry', 8815 'isotope-layout/js/layout-modes/fit-rows', 8816 'isotope-layout/js/layout-modes/vertical' 8817 ], 8818 function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) { 8819 return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ); 8820 }); 8821 } else if ( typeof module == 'object' && module.exports ) { 8822 // CommonJS 8823 module.exports = factory( 8824 window, 8825 require('outlayer'), 8826 require('get-size'), 8827 require('desandro-matches-selector'), 8828 require('fizzy-ui-utils'), 8829 require('isotope-layout/js/item'), 8830 require('isotope-layout/js/layout-mode'), 8831 // include default layout modes 8832 require('isotope-layout/js/layout-modes/masonry'), 8833 require('isotope-layout/js/layout-modes/fit-rows'), 8834 require('isotope-layout/js/layout-modes/vertical') 8835 ); 8836 } else { 8837 // browser global 8838 window.Isotope = factory( 8839 window, 8840 window.Outlayer, 8841 window.getSize, 8842 window.matchesSelector, 8843 window.fizzyUIUtils, 8844 window.Isotope.Item, 8845 window.Isotope.LayoutMode 8846 ); 8847 } 8848 8849}( window, function factory( window, Outlayer, getSize, matchesSelector, utils, 8850 Item, LayoutMode ) { 8851 8852 8853 8854// -------------------------- vars -------------------------- // 8855 8856var jQuery = window.jQuery; 8857 8858// -------------------------- helpers -------------------------- // 8859 8860var trim = String.prototype.trim ? 8861 function( str ) { 8862 return str.trim(); 8863 } : 8864 function( str ) { 8865 return str.replace( /^\s+|\s+$/g, '' ); 8866 }; 8867 8868// -------------------------- isotopeDefinition -------------------------- // 8869 8870 // create an Outlayer layout class 8871 var Isotope = Outlayer.create( 'isotope', { 8872 layoutMode: 'masonry', 8873 isJQueryFiltering: true, 8874 sortAscending: true 8875 }); 8876 8877 Isotope.Item = Item; 8878 Isotope.LayoutMode = LayoutMode; 8879 8880 var proto = Isotope.prototype; 8881 8882 proto._create = function() { 8883 this.itemGUID = 0; 8884 // functions that sort items 8885 this._sorters = {}; 8886 this._getSorters(); 8887 // call super 8888 Outlayer.prototype._create.call( this ); 8889 8890 // create layout modes 8891 this.modes = {}; 8892 // start filteredItems with all items 8893 this.filteredItems = this.items; 8894 // keep of track of sortBys 8895 this.sortHistory = [ 'original-order' ]; 8896 // create from registered layout modes 8897 for ( var name in LayoutMode.modes ) { 8898 this._initLayoutMode( name ); 8899 } 8900 }; 8901 8902 proto.reloadItems = function() { 8903 // reset item ID counter 8904 this.itemGUID = 0; 8905 // call super 8906 Outlayer.prototype.reloadItems.call( this ); 8907 }; 8908 8909 proto._itemize = function() { 8910 var items = Outlayer.prototype._itemize.apply( this, arguments ); 8911 // assign ID for original-order 8912 for ( var i=0; i < items.length; i++ ) { 8913 var item = items[i]; 8914 item.id = this.itemGUID++; 8915 } 8916 this._updateItemsSortData( items ); 8917 return items; 8918 }; 8919 8920 8921 // -------------------------- layout -------------------------- // 8922 8923 proto._initLayoutMode = function( name ) { 8924 var Mode = LayoutMode.modes[ name ]; 8925 // set mode options 8926 // HACK extend initial options, back-fill in default options 8927 var initialOpts = this.options[ name ] || {}; 8928 this.options[ name ] = Mode.options ? 8929 utils.extend( Mode.options, initialOpts ) : initialOpts; 8930 // init layout mode instance 8931 this.modes[ name ] = new Mode( this ); 8932 }; 8933 8934 8935 proto.layout = function() { 8936 // if first time doing layout, do all magic 8937 if ( !this._isLayoutInited && this._getOption('initLayout') ) { 8938 this.arrange(); 8939 return; 8940 } 8941 this._layout(); 8942 }; 8943 8944 // private method to be used in layout() & magic() 8945 proto._layout = function() { 8946 // don't animate first layout 8947 var isInstant = this._getIsInstant(); 8948 // layout flow 8949 this._resetLayout(); 8950 this._manageStamps(); 8951 this.layoutItems( this.filteredItems, isInstant ); 8952 8953 // flag for initalized 8954 this._isLayoutInited = true; 8955 }; 8956 8957 // filter + sort + layout 8958 proto.arrange = function( opts ) { 8959 // set any options pass 8960 this.option( opts ); 8961 this._getIsInstant(); 8962 // filter, sort, and layout 8963 8964 // filter 8965 var filtered = this._filter( this.items ); 8966 this.filteredItems = filtered.matches; 8967 8968 this._bindArrangeComplete(); 8969 8970 if ( this._isInstant ) { 8971 this._noTransition( this._hideReveal, [ filtered ] ); 8972 } else { 8973 this._hideReveal( filtered ); 8974 } 8975 8976 this._sort(); 8977 this._layout(); 8978 }; 8979 // alias to _init for main plugin method 8980 proto._init = proto.arrange; 8981 8982 proto._hideReveal = function( filtered ) { 8983 this.reveal( filtered.needReveal ); 8984 this.hide( filtered.needHide ); 8985 }; 8986 8987 // HACK 8988 // Don't animate/transition first layout 8989 // Or don't animate/transition other layouts 8990 proto._getIsInstant = function() { 8991 var isLayoutInstant = this._getOption('layoutInstant'); 8992 var isInstant = isLayoutInstant !== undefined ? isLayoutInstant : 8993 !this._isLayoutInited; 8994 this._isInstant = isInstant; 8995 return isInstant; 8996 }; 8997 8998 // listen for layoutComplete, hideComplete and revealComplete 8999 // to trigger arrangeComplete 9000 proto._bindArrangeComplete = function() { 9001 // listen for 3 events to trigger arrangeComplete 9002 var isLayoutComplete, isHideComplete, isRevealComplete; 9003 var _this = this; 9004 function arrangeParallelCallback() { 9005 if ( isLayoutComplete && isHideComplete && isRevealComplete ) { 9006 _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] ); 9007 } 9008 } 9009 this.once( 'layoutComplete', function() { 9010 isLayoutComplete = true; 9011 arrangeParallelCallback(); 9012 }); 9013 this.once( 'hideComplete', function() { 9014 isHideComplete = true; 9015 arrangeParallelCallback(); 9016 }); 9017 this.once( 'revealComplete', function() { 9018 isRevealComplete = true; 9019 arrangeParallelCallback(); 9020 }); 9021 }; 9022 9023 // -------------------------- filter -------------------------- // 9024 9025 proto._filter = function( items ) { 9026 var filter = this.options.filter; 9027 filter = filter || '*'; 9028 var matches = []; 9029 var hiddenMatched = []; 9030 var visibleUnmatched = []; 9031 9032 var test = this._getFilterTest( filter ); 9033 9034 // test each item 9035 for ( var i=0; i < items.length; i++ ) { 9036 var item = items[i]; 9037 if ( item.isIgnored ) { 9038 continue; 9039 } 9040 // add item to either matched or unmatched group 9041 var isMatched = test( item ); 9042 // item.isFilterMatched = isMatched; 9043 // add to matches if its a match 9044 if ( isMatched ) { 9045 matches.push( item ); 9046 } 9047 // add to additional group if item needs to be hidden or revealed 9048 if ( isMatched && item.isHidden ) { 9049 hiddenMatched.push( item ); 9050 } else if ( !isMatched && !item.isHidden ) { 9051 visibleUnmatched.push( item ); 9052 } 9053 } 9054 9055 // return collections of items to be manipulated 9056 return { 9057 matches: matches, 9058 needReveal: hiddenMatched, 9059 needHide: visibleUnmatched 9060 }; 9061 }; 9062 9063 // get a jQuery, function, or a matchesSelector test given the filter 9064 proto._getFilterTest = function( filter ) { 9065 if ( jQuery && this.options.isJQueryFiltering ) { 9066 // use jQuery 9067 return function( item ) { 9068 return jQuery( item.element ).is( filter ); 9069 }; 9070 } 9071 if ( typeof filter == 'function' ) { 9072 // use filter as function 9073 return function( item ) { 9074 return filter( item.element ); 9075 }; 9076 } 9077 // default, use filter as selector string 9078 return function( item ) { 9079 return matchesSelector( item.element, filter ); 9080 }; 9081 }; 9082 9083 // -------------------------- sorting -------------------------- // 9084 9085 /** 9086 * @params {Array} elems 9087 * @public 9088 */ 9089 proto.updateSortData = function( elems ) { 9090 // get items 9091 var items; 9092 if ( elems ) { 9093 elems = utils.makeArray( elems ); 9094 items = this.getItems( elems ); 9095 } else { 9096 // update all items if no elems provided 9097 items = this.items; 9098 } 9099 9100 this._getSorters(); 9101 this._updateItemsSortData( items ); 9102 }; 9103 9104 proto._getSorters = function() { 9105 var getSortData = this.options.getSortData; 9106 for ( var key in getSortData ) { 9107 var sorter = getSortData[ key ]; 9108 this._sorters[ key ] = mungeSorter( sorter ); 9109 } 9110 }; 9111 9112 /** 9113 * @params {Array} items - of Isotope.Items 9114 * @private 9115 */ 9116 proto._updateItemsSortData = function( items ) { 9117 // do not update if no items 9118 var len = items && items.length; 9119 9120 for ( var i=0; len && i < len; i++ ) { 9121 var item = items[i]; 9122 item.updateSortData(); 9123 } 9124 }; 9125 9126 // ----- munge sorter ----- // 9127 9128 // encapsulate this, as we just need mungeSorter 9129 // other functions in here are just for munging 9130 var mungeSorter = ( function() { 9131 // add a magic layer to sorters for convienent shorthands 9132 // `.foo-bar` will use the text of .foo-bar querySelector 9133 // `[foo-bar]` will use attribute 9134 // you can also add parser 9135 // `.foo-bar parseInt` will parse that as a number 9136 function mungeSorter( sorter ) { 9137 // if not a string, return function or whatever it is 9138 if ( typeof sorter != 'string' ) { 9139 return sorter; 9140 } 9141 // parse the sorter string 9142 var args = trim( sorter ).split(' '); 9143 var query = args[0]; 9144 // check if query looks like [an-attribute] 9145 var attrMatch = query.match( /^\[(.+)\]$/ ); 9146 var attr = attrMatch && attrMatch[1]; 9147 var getValue = getValueGetter( attr, query ); 9148 // use second argument as a parser 9149 var parser = Isotope.sortDataParsers[ args[1] ]; 9150 // parse the value, if there was a parser 9151 sorter = parser ? function( elem ) { 9152 return elem && parser( getValue( elem ) ); 9153 } : 9154 // otherwise just return value 9155 function( elem ) { 9156 return elem && getValue( elem ); 9157 }; 9158 9159 return sorter; 9160 } 9161 9162 // get an attribute getter, or get text of the querySelector 9163 function getValueGetter( attr, query ) { 9164 // if query looks like [foo-bar], get attribute 9165 if ( attr ) { 9166 return function getAttribute( elem ) { 9167 return elem.getAttribute( attr ); 9168 }; 9169 } 9170 9171 // otherwise, assume its a querySelector, and get its text 9172 return function getChildText( elem ) { 9173 var child = elem.querySelector( query ); 9174 return child && child.textContent; 9175 }; 9176 } 9177 9178 return mungeSorter; 9179 })(); 9180 9181 // parsers used in getSortData shortcut strings 9182 Isotope.sortDataParsers = { 9183 'parseInt': function( val ) { 9184 return parseInt( val, 10 ); 9185 }, 9186 'parseFloat': function( val ) { 9187 return parseFloat( val ); 9188 } 9189 }; 9190 9191 // ----- sort method ----- // 9192 9193 // sort filteredItem order 9194 proto._sort = function() { 9195 if ( !this.options.sortBy ) { 9196 return; 9197 } 9198 // keep track of sortBy History 9199 var sortBys = utils.makeArray( this.options.sortBy ); 9200 if ( !this._getIsSameSortBy( sortBys ) ) { 9201 // concat all sortBy and sortHistory, add to front, oldest goes in last 9202 this.sortHistory = sortBys.concat( this.sortHistory ); 9203 } 9204 // sort magic 9205 var itemSorter = getItemSorter( this.sortHistory, this.options.sortAscending ); 9206 this.filteredItems.sort( itemSorter ); 9207 }; 9208 9209 // check if sortBys is same as start of sortHistory 9210 proto._getIsSameSortBy = function( sortBys ) { 9211 for ( var i=0; i < sortBys.length; i++ ) { 9212 if ( sortBys[i] != this.sortHistory[i] ) { 9213 return false; 9214 } 9215 } 9216 return true; 9217 }; 9218 9219 // returns a function used for sorting 9220 function getItemSorter( sortBys, sortAsc ) { 9221 return function sorter( itemA, itemB ) { 9222 // cycle through all sortKeys 9223 for ( var i = 0; i < sortBys.length; i++ ) { 9224 var sortBy = sortBys[i]; 9225 var a = itemA.sortData[ sortBy ]; 9226 var b = itemB.sortData[ sortBy ]; 9227 if ( a > b || a < b ) { 9228 // if sortAsc is an object, use the value given the sortBy key 9229 var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc; 9230 var direction = isAscending ? 1 : -1; 9231 return ( a > b ? 1 : -1 ) * direction; 9232 } 9233 } 9234 return 0; 9235 }; 9236 } 9237 9238 // -------------------------- methods -------------------------- // 9239 9240 // get layout mode 9241 proto._mode = function() { 9242 var layoutMode = this.options.layoutMode; 9243 var mode = this.modes[ layoutMode ]; 9244 if ( !mode ) { 9245 // TODO console.error 9246 throw new Error( 'No layout mode: ' + layoutMode ); 9247 } 9248 // HACK sync mode's options 9249 // any options set after init for layout mode need to be synced 9250 mode.options = this.options[ layoutMode ]; 9251 return mode; 9252 }; 9253 9254 proto._resetLayout = function() { 9255 // trigger original reset layout 9256 Outlayer.prototype._resetLayout.call( this ); 9257 this._mode()._resetLayout(); 9258 }; 9259 9260 proto._getItemLayoutPosition = function( item ) { 9261 return this._mode()._getItemLayoutPosition( item ); 9262 }; 9263 9264 proto._manageStamp = function( stamp ) { 9265 this._mode()._manageStamp( stamp ); 9266 }; 9267 9268 proto._getContainerSize = function() { 9269 return this._mode()._getContainerSize(); 9270 }; 9271 9272 proto.needsResizeLayout = function() { 9273 return this._mode().needsResizeLayout(); 9274 }; 9275 9276 // -------------------------- adding & removing -------------------------- // 9277 9278 // HEADS UP overwrites default Outlayer appended 9279 proto.appended = function( elems ) { 9280 var items = this.addItems( elems ); 9281 if ( !items.length ) { 9282 return; 9283 } 9284 // filter, layout, reveal new items 9285 var filteredItems = this._filterRevealAdded( items ); 9286 // add to filteredItems 9287 this.filteredItems = this.filteredItems.concat( filteredItems ); 9288 }; 9289 9290 // HEADS UP overwrites default Outlayer prepended 9291 proto.prepended = function( elems ) { 9292 var items = this._itemize( elems ); 9293 if ( !items.length ) { 9294 return; 9295 } 9296 // start new layout 9297 this._resetLayout(); 9298 this._manageStamps(); 9299 // filter, layout, reveal new items 9300 var filteredItems = this._filterRevealAdded( items ); 9301 // layout previous items 9302 this.layoutItems( this.filteredItems ); 9303 // add to items and filteredItems 9304 this.filteredItems = filteredItems.concat( this.filteredItems ); 9305 this.items = items.concat( this.items ); 9306 }; 9307 9308 proto._filterRevealAdded = function( items ) { 9309 var filtered = this._filter( items ); 9310 this.hide( filtered.needHide ); 9311 // reveal all new items 9312 this.reveal( filtered.matches ); 9313 // layout new items, no transition 9314 this.layoutItems( filtered.matches, true ); 9315 return filtered.matches; 9316 }; 9317 9318 /** 9319 * Filter, sort, and layout newly-appended item elements 9320 * @param {Array or NodeList or Element} elems 9321 */ 9322 proto.insert = function( elems ) { 9323 var items = this.addItems( elems ); 9324 if ( !items.length ) { 9325 return; 9326 } 9327 // append item elements 9328 var i, item; 9329 var len = items.length; 9330 for ( i=0; i < len; i++ ) { 9331 item = items[i]; 9332 this.element.appendChild( item.element ); 9333 } 9334 // filter new stuff 9335 var filteredInsertItems = this._filter( items ).matches; 9336 // set flag 9337 for ( i=0; i < len; i++ ) { 9338 items[i].isLayoutInstant = true; 9339 } 9340 this.arrange(); 9341 // reset flag 9342 for ( i=0; i < len; i++ ) { 9343 delete items[i].isLayoutInstant; 9344 } 9345 this.reveal( filteredInsertItems ); 9346 }; 9347 9348 var _remove = proto.remove; 9349 proto.remove = function( elems ) { 9350 elems = utils.makeArray( elems ); 9351 var removeItems = this.getItems( elems ); 9352 // do regular thing 9353 _remove.call( this, elems ); 9354 // bail if no items to remove 9355 var len = removeItems && removeItems.length; 9356 // remove elems from filteredItems 9357 for ( var i=0; len && i < len; i++ ) { 9358 var item = removeItems[i]; 9359 // remove item from collection 9360 utils.removeFrom( this.filteredItems, item ); 9361 } 9362 }; 9363 9364 proto.shuffle = function() { 9365 // update random sortData 9366 for ( var i=0; i < this.items.length; i++ ) { 9367 var item = this.items[i]; 9368 item.sortData.random = Math.random(); 9369 } 9370 this.options.sortBy = 'random'; 9371 this._sort(); 9372 this._layout(); 9373 }; 9374 9375 /** 9376 * trigger fn without transition 9377 * kind of hacky to have this in the first place 9378 * @param {Function} fn 9379 * @param {Array} args 9380 * @returns ret 9381 * @private 9382 */ 9383 proto._noTransition = function( fn, args ) { 9384 // save transitionDuration before disabling 9385 var transitionDuration = this.options.transitionDuration; 9386 // disable transition 9387 this.options.transitionDuration = 0; 9388 // do it 9389 var returnValue = fn.apply( this, args ); 9390 // re-enable transition for reveal 9391 this.options.transitionDuration = transitionDuration; 9392 return returnValue; 9393 }; 9394 9395 // ----- helper methods ----- // 9396 9397 /** 9398 * getter method for getting filtered item elements 9399 * @returns {Array} elems - collection of item elements 9400 */ 9401 proto.getFilteredItemElements = function() { 9402 return this.filteredItems.map( function( item ) { 9403 return item.element; 9404 }); 9405 }; 9406 9407 // ----- ----- // 9408 9409 return Isotope; 9410 9411})); 9412
vendor: 29,252 bytes, lines 9413-10569
9413/*! 9414 * Packery layout mode PACKAGED v2.0.1 9415 * sub-classes Packery 9416 */ 9417 9418/** 9419 * Rect 9420 * low-level utility class for basic geometry 9421 */ 9422 9423( function( window, factory ) { 9424 // universal module definition 9425 /* jshint strict: false */ /* globals define, module */ 9426 if ( typeof define == 'function' && define.amd ) { 9427 // AMD 9428 define( 'packery/js/rect',factory ); 9429 } else if ( typeof module == 'object' && module.exports ) { 9430 // CommonJS 9431 module.exports = factory(); 9432 } else { 9433 // browser global 9434 window.Packery = window.Packery || {}; 9435 window.Packery.Rect = factory(); 9436 } 9437 9438}( window, function factory() { 9439 9440 9441// -------------------------- Rect -------------------------- // 9442 9443function Rect( props ) { 9444 // extend properties from defaults 9445 for ( var prop in Rect.defaults ) { 9446 this[ prop ] = Rect.defaults[ prop ]; 9447 } 9448 9449 for ( prop in props ) { 9450 this[ prop ] = props[ prop ]; 9451 } 9452 9453} 9454 9455Rect.defaults = { 9456 x: 0, 9457 y: 0, 9458 width: 0, 9459 height: 0 9460}; 9461 9462var proto = Rect.prototype; 9463 9464/** 9465 * Determines whether or not this rectangle wholly encloses another rectangle or point. 9466 * @param {Rect} rect 9467 * @returns {Boolean} 9468**/ 9469proto.contains = function( rect ) { 9470 // points don't have width or height 9471 var otherWidth = rect.width || 0; 9472 var otherHeight = rect.height || 0; 9473 return this.x <= rect.x && 9474 this.y <= rect.y && 9475 this.x + this.width >= rect.x + otherWidth && 9476 this.y + this.height >= rect.y + otherHeight; 9477}; 9478 9479/** 9480 * Determines whether or not the rectangle intersects with another. 9481 * @param {Rect} rect 9482 * @returns {Boolean} 9483**/ 9484proto.overlaps = function( rect ) { 9485 var thisRight = this.x + this.width; 9486 var thisBottom = this.y + this.height; 9487 var rectRight = rect.x + rect.width; 9488 var rectBottom = rect.y + rect.height; 9489 9490 // http://stackoverflow.com/a/306332 9491 return this.x < rectRight && 9492 thisRight > rect.x && 9493 this.y < rectBottom && 9494 thisBottom > rect.y; 9495}; 9496 9497/** 9498 * @param {Rect} rect - the overlapping rect 9499 * @returns {Array} freeRects - rects representing the area around the rect 9500**/ 9501proto.getMaximalFreeRects = function( rect ) { 9502 9503 // if no intersection, return false 9504 if ( !this.overlaps( rect ) ) { 9505 return false; 9506 } 9507 9508 var freeRects = []; 9509 var freeRect; 9510 9511 var thisRight = this.x + this.width; 9512 var thisBottom = this.y + this.height; 9513 var rectRight = rect.x + rect.width; 9514 var rectBottom = rect.y + rect.height; 9515 9516 // top 9517 if ( this.y < rect.y ) { 9518 freeRect = new Rect({ 9519 x: this.x, 9520 y: this.y, 9521 width: this.width, 9522 height: rect.y - this.y 9523 }); 9524 freeRects.push( freeRect ); 9525 } 9526 9527 // right 9528 if ( thisRight > rectRight ) { 9529 freeRect = new Rect({ 9530 x: rectRight, 9531 y: this.y, 9532 width: thisRight - rectRight, 9533 height: this.height 9534 }); 9535 freeRects.push( freeRect ); 9536 } 9537 9538 // bottom 9539 if ( thisBottom > rectBottom ) { 9540 freeRect = new Rect({ 9541 x: this.x, 9542 y: rectBottom, 9543 width: this.width, 9544 height: thisBottom - rectBottom 9545 }); 9546 freeRects.push( freeRect ); 9547 } 9548 9549 // left 9550 if ( this.x < rect.x ) { 9551 freeRect = new Rect({ 9552 x: this.x, 9553 y: this.y, 9554 width: rect.x - this.x, 9555 height: this.height 9556 }); 9557 freeRects.push( freeRect ); 9558 } 9559 9560 return freeRects; 9561}; 9562 9563proto.canFit = function( rect ) { 9564 return this.width >= rect.width && this.height >= rect.height; 9565}; 9566 9567return Rect; 9568 9569})); 9570 9571/** 9572 * Packer 9573 * bin-packing algorithm 9574 */ 9575 9576( function( window, factory ) { 9577 // universal module definition 9578 /* jshint strict: false */ /* globals define, module, require */ 9579 if ( typeof define == 'function' && define.amd ) { 9580 // AMD 9581 define( 'packery/js/packer',[ './rect' ], factory ); 9582 } else if ( typeof module == 'object' && module.exports ) { 9583 // CommonJS 9584 module.exports = factory( 9585 require('./rect') 9586 ); 9587 } else { 9588 // browser global 9589 var Packery = window.Packery = window.Packery || {}; 9590 Packery.Packer = factory( Packery.Rect ); 9591 } 9592 9593}( window, function factory( Rect ) { 9594 9595 9596// -------------------------- Packer -------------------------- // 9597 9598/** 9599 * @param {Number} width 9600 * @param {Number} height 9601 * @param {String} sortDirection 9602 * topLeft for vertical, leftTop for horizontal 9603 */ 9604function Packer( width, height, sortDirection ) { 9605 this.width = width || 0; 9606 this.height = height || 0; 9607 this.sortDirection = sortDirection || 'downwardLeftToRight'; 9608 9609 this.reset(); 9610} 9611 9612var proto = Packer.prototype; 9613 9614proto.reset = function() { 9615 this.spaces = []; 9616 9617 var initialSpace = new Rect({ 9618 x: 0, 9619 y: 0, 9620 width: this.width, 9621 height: this.height 9622 }); 9623 9624 this.spaces.push( initialSpace ); 9625 // set sorter 9626 this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight; 9627}; 9628 9629// change x and y of rect to fit with in Packer's available spaces 9630proto.pack = function( rect ) { 9631 for ( var i=0; i < this.spaces.length; i++ ) { 9632 var space = this.spaces[i]; 9633 if ( space.canFit( rect ) ) { 9634 this.placeInSpace( rect, space ); 9635 break; 9636 } 9637 } 9638}; 9639 9640proto.columnPack = function( rect ) { 9641 for ( var i=0; i < this.spaces.length; i++ ) { 9642 var space = this.spaces[i]; 9643 var canFitInSpaceColumn = space.x <= rect.x && 9644 space.x + space.width >= rect.x + rect.width && 9645 space.height >= rect.height - 0.01; // fudge number for rounding error 9646 if ( canFitInSpaceColumn ) { 9647 rect.y = space.y; 9648 this.placed( rect ); 9649 break; 9650 } 9651 } 9652}; 9653 9654proto.rowPack = function( rect ) { 9655 for ( var i=0; i < this.spaces.length; i++ ) { 9656 var space = this.spaces[i]; 9657 var canFitInSpaceRow = space.y <= rect.y && 9658 space.y + space.height >= rect.y + rect.height && 9659 space.width >= rect.width - 0.01; // fudge number for rounding error 9660 if ( canFitInSpaceRow ) { 9661 rect.x = space.x; 9662 this.placed( rect ); 9663 break; 9664 } 9665 } 9666}; 9667 9668proto.placeInSpace = function( rect, space ) { 9669 // place rect in space 9670 rect.x = space.x; 9671 rect.y = space.y; 9672 9673 this.placed( rect ); 9674}; 9675 9676// update spaces with placed rect 9677proto.placed = function( rect ) { 9678 // update spaces 9679 var revisedSpaces = []; 9680 for ( var i=0; i < this.spaces.length; i++ ) { 9681 var space = this.spaces[i]; 9682 var newSpaces = space.getMaximalFreeRects( rect ); 9683 // add either the original space or the new spaces to the revised spaces 9684 if ( newSpaces ) { 9685 revisedSpaces.push.apply( revisedSpaces, newSpaces ); 9686 } else { 9687 revisedSpaces.push( space ); 9688 } 9689 } 9690 9691 this.spaces = revisedSpaces; 9692 9693 this.mergeSortSpaces(); 9694}; 9695 9696proto.mergeSortSpaces = function() { 9697 // remove redundant spaces 9698 Packer.mergeRects( this.spaces ); 9699 this.spaces.sort( this.sorter ); 9700}; 9701 9702// add a space back 9703proto.addSpace = function( rect ) { 9704 this.spaces.push( rect ); 9705 this.mergeSortSpaces(); 9706}; 9707 9708// -------------------------- utility functions -------------------------- // 9709 9710/** 9711 * Remove redundant rectangle from array of rectangles 9712 * @param {Array} rects: an array of Rects 9713 * @returns {Array} rects: an array of Rects 9714**/ 9715Packer.mergeRects = function( rects ) { 9716 var i = 0; 9717 var rect = rects[i]; 9718 9719 rectLoop: 9720 while ( rect ) { 9721 var j = 0; 9722 var compareRect = rects[ i + j ]; 9723 9724 while ( compareRect ) { 9725 if ( compareRect == rect ) { 9726 j++; // next 9727 } else if ( compareRect.contains( rect ) ) { 9728 // remove rect 9729 rects.splice( i, 1 ); 9730 rect = rects[i]; // set next rect 9731 continue rectLoop; // bail on compareLoop 9732 } else if ( rect.contains( compareRect ) ) { 9733 // remove compareRect 9734 rects.splice( i + j, 1 ); 9735 } else { 9736 j++; 9737 } 9738 compareRect = rects[ i + j ]; // set next compareRect 9739 } 9740 i++; 9741 rect = rects[i]; 9742 } 9743 9744 return rects; 9745}; 9746 9747 9748// -------------------------- sorters -------------------------- // 9749 9750// functions for sorting rects in order 9751var sorters = { 9752 // top down, then left to right 9753 downwardLeftToRight: function( a, b ) { 9754 return a.y - b.y || a.x - b.x; 9755 }, 9756 // left to right, then top down 9757 rightwardTopToBottom: function( a, b ) { 9758 return a.x - b.x || a.y - b.y; 9759 } 9760}; 9761 9762 9763// -------------------------- -------------------------- // 9764 9765return Packer; 9766 9767})); 9768 9769/** 9770 * Packery Item Element 9771**/ 9772 9773( function( window, factory ) { 9774 // universal module definition 9775 /* jshint strict: false */ /* globals define, module, require */ 9776 if ( typeof define == 'function' && define.amd ) { 9777 // AMD 9778 define( 'packery/js/item',[ 9779 'outlayer/outlayer', 9780 './rect' 9781 ], 9782 factory ); 9783 } else if ( typeof module == 'object' && module.exports ) { 9784 // CommonJS 9785 module.exports = factory( 9786 require('outlayer'), 9787 require('./rect') 9788 ); 9789 } else { 9790 // browser global 9791 window.Packery.Item = factory( 9792 window.Outlayer, 9793 window.Packery.Rect 9794 ); 9795 } 9796 9797}( window, function factory( Outlayer, Rect ) { 9798 9799 9800// -------------------------- Item -------------------------- // 9801 9802var docElemStyle = document.documentElement.style; 9803 9804var transformProperty = typeof docElemStyle.transform == 'string' ? 9805 'transform' : 'WebkitTransform'; 9806 9807// sub-class Item 9808var Item = function PackeryItem() { 9809 Outlayer.Item.apply( this, arguments ); 9810}; 9811 9812var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 9813 9814var __create = proto._create; 9815proto._create = function() { 9816 // call default _create logic 9817 __create.call( this ); 9818 this.rect = new Rect(); 9819}; 9820 9821var _moveTo = proto.moveTo; 9822proto.moveTo = function( x, y ) { 9823 // don't shift 1px while dragging 9824 var dx = Math.abs( this.position.x - x ); 9825 var dy = Math.abs( this.position.y - y ); 9826 9827 var canHackGoTo = this.layout.dragItemCount && !this.isPlacing && 9828 !this.isTransitioning && dx < 1 && dy < 1; 9829 if ( canHackGoTo ) { 9830 this.goTo( x, y ); 9831 return; 9832 } 9833 _moveTo.apply( this, arguments ); 9834}; 9835 9836// -------------------------- placing -------------------------- // 9837 9838proto.enablePlacing = function() { 9839 this.removeTransitionStyles(); 9840 // remove transform property from transition 9841 if ( this.isTransitioning && transformProperty ) { 9842 this.element.style[ transformProperty ] = 'none'; 9843 } 9844 this.isTransitioning = false; 9845 this.getSize(); 9846 this.layout._setRectSize( this.element, this.rect ); 9847 this.isPlacing = true; 9848}; 9849 9850proto.disablePlacing = function() { 9851 this.isPlacing = false; 9852}; 9853 9854// ----- ----- // 9855 9856// remove element from DOM 9857proto.removeElem = function() { 9858 this.element.parentNode.removeChild( this.element ); 9859 // add space back to packer 9860 this.layout.packer.addSpace( this.rect ); 9861 this.emitEvent( 'remove', [ this ] ); 9862}; 9863 9864// ----- dropPlaceholder ----- // 9865 9866proto.showDropPlaceholder = function() { 9867 var dropPlaceholder = this.dropPlaceholder; 9868 if ( !dropPlaceholder ) { 9869 // create dropPlaceholder 9870 dropPlaceholder = this.dropPlaceholder = document.createElement('div'); 9871 dropPlaceholder.className = 'packery-drop-placeholder'; 9872 dropPlaceholder.style.position = 'absolute'; 9873 } 9874 9875 dropPlaceholder.style.width = this.size.width + 'px'; 9876 dropPlaceholder.style.height = this.size.height + 'px'; 9877 this.positionDropPlaceholder(); 9878 this.layout.element.appendChild( dropPlaceholder ); 9879}; 9880 9881proto.positionDropPlaceholder = function() { 9882 this.dropPlaceholder.style[ transformProperty ] = 'translate(' + 9883 this.rect.x + 'px, ' + this.rect.y + 'px)'; 9884}; 9885 9886proto.hideDropPlaceholder = function() { 9887 this.layout.element.removeChild( this.dropPlaceholder ); 9888}; 9889 9890// ----- ----- // 9891 9892return Item; 9893 9894})); 9895 9896/*! 9897 * Packery v2.0.0 9898 * Gapless, draggable grid layouts 9899 * 9900 * Licensed GPLv3 for open source use 9901 * or Packery Commercial License for commercial use 9902 * 9903 * http://packery.metafizzy.co 9904 * Copyright 2016 Metafizzy 9905 */ 9906 9907( function( window, factory ) { 9908 // universal module definition 9909 /* jshint strict: false */ /* globals define, module, require */ 9910 if ( typeof define == 'function' && define.amd ) { 9911 // AMD 9912 define( 'packery/js/packery',[ 9913 'get-size/get-size', 9914 'outlayer/outlayer', 9915 './rect', 9916 './packer', 9917 './item' 9918 ], 9919 factory ); 9920 } else if ( typeof module == 'object' && module.exports ) { 9921 // CommonJS 9922 module.exports = factory( 9923 require('get-size'), 9924 require('outlayer'), 9925 require('./rect'), 9926 require('./packer'), 9927 require('./item') 9928 ); 9929 } else { 9930 // browser global 9931 window.Packery = factory( 9932 window.getSize, 9933 window.Outlayer, 9934 window.Packery.Rect, 9935 window.Packery.Packer, 9936 window.Packery.Item 9937 ); 9938 } 9939 9940}( window, function factory( getSize, Outlayer, Rect, Packer, Item ) { 9941 9942 9943// ----- Rect ----- // 9944 9945// allow for pixel rounding errors IE8-IE11 & Firefox; #227 9946Rect.prototype.canFit = function( rect ) { 9947 return this.width >= rect.width - 1 && this.height >= rect.height - 1; 9948}; 9949 9950// -------------------------- Packery -------------------------- // 9951 9952// create an Outlayer layout class 9953var Packery = Outlayer.create('packery'); 9954Packery.Item = Item; 9955 9956var proto = Packery.prototype; 9957 9958proto._create = function() { 9959 // call super 9960 Outlayer.prototype._create.call( this ); 9961 9962 // initial properties 9963 this.packer = new Packer(); 9964 // packer for drop targets 9965 this.shiftPacker = new Packer(); 9966 this.isEnabled = true; 9967 9968 this.dragItemCount = 0; 9969 9970 // create drag handlers 9971 var _this = this; 9972 this.handleDraggabilly = { 9973 dragStart: function() { 9974 _this.itemDragStart( this.element ); 9975 }, 9976 dragMove: function() { 9977 _this.itemDragMove( this.element, this.position.x, this.position.y ); 9978 }, 9979 dragEnd: function() { 9980 _this.itemDragEnd( this.element ); 9981 } 9982 }; 9983 9984 this.handleUIDraggable = { 9985 start: function handleUIDraggableStart( event, ui ) { 9986 // HTML5 may trigger dragstart, dismiss HTML5 dragging 9987 if ( !ui ) { 9988 return; 9989 } 9990 _this.itemDragStart( event.currentTarget ); 9991 }, 9992 drag: function handleUIDraggableDrag( event, ui ) { 9993 if ( !ui ) { 9994 return; 9995 } 9996 _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top ); 9997 }, 9998 stop: function handleUIDraggableStop( event, ui ) { 9999 if ( !ui ) { 10000 return; 10001 } 10002 _this.itemDragEnd( event.currentTarget ); 10003 } 10004 }; 10005 10006}; 10007 10008 10009// ----- init & layout ----- // 10010 10011/** 10012 * logic before any new layout 10013 */ 10014proto._resetLayout = function() { 10015 this.getSize(); 10016 10017 this._getMeasurements(); 10018 10019 // reset packer 10020 var width, height, sortDirection; 10021 // packer settings, if horizontal or vertical 10022 if ( this._getOption('horizontal') ) { 10023 width = Infinity; 10024 height = this.size.innerHeight + this.gutter; 10025 sortDirection = 'rightwardTopToBottom'; 10026 } else { 10027 width = this.size.innerWidth + this.gutter; 10028 height = Infinity; 10029 sortDirection = 'downwardLeftToRight'; 10030 } 10031 10032 this.packer.width = this.shiftPacker.width = width; 10033 this.packer.height = this.shiftPacker.height = height; 10034 this.packer.sortDirection = this.shiftPacker.sortDirection = sortDirection; 10035 10036 this.packer.reset(); 10037 10038 // layout 10039 this.maxY = 0; 10040 this.maxX = 0; 10041}; 10042 10043/** 10044 * update columnWidth, rowHeight, & gutter 10045 * @private 10046 */ 10047proto._getMeasurements = function() { 10048 this._getMeasurement( 'columnWidth', 'width' ); 10049 this._getMeasurement( 'rowHeight', 'height' ); 10050 this._getMeasurement( 'gutter', 'width' ); 10051}; 10052 10053proto._getItemLayoutPosition = function( item ) { 10054 this._setRectSize( item.element, item.rect ); 10055 if ( this.isShifting || this.dragItemCount > 0 ) { 10056 var packMethod = this._getPackMethod(); 10057 this.packer[ packMethod ]( item.rect ); 10058 } else { 10059 this.packer.pack( item.rect ); 10060 } 10061 10062 this._setMaxXY( item.rect ); 10063 return item.rect; 10064}; 10065 10066proto.shiftLayout = function() { 10067 this.isShifting = true; 10068 this.layout(); 10069 delete this.isShifting; 10070}; 10071 10072proto._getPackMethod = function() { 10073 return this._getOption('horizontal') ? 'rowPack' : 'columnPack'; 10074}; 10075 10076 10077/** 10078 * set max X and Y value, for size of container 10079 * @param {Packery.Rect} rect 10080 * @private 10081 */ 10082proto._setMaxXY = function( rect ) { 10083 this.maxX = Math.max( rect.x + rect.width, this.maxX ); 10084 this.maxY = Math.max( rect.y + rect.height, this.maxY ); 10085}; 10086 10087/** 10088 * set the width and height of a rect, applying columnWidth and rowHeight 10089 * @param {Element} elem 10090 * @param {Packery.Rect} rect 10091 */ 10092proto._setRectSize = function( elem, rect ) { 10093 var size = getSize( elem ); 10094 var w = size.outerWidth; 10095 var h = size.outerHeight; 10096 // size for columnWidth and rowHeight, if available 10097 // only check if size is non-zero, #177 10098 if ( w || h ) { 10099 w = this._applyGridGutter( w, this.columnWidth ); 10100 h = this._applyGridGutter( h, this.rowHeight ); 10101 } 10102 // rect must fit in packer 10103 rect.width = Math.min( w, this.packer.width ); 10104 rect.height = Math.min( h, this.packer.height ); 10105}; 10106 10107/** 10108 * fits item to columnWidth/rowHeight and adds gutter 10109 * @param {Number} measurement - item width or height 10110 * @param {Number} gridSize - columnWidth or rowHeight 10111 * @returns measurement 10112 */ 10113proto._applyGridGutter = function( measurement, gridSize ) { 10114 // just add gutter if no gridSize 10115 if ( !gridSize ) { 10116 return measurement + this.gutter; 10117 } 10118 gridSize += this.gutter; 10119 // fit item to columnWidth/rowHeight 10120 var remainder = measurement % gridSize; 10121 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 10122 measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize; 10123 return measurement; 10124}; 10125 10126proto._getContainerSize = function() { 10127 if ( this._getOption('horizontal') ) { 10128 return { 10129 width: this.maxX - this.gutter 10130 }; 10131 } else { 10132 return { 10133 height: this.maxY - this.gutter 10134 }; 10135 } 10136}; 10137 10138 10139// -------------------------- stamp -------------------------- // 10140 10141/** 10142 * makes space for element 10143 * @param {Element} elem 10144 */ 10145proto._manageStamp = function( elem ) { 10146 10147 var item = this.getItem( elem ); 10148 var rect; 10149 if ( item && item.isPlacing ) { 10150 rect = item.rect; 10151 } else { 10152 var offset = this._getElementOffset( elem ); 10153 rect = new Rect({ 10154 x: this._getOption('originLeft') ? offset.left : offset.right, 10155 y: this._getOption('originTop') ? offset.top : offset.bottom 10156 }); 10157 } 10158 10159 this._setRectSize( elem, rect ); 10160 // save its space in the packer 10161 this.packer.placed( rect ); 10162 this._setMaxXY( rect ); 10163}; 10164 10165// -------------------------- methods -------------------------- // 10166 10167function verticalSorter( a, b ) { 10168 return a.position.y - b.position.y || a.position.x - b.position.x; 10169} 10170 10171function horizontalSorter( a, b ) { 10172 return a.position.x - b.position.x || a.position.y - b.position.y; 10173} 10174 10175proto.sortItemsByPosition = function() { 10176 var sorter = this._getOption('horizontal') ? horizontalSorter : verticalSorter; 10177 this.items.sort( sorter ); 10178}; 10179 10180/** 10181 * Fit item element in its current position 10182 * Packery will position elements around it 10183 * useful for expanding elements 10184 * 10185 * @param {Element} elem 10186 * @param {Number} x - horizontal destination position, optional 10187 * @param {Number} y - vertical destination position, optional 10188 */ 10189proto.fit = function( elem, x, y ) { 10190 var item = this.getItem( elem ); 10191 if ( !item ) { 10192 return; 10193 } 10194 10195 // stamp item to get it out of layout 10196 this.stamp( item.element ); 10197 // set placing flag 10198 item.enablePlacing(); 10199 this.updateShiftTargets( item ); 10200 // fall back to current position for fitting 10201 x = x === undefined ? item.rect.x: x; 10202 y = y === undefined ? item.rect.y: y; 10203 // position it best at its destination 10204 this.shift( item, x, y ); 10205 this._bindFitEvents( item ); 10206 item.moveTo( item.rect.x, item.rect.y ); 10207 // layout everything else 10208 this.shiftLayout(); 10209 // return back to regularly scheduled programming 10210 this.unstamp( item.element ); 10211 this.sortItemsByPosition(); 10212 item.disablePlacing(); 10213}; 10214 10215/** 10216 * emit event when item is fit and other items are laid out 10217 * @param {Packery.Item} item 10218 * @private 10219 */ 10220proto._bindFitEvents = function( item ) { 10221 var _this = this; 10222 var ticks = 0; 10223 function onLayout() { 10224 ticks++; 10225 if ( ticks != 2 ) { 10226 return; 10227 } 10228 _this.dispatchEvent( 'fitComplete', null, [ item ] ); 10229 } 10230 // when item is laid out 10231 item.once( 'layout', onLayout ); 10232 // when all items are laid out 10233 this.once( 'layoutComplete', onLayout ); 10234}; 10235 10236// -------------------------- resize -------------------------- // 10237 10238// debounced, layout on resize 10239proto.resize = function() { 10240 // don't trigger if size did not change 10241 // or if resize was unbound. See #285, outlayer#9 10242 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 10243 return; 10244 } 10245 10246 if ( this.options.shiftPercentResize ) { 10247 this.resizeShiftPercentLayout(); 10248 } else { 10249 this.layout(); 10250 } 10251}; 10252 10253/** 10254 * check if layout is needed post layout 10255 * @returns Boolean 10256 */ 10257proto.needsResizeLayout = function() { 10258 var size = getSize( this.element ); 10259 var innerSize = this._getOption('horizontal') ? 'innerHeight' : 'innerWidth'; 10260 return size[ innerSize ] != this.size[ innerSize ]; 10261}; 10262 10263proto.resizeShiftPercentLayout = function() { 10264 var items = this._getItemsForLayout( this.items ); 10265 10266 var isHorizontal = this._getOption('horizontal'); 10267 var coord = isHorizontal ? 'y' : 'x'; 10268 var measure = isHorizontal ? 'height' : 'width'; 10269 var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth'; 10270 var innerSize = isHorizontal ? 'innerHeight' : 'innerWidth'; 10271 10272 // proportional re-align items 10273 var previousSegment = this[ segmentName ]; 10274 previousSegment = previousSegment && previousSegment + this.gutter; 10275 10276 if ( previousSegment ) { 10277 this._getMeasurements(); 10278 var currentSegment = this[ segmentName ] + this.gutter; 10279 items.forEach( function( item ) { 10280 var seg = Math.round( item.rect[ coord ] / previousSegment ); 10281 item.rect[ coord ] = seg * currentSegment; 10282 }); 10283 } else { 10284 var currentSize = getSize( this.element )[ innerSize ] + this.gutter; 10285 var previousSize = this.packer[ measure ]; 10286 items.forEach( function( item ) { 10287 item.rect[ coord ] = ( item.rect[ coord ] / previousSize ) * currentSize; 10288 }); 10289 } 10290 10291 this.shiftLayout(); 10292}; 10293 10294// -------------------------- drag -------------------------- // 10295 10296/** 10297 * handle an item drag start event 10298 * @param {Element} elem 10299 */ 10300proto.itemDragStart = function( elem ) { 10301 if ( !this.isEnabled ) { 10302 return; 10303 } 10304 this.stamp( elem ); 10305 // this.ignore( elem ); 10306 var item = this.getItem( elem ); 10307 if ( !item ) { 10308 return; 10309 } 10310 10311 item.enablePlacing(); 10312 item.showDropPlaceholder(); 10313 this.dragItemCount++; 10314 this.updateShiftTargets( item ); 10315}; 10316 10317proto.updateShiftTargets = function( dropItem ) { 10318 this.shiftPacker.reset(); 10319 10320 // pack stamps 10321 this._getBoundingRect(); 10322 var isOriginLeft = this._getOption('originLeft'); 10323 var isOriginTop = this._getOption('originTop'); 10324 this.stamps.forEach( function( stamp ) { 10325 // ignore dragged item 10326 var item = this.getItem( stamp ); 10327 if ( item && item.isPlacing ) { 10328 return; 10329 } 10330 var offset = this._getElementOffset( stamp ); 10331 var rect = new Rect({ 10332 x: isOriginLeft ? offset.left : offset.right, 10333 y: isOriginTop ? offset.top : offset.bottom 10334 }); 10335 this._setRectSize( stamp, rect ); 10336 // save its space in the packer 10337 this.shiftPacker.placed( rect ); 10338 }, this ); 10339 10340 // reset shiftTargets 10341 var isHorizontal = this._getOption('horizontal'); 10342 var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth'; 10343 var measure = isHorizontal ? 'height' : 'width'; 10344 10345 this.shiftTargetKeys = []; 10346 this.shiftTargets = []; 10347 var boundsSize; 10348 var segment = this[ segmentName ]; 10349 segment = segment && segment + this.gutter; 10350 10351 if ( segment ) { 10352 var segmentSpan = Math.ceil( dropItem.rect[ measure ] / segment ); 10353 var segs = Math.floor( ( this.shiftPacker[ measure ] + this.gutter ) / segment ); 10354 boundsSize = ( segs - segmentSpan ) * segment; 10355 // add targets on top 10356 for ( var i=0; i < segs; i++ ) { 10357 this._addShiftTarget( i * segment, 0, boundsSize ); 10358 } 10359 } else { 10360 boundsSize = ( this.shiftPacker[ measure ] + this.gutter ) - dropItem.rect[ measure ]; 10361 this._addShiftTarget( 0, 0, boundsSize ); 10362 } 10363 10364 // pack each item to measure where shiftTargets are 10365 var items = this._getItemsForLayout( this.items ); 10366 var packMethod = this._getPackMethod(); 10367 items.forEach( function( item ) { 10368 var rect = item.rect; 10369 this._setRectSize( item.element, rect ); 10370 this.shiftPacker[ packMethod ]( rect ); 10371 10372 // add top left corner 10373 this._addShiftTarget( rect.x, rect.y, boundsSize ); 10374 // add bottom left / top right corner 10375 var cornerX = isHorizontal ? rect.x + rect.width : rect.x; 10376 var cornerY = isHorizontal ? rect.y : rect.y + rect.height; 10377 this._addShiftTarget( cornerX, cornerY, boundsSize ); 10378 10379 if ( segment ) { 10380 // add targets for each column on bottom / row on right 10381 var segSpan = Math.round( rect[ measure ] / segment ); 10382 for ( var i=1; i < segSpan; i++ ) { 10383 var segX = isHorizontal ? cornerX : rect.x + segment * i; 10384 var segY = isHorizontal ? rect.y + segment * i : cornerY; 10385 this._addShiftTarget( segX, segY, boundsSize ); 10386 } 10387 } 10388 }, this ); 10389 10390}; 10391 10392proto._addShiftTarget = function( x, y, boundsSize ) { 10393 var checkCoord = this._getOption('horizontal') ? y : x; 10394 if ( checkCoord !== 0 && checkCoord > boundsSize ) { 10395 return; 10396 } 10397 // create string for a key, easier to keep track of what targets 10398 var key = x + ',' + y; 10399 var hasKey = this.shiftTargetKeys.indexOf( key ) != -1; 10400 if ( hasKey ) { 10401 return; 10402 } 10403 this.shiftTargetKeys.push( key ); 10404 this.shiftTargets.push({ x: x, y: y }); 10405}; 10406 10407// -------------------------- drop -------------------------- // 10408 10409proto.shift = function( item, x, y ) { 10410 var shiftPosition; 10411 var minDistance = Infinity; 10412 var position = { x: x, y: y }; 10413 this.shiftTargets.forEach( function( target ) { 10414 var distance = getDistance( target, position ); 10415 if ( distance < minDistance ) { 10416 shiftPosition = target; 10417 minDistance = distance; 10418 } 10419 }); 10420 item.rect.x = shiftPosition.x; 10421 item.rect.y = shiftPosition.y; 10422}; 10423 10424function getDistance( a, b ) { 10425 var dx = b.x - a.x; 10426 var dy = b.y - a.y; 10427 return Math.sqrt( dx * dx + dy * dy ); 10428} 10429 10430// -------------------------- drag move -------------------------- // 10431 10432var DRAG_THROTTLE_TIME = 120; 10433 10434/** 10435 * handle an item drag move event 10436 * @param {Element} elem 10437 * @param {Number} x - horizontal change in position 10438 * @param {Number} y - vertical change in position 10439 */ 10440proto.itemDragMove = function( elem, x, y ) { 10441 var item = this.isEnabled && this.getItem( elem ); 10442 if ( !item ) { 10443 return; 10444 } 10445 10446 x -= this.size.paddingLeft; 10447 y -= this.size.paddingTop; 10448 10449 var _this = this; 10450 function onDrag() { 10451 _this.shift( item, x, y ); 10452 item.positionDropPlaceholder(); 10453 _this.layout(); 10454 } 10455 10456 // throttle 10457 var now = new Date(); 10458 if ( this._itemDragTime && now - this._itemDragTime < DRAG_THROTTLE_TIME ) { 10459 clearTimeout( this.dragTimeout ); 10460 this.dragTimeout = setTimeout( onDrag, DRAG_THROTTLE_TIME ); 10461 } else { 10462 onDrag(); 10463 this._itemDragTime = now; 10464 } 10465}; 10466 10467// -------------------------- drag end -------------------------- // 10468 10469/** 10470 * handle an item drag end event 10471 * @param {Element} elem 10472 */ 10473proto.itemDragEnd = function( elem ) { 10474 var item = this.isEnabled && this.getItem( elem ); 10475 if ( !item ) { 10476 return; 10477 } 10478 10479 clearTimeout( this.dragTimeout ); 10480 item.element.classList.add('is-positioning-post-drag'); 10481 10482 var completeCount = 0; 10483 var _this = this; 10484 function onDragEndLayoutComplete() { 10485 completeCount++; 10486 if ( completeCount != 2 ) { 10487 return; 10488 } 10489 // reset drag item 10490 item.element.classList.remove('is-positioning-post-drag'); 10491 item.hideDropPlaceholder(); 10492 _this.dispatchEvent( 'dragItemPositioned', null, [ item ] ); 10493 } 10494 10495 item.once( 'layout', onDragEndLayoutComplete ); 10496 this.once( 'layoutComplete', onDragEndLayoutComplete ); 10497 item.moveTo( item.rect.x, item.rect.y ); 10498 this.layout(); 10499 this.dragItemCount = Math.max( 0, this.dragItemCount - 1 ); 10500 this.sortItemsByPosition(); 10501 item.disablePlacing(); 10502 this.unstamp( item.element ); 10503}; 10504 10505/** 10506 * binds Draggabilly events 10507 * @param {Draggabilly} draggie 10508 */ 10509proto.bindDraggabillyEvents = function( draggie ) { 10510 this._bindDraggabillyEvents( draggie, 'on' ); 10511}; 10512 10513proto.unbindDraggabillyEvents = function( draggie ) { 10514 this._bindDraggabillyEvents( draggie, 'off' ); 10515}; 10516 10517proto._bindDraggabillyEvents = function( draggie, method ) { 10518 var handlers = this.handleDraggabilly; 10519 draggie[ method ]( 'dragStart', handlers.dragStart ); 10520 draggie[ method ]( 'dragMove', handlers.dragMove ); 10521 draggie[ method ]( 'dragEnd', handlers.dragEnd ); 10522}; 10523 10524/** 10525 * binds jQuery UI Draggable events 10526 * @param {jQuery} $elems 10527 */ 10528proto.bindUIDraggableEvents = function( $elems ) { 10529 this._bindUIDraggableEvents( $elems, 'on' ); 10530}; 10531 10532proto.unbindUIDraggableEvents = function( $elems ) { 10533 this._bindUIDraggableEvents( $elems, 'off' ); 10534}; 10535 10536proto._bindUIDraggableEvents = function( $elems, method ) { 10537 var handlers = this.handleUIDraggable; 10538 $elems 10539 [ method ]( 'dragstart', handlers.start ) 10540 [ method ]( 'drag', handlers.drag ) 10541 [ method ]( 'dragstop', handlers.stop ); 10542}; 10543 10544// ----- destroy ----- // 10545 10546var _destroy = proto.destroy; 10547proto.destroy = function() { 10548 _destroy.apply( this, arguments ); 10549 // disable flag; prevent drag events from triggering. #72 10550 this.isEnabled = false; 10551}; 10552 10553// ----- ----- // 10554 10555Packery.Rect = Rect; 10556Packery.Packer = Packer; 10557 10558return Packery; 10559 10560})); 10561 10562/*! 10563 * Packery layout mode v2.0.1 10564 * sub-classes Packery 10565 */ 10566 10567/*jshint browser: true, strict: true, undef: true, unused: true */ 10568 10569( function( window, factory ) {
10570 10571 // universal module definition 10572 if ( typeof define == 'function' && define.amd ) { 10573 // AMD 10574 define( [ 10575 'isotope-layout/js/layout-mode', 10576 'packery/js/packery' 10577 ], 10578 factory ); 10579 } else if ( typeof module == 'object' && module.exports ) { 10580 // CommonJS 10581 module.exports = factory( 10582 require('isotope-layout/js/layout-mode'), 10583 require('packery') 10584 ); 10585 } else { 10586 // browser global 10587 factory( 10588 window.Isotope.LayoutMode, 10589 window.Packery 10590 ); 10591 } 10592 10593}( window, function factor( LayoutMode, Packery ) { 10594 10595 10596 // create an Outlayer layout class 10597 var PackeryMode = LayoutMode.create('packery'); 10598 var proto = PackeryMode.prototype; 10599 10600 var keepModeMethods = { 10601 _getElementOffset: true, 10602 _getMeasurement: true 10603 }; 10604 10605 // inherit Packery prototype 10606 for ( var method in Packery.prototype ) { 10607 // do not inherit mode methods 10608 if ( !keepModeMethods[ method ] ) { 10609 proto[ method ] = Packery.prototype[ method ]; 10610 } 10611 } 10612 10613 // set packer in _resetLayout 10614 var _resetLayout = proto._resetLayout; 10615 proto._resetLayout = function() { 10616 this.packer = this.packer || new Packery.Packer(); 10617 this.shiftPacker = this.shiftPacker || new Packery.Packer(); 10618 _resetLayout.apply( this, arguments ); 10619 }; 10620 10621 var _getItemLayoutPosition = proto._getItemLayoutPosition; 10622 proto._getItemLayoutPosition = function( item ) { 10623 // set packery rect 10624 item.rect = item.rect || new Packery.Rect(); 10625 return _getItemLayoutPosition.call( this, item ); 10626 }; 10627 10628 // needsResizeLayout for vertical or horizontal 10629 var _needsResizeLayout = proto.needsResizeLayout; 10630 proto.needsResizeLayout = function() { 10631 if ( this._getOption('horizontal') ) { 10632 return this.needsVerticalResizeLayout(); 10633 } else { 10634 return _needsResizeLayout.call( this ); 10635 } 10636 }; 10637 10638 // point to mode options for horizontal 10639 var _getOption = proto._getOption; 10640 proto._getOption = function( option ) { 10641 if ( option == 'horizontal' ) { 10642 return this.options.isHorizontal !== undefined ? 10643 this.options.isHorizontal : this.options.horizontal; 10644 } 10645 return _getOption.apply( this.isotope, arguments ); 10646 }; 10647 10648 return PackeryMode; 10649 10650})); 10651 10652/*! 10653 * cellsByRows layout mode for Isotope 10654 * v1.1.3 10655 * http://isotope.metafizzy.co/layout-modes/cellsbyrow.html 10656 */ 10657 10658/*jshint browser: true, devel: false, strict: true, undef: true, unused: true */ 10659 10660( function( window, factory ) { 10661 // universal module definition 10662 /* jshint strict: false */ /*globals define, module, require */ 10663 if ( typeof define === 'function' && define.amd ) { 10664 // AMD 10665 define( [ 10666 'isotope/js/layout-mode' 10667 ], 10668 factory ); 10669 } else if ( typeof exports === 'object' ) { 10670 // CommonJS 10671 module.exports = factory( 10672 require('isotope-layout/js/layout-mode') 10673 ); 10674 } else { 10675 // browser global 10676 factory( 10677 window.Isotope.LayoutMode 10678 ); 10679 } 10680 10681}( window, function factory( LayoutMode ) { 10682 'use strict'; 10683 10684 var CellsByRow = LayoutMode.create( 'cellsByRow' ); 10685 var proto = CellsByRow.prototype; 10686 10687 proto._resetLayout = function() { 10688 // reset properties 10689 this.itemIndex = 0; 10690 // measurements 10691 this.getColumnWidth(); 10692 this.getRowHeight(); 10693 // set cols 10694 this.cols = Math.floor( this.isotope.size.innerWidth / this.columnWidth ); 10695 this.cols = Math.max( this.cols, 1 ); 10696 }; 10697 10698 proto._getItemLayoutPosition = function( item ) { 10699 item.getSize(); 10700 var col = this.itemIndex % this.cols; 10701 var row = Math.floor( this.itemIndex / this.cols ); 10702 // center item within cell 10703 var x = ( col + 0.5 ) * this.columnWidth - item.size.outerWidth / 2; 10704 var y = ( row + 0.5 ) * this.rowHeight - item.size.outerHeight / 2; 10705 this.itemIndex++; 10706 return { x: x, y: y }; 10707 }; 10708 10709 proto._getContainerSize = function() { 10710 return { 10711 height: Math.ceil( this.itemIndex / this.cols ) * this.rowHeight 10712 }; 10713 }; 10714 10715 return CellsByRow; 10716 10717})); 10718/*global jQuery: true */ 10719 10720/*! 10721 -------------------------------- 10722 Infinite Scroll 10723 -------------------------------- 10724 + https://github.com/paulirish/infinite-scroll 10725 + version 2.1.0 10726 + Copyright 2011/12 Paul Irish & Luke Shumard 10727 + Licensed under the MIT license 10728 10729 + Documentation: http://infinite-scroll.com/ 10730*/ 10731 10732// Uses AMD or browser globals to create a jQuery plugin. 10733(function (factory) { 10734 if (typeof define === 'function' && define.amd) { 10735 // AMD. Register as an anonymous module. 10736 define(['jquery'], factory); 10737 } else { 10738 // Browser globals 10739 factory(jQuery); 10740 } 10741}(function ($, undefined) { 10742 'use strict'; 10743
10744 $.infinitescroll = function infscr(options, callback, element) { 10745 this.element = $(element); 10746 10747 // Flag the object in the event of a failed creation 10748 if (!this._create(options, callback)) { 10749 this.failed = true; 10750 } 10751 }; 10752 10753 $.infinitescroll.defaults = { 10754 loading: { 10755 finished: undefined, 10756 finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>", 10757 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
10757MzExnbRvQ2Sy7vN0zvVtNfU2tLY3rPgLdnDvca4VQS/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
10757iqpQpZ4apwSwRtjqrB3muoF9BboaXKmshlqWqsWiGt2wphJkQbAU5hoCACH5BAUKABsALAcABADOAAsAAAX/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', 10758 msg: null, 10759 msgText: '<em>Loading the next set of posts...</em>', 10760 selector: null, 10761 speed: 'fast', 10762 start: undefined 10763 }, 10764 state: { 10765 isDuringAjax: false, 10766 isInvalidPage: false,
10767 isDestroyed: false, 10768 isDone: false, // For when it goes all the way through the archive. 10769 isPaused: false, 10770 isBeyondMaxPage: false, 10771 currPage: 1 10772 }, 10773 debug: false, 10774 behavior: undefined, 10775 binder: $(window), // used to cache the selector 10776 nextSelector: 'div.navigation a:first', 10777 navSelector: 'div.navigation', 10778 contentSelector: null, // rename to pageFragment 10779 extraScrollPx: 150, 10780 itemSelector: 'div.post', 10781 animate: false, 10782 pathParse: undefined, 10783 dataType: 'html', 10784 appendCallback: true, 10785 bufferPx: 40, 10786 errorCallback: function () { }, 10787 infid: 0, //Instance ID 10788 pixelsFromNavToBottom: undefined, 10789 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 10790 prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted 10791 maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work) 10792 }; 10793 10794 $.infinitescroll.prototype = { 10795 10796 /* 10797 ---------------------------- 10798 Private methods 10799 ---------------------------- 10800 */ 10801 10802 // Bind or unbind from scroll 10803 _binding: function infscr_binding(binding) { 10804 10805 var instance = this, 10806 opts = instance.options; 10807 10808 opts.v = '2.0b2.120520'; 10809 10810 // if behavior is defined and this function is extended, call that instead of default 10811 if (!!opts.behavior && this['_binding_'+opts.behavior] !== undefined) { 10812 this['_binding_'+opts.behavior].call(this); 10813 return; 10814 } 10815 10816 if (binding !== 'bind' && binding !== 'unbind') { 10817 this._debug('Binding value ' + binding + ' not valid'); 10818 return false; 10819 } 10820 10821 if (binding === 'unbind') { 10822 (this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid); 10823 } else { 10824 (this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () { 10825 instance.scroll(); 10826 }); 10827 } 10828 10829 this._debug('Binding', binding); 10830 }, 10831 10832 // Fundamental aspects of the plugin are initialized 10833 _create: function infscr_create(options, callback) { 10834 10835 // Add custom options to defaults 10836 var opts = $.extend(true, {}, $.infinitescroll.defaults, options); 10837 this.options = opts; 10838 var $window = $(window); 10839 var instance = this; 10840 10841 // Validate selectors 10842 if (!instance._validate(options)) { 10843 return false; 10844 } 10845 10846 // Validate page fragment path 10847 var path = $(opts.nextSelector).attr('href'); 10848 if (!path) { 10849 this._debug('Navigation selector not found'); 10850 return false; 10851 } 10852 10853 // Set the path to be a relative URL from root. 10854 opts.path = opts.path || this._determinepath(path); 10855 10856 // contentSelector is 'page fragment' option for .load() / .ajax() calls 10857 opts.contentSelector = opts.contentSelector || this.element; 10858 10859 // loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector 10860 opts.loading.selector = opts.loading.selector || opts.contentSelector; 10861 10862 // Define loading.msg 10863 opts.loading.msg = opts.loading.msg || $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>'); 10864 10865 // Preload loading.img 10866 (new Image()).src = opts.loading.img; 10867 10868 // distance from nav links to bottom 10869 // computed as: height of the document + top offset of container - top offset of nav link 10870 if(opts.pixelsFromNavToBottom === undefined) { 10871 opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top; 10872 this._debug('pixelsFromNavToBottom: ' + opts.pixelsFromNavToBottom); 10873 } 10874 10875 var self = this; 10876 10877 // determine loading.start actions 10878 opts.loading.start = opts.loading.start || function() { 10879 $(opts.navSelector).hide(); 10880 opts.loading.msg 10881 .appendTo(opts.loading.selector) 10882 .show(opts.loading.speed, $.proxy(function() { 10883 this.beginAjax(opts); 10884 }, self)); 10885 }; 10886 10887 // determine loading.finished actions 10888 opts.loading.finished = opts.loading.finished || function() { 10889 if (!opts.state.isBeyondMaxPage) 10890 opts.loading.msg.fadeOut(opts.loading.speed); 10891 }; 10892 10893 // callback loading 10894 opts.callback = function(instance, data, url) { 10895 if (!!opts.behavior && instance['_callback_'+opts.behavior] !== undefined) { 10896 instance['_callback_'+opts.behavior].call($(opts.contentSelector)[0], data, url); 10897 } 10898 10899 if (callback) { 10900 callback.call($(opts.contentSelector)[0], data, opts, url); 10901 } 10902 10903 if (opts.prefill) { 10904 $window.bind('resize.infinite-scroll', instance._prefill); 10905 } 10906 }; 10907 10908 if (options.debug) { 10909 // Tell IE9 to use its built-in console 10910 if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === 'object') { 10911 ['log','info','warn','error','assert','dir','clear','profile','profileEnd'] 10912 .forEach(function (method) { 10913 console[method] = this.call(console[method], console); 10914 }, Function.prototype.bind); 10915 } 10916 } 10917 10918 this._setup(); 10919 10920 // Setups the prefill method for use 10921 if (opts.prefill) { 10922 this._prefill(); 10923 } 10924 10925 // Return true to indicate successful creation 10926 return true; 10927 }, 10928 10929 _prefill: function infscr_prefill() { 10930 var instance = this; 10931 var $window = $(window); 10932 10933 function needsPrefill() { 10934 return ( $(instance.options.contentSelector).height() <= $window.height() ); 10935 } 10936 10937 this._prefill = function() { 10938 if (needsPrefill()) { 10939 instance.scroll(); 10940 } 10941 10942 $window.bind('resize.infinite-scroll', function() { 10943 if (needsPrefill()) { 10944 $window.unbind('resize.infinite-scroll'); 10945 instance.scroll(); 10946 } 10947 }); 10948 }; 10949 10950 // Call self after setting up the new function 10951 this._prefill(); 10952 }, 10953 10954 // Console log wrapper 10955 _debug: function infscr_debug() { 10956 if (true !== this.options.debug) { 10957 return; 10958 } 10959 10960 if (typeof console !== 'undefined' && typeof console.log === 'function') { 10961 // Modern browsers 10962 // Single argument, which is a string 10963 if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') { 10964 console.log( (Array.prototype.slice.call(arguments)).toString() ); 10965 } else { 10966 console.log( Array.prototype.slice.call(arguments) ); 10967 } 10968 } else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') { 10969 // IE8 10970 Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments)); 10971 } 10972 }, 10973 10974 // find the number to increment in the path.
10975 _determinepath: function infscr_determinepath(path) { 10976 10977 var opts = this.options; 10978 10979 // if behavior is defined and this function is extended, call that instead of default 10980 if (!!opts.behavior && this['_determinepath_'+opts.behavior] !== undefined) { 10981 return this['_determinepath_'+opts.behavior].call(this,path); 10982 } 10983 10984 if (!!opts.pathParse) { 10985 10986 this._debug('pathParse manual'); 10987 return opts.pathParse(path, this.options.state.currPage+1); 10988 10989 } else if (path.match(/^(.*?)\b2\b(.*?$)/)) { 10990 path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1); 10991 10992 // if there is any 2 in the url at all. 10993 } else if (path.match(/^(.*?)2(.*?$)/)) { 10994 10995 // page= is used in django: 10996 // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127 10997 if (path.match(/^(.*?page=)2(\/.*|$)/)) { 10998 path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1); 10999 return path; 11000 } 11001 11002 path = path.match(/^(.*?)2(.*?$)/).slice(1); 11003 11004 } else { 11005 11006 // page= is used in drupal too but second page is page=1 not page=2: 11007 // thx Jerod Fritz, vladikoff 11008 if (path.match(/^(.*?page=)1(\/.*|$)/)) { 11009 path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1); 11010 return path; 11011 } else { 11012 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."); 11013 // Get rid of isInvalidPage to allow permalink to state 11014 opts.state.isInvalidPage = true; //prevent it from running on this page. 11015 } 11016 } 11017 this._debug('determinePath', path); 11018 return path; 11019 11020 }, 11021 11022 // Custom error 11023 _error: function infscr_error(xhr) { 11024 11025 var opts = this.options; 11026 11027 // if behavior is defined and this function is extended, call that instead of default 11028 if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) { 11029 this['_error_'+opts.behavior].call(this,xhr); 11030 return; 11031 } 11032 11033 if (xhr !== 'destroy' && xhr !== 'end') { 11034 xhr = 'unknown'; 11035 } 11036 11037 this._debug('Error', xhr); 11038 11039 if (xhr === 'end' || opts.state.isBeyondMaxPage) { 11040 this._showdonemsg(); 11041 } 11042 11043 opts.state.isDone = true; 11044 opts.state.currPage = 1; // if you need to go back to this instance 11045 opts.state.isPaused = false; 11046 opts.state.isBeyondMaxPage = false; 11047 this._binding('unbind'); 11048 11049 }, 11050 11051 // Load Callback 11052 _loadcallback: function infscr_loadcallback(box, data, url) { 11053 var opts = this.options, 11054 callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK 11055 result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append', 11056 frag; 11057 11058 // if behavior is defined and this function is extended, call that instead of default 11059 if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) { 11060 this['_loadcallback_'+opts.behavior].call(this,box,data); 11061 return; 11062 } 11063 11064 switch (result) { 11065 case 'done': 11066 this._showdonemsg(); 11067 return false; 11068 11069 case 'no-append': 11070 if (opts.dataType === 'html') { 11071 data = '<div>' + data + '</div>'; 11072 data = $(data).find(opts.itemSelector); 11073 } 11074 11075 // if it didn't return anything 11076 if (data.length === 0) { 11077 return this._error('end'); 11078 } 11079 11080 break; 11081 11082 case 'append': 11083 var children = box.children(); 11084 // if it didn't return anything 11085 if (children.length === 0) { 11086 return this._error('end'); 11087 } 11088 11089 // use a documentFragment because it works when content is going into a table or UL 11090 frag = document.createDocumentFragment(); 11091 while (box[0].firstChild) { 11092 frag.appendChild(box[0].firstChild); 11093 } 11094 11095 this._debug('contentSelector', $(opts.contentSelector)[0]); 11096 $(opts.contentSelector)[0].appendChild(frag); 11097 // previously, we would pass in the new DOM element as context for the callback 11098 // however we're now using a documentfragment, which doesn't have parents or children, 11099 // so the context is the contentContainer guy, and we pass in an array 11100 // of the elements collected as the first argument. 11101 11102 data = children.get(); 11103 break; 11104 } 11105 11106 // loadingEnd function 11107 opts.loading.finished.call($(opts.contentSelector)[0],opts); 11108 11109 // smooth scroll to ease in the new content 11110 if (opts.animate) { 11111 var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px'; 11112 $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; }); 11113 } 11114 11115 if (!opts.animate) { 11116 // once the call is done, we can allow it again. 11117 opts.state.isDuringAjax = false;
11118 } 11119 11120 callback(this, data, url); 11121 11122 if (opts.prefill) { 11123 this._prefill(); 11124 } 11125 }, 11126 11127 _nearbottom: function infscr_nearbottom() { 11128 11129 var opts = this.options, 11130 pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height(); 11131 11132 // if behavior is defined and this function is extended, call that instead of default 11133 if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) { 11134 return this['_nearbottom_'+opts.behavior].call(this); 11135 } 11136 11137 this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom); 11138 11139 // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom.... 11140 return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom); 11141 11142 }, 11143 11144 // Pause / temporarily disable plugin from firing 11145 _pausing: function infscr_pausing(pause) { 11146 11147 var opts = this.options; 11148 11149 // if behavior is defined and this function is extended, call that instead of default 11150 if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) { 11151 this['_pausing_'+opts.behavior].call(this,pause); 11152 return; 11153 } 11154 11155 // If pause is not 'pause' or 'resume', toggle it's value 11156 if (pause !== 'pause' && pause !== 'resume' && pause !== null) { 11157 this._debug('Invalid argument. Toggling pause value instead'); 11158 } 11159 11160 pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle'; 11161 11162 switch (pause) { 11163 case 'pause': 11164 opts.state.isPaused = true; 11165 break; 11166 11167 case 'resume': 11168 opts.state.isPaused = false; 11169 break; 11170 11171 case 'toggle': 11172 opts.state.isPaused = !opts.state.isPaused; 11173 break; 11174 } 11175 11176 this._debug('Paused', opts.state.isPaused); 11177 return false; 11178 11179 }, 11180 11181 // Behavior is determined 11182 // If the behavior option is undefined, it will set to default and bind to scroll 11183 _setup: function infscr_setup() { 11184 11185 var opts = this.options; 11186 11187 // if behavior is defined and this function is extended, call that instead of default 11188 if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) { 11189 this['_setup_'+opts.behavior].call(this); 11190 return; 11191 } 11192 11193 this._binding('bind'); 11194 11195 return false; 11196 11197 }, 11198 11199 // Show done message 11200 _showdonemsg: function infscr_showdonemsg() { 11201 11202 var opts = this.options; 11203 11204 // if behavior is defined and this function is extended, call that instead of default 11205 if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) { 11206 this['_showdonemsg_'+opts.behavior].call(this); 11207 return; 11208 } 11209 11210 opts.loading.msg 11211 .find('img') 11212 .hide() 11213 .parent() 11214 .find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () { 11215 $(this).parent().fadeOut(opts.loading.speed); 11216 }); 11217 11218 // user provided callback when done 11219 opts.errorCallback.call($(opts.contentSelector)[0],'done'); 11220 }, 11221 11222 // grab each selector option and see if any fail 11223 _validate: function infscr_validate(opts) { 11224 for (var key in opts) { 11225 if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) { 11226 this._debug('Your ' + key + ' found no elements.'); 11227 return false; 11228 } 11229 } 11230 11231 return true; 11232 }, 11233 11234 /* 11235 ---------------------------- 11236 Public methods 11237 ---------------------------- 11238 */ 11239 11240 // Bind to scroll 11241 bind: function infscr_bind() { 11242 this._binding('bind'); 11243 }, 11244 11245 // Destroy current instance of plugin 11246 destroy: function infscr_destroy() { 11247 this.options.state.isDestroyed = true; 11248 this.options.loading.finished(); 11249 return this._error('destroy'); 11250 }, 11251 11252 // Set pause value to false 11253 pause: function infscr_pause() { 11254 this._pausing('pause'); 11255 }, 11256 11257 // Set pause value to false 11258 resume: function infscr_resume() { 11259 this._pausing('resume'); 11260 }, 11261 11262 beginAjax: function infscr_ajax(opts) { 11263 var instance = this, 11264 path = opts.path, 11265 box, desturl, method, condition; 11266 11267 // increment the URL bit. e.g. /page/3/ 11268 opts.state.currPage++; 11269 11270 // Manually control maximum page 11271 if ( opts.maxPage !== undefined && opts.state.currPage > opts.maxPage ){ 11272 opts.state.isBeyondMaxPage = true; 11273 this.destroy(); 11274 return; 11275 } 11276 11277 // if we're dealing with a table we can't use DIVs 11278 box = $(opts.contentSelector).is('table, tbody') ? $('<tbody/>') : $('<div/>'); 11279 11280 desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage); 11281 instance._debug('heading into ajax', desturl); 11282 11283 method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback'; 11284 if (opts.appendCallback && opts.dataType === 'html') { 11285 method += '+callback'; 11286 } 11287 11288 switch (method) { 11289 case 'html+callback': 11290 instance._debug('Using HTML via .load() method'); 11291 box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) { 11292 instance._loadcallback(box, responseText, desturl); 11293 }); 11294 11295 break; 11296 11297 case 'html': 11298 instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); 11299 $.ajax({ 11300 // params 11301 url: desturl, 11302 dataType: opts.dataType, 11303 complete: function infscr_ajax_callback(jqXHR, textStatus) { 11304 condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified'); 11305 if (condition) { 11306 instance._loadcallback(box, jqXHR.responseText, desturl); 11307 } else { 11308 instance._error('end'); 11309 } 11310 } 11311 }); 11312 11313 break; 11314 case 'json': 11315 instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); 11316 $.ajax({ 11317 dataType: 'json', 11318 type: 'GET', 11319 url: desturl, 11320 success: function (data, textStatus, jqXHR) { 11321 condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified'); 11322 if (opts.appendCallback) { 11323 // if appendCallback is true, you must defined template in options. 11324 // note that data passed into _loadcallback is already an html (after processed in opts.template(data)). 11325 if (opts.template !== undefined) { 11326 var theData = opts.template(data); 11327 box.append(theData); 11328 if (condition) { 11329 instance._loadcallback(box, theData); 11330 } else { 11331 instance._error('end'); 11332 } 11333 } else { 11334 instance._debug('template must be defined.'); 11335 instance._error('end'); 11336 } 11337 } else { 11338 // if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback. 11339 if (condition) { 11340 instance._loadcallback(box, data, desturl); 11341 } else { 11342 instance._error('end'); 11343 } 11344 } 11345 }, 11346 error: function() { 11347 instance._debug('JSON ajax request failed.'); 11348 instance._error('end'); 11349 } 11350 }); 11351 11352 break; 11353 } 11354 }, 11355 11356 // Retrieve next set of content items 11357 retrieve: function infscr_retrieve(pageNum) { 11358 pageNum = pageNum || null; 11359 11360 var instance = this, 11361 opts = instance.options; 11362 11363 // if behavior is defined and this function is extended, call that instead of default 11364 if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) { 11365 this['retrieve_'+opts.behavior].call(this,pageNum); 11366 return; 11367 } 11368 11369 // for manual triggers, if destroyed, get out of here 11370 if (opts.state.isDestroyed) { 11371 this._debug('Instance is destroyed'); 11372 return false;
11373 } 11374 11375 // we dont want to fire the ajax multiple times 11376 opts.state.isDuringAjax = true; 11377 11378 opts.loading.start.call($(opts.contentSelector)[0],opts); 11379 }, 11380 11381 // Check to see next page is needed 11382 scroll: function infscr_scroll() { 11383 11384 var opts = this.options, 11385 state = opts.state; 11386 11387 // if behavior is defined and this function is extended, call that instead of default 11388 if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) { 11389 this['scroll_'+opts.behavior].call(this); 11390 return; 11391 } 11392 11393 if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) { 11394 return; 11395 } 11396 11397 if (!this._nearbottom()) { 11398 return; 11399 } 11400 11401 this.retrieve(); 11402 11403 }, 11404 11405 // Toggle pause value 11406 toggle: function infscr_toggle() { 11407 this._pausing(); 11408 }, 11409 11410 // Unbind from scroll 11411 unbind: function infscr_unbind() { 11412 this._binding('unbind'); 11413 }, 11414 11415 // update options 11416 update: function infscr_options(key) { 11417 if ($.isPlainObject(key)) { 11418 this.options = $.extend(true,this.options,key); 11419 } 11420 } 11421 }; 11422 11423 11424 /* 11425 ---------------------------- 11426 Infinite Scroll function 11427 ---------------------------- 11428 11429 Borrowed logic from the following... 11430 11431 jQuery UI 11432 - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js 11433 11434 jCarousel 11435 - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js 11436 11437 Masonry 11438 - https://github.com/desandro/masonry/blob/master/jquery.masonry.js 11439 11440*/ 11441 11442 $.fn.infinitescroll = function infscr_init(options, callback) { 11443 11444 11445 var thisCall = typeof options; 11446 11447 switch (thisCall) { 11448 11449 // method 11450 case 'string': 11451 var args = Array.prototype.slice.call(arguments, 1); 11452 11453 this.each(function () { 11454 var instance = $.data(this, 'infinitescroll'); 11455 11456 if (!instance) { 11457 // not setup yet 11458 // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup'); 11459 return false; 11460 } 11461 11462 if (!$.isFunction(instance[options]) || options.charAt(0) === '_') { 11463 // return $.error('No such method ' + options + ' for Infinite Scroll'); 11464 return false; 11465 } 11466 11467 // no errors! 11468 instance[options].apply(instance, args); 11469 }); 11470 11471 break; 11472 11473 // creation 11474 case 'object': 11475 11476 this.each(function () { 11477 11478 var instance = $.data(this, 'infinitescroll'); 11479 11480 if (instance) { 11481 11482 // update options of current instance 11483 instance.update(options); 11484 11485 } else { 11486 11487 // initialize new instance 11488 instance = new $.infinitescroll(options, callback, this); 11489 11490 // don't attach if instantiation failed 11491 if (!instance.failed) { 11492 $.data(this, 'infinitescroll', instance); 11493 } 11494 11495 } 11496 11497 }); 11498 11499 break; 11500 11501 } 11502 11503 return this; 11504 }; 11505 11506 11507 11508 /* 11509 * smartscroll: debounced scroll event for jQuery * 11510 * https://github.com/lukeshumard/smartscroll 11511 * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js * 11512 * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. * 11513 */ 11514 11515 var event = $.event, 11516 scrollTimeout; 11517 11518 event.special.smartscroll = { 11519 setup: function () { 11520 $(this).bind('scroll', event.special.smartscroll.handler); 11521 }, 11522 teardown: function () { 11523 $(this).unbind('scroll', event.special.smartscroll.handler); 11524 }, 11525 handler: function (event, execAsap) { 11526 // Save the context 11527 var context = this, 11528 args = arguments; 11529 11530 // set correct event type 11531 event.type = 'smartscroll'; 11532 11533 if (scrollTimeout) { clearTimeout(scrollTimeout); } 11534 scrollTimeout = setTimeout(function () { 11535 $(context).trigger('smartscroll', args); 11536 }, execAsap === 'execAsap' ? 0 : 100); 11537 } 11538 }; 11539 11540 $.fn.smartscroll = function (fn) {
11541 return fn ? this.bind('smartscroll', fn) : this.trigger('smartscroll', ['execAsap']); 11542 }; 11543 11544})); 11545 11546/*! 11547Waypoints - 4.0.1 11548Copyright © 2011-2016 Caleb Troughton 11549Licensed under the MIT license. 11550https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 11551*/ 11552(function() { 11553 'use strict' 11554 11555 var keyCounter = 0 11556 var allWaypoints = {} 11557 11558 /* http://imakewebthings.com/waypoints/api/waypoint */ 11559 function Waypoint(options) { 11560 if (!options) { 11561 throw new Error('No options passed to Waypoint constructor') 11562 } 11563 if (!options.element) { 11564 throw new Error('No element option passed to Waypoint constructor') 11565 } 11566 if (!options.handler) { 11567 throw new Error('No handler option passed to Waypoint constructor') 11568 } 11569 11570 this.key = 'waypoint-' + keyCounter 11571 this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options) 11572 this.element = this.options.element 11573 this.adapter = new Waypoint.Adapter(this.element) 11574 this.callback = options.handler 11575 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 11576 this.enabled = this.options.enabled 11577 this.triggerPoint = null 11578 this.group = Waypoint.Group.findOrCreate({ 11579 name: this.options.group, 11580 axis: this.axis 11581 }) 11582 this.context = Waypoint.Context.findOrCreateByElement(this.options.context) 11583 11584 if (Waypoint.offsetAliases[this.options.offset]) { 11585 this.options.offset = Waypoint.offsetAliases[this.options.offset] 11586 } 11587 this.group.add(this) 11588 this.context.add(this) 11589 allWaypoints[this.key] = this 11590 keyCounter += 1 11591 } 11592 11593 /* Private */ 11594 Waypoint.prototype.queueTrigger = function(direction) { 11595 this.group.queueTrigger(this, direction) 11596 } 11597 11598 /* Private */ 11599 Waypoint.prototype.trigger = function(args) { 11600 if (!this.enabled) { 11601 return 11602 } 11603 if (this.callback) { 11604 this.callback.apply(this, args) 11605 } 11606 } 11607 11608 /* Public */ 11609 /* http://imakewebthings.com/waypoints/api/destroy */ 11610 Waypoint.prototype.destroy = function() { 11611 this.context.remove(this) 11612 this.group.remove(this) 11613 delete allWaypoints[this.key] 11614 } 11615 11616 /* Public */ 11617 /* http://imakewebthings.com/waypoints/api/disable */ 11618 Waypoint.prototype.disable = function() { 11619 this.enabled = false 11620 return this 11621 } 11622 11623 /* Public */ 11624 /* http://imakewebthings.com/waypoints/api/enable */ 11625 Waypoint.prototype.enable = function() { 11626 this.context.refresh() 11627 this.enabled = true 11628 return this 11629 } 11630 11631 /* Public */ 11632 /* http://imakewebthings.com/waypoints/api/next */ 11633 Waypoint.prototype.next = function() { 11634 return this.group.next(this) 11635 } 11636 11637 /* Public */ 11638 /* http://imakewebthings.com/waypoints/api/previous */ 11639 Waypoint.prototype.previous = function() { 11640 return this.group.previous(this) 11641 } 11642 11643 /* Private */ 11644 Waypoint.invokeAll = function(method) { 11645 var allWaypointsArray = []
11646 for (var waypointKey in allWaypoints) { 11647 allWaypointsArray.push(allWaypoints[waypointKey]) 11648 } 11649 for (var i = 0, end = allWaypointsArray.length; i < end; i++) { 11650 allWaypointsArray[i][method]() 11651 } 11652 } 11653 11654 /* Public */ 11655 /* http://imakewebthings.com/waypoints/api/destroy-all */ 11656 Waypoint.destroyAll = function() { 11657 Waypoint.invokeAll('destroy') 11658 } 11659 11660 /* Public */ 11661 /* http://imakewebthings.com/waypoints/api/disable-all */ 11662 Waypoint.disableAll = function() { 11663 Waypoint.invokeAll('disable') 11664 } 11665 11666 /* Public */ 11667 /* http://imakewebthings.com/waypoints/api/enable-all */ 11668 Waypoint.enableAll = function() { 11669 Waypoint.Context.refreshAll() 11670 for (var waypointKey in allWaypoints) { 11671 allWaypoints[waypointKey].enabled = true 11672 } 11673 return this 11674 } 11675 11676 /* Public */ 11677 /* http://imakewebthings.com/waypoints/api/refresh-all */ 11678 Waypoint.refreshAll = function() { 11679 Waypoint.Context.refreshAll() 11680 } 11681 11682 /* Public */ 11683 /* http://imakewebthings.com/waypoints/api/viewport-height */ 11684 Waypoint.viewportHeight = function() { 11685 return window.innerHeight || document.documentElement.clientHeight 11686 } 11687 11688 /* Public */ 11689 /* http://imakewebthings.com/waypoints/api/viewport-width */ 11690 Waypoint.viewportWidth = function() { 11691 return document.documentElement.clientWidth 11692 } 11693 11694 Waypoint.adapters = [] 11695 11696 Waypoint.defaults = { 11697 context: window, 11698 continuous: true, 11699 enabled: true, 11700 group: 'default', 11701 horizontal: false, 11702 offset: 0 11703 } 11704 11705 Waypoint.offsetAliases = { 11706 'bottom-in-view': function() { 11707 return this.context.innerHeight() - this.adapter.outerHeight() 11708 }, 11709 'right-in-view': function() { 11710 return this.context.innerWidth() - this.adapter.outerWidth() 11711 } 11712 } 11713 11714 window.Waypoint = Waypoint 11715}()) 11716;(function() { 11717 'use strict' 11718 11719 function requestAnimationFrameShim(callback) { 11720 window.setTimeout(callback, 1000 / 60) 11721 } 11722 11723 var keyCounter = 0 11724 var contexts = {} 11725 var Waypoint = window.Waypoint 11726 var oldWindowLoad = window.onload 11727 11728 /* http://imakewebthings.com/waypoints/api/context */ 11729 function Context(element) { 11730 this.element = element 11731 this.Adapter = Waypoint.Adapter 11732 this.adapter = new this.Adapter(element) 11733 this.key = 'waypoint-context-' + keyCounter 11734 this.didScroll = false 11735 this.didResize = false 11736 this.oldScroll = { 11737 x: this.adapter.scrollLeft(), 11738 y: this.adapter.scrollTop() 11739 } 11740 this.waypoints = { 11741 vertical: {}, 11742 horizontal: {} 11743 } 11744 11745 element.waypointContextKey = this.key 11746 contexts[element.waypointContextKey] = this 11747 keyCounter += 1 11748 if (!Waypoint.windowContext) { 11749 Waypoint.windowContext = true 11750 Waypoint.windowContext = new Context(window) 11751 } 11752 11753 this.createThrottledScrollHandler() 11754 this.createThrottledResizeHandler() 11755 } 11756 11757 /* Private */ 11758 Context.prototype.add = function(waypoint) { 11759 var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical' 11760 this.waypoints[axis][waypoint.key] = waypoint 11761 this.refresh() 11762 } 11763 11764 /* Private */ 11765 Context.prototype.checkEmpty = function() { 11766 var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal) 11767 var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical) 11768 var isWindow = this.element == this.element.window 11769 if (horizontalEmpty && verticalEmpty && !isWindow) { 11770 this.adapter.off('.waypoints') 11771 delete contexts[this.key] 11772 } 11773 } 11774 11775 /* Private */ 11776 Context.prototype.createThrottledResizeHandler = function() { 11777 var self = this 11778 11779 function resizeHandler() { 11780 self.handleResize() 11781 self.didResize = false 11782 } 11783 11784 this.adapter.on('resize.waypoints', function() { 11785 if (!self.didResize) { 11786 self.didResize = true 11787 Waypoint.requestAnimationFrame(resizeHandler) 11788 } 11789 }) 11790 } 11791 11792 /* Private */ 11793 Context.prototype.createThrottledScrollHandler = function() { 11794 var self = this 11795 function scrollHandler() { 11796 self.handleScroll() 11797 self.didScroll = false 11798 } 11799 11800 this.adapter.on('scroll.waypoints', function() { 11801 if (!self.didScroll || Waypoint.isTouch) { 11802 self.didScroll = true 11803 Waypoint.requestAnimationFrame(scrollHandler) 11804 } 11805 }) 11806 } 11807 11808 /* Private */ 11809 Context.prototype.handleResize = function() { 11810 Waypoint.Context.refreshAll() 11811 } 11812 11813 /* Private */ 11814 Context.prototype.handleScroll = function() { 11815 var triggeredGroups = {} 11816 var axes = { 11817 horizontal: { 11818 newScroll: this.adapter.scrollLeft(), 11819 oldScroll: this.oldScroll.x, 11820 forward: 'right', 11821 backward: 'left' 11822 }, 11823 vertical: { 11824 newScroll: this.adapter.scrollTop(), 11825 oldScroll: this.oldScroll.y, 11826 forward: 'down', 11827 backward: 'up' 11828 } 11829 } 11830 11831 for (var axisKey in axes) { 11832 var axis = axes[axisKey] 11833 var isForward = axis.newScroll > axis.oldScroll 11834 var direction = isForward ? axis.forward : axis.backward 11835
11836 for (var waypointKey in this.waypoints[axisKey]) { 11837 var waypoint = this.waypoints[axisKey][waypointKey] 11838 if (waypoint.triggerPoint === null) { 11839 continue 11840 } 11841 var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint 11842 var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint 11843 var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint 11844 var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint 11845 if (crossedForward || crossedBackward) { 11846 waypoint.queueTrigger(direction) 11847 triggeredGroups[waypoint.group.id] = waypoint.group 11848 } 11849 } 11850 } 11851 11852 for (var groupKey in triggeredGroups) { 11853 triggeredGroups[groupKey].flushTriggers() 11854 } 11855 11856 this.oldScroll = { 11857 x: axes.horizontal.newScroll, 11858 y: axes.vertical.newScroll 11859 } 11860 } 11861 11862 /* Private */ 11863 Context.prototype.innerHeight = function() { 11864 /*eslint-disable eqeqeq */ 11865 if (this.element == this.element.window) { 11866 return Waypoint.viewportHeight() 11867 } 11868 /*eslint-enable eqeqeq */ 11869 return this.adapter.innerHeight() 11870 } 11871 11872 /* Private */ 11873 Context.prototype.remove = function(waypoint) { 11874 delete this.waypoints[waypoint.axis][waypoint.key] 11875 this.checkEmpty() 11876 } 11877 11878 /* Private */ 11879 Context.prototype.innerWidth = function() { 11880 /*eslint-disable eqeqeq */ 11881 if (this.element == this.element.window) { 11882 return Waypoint.viewportWidth() 11883 } 11884 /*eslint-enable eqeqeq */ 11885 return this.adapter.innerWidth() 11886 } 11887 11888 /* Public */ 11889 /* http://imakewebthings.com/waypoints/api/context-destroy */ 11890 Context.prototype.destroy = function() { 11891 var allWaypoints = [] 11892 for (var axis in this.waypoints) {
11893 for (var waypointKey in this.waypoints[axis]) { 11894 allWaypoints.push(this.waypoints[axis][waypointKey]) 11895 } 11896 } 11897 for (var i = 0, end = allWaypoints.length; i < end; i++) { 11898 allWaypoints[i].destroy() 11899 } 11900 } 11901 11902 /* Public */ 11903 /* http://imakewebthings.com/waypoints/api/context-refresh */ 11904 Context.prototype.refresh = function() { 11905 /*eslint-disable eqeqeq */ 11906 var isWindow = this.element == this.element.window 11907 /*eslint-enable eqeqeq */ 11908 var contextOffset = isWindow ? undefined : this.adapter.offset() 11909 var triggeredGroups = {} 11910 var axes 11911 11912 this.handleScroll() 11913 axes = { 11914 horizontal: { 11915 contextOffset: isWindow ? 0 : contextOffset.left, 11916 contextScroll: isWindow ? 0 : this.oldScroll.x, 11917 contextDimension: this.innerWidth(), 11918 oldScroll: this.oldScroll.x, 11919 forward: 'right', 11920 backward: 'left', 11921 offsetProp: 'left' 11922 }, 11923 vertical: { 11924 contextOffset: isWindow ? 0 : contextOffset.top, 11925 contextScroll: isWindow ? 0 : this.oldScroll.y, 11926 contextDimension: this.innerHeight(), 11927 oldScroll: this.oldScroll.y, 11928 forward: 'down', 11929 backward: 'up', 11930 offsetProp: 'top' 11931 } 11932 } 11933 11934 for (var axisKey in axes) { 11935 var axis = axes[axisKey]
11936 for (var waypointKey in this.waypoints[axisKey]) { 11937 var waypoint = this.waypoints[axisKey][waypointKey] 11938 var adjustment = waypoint.options.offset 11939 var oldTriggerPoint = waypoint.triggerPoint 11940 var elementOffset = 0 11941 var freshWaypoint = oldTriggerPoint == null 11942 var contextModifier, wasBeforeScroll, nowAfterScroll 11943 var triggeredBackward, triggeredForward 11944 11945 if (waypoint.element !== waypoint.element.window) { 11946 elementOffset = waypoint.adapter.offset()[axis.offsetProp] 11947 } 11948 11949 if (typeof adjustment === 'function') { 11950 adjustment = adjustment.apply(waypoint) 11951 } 11952 else if (typeof adjustment === 'string') { 11953 adjustment = parseFloat(adjustment) 11954 if (waypoint.options.offset.indexOf('%') > - 1) { 11955 adjustment = Math.ceil(axis.contextDimension * adjustment / 100) 11956 } 11957 } 11958 11959 contextModifier = axis.contextScroll - axis.contextOffset 11960 waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment) 11961 wasBeforeScroll = oldTriggerPoint < axis.oldScroll 11962 nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll 11963 triggeredBackward = wasBeforeScroll && nowAfterScroll 11964 triggeredForward = !wasBeforeScroll && !nowAfterScroll 11965 11966 if (!freshWaypoint && triggeredBackward) { 11967 waypoint.queueTrigger(axis.backward) 11968 triggeredGroups[waypoint.group.id] = waypoint.group 11969 } 11970 else if (!freshWaypoint && triggeredForward) { 11971 waypoint.queueTrigger(axis.forward) 11972 triggeredGroups[waypoint.group.id] = waypoint.group 11973 } 11974 else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) { 11975 waypoint.queueTrigger(axis.forward) 11976 triggeredGroups[waypoint.group.id] = waypoint.group 11977 } 11978 } 11979 } 11980 11981 Waypoint.requestAnimationFrame(function() { 11982 for (var groupKey in triggeredGroups) { 11983 triggeredGroups[groupKey].flushTriggers() 11984 } 11985 }) 11986 11987 return this 11988 } 11989 11990 /* Private */ 11991 Context.findOrCreateByElement = function(element) { 11992 return Context.findByElement(element) || new Context(element) 11993 } 11994 11995 /* Private */ 11996 Context.refreshAll = function() { 11997 for (var contextId in contexts) { 11998 contexts[contextId].refresh() 11999 } 12000 } 12001 12002 /* Public */ 12003 /* http://imakewebthings.com/waypoints/api/context-find-by-element */ 12004 Context.findByElement = function(element) { 12005 return contexts[element.waypointContextKey] 12006 } 12007 12008 window.onload = function() { 12009 if (oldWindowLoad) { 12010 oldWindowLoad() 12011 } 12012 Context.refreshAll() 12013 } 12014 12015 12016 Waypoint.requestAnimationFrame = function(callback) { 12017 var requestFn = window.requestAnimationFrame || 12018 window.mozRequestAnimationFrame || 12019 window.webkitRequestAnimationFrame || 12020 requestAnimationFrameShim 12021 requestFn.call(window, callback) 12022 } 12023 Waypoint.Context = Context 12024}()) 12025;(function() { 12026 'use strict' 12027 12028 function byTriggerPoint(a, b) { 12029 return a.triggerPoint - b.triggerPoint 12030 } 12031 12032 function byReverseTriggerPoint(a, b) { 12033 return b.triggerPoint - a.triggerPoint 12034 } 12035 12036 var groups = { 12037 vertical: {}, 12038 horizontal: {} 12039 } 12040 var Waypoint = window.Waypoint 12041 12042 /* http://imakewebthings.com/waypoints/api/group */ 12043 function Group(options) { 12044 this.name = options.name 12045 this.axis = options.axis 12046 this.id = this.name + '-' + this.axis 12047 this.waypoints = [] 12048 this.clearTriggerQueues() 12049 groups[this.axis][this.name] = this 12050 } 12051 12052 /* Private */ 12053 Group.prototype.add = function(waypoint) { 12054 this.waypoints.push(waypoint) 12055 } 12056 12057 /* Private */ 12058 Group.prototype.clearTriggerQueues = function() { 12059 this.triggerQueues = { 12060 up: [], 12061 down: [], 12062 left: [], 12063 right: [] 12064 } 12065 } 12066 12067 /* Private */ 12068 Group.prototype.flushTriggers = function() { 12069 for (var direction in this.triggerQueues) { 12070 var waypoints = this.triggerQueues[direction] 12071 var reverse = direction === 'up' || direction === 'left' 12072 waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint) 12073 for (var i = 0, end = waypoints.length; i < end; i += 1) { 12074 var waypoint = waypoints[i] 12075 if (waypoint.options.continuous || i === waypoints.length - 1) { 12076 waypoint.trigger([direction]) 12077 } 12078 } 12079 } 12080 this.clearTriggerQueues() 12081 } 12082 12083 /* Private */ 12084 Group.prototype.next = function(waypoint) { 12085 this.waypoints.sort(byTriggerPoint) 12086 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12087 var isLast = index === this.waypoints.length - 1 12088 return isLast ? null : this.waypoints[index + 1] 12089 } 12090 12091 /* Private */ 12092 Group.prototype.previous = function(waypoint) { 12093 this.waypoints.sort(byTriggerPoint) 12094 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12095 return index ? this.waypoints[index - 1] : null 12096 } 12097 12098 /* Private */ 12099 Group.prototype.queueTrigger = function(waypoint, direction) { 12100 this.triggerQueues[direction].push(waypoint) 12101 } 12102 12103 /* Private */ 12104 Group.prototype.remove = function(waypoint) { 12105 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12106 if (index > -1) { 12107 this.waypoints.splice(index, 1) 12108 } 12109 } 12110 12111 /* Public */ 12112 /* http://imakewebthings.com/waypoints/api/first */ 12113 Group.prototype.first = function() { 12114 return this.waypoints[0] 12115 } 12116 12117 /* Public */ 12118 /* http://imakewebthings.com/waypoints/api/last */ 12119 Group.prototype.last = function() { 12120 return this.waypoints[this.waypoints.length - 1] 12121 } 12122 12123 /* Private */ 12124 Group.findOrCreate = function(options) { 12125 return groups[options.axis][options.name] || new Group(options) 12126 } 12127 12128 Waypoint.Group = Group 12129}()) 12130;(function() { 12131 'use strict' 12132 12133 var $ = window.jQuery 12134 var Waypoint = window.Waypoint 12135 12136 function JQueryAdapter(element) { 12137 this.$element = $(element) 12138 } 12139 12140 $.each([
12141 'innerHeight', 12142 'innerWidth', 12143 'off', 12144 'offset', 12145 'on', 12146 'outerHeight', 12147 'outerWidth', 12148 'scrollLeft', 12149 'scrollTop' 12150 ], function(i, method) { 12151 JQueryAdapter.prototype[method] = function() { 12152 var args = Array.prototype.slice.call(arguments) 12153 return this.$element[method].apply(this.$element, args) 12154 } 12155 }) 12156 12157 $.each([ 12158 'extend', 12159 'inArray', 12160 'isEmptyObject' 12161 ], function(i, method) { 12162 JQueryAdapter[method] = $[method] 12163 }) 12164 12165 Waypoint.adapters.push({ 12166 name: 'jquery', 12167 Adapter: JQueryAdapter 12168 }) 12169 Waypoint.Adapter = JQueryAdapter 12170}()) 12171;(function() { 12172 'use strict' 12173 12174 var Waypoint = window.Waypoint 12175 12176 function createExtension(framework) { 12177 return function() { 12178 var waypoints = [] 12179 var overrides = arguments[0] 12180 12181 if (framework.isFunction(arguments[0])) { 12182 overrides = framework.extend({}, arguments[1]) 12183 overrides.handler = arguments[0] 12184 } 12185 12186 this.each(function() { 12187 var options = framework.extend({}, overrides, { 12188 element: this 12189 }) 12190 if (typeof options.context === 'string') { 12191 options.context = framework(this).closest(options.context)[0] 12192 } 12193 waypoints.push(new Waypoint(options)) 12194 }) 12195 12196 return waypoints 12197 } 12198 } 12199 12200 if (window.jQuery) { 12201 window.jQuery.fn.waypoint = createExtension(window.jQuery) 12202 } 12203 if (window.Zepto) { 12204 window.Zepto.fn.waypoint = createExtension(window.Zepto) 12205 } 12206}()) 12207; 12208/*! 12209Waypoints Inview Shortcut - 4.0.1 12210Copyright © 2011-2016 Caleb Troughton 12211Licensed under the MIT license. 12212https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 12213*/ 12214(function() { 12215 'use strict' 12216 12217 function noop() {} 12218 12219 var Waypoint = window.Waypoint 12220 12221 /* http://imakewebthings.com/waypoints/shortcuts/inview */ 12222 function Inview(options) { 12223 this.options = Waypoint.Adapter.extend({}, Inview.defaults, options) 12224 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 12225 this.waypoints = [] 12226 this.element = this.options.element 12227 this.createWaypoints() 12228 } 12229 12230 /* Private */ 12231 Inview.prototype.createWaypoints = function() { 12232 var configs = { 12233 vertical: [{ 12234 down: 'enter', 12235 up: 'exited', 12236 offset: '100%' 12237 }, { 12238 down: 'entered', 12239 up: 'exit', 12240 offset: 'bottom-in-view' 12241 }, { 12242 down: 'exit', 12243 up: 'entered', 12244 offset: 0 12245 }, { 12246 down: 'exited', 12247 up: 'enter', 12248 offset: function() { 12249 return -this.adapter.outerHeight() 12250 } 12251 }], 12252 horizontal: [{ 12253 right: 'enter', 12254 left: 'exited', 12255 offset: '100%' 12256 }, { 12257 right: 'entered', 12258 left: 'exit', 12259 offset: 'right-in-view' 12260 }, { 12261 right: 'exit', 12262 left: 'entered', 12263 offset: 0 12264 }, { 12265 right: 'exited', 12266 left: 'enter', 12267 offset: function() { 12268 return -this.adapter.outerWidth() 12269 } 12270 }] 12271 } 12272 12273 for (var i = 0, end = configs[this.axis].length; i < end; i++) { 12274 var config = configs[this.axis][i] 12275 this.createWaypoint(config) 12276 } 12277 } 12278 12279 /* Private */ 12280 Inview.prototype.createWaypoint = function(config) { 12281 var self = this 12282 this.waypoints.push(new Waypoint({ 12283 context: this.options.context, 12284 element: this.options.element, 12285 enabled: this.options.enabled, 12286 handler: (function(config) { 12287 return function(direction) { 12288 self.options[config[direction]].call(self, direction) 12289 } 12290 }(config)), 12291 offset: config.offset, 12292 horizontal: this.options.horizontal 12293 })) 12294 } 12295 12296 /* Public */ 12297 Inview.prototype.destroy = function() { 12298 for (var i = 0, end = this.waypoints.length; i < end; i++) { 12299 this.waypoints[i].destroy() 12300 } 12301 this.waypoints = [] 12302 } 12303 12304 Inview.prototype.disable = function() { 12305 for (var i = 0, end = this.waypoints.length; i < end; i++) { 12306 this.waypoints[i].disable() 12307 } 12308 } 12309 12310 Inview.prototype.enable = function() { 12311 for (var i = 0, end = this.waypoints.length; i < end; i++) { 12312 this.waypoints[i].enable() 12313 } 12314 } 12315 12316 Inview.defaults = { 12317 context: window, 12318 enabled: true, 12319 enter: noop, 12320 entered: noop,
12321 exit: noop, 12322 exited: noop 12323 } 12324 12325 Waypoint.Inview = Inview 12326}()) 12327; 12328 12329/* 12330 * SmartMenus jQuery v0.9.6 12331 * http://www.smartmenus.org/ 12332 * 12333 * Copyright 2014 Vasil Dinkov, Vadikom Web Ltd. 12334 * http://vadikom.com/ 12335 * 12336 * Released under the MIT license: 12337 * http://www.opensource.org/licenses/MIT 12338 */ 12339 12340(function($) { 12341 12342 var menuTrees = [], 12343 IE = !!window.createPopup, // we need to detect it, unfortunately 12344 IElt9 = IE && !document.defaultView, 12345 IElt8 = IE && !document.querySelector, 12346 IE6 = IE && typeof document.documentElement.currentStyle.minWidth == 'undefined', 12347 mouse = false, // optimize for touch by default - we will detect for mouse input 12348 mouseDetectionEnabled = false; 12349 12350 // Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.) 12351 function initMouseDetection(disable) { 12352 if (!mouseDetectionEnabled && !disable) { 12353 // if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present 12354 // 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) 12355 var firstTime = true, 12356 lastMove = null; 12357 $(document).bind({ 12358 'mousemove.smartmenus_mouse': function(e) { 12359 var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() }; 12360 if (lastMove) { 12361 var deltaX = Math.abs(lastMove.x - thisMove.x), 12362 deltaY = Math.abs(lastMove.y - thisMove.y); 12363 if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) { 12364 mouse = true; 12365 // 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 12366 if (firstTime) { 12367 var $a = $(e.target).closest('a'); 12368 if ($a.is('a')) { 12369 $.each(menuTrees, function() { 12370 if ($.contains(this.$root[0], $a[0])) { 12371 this.itemEnter({ currentTarget: $a[0] }); 12372 return false; 12373 } 12374 }); 12375 } 12376 firstTime = false; 12377 } 12378 } 12379 } 12380 lastMove = thisMove; 12381 }, 12382 'touchstart.smartmenus_mouse pointerover.smartmenus_mouse MSPointerOver.smartmenus_mouse': function(e) { 12383 if (!/^(4|mouse|pen)$/.test(e.originalEvent.pointerType)) { 12384 mouse = false; 12385 } 12386 } 12387 }); 12388 mouseDetectionEnabled = true; 12389 } else if (mouseDetectionEnabled && disable) { 12390 $(document).unbind('.smartmenus_mouse'); 12391 mouseDetectionEnabled = false; 12392 } 12393 }; 12394 12395 $.SmartMenus = function(elm, options) { 12396 this.$root = $(elm); 12397 this.opts = options; 12398 this.rootId = ''; // internal 12399 this.$subArrow = null; 12400 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) 12401 this.activatedItems = []; // stores last activated A's for each level 12402 this.visibleSubMenus = []; // stores visible sub menus UL's 12403 this.showTimeout = 0; 12404 this.hideTimeout = 0; 12405 this.scrollTimeout = 0; 12406 this.clickActivated = false; 12407 this.zIndexInc = 0; 12408 this.$firstLink = null; // we'll use these for some tests 12409 this.$firstSub = null; // at runtime so we'll cache them 12410 this.disabled = false; 12411 this.$disableOverlay = null; 12412 this.init(); 12413 }; 12414 12415 $.extend($.SmartMenus, { 12416 hideAll: function() { 12417 $.each(menuTrees, function() { 12418 this.menuHideAll(); 12419 }); 12420 }, 12421 destroy: function() { 12422 while (menuTrees.length) { 12423 menuTrees[0].destroy(); 12424 } 12425 initMouseDetection(true); 12426 }, 12427 prototype: { 12428 init: function(refresh) { 12429 var self = this; 12430 12431 if (!refresh) { 12432 menuTrees.push(this); 12433 12434 this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, ''); 12435 12436 if (this.$root.hasClass('sm-rtl')) { 12437 this.opts.rightToLeftSubMenus = true; 12438 } 12439 12440 // init root (main menu) 12441 this.$root 12442 .data('smartmenus', this) 12443 .attr('data-smartmenus-id', this.rootId) 12444 .dataSM('level', 1) 12445 .bind({ 12446 'mouseover.smartmenus focusin.smartmenus': $.proxy(this.rootOver, this),
12447 'mouseout.smartmenus focusout.smartmenus': $.proxy(this.rootOut, this) 12448 }) 12449 .delegate('a, div.logo-container', { 12450 'mouseenter.smartmenus': $.proxy(this.itemEnter, this), 12451 'mouseleave.smartmenus': $.proxy(this.itemLeave, this), 12452 'mousedown.smartmenus': $.proxy(this.itemDown, this), 12453 'focus.smartmenus': $.proxy(this.itemFocus, this), 12454 'blur.smartmenus': $.proxy(this.itemBlur, this), 12455 'click.smartmenus': $.proxy(this.itemClick, this), 12456 'touchend.smartmenus': $.proxy(this.itemTouchEnd, this) 12457 }); 12458 12459 var eNamespace = '.smartmenus' + this.rootId; 12460 // hide menus on tap or click outside the root UL 12461 if (this.opts.hideOnClick) { 12462 $(document).on('touchstart' + eNamespace, $.proxy(this.docTouchStart, this)) 12463 .on('touchmove' + eNamespace, $.proxy(this.docTouchMove, this)) 12464 .on('touchend' + eNamespace, $.proxy(this.docTouchEnd, this)) 12465 // for Opera Mobile < 11.5, webOS browser, etc. we'll check click too 12466 .on('click' + eNamespace, $.proxy(this.docClick, this)); 12467 } 12468 // hide sub menus on resize 12469 $(window).on('resize' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this)); 12470 $(window).on('scroll' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this)); 12471 12472 if (this.opts.subIndicators) { 12473 this.$subArrow = $('<span/>').addClass('sub-arrow'); 12474 if (this.opts.subIndicatorsText) { 12475 this.$subArrow.html(this.opts.subIndicatorsText); 12476 } 12477 } 12478 12479 // make sure mouse detection is enabled 12480 initMouseDetection(); 12481 } 12482 12483 // init sub menus 12484 this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0); 12485 12486 this.$firstLink = this.$root.find('a').eq(0); 12487 12488 // find current item 12489 if (this.opts.markCurrentItem) { 12490 var reDefaultDoc = /(index|default)\.[^#\?\/]*/i, 12491 reHash = /#.*/, 12492 locHref = window.location.href.replace(reDefaultDoc, ''), 12493 locHrefNoHash = locHref.replace(reHash, ''); 12494 this.$root.find('a').each(function() { 12495 var href = this.href.replace(reDefaultDoc, ''), 12496 $this = $(this); 12497 if (href == locHref || href == locHrefNoHash) { 12498 $this.addClass('current'); 12499 if (self.opts.markCurrentTree) { 12500 $this.parents('li').each(function() { 12501 var $this = $(this); 12502 if ($this.dataSM('sub')) { 12503 $this.children('a').addClass('current'); 12504 } 12505 }); 12506 } 12507 } 12508 }); 12509 } 12510 }, 12511 destroy: function() { 12512 this.menuHideAll(); 12513 this.$root 12514 .removeData('smartmenus') 12515 .removeAttr('data-smartmenus-id') 12516 .removeDataSM('level') 12517 .unbind('.smartmenus') 12518 .undelegate('.smartmenus'); 12519 var eNamespace = '.smartmenus' + this.rootId; 12520 $(document).unbind(eNamespace); 12521 $(window).unbind(eNamespace); 12522 if (this.opts.subIndicators) { 12523 this.$subArrow = null; 12524 } 12525 var self = this; 12526 $.each(this.subMenus, function() { 12527 if (this.hasClass('mega-menu')) { 12528 this.find('ul').removeDataSM('in-mega'); 12529 } 12530 if (this.dataSM('shown-before')) { 12531 if (IElt8) { 12532 this.children().css({ styleFloat: '', width: '' }); 12533 } 12534 if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) { 12535 if (!IE6) { 12536 this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap'); 12537 } else { 12538 this.css({ width: '', overflowX: '', overflowY: '' }).children().children('a').css('white-space', ''); 12539 } 12540 } 12541 if (this.dataSM('scroll-arrows')) { 12542 this.dataSM('scroll-arrows').remove(); 12543 } 12544 this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' }); 12545 } 12546 if (self.opts.subIndicators) { 12547 this.dataSM('parent-a').removeClass('has-submenu').children('span.sub-arrow').remove(); 12548 } 12549 this.removeDataSM('shown-before') 12550 .removeDataSM('ie-shim') 12551 .removeDataSM('scroll-arrows') 12552 .removeDataSM('parent-a') 12553 .removeDataSM('level') 12554 .removeDataSM('beforefirstshowfired') 12555 .parent().removeDataSM('sub'); 12556 }); 12557 if (this.opts.markCurrentItem) { 12558 this.$root.find('a.current').removeClass('current'); 12559 } 12560 this.$root = null; 12561 this.$firstLink = null; 12562 this.$firstSub = null; 12563 if (this.$disableOverlay) { 12564 this.$disableOverlay.remove(); 12565 this.$disableOverlay = null; 12566 } 12567 menuTrees.splice($.inArray(this, menuTrees), 1); 12568 }, 12569 disable: function(noOverlay) { 12570 if (!this.disabled) { 12571 this.menuHideAll(); 12572 // display overlay over the menu to prevent interaction 12573 if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) { 12574 var pos = this.$root.offset(); 12575 this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({ 12576 position: 'absolute', 12577 top: pos.top, 12578 left: pos.left, 12579 width: this.$root.outerWidth(), 12580 height: this.$root.outerHeight(),
12581 zIndex: this.getStartZIndex() + 1, 12582 opacity: 0 12583 }).appendTo(document.body); 12584 } 12585 this.disabled = true; 12586 } 12587 }, 12588 docClick: function(e) { 12589 // hide on any click outside the menu or on a menu link 12590 if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a')) { 12591 this.menuHideAll($(e.target)); 12592 } 12593 }, 12594 docTouchEnd: function(e) { 12595 if (!this.lastTouch) { 12596 return; 12597 } 12598 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))) { 12599 if (this.hideTimeout) { 12600 clearTimeout(this.hideTimeout); 12601 this.hideTimeout = 0; 12602 } 12603 // hide with a delay to prevent triggering accidental unwanted click on some page element 12604 var self = this; 12605 this.hideTimeout = setTimeout(function() { self.menuHideAll($(e.target)); }, 350); 12606 } 12607 this.lastTouch = null; 12608 }, 12609 docTouchMove: function(e) { 12610 if (!this.lastTouch) { 12611 return; 12612 } 12613 var touchPoint = e.originalEvent.touches[0]; 12614 this.lastTouch.x2 = touchPoint.pageX; 12615 this.lastTouch.y2 = touchPoint.pageY; 12616 }, 12617 docTouchStart: function(e) { 12618 var touchPoint = e.originalEvent.touches[0]; 12619 this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target }; 12620 }, 12621 enable: function() { 12622 if (this.disabled) { 12623 if (this.$disableOverlay) { 12624 this.$disableOverlay.remove(); 12625 this.$disableOverlay = null; 12626 } 12627 this.disabled = false; 12628 } 12629 }, 12630 getHeight: function($elm) { 12631 return this.getOffset($elm, true); 12632 }, 12633 // returns precise width/height float values in IE9+, FF4+, recent WebKit 12634 // http://vadikom.com/dailies/offsetwidth-offsetheight-useless-in-ie9-firefox4/ 12635 getOffset: function($elm, height) { 12636 var old, 12637 $win = $(window), 12638 winW = $win.width(); 12639 if ($elm.css('display') == 'none') { 12640 old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility }; 12641 $elm.css({ position: 'absolute', visibility: 'hidden' }).show(); 12642 if ( 12643 ($('body').hasClass('menu-mobile-off-canvas') && winW < 960 && $elm.closest('.main-menu-container').length) 12644 || 12645 ($('body').hasClass('vmenu-offcanvas-overlay') && winW >= 960 && $elm.closest('.main-menu-container').length) 12646 ) { 12647 $elm.closest('li').addClass('smartmenu-open-item'); 12648 } 12649 } 12650 var defaultView = $elm[0].ownerDocument.defaultView, 12651 compStyle = defaultView && defaultView.getComputedStyle && defaultView.getComputedStyle($elm[0], null), 12652 val = compStyle && parseFloat(compStyle[height ? 'height' : 'width']); 12653 if (val) { 12654 val += parseFloat(compStyle[height ? 'paddingTop' : 'paddingLeft']) 12655 + parseFloat(compStyle[height ? 'paddingBottom' : 'paddingRight']) 12656 + parseInt(compStyle[height ? 'borderTopWidth' : 'borderLeftWidth']) 12657 + parseInt(compStyle[height ? 'borderBottomWidth' : 'borderRightWidth']); 12658 } else { 12659 val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth; 12660 } 12661 if (old) { 12662 $elm.hide().css(old); 12663 } 12664 return val; 12665 }, 12666 getWidth: function($elm) { 12667 return this.getOffset($elm); 12668 }, 12669 getStartZIndex: function() { 12670 var zIndex = parseInt(this.$root.css('z-index')); 12671 return !isNaN(zIndex) ? zIndex : 1; 12672 }, 12673 handleEvents: function() { 12674 return !this.disabled && this.isCSSOn(); 12675 }, 12676 handleItemEvents: function($a) { 12677 return this.handleEvents() && !this.isLinkInMegaMenu($a); 12678 }, 12679 isCollapsible: function() { 12680 return this.$firstSub.css('position') == 'static'; 12681 }, 12682 isCSSOn: function() { 12683 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'; 12684 }, 12685 isFixed: function() { 12686 return this.$root.css('position') == 'fixed'; 12687 }, 12688 isLinkInMegaMenu: function($a) { 12689 return !$a.parent().parent().dataSM('level'); 12690 }, 12691 isTouchMode: function() { 12692 return !mouse || this.isCollapsible(); 12693 }, 12694 itemActivate: function($a) { 12695 var $li = $a.parent(), 12696 $ul = $li.parent(), 12697 level = $ul.dataSM('level'); 12698 // 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 12699 if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) { 12700 var self = this; 12701 $($ul.parentsUntil('[data-smartmenus-id]', 'ul').get().reverse()).add($ul).each(function() { 12702 self.itemActivate($(this).dataSM('parent-a')); 12703 }); 12704 } 12705 // hide any visible deeper level sub menus 12706 if (this.visibleSubMenus.length > level) { 12707 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--) { 12708 //if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) { 12709 this.menuHide(this.visibleSubMenus[i]); 12710 //} 12711 } 12712 } 12713 // save new active item and sub menu for this level 12714 this.activatedItems[level - 1] = $a; 12715 this.visibleSubMenus[level - 1] = $ul; 12716 if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) { 12717 return; 12718 } 12719 // show the sub menu if this item has one 12720 var $sub = $li.dataSM('sub'); 12721 if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) { 12722 this.menuShow($sub); 12723 } 12724 }, 12725 itemBlur: function(e) { 12726 var $a = $(e.currentTarget); 12727 if (!this.handleItemEvents($a)) { 12728 return; 12729 } 12730 this.$root.triggerHandler('blur.smapi', $a[0]); 12731 }, 12732 itemClick: function(e) { 12733 var $a = $(e.currentTarget); 12734 12735 if (!this.handleItemEvents($a)) { 12736 return; 12737 } 12738 $a.removeDataSM('mousedown'); 12739 if (this.$root.triggerHandler('click.smapi', $a[0]) === false) { 12740 return false;
12741 } 12742 var $sub = $a.parent().dataSM('sub'); 12743 if (this.isTouchMode()) { 12744 // undo fix: prevent the address bar on iPhone from sliding down when expanding a sub menu 12745 if ($a.dataSM('href')) { 12746 $a.attr('href', $a.dataSM('href')).removeDataSM('href'); 12747 } 12748 // if the sub is not visible 12749 if ($sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 12750 // try to activate the item and show the sub 12751 this.itemActivate($a); 12752 // if "itemActivate" showed the sub, prevent the click so that the link is not loaded 12753 // 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 12754 if ($sub.is(':visible')) { 12755 return false; 12756 } 12757 } 12758 } else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub) { 12759 this.clickActivated = true; 12760 this.menuShow($sub); 12761 return false; 12762 } 12763 if ($a.hasClass('disabled')) { 12764 return false; 12765 } 12766 if (this.$root.triggerHandler('select.smapi', $a[0]) === false) { 12767 return false; 12768 } 12769 }, 12770 itemDown: function(e) { 12771 var $a = $(e.currentTarget); 12772 if (!this.handleItemEvents($a)) { 12773 return; 12774 } 12775 $a.dataSM('mousedown', true); 12776 }, 12777 itemEnter: function(e) { 12778 var $a = $(e.currentTarget); 12779 if (!this.handleItemEvents($a)) { 12780 return; 12781 } 12782 if (!this.isTouchMode()) { 12783 if (this.showTimeout) { 12784 clearTimeout(this.showTimeout); 12785 this.showTimeout = 0; 12786 } 12787 var self = this; 12788 this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 ? 1 : this.opts.showTimeout); 12789 } 12790 this.$root.triggerHandler('mouseenter.smapi', $a[0]); 12791 }, 12792 itemFocus: function(e) { 12793 var $a = $(e.currentTarget); 12794 if (!this.handleItemEvents($a)) { 12795 return; 12796 } 12797 // 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 12798 if ((!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) { 12799 this.itemActivate($a); 12800 } 12801 this.$root.triggerHandler('focus.smapi', $a[0]); 12802 }, 12803 itemLeave: function(e) { 12804 var $a = $(e.currentTarget); 12805 if (!this.handleItemEvents($a)) { 12806 return; 12807 } 12808 if (!this.isTouchMode()) { 12809 if ($a[0].blur) { 12810 $a[0].blur(); 12811 } 12812 if (this.showTimeout) { 12813 clearTimeout(this.showTimeout); 12814 this.showTimeout = 0; 12815 } 12816 } 12817 $a.removeDataSM('mousedown'); 12818 this.$root.triggerHandler('mouseleave.smapi', $a[0]); 12819 }, 12820 itemTouchEnd: function(e) { 12821 var $a = $(e.currentTarget); 12822 if (!this.handleItemEvents($a)) { 12823 return; 12824 } 12825 // prevent the address bar on iPhone from sliding down when expanding a sub menu 12826 var $sub = $a.parent().dataSM('sub'); 12827 if ($a.attr('href').charAt(0) !== '#' && $sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 12828 $a.dataSM('href', $a.attr('href')); 12829 $a.attr('href', '#'); 12830 } 12831 }, 12832 menuFixLayout: function($ul) { 12833 // fixes a menu that is being shown for the first time 12834 if (!$ul.dataSM('shown-before')) { 12835 $ul.hide().dataSM('shown-before', true); 12836 // fix the layout of the items in IE<8 12837 if (IElt8) { 12838 $ul.children().css({ styleFloat: 'left', width: '100%' }); 12839 } 12840 } 12841 }, 12842 menuHide: function($sub) { 12843 if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) { 12844 return; 12845 } 12846 $sub.stop(true, true); 12847 if ($sub.is(':visible')) { 12848 var complete = function() { 12849 // unset z-index 12850 if (IElt9) { 12851 $sub.parent().css('z-index', ''); 12852 } else { 12853 $sub.css('z-index', ''); 12854 } 12855 }; 12856 // if sub is collapsible (mobile view) 12857 if (this.isCollapsible()) { 12858 if (this.opts.collapsibleHideFunction) { 12859 this.opts.collapsibleHideFunction.call(this, $sub, complete); 12860 } else { 12861 $sub.hide(this.opts.collapsibleHideDuration, complete); 12862 } 12863 } else { 12864 if (this.opts.hideFunction) { 12865 this.opts.hideFunction.call(this, $sub, complete); 12866 } else { 12867 $sub.hide(this.opts.hideDuration, complete); 12868 } 12869 } 12870 // remove IE iframe shim 12871 if ($sub.dataSM('ie-shim')) { 12872 $sub.dataSM('ie-shim').remove(); 12873 } 12874 // deactivate scrolling if it is activated for this sub 12875 if ($sub.dataSM('scroll')) { 12876 $sub.unbind('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide(); 12877 } 12878 // unhighlight parent item 12879 $sub.dataSM('parent-a').removeClass('highlighted'); 12880 var level = $sub.dataSM('level'); 12881 this.activatedItems.splice(level - 1, 1); 12882 this.visibleSubMenus.splice(level - 1, 1); 12883 this.$root.triggerHandler('hide.smapi', $sub[0]); 12884 } 12885 }, 12886 menuHideAll: function($item) { 12887 if ($item != undefined && $item.parent().hasClass('menu-item') && !$item.parent().hasClass('menu-item-has-children')) return; 12888 var $win = $(window), 12889 winW = $win.width(); 12890 if (this.showTimeout) { 12891 clearTimeout(this.showTimeout); 12892 this.showTimeout = 0; 12893 } 12894 // hide all subs 12895 for (var i = this.visibleSubMenus.length - 1; i > 0; i--) { 12896 if ( this.visibleSubMenus[i].closest('.smartmenu-open-item').length ) { 12897 if ( $item != undefined && $item.closest('.smartmenu-open-item').length ) { 12898 this.menuHide(this.visibleSubMenus[i]); 12899 $(this.visibleSubMenus[i]).closest('.smartmenu-open-item').removeClass('smartmenu-open-item'); 12900 } else { 12901 return; 12902 } 12903 } else { 12904 this.menuHide(this.visibleSubMenus[i]); 12905 } 12906 } 12907 // hide root if it's popup 12908 if (this.opts.isPopup) { 12909 this.$root.stop(true, true); 12910 if (this.$root.is(':visible')) { 12911 if (this.opts.hideFunction) { 12912 this.opts.hideFunction.call(this, this.$root); 12913 } else { 12914 this.$root.hide(this.opts.hideDuration); 12915 } 12916 // remove IE iframe shim 12917 if (this.$root.dataSM('ie-shim')) { 12918 this.$root.dataSM('ie-shim').remove(); 12919 } 12920 } 12921 } 12922 this.activatedItems = []; 12923 this.visibleSubMenus = []; 12924 this.clickActivated = false;
12925 // reset z-index increment 12926 this.zIndexInc = 0; 12927 }, 12928 menuIframeShim: function($ul) { 12929 // create iframe shim for the menu 12930 if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) { 12931 $ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 }) 12932 .css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' }) 12933 ); 12934 } 12935 }, 12936 menuInit: function($ul) { 12937 if (!$ul.dataSM('in-mega')) { 12938 this.subMenus.push($ul); 12939 // mark UL's in mega drop downs (if any) so we can neglect them 12940 if ($ul.hasClass('mega-menu')) { 12941 $ul.find('ul').dataSM('in-mega', true); 12942 } 12943 // get level (much faster than, for example, using parentsUntil) 12944 var level = 2, 12945 par = $ul[0]; 12946 while (par != null && par.parentNode != null && ( par = par.parentNode.parentNode) != this.$root[0]) { 12947 level++; 12948 } 12949 // cache stuff 12950 $ul.dataSM('parent-a', $ul.prevAll('a').eq(-1)) 12951 .dataSM('level', level) 12952 .parent().dataSM('sub', $ul); 12953 // add sub indicator to parent item 12954 if (this.opts.subIndicators) { 12955 $ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone()); 12956 } 12957 } 12958 }, 12959 menuPosition: function($sub) { 12960 var fixIE = $('html.ie').length; 12961 // if (fixIE) { 12962 // var $rowParent = $($sub).closest('.main-menu-container'); 12963 // $rowParent.height($rowParent.height()); 12964 // } 12965 var $a = $sub.dataSM('parent-a'), 12966 $li = $sub.parent(), 12967 $ul = $sub.parent().parent(), 12968 // $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'), 12969 $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'), 12970 level = $sub.dataSM('level'), 12971 subW = this.getWidth($sub), 12972 subH = this.getHeight($sub), 12973 itemOffset = $a.offset(), 12974 itemX = itemOffset.left, 12975 itemY = itemOffset.top, 12976 itemW = this.getWidth($a), 12977 itemH = this.getHeight($a), 12978 $win = $(window), 12979 winX = $win.scrollLeft(), 12980 winY = $win.scrollTop(), 12981 winW = $win.width(), 12982 winH = $win.height(), 12983 containerW = $container.width(), 12984 containerOffsetX = containerW + ((winW - containerW) / 2), 12985 horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'), 12986 subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX, 12987 subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY, 12988 x, y, leftPos; 12989 12990 if (horizontalParent) { 12991 x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX; 12992 y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY; 12993 } else { 12994 x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : subW - subOffsetX; 12995 y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY; 12996 } 12997 if (this.opts.keepInViewport && !this.isCollapsible()) { 12998 if (this.isFixed()) { 12999 itemX -= winX; 13000 itemY -= winY; 13001 winX = winY = 0; 13002 } 13003 var absX = itemX + x, 13004 absY = itemY + y; 13005 if (this.opts.rightToLeftSubMenus && absX < winX) { 13006 x = horizontalParent ? winX - absX + x : itemW - subOffsetX; 13007 } else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) { 13008 x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW; 13009 } 13010 if (!horizontalParent) { 13011 if (subH < winH && absY + subH > winY + winH) { 13012 y += winY + winH - subH - absY; 13013 } else if (subH >= winH || absY < winY) { 13014 y += winY - absY; 13015 } 13016 } 13017 // do we need scrolling? 13018 // 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH" 13019 if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) { 13020 var self = this; 13021 if (!$sub.dataSM('scroll-arrows')) { 13022 $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]]) 13023 .bind({ 13024 mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); }, 13025 mouseleave: function(e) { 13026 self.menuScrollStop($sub); 13027 self.menuScrollOut($sub, e); 13028 }, 13029 'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); } 13030 }) 13031 .insertAfter($sub) 13032 ); 13033 } 13034 // bind events to show/hide arrows on hover and save scrolling data for this sub 13035 var vportY = winY - (itemY + itemH); 13036 $sub.dataSM('scroll', { 13037 vportY: vportY, 13038 subH: subH, 13039 winH: winH, 13040 step: 1 13041 }) 13042 .bind({ 13043 'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); }, 13044 'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); }, 13045 'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); } 13046 }) 13047 .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
13047StartZIndex() + this.zIndexInc }) 13048 .eq(0).css('margin-top', vportY).end() 13049 .eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end() 13050 .eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show(); 13051 } 13052 } 13053 if ( !$sub.closest('.menu-accordion').length ) { 13054 var rightPos = 'auto'; 13055 if ( $sub.closest('.grid-filters').length ) { 13056 if ( $sub.closest('.text-right').length ) { 13057 leftPos = '0px'; 13058 rightPos = 'auto'; 13059 } else { 13060 leftPos = 'auto'; 13061 rightPos = '0px'; 13062 } 13063 x = 0; 13064 } else { 13065 if ( $sub.hasClass('mega-menu-inner') ) { 13066 $sub.css({ width: containerW}); 13067 leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.row-menu').offset().left)); 13068 if ( ! $('body').hasClass('megamenu-side-to-side') ) { 13069 leftPos += parseFloat($sub.closest('.row-menu-inner').css('paddingLeft')); 13070 } 13071 x = 0; 13072 } else { 13073 leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul').css('paddingLeft')) : $li.position().left ) + 'px'; 13074 x = (level > 2 && x >= 0) ? x + 1 : x - 1; 13075 } 13076 } 13077 } 13078 13079 // $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) }); 13080 $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) }); 13081 // IE iframe shim 13082 this.menuIframeShim($sub); 13083 if ($sub.dataSM('ie-shim')) { 13084 $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) }); 13085 } 13086 }, 13087 menuScroll: function($sub, up, wheel) { 13088 var y = parseFloat($sub.css('margin-top')), 13089 scroll = $sub.dataSM('scroll'), 13090 end = scroll.vportY + (up ? 0 : scroll.winH - scroll.subH), 13091 step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step); 13092 $sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end); 13093 y = parseFloat($sub.css('margin-top')); 13094 // show opposite arrow if appropriate 13095 if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) { 13096 $sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show(); 13097 } 13098 // accelerate when not using mousewheel to scroll 13099 if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) { 13100 $sub.dataSM('scroll').step += 0.5; 13101 } 13102 // "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used 13103 if (Math.abs(y - end) < 1) { 13104 $sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide(); 13105 $sub.dataSM('scroll').step = 1; 13106 } else if (!wheel) { 13107 var self = this; 13108 this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval); 13109 } 13110 }, 13111 menuScrollMousewheel: function($sub, e) { 13112 var $closestSub = $(e.target).closest('ul'); 13113 while ($closestSub.dataSM('in-mega')) { 13114 $closestSub = $closestSub.parent().closest('ul'); 13115 } 13116 if ($closestSub[0] == $sub[0]) { 13117 var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0; 13118 if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) { 13119 this.menuScroll($sub, up, true); 13120 } 13121 } 13122 e.preventDefault(); 13123 }, 13124 menuScrollOut: function($sub, e) { 13125 var reClass = /^scroll-(up|down)/, 13126 $closestSub = $(e.relatedTarget).closest('ul'); 13127 while ($closestSub.dataSM('in-mega')) { 13128 $closestSub = $closestSub.parent().closest('ul'); 13129 } 13130 if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) { 13131 $sub.dataSM('scroll-arrows').css('visibility', 'hidden'); 13132 } 13133 }, 13134 menuScrollOver: function($sub, e) { 13135 var reClass = /^scroll-(up|down)/, 13136 $closestSub = $(e.target).closest('ul'); 13137 while ($closestSub.dataSM('in-mega')) { 13138 $closestSub = $closestSub.parent().closest('ul'); 13139 } 13140 if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) { 13141 $sub.dataSM('scroll-arrows').css('visibility', 'visible'); 13142 } 13143 }, 13144 menuScrollStop: function($sub) { 13145 if (this.scrollTimeout) { 13146 clearTimeout(this.scrollTimeout); 13147 this.scrollTimeout = 0; 13148 $sub.dataSM('scroll').step = 1; 13149 } 13150 }, 13151 menuShow: function($sub) { 13152 if (!$sub.dataSM('beforefirstshowfired')) { 13153 $sub.dataSM('beforefirstshowfired', true); 13154 if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) { 13155 return; 13156 } 13157 } 13158 if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) { 13159 return; 13160 } 13161 this.menuFixLayout($sub); 13162 $sub.stop(true, true); 13163 if (!$sub.is(':visible')) { 13164 $sub.css({ 13165 'visibility': 'visible', 13166 'pointer-events': 'auto', 13167 }); 13168 // set z-index - for IE < 9 set it to the parent LI
13169 var zIndex = this.getStartZIndex() + (++this.zIndexInc); 13170 if (IElt9) { 13171 $sub.parent().css('z-index', zIndex); 13172 } else { 13173 $sub.css('z-index', zIndex); 13174 } 13175 // highlight parent item 13176 if (this.opts.keepHighlighted || this.isCollapsible()) { 13177 if ($sub.dataSM('parent-a').attr('data-type') != 'title') 13178 $sub.dataSM('parent-a').addClass('highlighted'); 13179 } 13180 // min/max-width fix - no way to rely purely on CSS as all UL's are nested 13181 if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) { 13182 if (!IElt8) { 13183 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 13184 if (this.opts.subMenusMinWidth) { 13185 $sub.css('min-width', this.opts.subMenusMinWidth); 13186 } 13187 if (this.opts.subMenusMaxWidth) { 13188 var noMaxWidth = this.getWidth($sub); 13189 if ( ! $sub.hasClass('mega-menu-inner') ) { 13190 $sub.css('max-width', this.opts.subMenusMaxWidth); 13191 } 13192 if (noMaxWidth > this.getWidth($sub)) { 13193 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 13194 } 13195 } 13196 // IE6,7 13197 } else { 13198 $sub.children().css('styleFloat', 'none'); 13199 if (IE6) { 13200 $sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1) 13201 .children().children('a').css('white-space', 'nowrap'); 13202 } else { // IE7 13203 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 13204 if (this.opts.subMenusMinWidth) { 13205 $sub.css('min-width', this.opts.subMenusMinWidth); 13206 } 13207 } 13208 if (this.opts.subMenusMaxWidth) { 13209 var noMaxWidth = $sub.width(); 13210 if (IE6) { 13211 var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width(); 13212 if (noMaxWidth > maxWidth) { 13213 $sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', ''); 13214 } else { 13215 $sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' }); 13216 } 13217 } else { // IE7 13218 if ( ! $sub.hasClass('mega-menu-inner') ) { 13219 $sub.css('max-width', this.opts.subMenusMaxWidth); 13220 } 13221 if (noMaxWidth > $sub.width()) { 13222 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 13223 } else { 13224 $sub.width(noMaxWidth); 13225 } 13226 } 13227 } else { 13228 $sub.width($sub.width()); 13229 } 13230 $sub.children().css('styleFloat', 'left'); 13231 } 13232 } 13233 this.menuPosition($sub); 13234 // insert IE iframe shim 13235 if ($sub.dataSM('ie-shim')) { 13236 $sub.dataSM('ie-shim').insertBefore($sub); 13237 } 13238 var complete = function() { 13239 // fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used 13240 $sub.css('overflow', ''); 13241 }; 13242 // if sub is collapsible (mobile view) 13243 if (this.isCollapsible()) { 13244 if (this.opts.collapsibleShowFunction) { 13245 this.opts.collapsibleShowFunction.call(this, $sub, complete); 13246 } else { 13247 $sub.show(this.opts.collapsibleShowDuration, complete); 13248 } 13249 } else { 13250 if (this.opts.showFunction) { 13251 this.opts.showFunction.call(this, $sub, complete); 13252 } else { 13253 $sub.show(this.opts.showDuration, complete); 13254 } 13255 } 13256 // save new sub menu for this level 13257 this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub; 13258 this.$root.triggerHandler('show.smapi', $sub[0]); 13259 } 13260 }, 13261 popupHide: function(noHideTimeout) { 13262 if (this.hideTimeout) { 13263 clearTimeout(this.hideTimeout); 13264 this.hideTimeout = 0; 13265 } 13266 var self = this; 13267 this.hideTimeout = setTimeout(function() { 13268 self.menuHideAll(); 13269 }, noHideTimeout ? 1 : this.opts.hideTimeout); 13270 }, 13271 popupShow: function(left, top) { 13272 if (!this.opts.isPopup) { 13273 alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'); 13274 return; 13275 } 13276 if (this.hideTimeout) { 13277 clearTimeout(this.hideTimeout); 13278 this.hideTimeout = 0; 13279 } 13280 this.menuFixLayout(this.$root); 13281 this.$root.stop(true, true); 13282 if (!this.$root.is(':visible')) { 13283 this.$root.css({ left: left, top: top }); 13284 // IE iframe shim 13285 this.menuIframeShim(this.$root); 13286 if (this.$root.dataSM('ie-shim')) { 13287 this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
13287: left, top: top }).insertBefore(this.$root); 13288 } 13289 // show menu 13290 if (this.opts.showFunction) { 13291 this.opts.showFunction.call(this, this.$root); 13292 } else { 13293 this.$root.show(this.opts.showDuration); 13294 } 13295 this.visibleSubMenus[0] = this.$root; 13296 } 13297 }, 13298 refresh: function() { 13299 this.menuHideAll(); 13300 this.$root.find('ul').each(function() { 13301 var $this = $(this); 13302 if ($this.dataSM('scroll-arrows')) { 13303 $this.dataSM('scroll-arrows').remove(); 13304 } 13305 }) 13306 .removeDataSM('in-mega') 13307 .removeDataSM('shown-before') 13308 .removeDataSM('ie-shim') 13309 .removeDataSM('scroll-arrows') 13310 .removeDataSM('parent-a') 13311 .removeDataSM('level') 13312 .removeDataSM('beforefirstshowfired'); 13313 this.$root.find('a.has-submenu').removeClass('has-submenu') 13314 .parent().removeDataSM('sub'); 13315 if (this.opts.subIndicators) { 13316 this.$root.find('span.sub-arrow').remove(); 13317 } 13318 if (this.opts.markCurrentItem) { 13319 this.$root.find('a.current').removeClass('current'); 13320 } 13321 this.subMenus = []; 13322 this.init(true); 13323 }, 13324 rootOut: function(e) { 13325 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 13326 return; 13327 } 13328 if (this.hideTimeout) { 13329 clearTimeout(this.hideTimeout); 13330 this.hideTimeout = 0; 13331 } 13332 if (!this.opts.showOnClick || !this.opts.hideOnClick) { 13333 var self = this; 13334 this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout); 13335 } 13336 }, 13337 rootOver: function(e) { 13338 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 13339 return; 13340 } 13341 if (this.hideTimeout) { 13342 clearTimeout(this.hideTimeout); 13343 this.hideTimeout = 0; 13344 } 13345 }, 13346 winResize: function(e) { 13347 if (!this.handleEvents()) { 13348 // we still need to resize the disable overlay if it's visible 13349 if (this.$disableOverlay) { 13350 var pos = this.$root.offset(); 13351 this.$disableOverlay.css({ 13352 top: pos.top, 13353 left: pos.left, 13354 width: this.$root.outerWidth(), 13355 height: this.$root.outerHeight() 13356 }); 13357 } 13358 return; 13359 } 13360 // hide sub menus on resize - on mobile do it only on orientation change 13361 if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) { 13362 if (this.activatedItems.length) { 13363 this.activatedItems[this.activatedItems.length - 1][0].blur(); 13364 } 13365 this.menuHideAll(); 13366 } 13367 } 13368 } 13369 }); 13370 13371 $.fn.dataSM = function(key, val) { 13372 if (val) { 13373 return this.data(key + '_smartmenus', val); 13374 } 13375 return this.data(key + '_smartmenus'); 13376 } 13377 13378 $.fn.removeDataSM = function(key) { 13379 return this.removeData(key + '_smartmenus'); 13380 } 13381 13382 $.fn.smartmenus = function(options) { 13383 if (typeof options == 'string') { 13384 var args = arguments, 13385 method = options; 13386 Array.prototype.shift.call(args); 13387 return this.each(function() { 13388 var smartmenus = $(this).data('smartmenus'); 13389 if (smartmenus && smartmenus[method]) { 13390 smartmenus[method].apply(smartmenus, args); 13391 } 13392 }); 13393 } 13394 var opts = $.extend({}, $.fn.smartmenus.defaults, options); 13395 return this.each(function() { 13396 new $.SmartMenus(this, opts); 13397 }); 13398 } 13399 13400 // default settings 13401 $.fn.smartmenus.defaults = { 13402 isPopup: false, // is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar 13403 mainMenuSubOffsetX: 0, // pixels offset from default position
13404 mainMenuSubOffsetY: 0, // pixels offset from default position 13405 subMenusSubOffsetX: 0, // pixels offset from default position 13406 subMenusSubOffsetY: 0, // pixels offset from default position 13407 subMenusMinWidth: false, //'10em', // min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 13408 subMenusMaxWidth: false, //'20em', // max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 13409 subIndicators: true, // create sub menu indicators - creates a SPAN and inserts it in the A 13410 subIndicatorsPos: 'prepend', // position of the SPAN relative to the menu item content ('prepend', 'append') 13411 subIndicatorsText: '+', // [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too) 13412 scrollStep: 30, // pixels step when scrolling long sub menus that do not fit in the viewport height 13413 scrollInterval: 30, // interval between each scrolling step 13414 scrollAccelerate: true, // accelerate scrolling or use a fixed step 13415 showTimeout: 250, // timeout before showing the sub menus 13416 hideTimeout: 500, // timeout before hiding the sub menus 13417 showDuration: 0, // duration for show animation - set to 0 for no animation - matters only if showFunction:null 13418 showFunction: null, // custom function to use when showing a sub menu (the default is the jQuery 'show') 13419 // don't forget to call complete() at the end of whatever you do 13420 // e.g.: function($ul, complete) { $ul.fadeIn(250, complete); } 13421 hideDuration: 0, // duration for hide animation - set to 0 for no animation - matters only if hideFunction:null 13422 hideFunction: function($ul, complete) { $ul.fadeOut(200, complete); }, // custom function to use when hiding a sub menu (the default is the jQuery 'hide') 13423 // don't forget to call complete() at the end of whatever you do 13424 // e.g.: function($ul, complete) { $ul.fadeOut(250, complete); } 13425 collapsibleShowDuration:0, // duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null 13426 collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); }, // custom function to use when showing a collapsible sub menu 13427 // (i.e. when mobile styles are used to make the sub menus collapsible) 13428 collapsibleHideDuration:0, // duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null 13429 collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); }, // custom function to use when hiding a collapsible sub menu 13430 // (i.e. when mobile styles are used to make the sub menus collapsible) 13431 showOnClick: false, // show the first-level sub menus onclick instead of onmouseover (matters only for mouse input) 13432 hideOnClick: true, // hide the sub menus on click/tap anywhere on the page 13433 keepInViewport: true, // reposition the sub menus if needed to make sure they always appear inside the viewport 13434 keepHighlighted: true, // keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's) 13435 markCurrentItem: false, // automatically add the 'current' class to the A element of the item linking to the current URL 13436 markCurrentTree: true, // add the 'current' class also to the A elements of all ancestor items of the current item 13437 rightToLeftSubMenus: false, // right to left display of the sub menus (check the CSS for the sub indicators' position) 13438 bottomToTopSubMenus: false, // bottom to top display of the sub menus 13439 overlapControlsInIE: true // make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.) 13440 }; 13441 13442})(jQuery); 13443/* 13444 * jQuery Easing v1.4.1 - http://gsgd.co.uk/sandbox/jquery/easing/ 13445 * Open source under the BSD License. 13446 * Copyright © 2008 George McGinley Smith 13447 * All rights reserved. 13448 * https://raw.github.com/gdsmith/jquery.easing/master/LICENSE 13449*/ 13450 13451/* globals jQuery, define, module, require */ 13452(function (factory) { 13453 if (typeof define === "function" && define.amd) { 13454 define(['jquery'], function ($) { 13455 return factory($); 13456 }); 13457 } else if (typeof module === "object" && typeof module.exports === "object") { 13458 module.exports = factory(require('jquery')); 13459 } else { 13460 factory(jQuery); 13461 } 13462})(function($){ 13463 13464 // Preserve the original jQuery "swing" easing as "jswing" 13465 if (typeof $.easing !== 'undefined') { 13466 $.easing['jswing'] = $.easing['swing']; 13467 } 13468 13469 var pow = Math.pow, 13470 sqrt = Math.sqrt, 13471 sin = Math.sin, 13472 cos = Math.cos, 13473 PI = Math.PI,
13474 c1 = 1.70158, 13475 c2 = c1 * 1.525, 13476 c3 = c1 + 1, 13477 c4 = ( 2 * PI ) / 3, 13478 c5 = ( 2 * PI ) / 4.5; 13479 13480 // x is the fraction of animation progress, in the range 0..1 13481 function bounceOut(x) { 13482 var n1 = 7.5625, 13483 d1 = 2.75; 13484 if ( x < 1/d1 ) { 13485 return n1*x*x; 13486 } else if ( x < 2/d1 ) { 13487 return n1*(x-=(1.5/d1))*x + .75; 13488 } else if ( x < 2.5/d1 ) { 13489 return n1*(x-=(2.25/d1))*x + .9375; 13490 } else { 13491 return n1*(x-=(2.625/d1))*x + .984375; 13492 } 13493 } 13494 13495 $.extend( $.easing, { 13496 def: 'easeOutQuad', 13497 swing: function (x) { 13498 return $.easing[$.easing.def](x); 13499 }, 13500 easeInQuad: function (x) { 13501 return x * x; 13502 }, 13503 easeOutQuad: function (x) { 13504 return 1 - ( 1 - x ) * ( 1 - x ); 13505 }, 13506 easeInOutQuad: function (x) { 13507 return x < 0.5 ? 13508 2 * x * x : 13509 1 - pow( -2 * x + 2, 2 ) / 2; 13510 }, 13511 easeInCubic: function (x) { 13512 return x * x * x; 13513 }, 13514 easeOutCubic: function (x) { 13515 return 1 - pow( 1 - x, 3 ); 13516 }, 13517 easeInOutCubic: function (x) { 13518 return x < 0.5 ? 13519 4 * x * x * x : 13520 1 - pow( -2 * x + 2, 3 ) / 2; 13521 }, 13522 easeInQuart: function (x) { 13523 return x * x * x * x; 13524 }, 13525 easeOutQuart: function (x) { 13526 return 1 - pow( 1 - x, 4 ); 13527 }, 13528 easeInOutQuart: function (x) { 13529 return x < 0.5 ? 13530 8 * x * x * x * x : 13531 1 - pow( -2 * x + 2, 4 ) / 2; 13532 }, 13533 easeInQuint: function (x) { 13534 return x * x * x * x * x; 13535 }, 13536 easeOutQuint: function (x) { 13537 return 1 - pow( 1 - x, 5 ); 13538 }, 13539 easeInOutQuint: function (x) { 13540 return x < 0.5 ? 13541 16 * x * x * x * x * x : 13542 1 - pow( -2 * x + 2, 5 ) / 2; 13543 }, 13544 easeInSine: function (x) { 13545 return 1 - cos( x * PI/2 ); 13546 }, 13547 easeOutSine: function (x) { 13548 return sin( x * PI/2 ); 13549 }, 13550 easeInOutSine: function (x) { 13551 return -( cos( PI * x ) - 1 ) / 2; 13552 }, 13553 easeInExpo: function (x) { 13554 return x === 0 ? 0 : pow( 2, 10 * x - 10 ); 13555 }, 13556 easeOutExpo: function (x) { 13557 return x === 1 ? 1 : 1 - pow( 2, -10 * x ); 13558 }, 13559 easeInOutExpo: function (x) { 13560 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 13561 pow( 2, 20 * x - 10 ) / 2 : 13562 ( 2 - pow( 2, -20 * x + 10 ) ) / 2; 13563 }, 13564 easeInCirc: function (x) { 13565 return 1 - sqrt( 1 - pow( x, 2 ) ); 13566 }, 13567 easeOutCirc: function (x) { 13568 return sqrt( 1 - pow( x - 1, 2 ) ); 13569 }, 13570 easeInOutCirc: function (x) { 13571 return x < 0.5 ? 13572 ( 1 - sqrt( 1 - pow( 2 * x, 2 ) ) ) / 2 : 13573 ( sqrt( 1 - pow( -2 * x + 2, 2 ) ) + 1 ) / 2; 13574 }, 13575 easeInElastic: function (x) { 13576 return x === 0 ? 0 : x === 1 ? 1 : 13577 -pow( 2, 10 * x - 10 ) * sin( ( x * 10 - 10.75 ) * c4 ); 13578 }, 13579 easeOutElastic: function (x) { 13580 return x === 0 ? 0 : x === 1 ? 1 : 13581 pow( 2, -10 * x ) * sin( ( x * 10 - 0.75 ) * c4 ) + 1; 13582 }, 13583 easeInOutElastic: function (x) { 13584 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 13585 -( pow( 2, 20 * x - 10 ) * sin( ( 20 * x - 11.125 ) * c5 )) / 2 : 13586 pow( 2, -20 * x + 10 ) * sin( ( 20 * x - 11.125 ) * c5 ) / 2 + 1; 13587 }, 13588 easeInBack: function (x) { 13589 return c3 * x * x * x - c1 * x * x; 13590 }, 13591 easeOutBack: function (x) { 13592 return 1 + c3 * pow( x - 1, 3 ) + c1 * pow( x - 1, 2 ); 13593 }, 13594 easeInOutBack: function (x) { 13595 return x < 0.5 ? 13596 ( pow( 2 * x, 2 ) * ( ( c2 + 1 ) * 2 * x - c2 ) ) / 2 : 13597 ( pow( 2 * x - 2, 2 ) *( ( c2 + 1 ) * ( x * 2 - 2 ) + c2 ) + 2 ) / 2; 13598 }, 13599 easeInBounce: function (x) { 13600 return 1 - bounceOut( 1 - x ); 13601 }, 13602 easeOutBounce: bounceOut, 13603 easeInOutBounce: function (x) { 13604 return x < 0.5 ? 13605 ( 1 - bounceOut( 1 - 2 * x ) ) / 2 : 13606 ( 1 + bounceOut( 2 * x - 1 ) ) / 2; 13607 } 13608 }); 13609 return $; 13610}); 13611 13612/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 13613 * Licensed under the MIT License (LICENSE.txt). 13614 * 13615 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 13616 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 13617 * Thanks to: Seamus Leahy for adding deltaX and deltaY 13618 * 13619 * Version: 3.0.6 13620 * 13621 * Requires: 1.2.2+ 13622 */ 13623(function($) { 13624 var types = ['DOMMouseScroll', 'mousewheel']; 13625 if ($.event.fixHooks) { 13626 for (var i = types.length; i;) { 13627 $.event.fixHooks[types[--i]] = $.event.mouseHooks; 13628 } 13629 } 13630 $.event.special.mousewheel = { 13631 setup: function() { 13632 if (this.addEventListener) { 13633 for (var i = types.length; i;) { 13634 this.addEventListener(types[--i], handler, false); 13635 } 13636 } else { 13637 this.onmousewheel = handler; 13638 } 13639 }, 13640 teardown: function() { 13641 if (this.removeEventListener) { 13642 for (var i = types.length; i;) { 13643 this.removeEventListener(types[--i], handler, false); 13644 } 13645 } else { 13646 this.onmousewheel = null; 13647 } 13648 } 13649 }; 13650 $.fn.extend({ 13651 mousewheel: function(fn) { 13652 return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); 13653 }, 13654 unmousewheel: function(fn) { 13655 return this.unbind("mousewheel", fn); 13656 } 13657 }); 13658 13659 function handler(event) { 13660 var orgEvent = event || window.event, 13661 args = [].slice.call(arguments, 1), 13662 delta = 0, 13663 returnValue = true, 13664 deltaX = 0, 13665 deltaY = 0; 13666 event = $.event.fix(orgEvent); 13667 event.type = "mousewheel"; 13668 // Old school scrollwheel delta 13669 if (orgEvent.wheelDelta) { 13670 delta = orgEvent.wheelDelta / 120; 13671 } 13672 if (orgEvent.detail) { 13673 delta = -orgEvent.detail / 3; 13674 } 13675 // New school multidimensional scroll (touchpads) deltas 13676 deltaY = delta; 13677 // Gecko 13678 if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) { 13679 deltaY = 0; 13680 deltaX = -1 * delta; 13681 } 13682 // Webkit 13683 if (orgEvent.wheelDeltaY !== undefined) { 13684 deltaY = orgEvent.wheelDeltaY / 120; 13685 } 13686 if (orgEvent.wheelDeltaX !== undefined) { 13687 deltaX = -1 * orgEvent.wheelDeltaX / 120; 13688 } 13689 // Add event and delta to the front of the arguments 13690 args.unshift(event, delta, deltaX, deltaY); 13691 return ($.event.dispatch || $.event.handle).apply(this, args); 13692 } 13693})(jQuery); 13694/** 13695 * jQuery iLightBox - Revolutionary Lightbox Plugin 13696 * http://www.ilightbox.net/ 13697 * 13698 * @version: 2.2.4 - October 14, 2017 13699 * 13700 * @author: iProDev (Hemn Chawroka) 13701 * http://www.iprodev.com/ 13702 * 13703 */ 13704(function($, window, undefined) { 13705 13706 var extensions = { 13707 flash: ['swf'], 13708 image: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe', 'webp'], 13709 iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'jsp', 'php', 'pl', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt'], 13710 video: ['avi', 'mov', 'mpg', 'mpeg', 'movie', 'mp4', 'webm', 'ogv', 'ogg', '3gp', 'm4v'] 13711 }, 13712 13713 // Global DOM elements 13714 $win = $(window), 13715 $doc = $(document), 13716
13717 // Support indicators 13718 browser, 13719 transform, 13720 gpuAcceleration, 13721 fullScreenApi = '', 13722 userAgent = navigator.userAgent || navigator.vendor || window.opera, 13723 supportTouch = "ontouchstart" in window || navigator.msMaxTouchPoints || (navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1), 13724 ishybrid = navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1, 13725 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)), 13726 13727 // Events 13728 clickEvent = ishybrid ? "itap.iLightBox click.iLightBox" : supportTouch ? "itap.iLightBox" : "click.iLightBox", 13729 touchStartEvent = ishybrid ? "touchstart.iLightBox mousedown.iLightBox" : supportTouch ? "touchstart.iLightBox" : "mousedown.iLightBox", 13730 touchStopEvent = ishybrid ? "touchend.iLightBox mouseup.iLightBox" : supportTouch ? "touchend.iLightBox" : "mouseup.iLightBox", 13731 touchMoveEvent = ishybrid ? "touchmove.iLightBox mousemove.iLightBox" : supportTouch ? "touchmove.iLightBox" : "mousemove.iLightBox", 13732 13733 // Math shorthands 13734 abs = Math.abs, 13735 sqrt = Math.sqrt, 13736 round = Math.round, 13737 max = Math.max, 13738 min = Math.min, 13739 floor = Math.floor, 13740 random = Math.random, 13741 13742 pluginspages = { 13743 quicktime: 'http://www.apple.com/quicktime/download', 13744 flash: 'http://www.adobe.com/go/getflash' 13745 }, 13746 13747 iLightBox = function(el, options, items, instant) { 13748 var iL = this; 13749 13750 iL.options = options, 13751 iL.selector = options.selector || el, 13752 iL.context = document, 13753 iL.instant = instant; 13754 13755 if (items.length < 1) iL.attachItems(); 13756 else iL.items = items; 13757 13758 iL.vars = { 13759 total: iL.items.length, 13760 start: 0, 13761 current: null, 13762 next: null, 13763 prev: null, 13764 BODY: $('body'), 13765 loadRequests: 0, 13766 overlay: $('<div class="ilightbox-overlay"></div>'), 13767 loader: $('<div class="ilightbox-loader"><div></div></div>'), 13768 toolbar: $('<div class="ilightbox-toolbar"></div>'), 13769 innerToolbar: $('<div class="ilightbox-inner-toolbar"></div>'), 13770 title: $('<div class="ilightbox-title"></div>'), 13771 closeButton: $('<a class="ilightbox-close" title="' + iL.options.text.close + '"></a>'), 13772 fullScreenButton: $('<a class="ilightbox-fullscreen" title="' + iL.options.text.enterFullscreen + '"></a>'), 13773 innerPlayButton: $('<a class="ilightbox-play" title="' + iL.options.text.slideShow + '"></a>'), 13774 innerNextButton: $('<a class="ilightbox-next-button" title="' + iL.options.text.next + '"></a>'), 13775 innerPrevButton: $('<a class="ilightbox-prev-button" title="' + iL.options.text.previous + '"></a>'), 13776 holder: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + '" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13777 nextPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-next" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13778 prevPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-prev" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13779 nextButton: $('<a class="ilightbox-button ilightbox-next-button" ondragstart="return false;" title="' + iL.options.text.next + '"><span></span></a>'), 13780 prevButton: $('<a class="ilightbox-button ilightbox-prev-button" ondragstart="return false;" title="' + iL.options.text.previous + '"><span></span></a>'),
13781 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>'), 13782 thumbs: false, 13783 nextLock: false, 13784 prevLock: false, 13785 hashLock: false, 13786 isMobile: false, 13787 mobileMaxWidth: 980, 13788 isInFullScreen: false, 13789 isSwipe: false, 13790 mouseID: 0, 13791 cycleID: 0, 13792 isPaused: 0, 13793 captionHeight: 39, 13794 }; 13795 13796 // Hideable elements with mousemove event 13797 iL.vars.hideableElements = iL.vars.nextButton.add(iL.vars.prevButton); 13798 13799 iL.normalizeItems(); 13800 13801 //Check necessary plugins 13802 iL.availPlugins(); 13803 13804 //Set startFrom 13805 iL.options.startFrom = (iL.options.startFrom > 0 && iL.options.startFrom >= iL.vars.total) ? iL.vars.total - 1 : iL.options.startFrom; 13806 13807 //If randomStart 13808 iL.options.startFrom = (iL.options.randomStart) ? floor(random() * iL.vars.total) : iL.options.startFrom; 13809 iL.vars.start = iL.options.startFrom; 13810 13811 if (instant) iL.instantCall(); 13812 else iL.patchItemsEvents(); 13813 13814 if (iL.options.linkId) { 13815 iL.hashChangeHandler(); 13816 $win.iLightBoxHashChange(function() { 13817 iL.hashChangeHandler(); 13818 }); 13819 } 13820 13821 if (supportTouch) { 13822 var RegExp = /(click|mouseenter|mouseleave|mouseover|mouseout)/ig, 13823 replace = "itap"; 13824 iL.options.caption.show = iL.options.caption.show.replace(RegExp, replace), 13825 iL.options.caption.hide = iL.options.caption.hide.replace(RegExp, replace), 13826 iL.options.social.show = iL.options.social.show.replace(RegExp, replace), 13827 iL.options.social.hide = iL.options.social.hide.replace(RegExp, replace); 13828 } 13829 13830 if (iL.options.controls.arrows || $(window).width() < UNCODE.mediaQuery) { 13831 $.extend(iL.options.styles, { 13832 nextOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13833 prevOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13834 nextOpacity: 0, 13835 prevOpacity: 0 13836 }); 13837 } 13838 }; 13839 13840 //iLightBox helpers 13841 iLightBox.prototype = { 13842 showLoader: function() { 13843 var iL = this; 13844 iL.vars.loadRequests += 1; 13845 if (iL.options.path.toLowerCase() == "horizontal") iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13846 //top: '-30px' 13847 opacity: '1' 13848 }, iL.options.show.speed, 'easeOutCirc'); 13849 else iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13850 //left: '-30px' 13851 opacity: '1' 13852 }, iL.options.show.speed, 'easeOutCirc'); 13853 }, 13854 13855 hideLoader: function() { 13856 var iL = this; 13857 iL.vars.loadRequests -= 1; 13858 iL.vars.loadRequests = (iL.vars.loadRequests < 0) ? 0 : iL.vars.loadRequests; 13859 if (iL.options.path.toLowerCase() == "horizontal") { 13860 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13861 //top: '-192px' 13862 opacity: '0' 13863 }, iL.options.show.speed, 'easeInCirc'); 13864 } else { 13865 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13866 //left: '-192px' 13867 opacity: '0' 13868 }, iL.options.show.speed, 'easeInCirc'); 13869 } 13870 }, 13871 13872 createUI: function() { 13873 var iL = this; 13874 13875 iL.ui = { 13876 currentElement: iL.vars.holder, 13877 nextElement: iL.vars.nextPhoto, 13878 prevElement: iL.vars.prevPhoto, 13879 currentItem: iL.vars.current, 13880 nextItem: iL.vars.next, 13881 prevItem: iL.vars.prev, 13882 hide: function() { 13883 iL.closeAction(); 13884 }, 13885 refresh: function() { 13886 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 13887 }, 13888 fullscreen: function() { 13889 iL.fullScreenAction(); 13890 } 13891 }; 13892 }, 13893 13894 attachItems: function() { 13895 var iL = this, 13896 itemsObject = new Array(), 13897 items = new Array(); 13898 13899 $(iL.selector, iL.context).each(function() { 13900 var t = $(this), 13901 URL = t.attr(iL.options.attr) || null, 13902 options = t.data("options") && eval("({" + t.data("options") + "})") || {}, 13903 caption = t.data('caption'), 13904 title = t.data('title'), 13905 type = t.data('type') || getTypeByExtension(URL), 13906 clone = t.data('lbox-clone') || false; 13907 13908 //Uncode addition ##START## 13909 if (type === false) { 13910 return; 13911 } 13912 //Uncode addition ##END## 13913 13914 if (t.data('lbox-clone') != undefined) return; 13915 13916 //Uncode addition ##START## 13917 if ( typeof t.attr('data-album') != 'undefined' && t.attr('data-album') != '' ) { 13918 var ALBUM_URLS = JSON.parse(t.attr('data-album')), 13919 URL_i, 13920 URLS_LENGHT = ALBUM_URLS.length; 13921 13922 for (URL_i = 0; URL_i < URLS_LENGHT; URL_i++) { 13923 if ( typeof ALBUM_URLS[URL_i].url !== 'undefined' && ALBUM_URLS[URL_i].url != '' ) { 13924 var item_opts = 'width:' + ALBUM_URLS[URL_i].width + ',height:' + ALBUM_URLS[URL_i].height + ',thumbnail: \'' + ALBUM_URLS[URL_i].thumbnail + '\''; 13925 item_opts = item_opts && eval("({" + item_opts + "})") || {}, 13926 items.push({ 13927 URL: ALBUM_URLS[URL_i].url, 13928 caption: ALBUM_URLS[URL_i].caption, 13929 title: ALBUM_URLS[URL_i].title, 13930 type: getTypeByExtension(ALBUM_URLS[URL_i].url), 13931 options: item_opts, 13932 clone: clone 13933 }); 13934 var newT = t; 13935 newT.attr('href',ALBUM_URLS[URL_i].url); 13936 if (!iL.instant) itemsObject.push(newT); 13937 } 13938 } 13939 } else { 13940 //Uncode addition ##END## 13941 items.push({ 13942 URL: URL, 13943 caption: caption, 13944 title: title, 13945 type: type, 13946 options: options, 13947 clone: clone 13948 }); 13949 } 13950 13951 13952 if (iL.vars != undefined) iL.vars.total = items.length; 13953 13954 if (!iL.instant) itemsObject.push(t); 13955 }); 13956 13957 iL.items = items, 13958 iL.itemsObject = itemsObject; 13959 13960 }, 13961 13962 normalizeItems: function() { 13963 var iL = this, 13964 newItems = new Array(); 13965 13966 $.each(iL.items, function(key, val) { 13967 13968 if (typeof val == "string") val = { 13969 url: val 13970 }; 13971 13972 var URL = val.url || val.URL || null, 13973 options = val.options || {}, 13974 caption = val.caption || null, 13975 title = val.title || null, 13976 type = (val.type) ? val.type.toLowerCase() : getTypeByExtension(URL), 13977 ext = (typeof URL != 'object') ? getExtension(URL) : ''; 13978 13979 options.thumbnail = options.thumbnail || ((type == "image") ? URL : null),
13980 options.videoType = options.videoType || null, 13981 options.skin = options.skin || iL.options.skin, 13982 options.width = options.width || null, 13983 options.height = options.height || null, 13984 options.mousewheel = (typeof options.mousewheel != 'undefined') ? options.mousewheel : true, 13985 options.swipe = (typeof options.swipe != 'undefined') ? options.swipe : true, 13986 options.social = (typeof options.social != 'undefined') ? options.social : iL.options.social.buttons && $.extend({}, {}, iL.options.social.buttons); 13987 13988 if (type == "video") { 13989 options.html5video = (typeof options.html5video != 'undefined') ? options.html5video : {}; 13990 13991 options.html5video.webm = options.html5video.webm || options.html5video.WEBM || null; 13992 options.html5video.controls = (typeof options.html5video.controls != 'undefined') ? options.html5video.controls : "controls"; 13993 options.html5video.preload = options.html5video.preload || "metadata"; 13994 options.html5video.autoplay = (typeof options.html5video.autoplay != 'undefined') ? options.html5video.autoplay : false; 13995 //UNCODE addition 13996 options.html5video.loop = (typeof options.html5video.loop != 'undefined') ? options.html5video.loop : false; 13997 } 13998 13999 if (!options.width || !options.height) { 14000 if (type == "video") options.width = 1280, options.height = 720; 14001 else if (type == "iframe") options.width = '100%', options.height = '90%'; 14002 else if (type == "flash") options.width = 1280, options.height = 720; 14003 } 14004 14005 delete val.url; 14006 val.index = key; 14007 val.URL = URL; 14008 val.caption = caption; 14009 val.title = title; 14010 val.type = type; 14011 val.options = options; 14012 val.ext = ext; 14013 14014 newItems.push(val); 14015 }); 14016 14017 iL.items = newItems; 14018 }, 14019 14020 instantCall: function() { 14021 var iL = this, 14022 key = iL.vars.start; 14023 14024 iL.vars.current = key; 14025 iL.vars.next = (iL.items[key + 1]) ? key + 1 : null; 14026 iL.vars.prev = (iL.items[key - 1]) ? key - 1 : null; 14027 14028 iL.addContents(); 14029 iL.patchEvents(); 14030 }, 14031 14032 addContents: function() { 14033 var iL = this, 14034 vars = iL.vars, 14035 opts = iL.options, 14036 viewport = getViewport(), 14037 path = opts.path.toLowerCase(), 14038 recognizingItems = vars.total > 0 && iL.items.filter(function(e, i, arr) { 14039 return ['image', 'flash', 'video'].indexOf(e.type) === -1 && typeof e.recognized === 'undefined' && (opts.smartRecognition || e.options.smartRecognition); 14040 }), 14041 needRecognition = recognizingItems.length > 0; 14042 14043 if (opts.mobileOptimizer && !opts.innerToolbar) 14044 vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14045 14046 vars.overlay.addClass(opts.skin).hide().css('opacity', opts.overlay.opacity); 14047 14048 if (opts.linkId) 14049 vars.overlay[0].setAttribute('linkid', opts.linkId); 14050 14051 //Add Toolbar Buttons 14052 if (opts.controls.toolbar) { 14053 vars.toolbar.addClass(opts.skin).append(vars.closeButton); 14054 if (opts.controls.fullscreen) 14055 vars.toolbar.append(vars.fullScreenButton); 14056 if (opts.controls.slideshow) 14057 vars.toolbar.append(vars.innerPlayButton); 14058 if (vars.total > 1) 14059 vars.toolbar.append(vars.innerPrevButton).append(vars.innerNextButton); 14060 } 14061 14062 //Append elements to body 14063 vars.BODY.addClass('ilightbox-noscroll').append(vars.overlay).append(vars.loader).append(vars.holder).append(vars.nextPhoto).append(vars.prevPhoto); 14064 14065 if (!opts.innerToolbar) 14066 vars.BODY.append(vars.toolbar); 14067 if (opts.controls.arrows) 14068 vars.BODY.append(vars.nextButton).append(vars.prevButton); 14069 14070 if (opts.controls.thumbnail && vars.total > 1) { 14071 vars.BODY.append(vars.thumbnails); 14072 vars.thumbnails.addClass(opts.skin).addClass('ilightbox-' + path); 14073 $('div.ilightbox-thumbnails-grid', vars.thumbnails).empty(); 14074 vars.thumbs = true; 14075 } 14076 14077 //Configure loader and arrows 14078 var loaderCss = (opts.path.toLowerCase() == "horizontal") ? { 14079 left: parseInt((viewport.width / 2) - (vars.loader.outerWidth() / 2)) 14080 } : { 14081 top: parseInt((viewport.height / 2) - (vars.loader.outerHeight() / 2)) 14082 }; 14083 vars.loader.addClass(opts.skin).css(loaderCss); 14084 vars.nextButton.add(vars.prevButton).addClass(opts.skin); 14085 if (path == "horizontal") 14086 vars.loader.add(vars.nextButton).add(vars.prevButton).addClass('horizontal'); 14087 14088 // Configure arrow buttons 14089 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 14090 14091 if (!opts.infinite) { 14092 vars.prevButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 14093 14094 if (vars.current == 0) 14095 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 14096 if (vars.current >= vars.total - 1) 14097 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 14098 } 14099 14100 if (opts.show.effect) { 14101 vars.overlay.stop().fadeIn(opts.show.speed); 14102 vars.toolbar.stop().fadeIn(opts.show.speed); 14103 } else { 14104 vars.overlay.show(); 14105 vars.toolbar.show(); 14106 } 14107 14108 var length = recognizingItems.length; 14109 if (needRecognition) { 14110 iL.showLoader(); 14111 14112 $.each(recognizingItems, function(key, val) { 14113 var resultFnc = function(result) { 14114 var key = -1, 14115 filter = iL.items.filter(function(e, i, arr) { 14116 if (e.URL == result.url) 14117 key = i; 14118 14119 return e.URL == result.url; 14120 }), 14121 self = iL.items[key]; 14122 14123 if (result) 14124 $.extend(true, self, { 14125 URL: result.source, 14126 type: result.type, 14127 recognized: true, 14128 options: { 14129 html5video: result.html5video, 14130 width: (result.type == "image") ? 0 : (result.width || self.width), 14131 height: (result.type == "image") ? 0 : (result.height || self.height), 14132 thumbnail: self.options.thumbnail || result.thumbnail 14133 } 14134 }); 14135 14136 length--; 14137 14138 if (length == 0) { 14139 iL.hideLoader(); 14140 14141 vars.dontGenerateThumbs = false;
14142 iL.generateThumbnails(); 14143 14144 if (opts.show.effect) 14145 setTimeout(function() { 14146 iL.generateBoxes(); 14147 }, opts.show.speed); 14148 else 14149 iL.generateBoxes(); 14150 } 14151 }; 14152 14153 iL.ogpRecognition(this, resultFnc); 14154 }); 14155 } 14156 else { 14157 if (opts.show.effect) 14158 setTimeout(function() { 14159 iL.generateBoxes(); 14160 }, opts.show.speed); 14161 else 14162 iL.generateBoxes(); 14163 } 14164 14165 iL.createUI(); 14166 14167 window.iLightBox = { 14168 close: function() { 14169 iL.closeAction(); 14170 }, 14171 fullscreen: function() { 14172 iL.fullScreenAction(); 14173 }, 14174 moveNext: function() { 14175 iL.moveTo('next'); 14176 }, 14177 movePrev: function() { 14178 iL.moveTo('prev'); 14179 }, 14180 goTo: function(index) { 14181 iL.goTo(index); 14182 }, 14183 refresh: function() { 14184 iL.refresh(); 14185 }, 14186 reposition: function() { 14187 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 14188 }, 14189 setOption: function(options) { 14190 iL.setOption(options); 14191 }, 14192 destroy: function() { 14193 iL.closeAction(); 14194 iL.dispatchItemsEvents(); 14195 } 14196 }; 14197 14198 if (opts.linkId) { 14199 vars.hashLock = true; 14200 window.location.hash = opts.linkId + '/' + vars.current; 14201 setTimeout(function() { 14202 vars.hashLock = false; 14203 }, 55); 14204 } 14205 14206 if (!opts.slideshow.startPaused) { 14207 iL.resume(); 14208 vars.innerPlayButton.removeClass('ilightbox-play').addClass('ilightbox-pause'); 14209 } 14210 14211 //Trigger the onOpen callback 14212 if (typeof iL.options.callback.onOpen == 'function') iL.options.callback.onOpen.call(iL); 14213 }, 14214 14215 loadContent: function(obj, opt, speed) { 14216 var iL = this, 14217 holder, item; 14218 14219 iL.createUI(); 14220 14221 obj.speed = speed || iL.options.effects.loadedFadeSpeed; 14222 14223 if (opt == 'current') { 14224 if (!obj.options.mousewheel) iL.vars.lockWheel = true; 14225 else iL.vars.lockWheel = false; 14226 14227 if (!obj.options.swipe) iL.vars.lockSwipe = true; 14228 else iL.vars.lockSwipe = false; 14229 } 14230 14231 switch (opt) { 14232 case 'current': 14233 holder = iL.vars.holder, item = iL.vars.current; 14234 break; 14235 case 'next': 14236 holder = iL.vars.nextPhoto, item = iL.vars.next; 14237 break; 14238 case 'prev': 14239 holder = iL.vars.prevPhoto, item = iL.vars.prev; 14240 break; 14241 } 14242 14243 holder.removeAttr('style class').addClass('ilightbox-holder' + (supportTouch ? ' supportTouch' : '')).addClass(obj.options.skin); 14244 $('div.ilightbox-inner-toolbar', holder).remove(); 14245 14246 if (obj.title || iL.options.innerToolbar) { 14247 var innerToolbar = iL.vars.innerToolbar.clone(); 14248 if (obj.title && iL.options.show.title) { 14249 var title = iL.vars.title.clone(); 14250 title.empty().html(obj.title); 14251 innerToolbar.append(title); 14252 } 14253 if (iL.options.innerToolbar) { 14254 innerToolbar.append((iL.vars.total > 1) ? iL.vars.toolbar.clone() : iL.vars.toolbar); 14255 } 14256 holder.prepend(innerToolbar); 14257 } 14258 14259 //console.warn('loadContent', arguments); 14260 14261 iL.loadSwitcher(obj, holder, item, opt); 14262 }, 14263 14264 loadSwitcher: function(obj, holder, item, opt) { 14265 var iL = this, 14266 opts = iL.options, 14267 api = { 14268 element: holder, 14269 position: item 14270 }; 14271 14272 switch (obj.type) { 14273 case 'image': 14274 //Trigger the onBeforeLoad callback 14275 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14276 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14277 14278 iL.loadImage(obj.URL, function(img) { 14279 //Trigger the onAfterLoad callback 14280 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14281 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14282 14283 var width = (img) ? img.width : 400, 14284 height = (img) ? img.height : 200; 14285 14286 holder.data({ 14287 naturalWidth: width, 14288 naturalHeight: height 14289 }); 14290 14291 $('div.ilightbox-container', holder).empty().append((img) ? '<img src="' + obj.URL + '" class="ilightbox-image" />' : '<span class="ilightbox-alert">' + opts.errors.loadImage + '</span>'); 14292 14293 //Trigger the onRender callback 14294 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14295 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14296 14297 iL.configureHolder(obj, opt, holder); 14298 }); 14299 14300 break; 14301
14302 case 'video': 14303 holder.data({ 14304 naturalWidth: obj.options.width, 14305 naturalHeight: obj.options.height 14306 }); 14307 14308 if (opt === 'current') { 14309 iL.addContent(holder, obj); 14310 14311 //Trigger the onRender callback 14312 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14313 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14314 } else { 14315 $('div.ilightbox-container', holder).empty(); 14316 } 14317 14318 iL.configureHolder(obj, opt, holder); 14319 14320 break; 14321 14322 case 'iframe': 14323 //iL.showLoader(); 14324 holder.data({ 14325 naturalWidth: obj.options.width, 14326 naturalHeight: obj.options.height 14327 }); 14328 14329 iL.configureHolder(obj, opt, holder); 14330 14331 if (opt === 'current') { 14332 var el = iL.addContent(holder, obj); 14333 14334 //Trigger the onRender callback 14335 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14336 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14337 14338 //Trigger the onBeforeLoad callback 14339 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14340 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14341 14342 el.bind('load', function() { 14343 //Trigger the onAfterLoad callback 14344 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14345 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14346 14347 //iL.hideLoader(); 14348 el.unbind('load'); 14349 }); 14350 } else { 14351 $('div.ilightbox-container', holder).empty(); 14352 } 14353 14354 break; 14355 14356 case 'inline': 14357 var el = $(obj.URL), 14358 content = iL.addContent(holder, obj), 14359 images = findImageInElement(holder); 14360 14361 holder.data({ 14362 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 14363 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 14364 }); 14365 content.children().eq(0).show(); 14366 14367 //Trigger the onRender callback 14368 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14369 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14370 14371 //Trigger the onBeforeLoad callback 14372 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14373 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14374 14375 iL.loadImage(images, function() { 14376 //Trigger the onAfterLoad callback 14377 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14378 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14379 14380 iL.configureHolder(obj, opt, holder); 14381 }); 14382 14383 break; 14384 14385 case 'flash': 14386 var el = iL.addContent(holder, obj); 14387 14388 holder.data({ 14389 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 14390 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 14391 }); 14392 14393 //Trigger the onRender callback 14394 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14395 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14396 14397 iL.configureHolder(obj, opt, holder); 14398 14399 break; 14400 14401 case 'ajax': 14402 var ajax = obj.options.ajax || {}; 14403 //Trigger the onBeforeLoad callback 14404 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14405 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14406 14407 iL.showLoader(); 14408 $.ajax({ 14409 url: obj.URL || opts.ajaxSetup.url, 14410 data: ajax.data || null, 14411 dataType: ajax.dataType || "html", 14412 type: ajax.type || opts.ajaxSetup.type, 14413 cache: ajax.cache || opts.ajaxSetup.cache, 14414 crossDomain: ajax.crossDomain || opts.ajaxSetup.crossDomain, 14415 global: ajax.global || opts.ajaxSetup.global, 14416 ifModified: ajax.ifModified || opts.ajaxSetup.ifModified, 14417 username: ajax.username || opts.ajaxSetup.username, 14418 password: ajax.password || opts.ajaxSetup.password, 14419 beforeSend: ajax.beforeSend || opts.ajaxSetup.beforeSend, 14420 complete: ajax.complete || opts.ajaxSetup.complete, 14421 success: function(data, textStatus, jqXHR) { 14422 iL.hideLoader(); 14423 14424 var el = $(data), 14425 container = $('div.ilightbox-container', holder), 14426 elWidth = iL.items[item].options.width || parseInt(el[0].getAttribute('width')), 14427 elHeight = iL.items[item].options.height || parseInt(el[0].getAttribute('height')), 14428 css = (el[0].getAttribute('width') && el[0].getAttribute('height')) ? { 14429 'overflow': 'hidden' 14430 } : {}; 14431 14432 container.empty().append($('<div class="ilightbox-wrapper"></div>').css(css).html(el)); 14433 holder.show().data({
14434 naturalWidth: (elWidth || container.outerWidth()), 14435 naturalHeight: (elHeight || container.outerHeight()) 14436 }).hide(); 14437 14438 //Trigger the onRender callback 14439 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14440 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14441 14442 var images = findImageInElement(holder); 14443 iL.loadImage(images, function() { 14444 //Trigger the onAfterLoad callback 14445 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14446 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14447 14448 iL.configureHolder(obj, opt, holder); 14449 }); 14450 14451 opts.ajaxSetup.success(data, textStatus, jqXHR); 14452 if (typeof ajax.success == 'function') ajax.success(data, textStatus, jqXHR); 14453 }, 14454 error: function(jqXHR, textStatus, errorThrown) { 14455 //Trigger the onAfterLoad callback 14456 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14457 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14458 14459 iL.hideLoader(); 14460 $('div.ilightbox-container', holder).empty().append('<span class="ilightbox-alert">' + opts.errors.loadContents + '</span>'); 14461 iL.configureHolder(obj, opt, holder); 14462 14463 opts.ajaxSetup.error(jqXHR, textStatus, errorThrown); 14464 if (typeof ajax.error == 'function') ajax.error(jqXHR, textStatus, errorThrown); 14465 } 14466 }); 14467 14468 break; 14469 14470 case 'html': 14471 var object = obj.URL, 14472 el 14473 container = $('div.ilightbox-container', holder); 14474 14475 if (object[0].nodeName) el = object.clone(); 14476 else { 14477 var dom = $(object); 14478 if (dom.selector) el = $('<div>' + dom + '</div>'); 14479 else el = dom; 14480 } 14481 14482 var elWidth = iL.items[item].options.width || parseInt(el.attr('width')), 14483 elHeight = iL.items[item].options.height || parseInt(el.attr('height')); 14484 14485 iL.addContent(holder, obj); 14486 14487 el.appendTo(document.documentElement).hide(); 14488 14489 //Trigger the onRender callback 14490 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14491 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14492 14493 var images = findImageInElement(holder); 14494 14495 //Trigger the onBeforeLoad callback 14496 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14497 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14498 14499 iL.loadImage(images, function() { 14500 //Trigger the onAfterLoad callback 14501 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14502 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14503 14504 holder.show().data({ 14505 naturalWidth: (elWidth || container.outerWidth()), 14506 naturalHeight: (elHeight || container.outerHeight()) 14507 }).hide(); 14508 el.remove(); 14509 14510 iL.configureHolder(obj, opt, holder); 14511 }); 14512 14513 break; 14514 } 14515 }, 14516 14517 configureHolder: function(obj, opt, holder) { 14518 var iL = this, 14519 vars = iL.vars, 14520 opts = iL.options; 14521 14522 if (opt != "current")(opt == "next") ? holder.addClass('ilightbox-next') : holder.addClass('ilightbox-prev'); 14523 14524 if (opt == "current") 14525 var item = vars.current; 14526 else if (opt == "next") 14527 var opacity = opts.styles.nextOpacity, 14528 item = vars.next; 14529 else 14530 var opacity = opts.styles.prevOpacity, 14531 item = vars.prev; 14532 14533 var api = { 14534 element: holder, 14535 position: item 14536 }; 14537 14538 iL.items[item].options.width = iL.items[item].options.width || 0, 14539 iL.items[item].options.height = iL.items[item].options.height || 0; 14540 14541 if (opt == "current") { 14542 if (opts.show.effect) holder.css(transform, gpuAcceleration).fadeIn(obj.speed, function() { 14543 holder.css(transform, ''); 14544 if (obj.caption) { 14545 iL.setCaption(obj, holder); 14546 var caption = $('div.ilightbox-caption', holder), 14547 percent = parseInt((caption.outerHeight() / holder.outerHeight()) * 100); 14548 if (opts.caption.start & percent <= 50) caption.fadeIn(opts.effects.fade
14548Speed); 14549 } 14550 14551 var social = obj.options.social; 14552 if (social) { 14553 iL.setSocial(social, obj.URL, holder); 14554 if (opts.social.start) $('div.ilightbox-social', holder).fadeIn(opts.effects.fadeSpeed); 14555 } 14556 14557 //Generate thumbnails 14558 iL.generateThumbnails(); 14559 14560 //Trigger the onShow callback 14561 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14562 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14563 }); 14564 else { 14565 holder.show(); 14566 14567 //Generate thumbnails 14568 iL.generateThumbnails(); 14569 14570 //Trigger the onShow callback 14571 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14572 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14573 } 14574 } else { 14575 if (opts.show.effect) holder.fadeTo(obj.speed, opacity, function() { 14576 if (opt == "next") vars.nextLock = false; 14577 else vars.prevLock = false; 14578 14579 //Generate thumbnails 14580 iL.generateThumbnails(); 14581 14582 //Trigger the onShow callback 14583 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14584 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14585 }); 14586 else { 14587 holder.css({ 14588 opacity: opacity 14589 }).show(); 14590 if (opt == "next") vars.nextLock = false; 14591 else vars.prevLock = false; 14592 14593 //Generate thumbnails 14594 iL.generateThumbnails(); 14595 14596 //Trigger the onShow callback 14597 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14598 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14599 } 14600 } 14601 14602 setTimeout(function() { 14603 iL.repositionPhoto(); 14604 }, 0); 14605 }, 14606 14607 generateBoxes: function() { 14608 var iL = this, 14609 vars = iL.vars, 14610 opts = iL.options; 14611 14612 if (opts.infinite && vars.total >= 3) { 14613 if (vars.current == vars.total - 1) vars.next = 0; 14614 if (vars.current == 0) vars.prev = vars.total - 1; 14615 } else opts.infinite = false; 14616 14617 //UNCODE addition 14618 if ( typeof iL.items[vars.current] == 'undefined' ) 14619 vars.current = 0; 14620 14621 iL.loadContent(iL.items[vars.current], 'current', opts.show.speed); 14622 14623 if (iL.items[vars.next]) iL.loadContent(iL.items[vars.next], 'next', opts.show.speed); 14624 if (iL.items[vars.prev]) iL.loadContent(iL.items[vars.prev], 'prev', opts.show.speed); 14625 }, 14626 14627 generateThumbnails: function() { 14628 var iL = this, 14629 vars = iL.vars, 14630 opts = iL.options, 14631 timeOut = null; 14632 14633 if (vars.thumbs && !iL.vars.dontGenerateThumbs) { 14634 var thumbnails = vars.thumbnails, 14635 container = $('div.ilightbox-thumbnails-container', thumbnails), 14636 grid = $('div.ilightbox-thumbnails-grid', container), 14637 i = 0; 14638 14639 grid.removeAttr('style').empty(); 14640 14641 $.each(iL.items, function(key, val) { 14642 var isActive = (vars.current == key) ? 'ilightbox-active' : '', 14643 opacity = (vars.current == key) ? opts.thumbnails.activeOpacity : opts.thumbnails.normalOpacity, 14644 thumb = val.options.thumbnail, 14645 thumbnail = $('<div class="ilightbox-thumbnail"></div>'), 14646 icon = $('<div class="ilightbox-thumbnail-icon"></div>'); 14647 14648 thumbnail.css({ 14649 opacity: 0 14650 }).addClass(isActive); 14651 14652 if ((val.type == "video" || val.type == "flash") && typeof val.options.icon == 'undefined') { 14653 icon.addClass('ilightbox-thumbnail-video'); 14654 thumbnail.append(icon); 14655 } else if (val.options.icon) { 14656 icon.addClass('ilightbox-thumbnail-' + val.options.icon); 14657 thumbnail.append(icon); 14658 } 14659 14660 if (thumb) iL.loadImage(thumb, function(img) { 14661 i++; 14662 if (img) thumbnail.data({ 14663 naturalWidth: img.width, 14664 naturalHeight: img.height 14665 }).append('<img src="' + thumb + '" border="0" />'); 14666 else thumbnail.data({ 14667 naturalWidth: opts.thumbnails.maxWidth, 14668 naturalHeight: opts.thumbnails.maxHeight 14669 }); 14670 14671 clearTimeout(timeOut); 14672 timeOut = setTimeout(function() { 14673 iL.positionThumbnails(thumbnails, container, grid); 14674 }, 20); 14675 setTimeout(function() { 14676 thumbnail.fadeTo(opts.effects.loadedFadeSpeed, opacity); 14677 }, i * 20); 14678 }); 14679 14680 grid.append(thumbnail); 14681 }); 14682 iL.vars.dontGenerateThumbs = true; 14683 } 14684 }, 14685
14686 positionThumbnails: function(thumbnails, container, grid) { 14687 var iL = this, 14688 vars = iL.vars, 14689 opts = iL.options, 14690 viewport = getViewport(), 14691 path = opts.path.toLowerCase(); 14692 14693 if (!thumbnails) thumbnails = vars.thumbnails; 14694 if (!container) container = $('div.ilightbox-thumbnails-container', thumbnails); 14695 if (!grid) grid = $('div.ilightbox-thumbnails-grid', container); 14696 14697 var thumbs = $('.ilightbox-thumbnail', grid), 14698 widthAvail = (path == 'horizontal') ? viewport.width - opts.styles.pageOffsetX : thumbs.eq(0).outerWidth() - opts.styles.pageOffsetX, 14699 heightAvail = (path == 'horizontal') ? thumbs.eq(0).outerHeight() - opts.styles.pageOffsetY : viewport.height - opts.styles.pageOffsetY, 14700 gridWidth = (path == 'horizontal') ? 0 : widthAvail, 14701 gridHeight = (path == 'horizontal') ? heightAvail : 0, 14702 active = $('.ilightbox-active', grid), 14703 gridCss = {}, 14704 css = {}; 14705 14706 if (arguments.length < 3) { 14707 thumbs.css({ 14708 opacity: opts.thumbnails.normalOpacity 14709 }); 14710 active.css({ 14711 opacity: opts.thumbnails.activeOpacity 14712 }); 14713 } 14714 14715 thumbs.each(function(i) { 14716 var t = $(this), 14717 data = t.data(), 14718 width = (path == 'horizontal') ? 0 : opts.thumbnails.maxWidth; 14719 height = (path == 'horizontal') ? opts.thumbnails.maxHeight : 0; 14720 dims = iL.getNewDimenstions(width, height, data.naturalWidth, data.naturalHeight, true); 14721 14722 t.css({ 14723 width: dims.width, 14724 height: dims.height 14725 }); 14726 if (path == 'horizontal') t.css({ 14727 'float': 'left' 14728 }); 14729 14730 (path == 'horizontal') ? ( 14731 gridWidth += t.outerWidth() 14732 ) : ( 14733 gridHeight += t.outerHeight() 14734 ); 14735 }); 14736 14737 gridCss = { 14738 width: gridWidth, 14739 height: gridHeight 14740 }; 14741 14742 grid.css(gridCss); 14743 14744 gridCss = {}; 14745 14746 var gridOffset = grid.offset(), 14747 activeOffset = (active.length) ? active.offset() : { 14748 top: parseInt(heightAvail / 2), 14749 left: parseInt(widthAvail / 2) 14750 }; 14751 14752 gridOffset.top = (gridOffset.top - $doc.scrollTop()), 14753 gridOffset.left = (gridOffset.left - $doc.scrollLeft()), 14754 activeOffset.top = (activeOffset.top - gridOffset.top - $doc.scrollTop()), 14755 activeOffset.left = (activeOffset.left - gridOffset.left - $doc.scrollLeft()); 14756 14757 (path == 'horizontal') ? ( 14758 gridCss.top = 0, 14759 gridCss.left = parseInt((widthAvail / 2) - activeOffset.left - (active.outerWidth() / 2)) 14760 ) : ( 14761 gridCss.top = parseInt(((heightAvail / 2) - activeOffset.top - (active.outerHeight() / 2))), 14762 gridCss.left = 0 14763 ); 14764 14765 if (arguments.length < 3) grid.stop().animate(gridCss, opts.effects.repositionSpeed, 'easeOutCirc'); 14766 else grid.css(gridCss); 14767 }, 14768 14769 loadImage: function(image, callback) { 14770 if (!$.isArray(image)) image = [image]; 14771 14772 var iL = this, 14773 length = image.length; 14774 14775 if (length > 0) { 14776 iL.showLoader(); 14777 $.each(image, function(index, value) { 14778 var img = new Image(); 14779 img.onload = function() { 14780 length -= 1; 14781 if (length == 0) { 14782 iL.hideLoader(); 14783 callback(img); 14784 } 14785 }; 14786 img.onerror = img.onabort = function() { 14787 length -= 1; 14788 if (length == 0) { 14789 iL.hideLoader(); 14790 callback(false); 14791 } 14792 }; 14793 img.src = image[index]; 14794 }); 14795 } else callback(false); 14796 }, 14797 14798 patchItemsEvents: function() { 14799 var iL = this, 14800 vars = iL.vars, 14801 clickEvent = ishybrid ? "itap.iL click.iL" : supportTouch ? "itap.iL" : "click.iL", 14802 vEvent = ishybrid ? "click.iL itap.iL" : supportTouch ? "click.iL" : "itap.iL"; 14803 14804 if (iL.context && iL.selector) { 14805 var $items = $(iL.selector, iL.context); 14806 14807 $(iL.context).on(clickEvent, iL.selector, function() { 14808 var $this = $(this), 14809 //UNCODE addition 14810 key = typeof $(this).data('lb-index') !== '' && $(this).closest('.owl-item').length ? $(this).data('lb-index') : $items.index($this); 14811 if (UNCODE.isMobile) { 14812 var isCarousel = $this.closest('.owl-carousel'); 14813 if (isCarousel.length) { 14814 if (isCarousel.hasClass('owl-translating')) return false; 14815 } 14816 } 14817 14818 vars.current = key; 14819 vars.next = iL.items[key + 1] ? key + 1 : null; 14820 vars.prev = iL.items[key - 1] ? key - 1 : null; 14821 14822 //UNCODE addition 14823 if ( vars.BODY.hasClass('fp-slide-scrolling') ) 14824 return false;
14825 14826 iL.addContents(); 14827 iL.patchEvents(); 14828 14829 return false; 14830 }).on(vEvent, iL.selector, function() { 14831 return false; 14832 }); 14833 } else 14834 $.each(iL.itemsObject, function(key, val) { 14835 val.on(clickEvent, function() { 14836 vars.current = key; 14837 vars.next = iL.items[key + 1] ? key + 1 : null; 14838 vars.prev = iL.items[key - 1] ? key - 1 : null; 14839 14840 iL.addContents(); 14841 iL.patchEvents(); 14842 14843 return false; 14844 }).on(vEvent, function() { 14845 return false; 14846 }); 14847 }); 14848 }, 14849 14850 dispatchItemsEvents: function() { 14851 var iL = this, 14852 vars = iL.vars, 14853 opts = iL.options; 14854 14855 if (iL.context && iL.selector) 14856 $(iL.context).off('.iL', iL.selector); 14857 else 14858 $.each(iL.itemsObject, function(key, val) { 14859 val.off('.iL'); 14860 }); 14861 }, 14862 14863 refresh: function() { 14864 var iL = this; 14865 14866 iL.dispatchItemsEvents(); 14867 iL.attachItems(); 14868 iL.normalizeItems(); 14869 iL.patchItemsEvents(); 14870 }, 14871 14872 patchEvents: function() { 14873 var iL = this, 14874 vars = iL.vars, 14875 opts = iL.options, 14876 path = opts.path.toLowerCase(), 14877 holders = $('.ilightbox-holder'), 14878 fullscreenEvent = fullScreenApi.fullScreenEventName + '.iLightBox', 14879 durationThreshold = 1000, 14880 horizontalDistanceThreshold = 14881 verticalDistanceThreshold = 100, 14882 buttonsArray = [vars.nextButton[0], vars.prevButton[0], vars.nextButton[0].firstChild, vars.prevButton[0].firstChild]; 14883 14884 $win.bind('resize.iLightBox', function() { 14885 var viewport = getViewport(); 14886 14887 if (opts.mobileOptimizer && !opts.innerToolbar) vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14888 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 14889 14890 iL.repositionPhoto(null); 14891 if (supportTouch) { 14892 clearTimeout(vars.setTime); 14893 vars.setTime = setTimeout(function() { 14894 var scrollTop = getScrollXY().y; 14895 window.scrollTo(0, scrollTop - 30); 14896 window.scrollTo(0, scrollTop + 30); 14897 window.scrollTo(0, scrollTop); 14898 }, 2000); 14899 } 14900 if (vars.thumbs) iL.positionThumbnails(); 14901 }).bind('keydown.iLightBox', function(event) { 14902 if (opts.controls.keyboard) { 14903 switch (event.keyCode) { 14904 case 13: 14905 if (event.shiftKey && opts.keyboard.shift_enter) iL.fullScreenAction(); 14906 break; 14907 case 27: 14908 if (opts.keyboard.esc) iL.closeAction(); 14909 break; 14910 case 37: 14911 if (opts.keyboard.left && !vars.lockKey) iL.moveTo('prev'); 14912 break; 14913 case 38: 14914 if (opts.keyboard.up && !vars.lockKey) iL.moveTo('prev'); 14915 break; 14916 case 39: 14917 if (opts.keyboard.right && !vars.lockKey) iL.moveTo('next'); 14918 break; 14919 case 40: 14920 if (opts.keyboard.down && !vars.lockKey) iL.moveTo('next'); 14921 break; 14922 } 14923 } 14924 }); 14925 14926 if (fullScreenApi.supportsFullScreen) $win.bind(fullscreenEvent, function() { 14927 iL.doFullscreen(); 14928 }); 14929 14930 var holderEventsArr = [opts.caption.show + '.iLightBox', opts.caption.hide + '.iLightBox', opts.social.show + '.iLightBox', opts.social.hide + '.iLightBox'].filter(function(e, i, arr) { 14931 return arr.lastIndexOf(e) === i; 14932 }), 14933 holderEvents = ""; 14934 14935 $.each(holderEventsArr, function(key, val) { 14936 if (key != 0) holderEvents += ' '; 14937 holderEvents += val; 14938 }); 14939 14940 $doc.on(clickEvent, '.ilightbox-overlay', function() { 14941 if (opts.overlay.blur) iL.closeAction(); 14942 }).on(clickEvent, '.ilightbox-next, .ilightbox-next-button', function() { 14943 iL.moveTo('next'); 14944 }).on(clickEvent, '.ilightbox-prev, .ilightbox-prev-button', function() { 14945 iL.moveTo('prev'); 14946 }).on(clickEvent, '.ilightbox-thumbnail', function() { 14947 var t = $(this), 14948 thumbs = $('.ilightbox-thumbnail', vars.thumbnails), 14949 index = thumbs.index(t); 14950 14951 if (index != vars.current) iL.goTo(index); 14952 }).on(holderEvents, '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 14953 var caption = $('div.ilightbox-caption', vars.holder), 14954 social = $('div.ilightbox-social', vars.holder), 14955 fadeSpeed = opts.effects.fadeSpeed; 14956 14957 if (vars.nextLock || vars.prevLock) { 14958 if (e.type == opts.caption.show && !caption.is(':visible')) caption.fadeIn(fadeSpeed); 14959 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.fadeOut(fadeSpeed); 14960 14961 if (e.type == opts.social.show && !social.is(':visible')) social.fadeIn(fadeSpeed); 14962 else if (e.type == opts.social.hide && social.is(':visible')) social.fadeOut(fadeSpeed); 14963 } else { 14964 if (e.type == opts.caption.show && !caption.is(':visible')) caption.stop().fadeIn(fadeSpeed); 14965 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.stop().fadeOut(fadeSpeed); 14966 14967 if (e.type == opts.social.show && !social.is(':visible')) social.stop().fadeIn(fadeSpeed); 14968 else if (e.type == opts.social.hide && social.is(':visible')) social.stop().fadeOut(fadeSpeed); 14969 } 14970 }).on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-wrapper', function(e) { 14971 if (e.type == 'mouseenter') vars.lockWheel = true; 14972 else vars.lockWheel = false;
14973 }).on(clickEvent, '.ilightbox-toolbar a.ilightbox-close, .ilightbox-toolbar a.ilightbox-fullscreen, .ilightbox-toolbar a.ilightbox-play, .ilightbox-toolbar a.ilightbox-pause', function() { 14974 var t = $(this); 14975 14976 if (t.hasClass('ilightbox-fullscreen')) iL.fullScreenAction(); 14977 else if (t.hasClass('ilightbox-play')) { 14978 iL.resume(); 14979 t.addClass('ilightbox-pause').removeClass('ilightbox-play'); 14980 } else if (t.hasClass('ilightbox-pause')) { 14981 iL.pause(); 14982 t.addClass('ilightbox-play').removeClass('ilightbox-pause'); 14983 } else iL.closeAction(); 14984 }).on(touchMoveEvent, '.ilightbox-overlay, .ilightbox-thumbnails-container', function(e) { 14985 // prevent scrolling 14986 e.preventDefault(); 14987 }); 14988 14989 function mouseMoveHandler(e) { 14990 if (!vars.isMobile) { 14991 if (!vars.mouseID) { 14992 vars.hideableElements.show(); 14993 } 14994 14995 vars.mouseID = clearTimeout(vars.mouseID); 14996 14997 if (buttonsArray.indexOf(e.target) === -1) 14998 vars.mouseID = setTimeout(function() { 14999 vars.hideableElements.hide(); 15000 vars.mouseID = clearTimeout(vars.mouseID); 15001 }, 3000); 15002 } 15003 } 15004 15005 if (opts.controls.arrows && !supportTouch) $doc.on('mousemove.iLightBox', mouseMoveHandler); 15006 15007 if (opts.controls.slideshow && opts.slideshow.pauseOnHover) $doc.on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 15008 if (e.type == 'mouseenter' && vars.cycleID) iL.pause(); 15009 else if (e.type == 'mouseleave' && vars.isPaused) iL.resume(); 15010 }); 15011 15012 var switchers = $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails'), 15013 delay = false; 15014 15015 if (opts.controls.mousewheel) switchers.on('mousewheel.iLightBox', function(event, delta) { 15016 event.preventDefault(); 15017 if (delay) return; 15018 delay = true; 15019 if (!vars.lockWheel) { 15020 event.preventDefault(); 15021 if (delta < 0) { 15022 iL.moveTo('next'); 15023 } else if (delta > 0) { 15024 iL.moveTo('prev'); 15025 } 15026 } 15027 setTimeout(function(){
15028 delay = false; 15029 }, 2000); 15030 }); 15031 15032 if (opts.controls.swipe) holders.on(touchStartEvent, function(event) { 15033 if (vars.nextLock || vars.prevLock || vars.total == 1 || vars.lockSwipe) return; 15034 15035 vars.BODY.addClass('ilightbox-closedhand'); 15036 15037 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event, 15038 scrollTop = $doc.scrollTop(), 15039 scrollLeft = $doc.scrollLeft(), 15040 offsets = [ 15041 holders.eq(0).offset(), 15042 holders.eq(1).offset(), 15043 holders.eq(2).offset() 15044 ], 15045 offSet = [{ 15046 top: offsets[0].top - scrollTop, 15047 left: offsets[0].left - scrollLeft 15048 }, { 15049 top: offsets[1].top - scrollTop, 15050 left: offsets[1].left - scrollLeft 15051 }, { 15052 top: offsets[2].top - scrollTop, 15053 left: offsets[2].left - scrollLeft 15054 }], 15055 start = { 15056 time: (new Date()).getTime(), 15057 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 15058 }, 15059 stop; 15060 15061 function moveEachHandler(i) { 15062 var t = $(this), 15063 offset = offSet[i], 15064 scroll = [(start.coords[0] - stop.coords[0]), (start.coords[1] - stop.coords[1])]; 15065 15066 t[0].style[path == "horizontal" ? 'left' : 'top'] = (path == "horizontal" ? offset.left - scroll[0] : offset.top - scroll[1]) + 'px'; 15067 } 15068 15069 function moveHandler(event) { 15070 15071 if (!start) return; 15072 15073 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event; 15074 15075 stop = { 15076 time: (new Date()).getTime(), 15077 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 15078 }; 15079 15080 holders.each(moveEachHandler); 15081 15082 // prevent scrolling 15083 event.preventDefault(); 15084 } 15085 15086 function repositionHolders() { 15087 holders.each(function() { 15088 var t = $(this), 15089 offset = t.data('offset') || { 15090 top: t.offset().top - scrollTop, 15091 left: t.offset().left - scrollLeft 15092 }, 15093 top = offset.top, 15094 left = offset.left; 15095 15096 t.css(transform, gpuAcceleration).stop().animate({ 15097 top: top, 15098 left: left 15099 }, 500, 'easeOutCirc', function() { 15100 t.css(transform, ''); 15101 }); 15102 }); 15103 } 15104 15105 holders.bind(touchMoveEvent, moveHandler); 15106 $doc.one(touchStopEvent, function(event) { 15107 holders.unbind(touchMoveEvent, moveHandler); 15108 15109 vars.BODY.removeClass('ilightbox-closedhand'); 15110 15111 if (start && stop) { 15112 if (path == "horizontal" && stop.time - start.time < durationThreshold && abs(start.coords[0] - stop.coords[0]) > horizontalDistanceThreshold && abs(start.coords[1] - stop.coords[1]) < verticalDistanceThreshold) { 15113 if (start.coords[0] > stop.coords[0]) { 15114 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 15115 else { 15116 vars.isSwipe = true; 15117 iL.moveTo('next'); 15118 } 15119 } else { 15120 if (vars.current == 0 && !opts.infinite) repositionHolders(); 15121 else { 15122 vars.isSwipe = true; 15123 iL.moveTo('prev'); 15124 } 15125 } 15126 } 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) { 15127 if (start.coords[1] > stop.coords[1]) { 15128 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 15129 else { 15130 vars.isSwipe = true; 15131 iL.moveTo('next'); 15132 } 15133 } else { 15134 if (vars.current == 0 && !opts.infinite) repositionHolders(); 15135 else { 15136 vars.isSwipe = true; 15137 iL.moveTo('prev'); 15138 } 15139 } 15140 } else repositionHolders(); 15141 } 15142 start = stop = undefined; 15143 }); 15144 }); 15145 15146 }, 15147 15148 goTo: function(index) { 15149 var iL = this, 15150 vars = iL.vars, 15151 opts = iL.options, 15152 diff = (index - vars.current); 15153 15154 if (opts.infinite) { 15155 if (index == vars.total - 1 && vars.current == 0) diff = -1; 15156 if (vars.current == vars.total - 1 && index == 0) diff = 1; 15157 } 15158 15159 if (diff == 1) iL.moveTo('next'); 15160 else if (diff == -1) iL.moveTo('prev'); 15161 else { 15162 15163 if (vars.nextLock || vars.prevLock) return false; 15164 15165 //Trigger the onBeforeChange callback 15166 if (typeof opts.callback.onBeforeChange == 'function') opts.callback.onBeforeChange.call(iL, iL.ui); 15167 15168 if (opts.linkId) { 15169 vars.hashLock = true; 15170 window.location.hash = opts.linkId + '/' + index; 15171 } 15172 15173 if (iL.items[index]) { 15174 if (!iL.items[index].options.mousewheel) vars.lockWheel = true; 15175 else iL.vars.lockWheel = false;
15176 15177 if (!iL.items[index].options.swipe) vars.lockSwipe = true; 15178 else vars.lockSwipe = false; 15179 } 15180 15181 $.each([vars.holder, vars.nextPhoto, vars.prevPhoto], function(key, val) { 15182 val.css(transform, gpuAcceleration).fadeOut(opts.effects.loadedFadeSpeed); 15183 }); 15184 15185 vars.current = index; 15186 vars.next = index + 1; 15187 vars.prev = index - 1; 15188 15189 iL.createUI(); 15190 15191 setTimeout(function() { 15192 iL.generateBoxes(); 15193 }, opts.effects.loadedFadeSpeed + 50); 15194 15195 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(index).addClass('ilightbox-active'); 15196 iL.positionThumbnails(); 15197 15198 if (opts.linkId) setTimeout(function() { 15199 vars.hashLock = false; 15200 }, 55); 15201 15202 // Configure arrow buttons 15203 if (!opts.infinite) { 15204 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15205 15206 if (vars.current == 0) { 15207 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 15208 } 15209 if (vars.current >= vars.total - 1) { 15210 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 15211 } 15212 } 15213 15214 // Reset next cycle timeout 15215 iL.resetCycle(); 15216 15217 //Trigger the onAfterChange callback 15218 if (typeof opts.callback.onAfterChange == 'function') opts.callback.onAfterChange.call(iL, iL.ui); 15219 } 15220 }, 15221 15222 moveTo: function(side) { 15223 var iL = this, 15224 vars = iL.vars, 15225 opts = iL.options, 15226 path = opts.path.toLowerCase(), 15227 viewport = getViewport(), 15228 switchSpeed = opts.effects.switchSpeed; 15229 15230 if (vars.nextLock || vars.prevLock) return false; 15231 else { 15232 15233 var item = (side == "next") ? vars.next : vars.prev; 15234 15235 if (opts.linkId) { 15236 vars.hashLock = true; 15237 window.location.hash = opts.linkId + '/' + item; 15238 } 15239 15240 if (side == "next") { 15241 if (!iL.items[item]) return false; 15242 var firstHolder = vars.nextPhoto, 15243 secondHolder = vars.holder, 15244 lastHolder = vars.prevPhoto, 15245 firstClass = 'ilightbox-prev', 15246 secondClass = 'ilightbox-next'; 15247 } else if (side == "prev") { 15248 if (!iL.items[item]) return false; 15249 var firstHolder = vars.prevPhoto, 15250 secondHolder = vars.holder, 15251 lastHolder = vars.nextPhoto, 15252 firstClass = 'ilightbox-next', 15253 secondClass = 'ilightbox-prev'; 15254 } 15255 15256 //Trigger the onBeforeChange callback 15257 if (typeof opts.callback.onBeforeChange == 'function') 15258 opts.callback.onBeforeChange.call(iL, iL.ui); 15259 15260 (side == "next") ? vars.nextLock = true: vars.prevLock = true; 15261 15262 var captionFirst = $('div.ilightbox-caption', secondHolder), 15263 socialFirst = $('div.ilightbox-social', secondHolder); 15264 15265 if (captionFirst.length) 15266 captionFirst.stop().fadeOut(switchSpeed, function() { 15267 $(this).remove(); 15268 }); 15269 if (socialFirst.length) 15270 socialFirst.stop().fadeOut(switchSpeed, function() { 15271 $(this).remove(); 15272 }); 15273 15274 if (iL.items[item].caption) { 15275 iL.setCaption(iL.items[item], firstHolder); 15276 var caption = $('div.ilightbox-caption', firstHolder), 15277 percent = parseInt((caption.outerHeight() / firstHolder.outerHeight()) * 100); 15278 if (opts.caption.start && percent <= 50) caption.fadeIn(switchSpeed); 15279 } 15280 15281 var social = iL.items[item].options.social; 15282 if (social) { 15283 iL.setSocial(social, iL.items[item].URL, firstHolder); 15284 if (opts.social.start) $('div.ilightbox-social', firstHolder).fadeIn(opts.effects.fadeSpeed); 15285 } 15286 15287 $.each([firstHolder, secondHolder, lastHolder], function(key, val) { 15288 val.removeClass('ilightbox-next ilightbox-prev'); 15289 }); 15290 15291 var firstOffset = firstHolder.data('offset'), 15292 winW = (viewport.width - (opts.styles.pageOffsetX)), 15293 winH = (viewport.height - (opts.styles.pageOffsetY)), 15294 width = firstOffset.newDims.width, 15295 height = firstOffset.newDims.height, 15296 thumbsOffset = firstOffset.thumbsOffset, 15297 diff = firstOffset.diff, 15298 top = parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)), 15299 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15300 15301 var secondOffset = secondHolder.data('offset'), 15302 object = secondOffset.object; 15303 15304 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 15305 var objRatio = width / height; 15306 height = height - vars.captionHeight; 15307 width = height * objRatio; 15308 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top, 15309 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15310 }*/ 15311 15312 firstHolder.show().css(transform, gpuAcceleration).animate({ 15313 top: top, 15314 left: left, 15315 opacity: 1 15316 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15317 firstHolder.css(transform, ''); 15318 }); 15319 15320 $('div.ilightbox-container', firstHolder).animate({ 15321 width: width, 15322 height: height 15323 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 15324 15325 diff = secondOffset.diff; 15326 15327 width = secondOffset.newDims.width, 15328 height = secondOffset.newDims.height; 15329 15330 width = parseInt(width * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 15331 height = parseInt(height * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 15332 top = (path == 'horizontal') ? parseInt((winH / 2) - object.offsetY - (height / 2) - diff.H - (thumbsOffset.H / 2)) : parseInt(winH - object.offsetX - diff.H - (thumbsOffset.H / 2)); 15333 15334 if (side == 'prev') 15335 left = (path == 'horizontal') ? parseInt(winW - object.offsetX - diff.W - (thumbsOffset.W / 2)) : parseInt((winW / 2) - (width / 2) - diff.W - object.offsetY - (thumbsOffset.W / 2)); 15336 else { 15337 top = (path == 'horizontal') ? top : parseInt(object.offsetX - diff.H - height - (thumbsOffset.H / 2)), 15338 left = (path == 'horizontal') ? parseInt(object.offsetX - diff.W - width - (thumbsOffset.W / 2)) : parseInt((winW / 2) - object.offsetY - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15339 } 15340 15341 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 15342 var objRatio = width / height; 15343 height = height - vars.captionHeight; 15344 width = height * objRatio; 15345 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top; 15346 }*/ 15347 15348 $('div.ilightbox-container', secondHolder).animate({ 15349 width: width, 15350 height: height 15351 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 15352 15353 secondHolder.addClass(firstClass).css(transform, gpuAcceleration).animate({ 15354 top: top, 15355 left: left, 15356 opacity: opts.styles.prevOpacity, 15357 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15358 secondHolder.css(transform, ''); 15359
15360 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(item).addClass('ilightbox-active'); 15361 iL.positionThumbnails(); 15362 15363 if (iL.items[item]) { 15364 if (!iL.items[item].options.mousewheel) vars.lockWheel = true; 15365 else vars.lockWheel = false; 15366 15367 if (!iL.items[item].options.swipe) vars.lockSwipe = true; 15368 else vars.lockSwipe = false; 15369 } 15370 15371 vars.isSwipe = false; 15372 15373 // Remove iframe & video from previous slide 15374 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 15375 $('div.ilightbox-container', secondHolder).empty(); 15376 } 15377 15378 if (side == "next") { 15379 vars.nextPhoto = lastHolder, 15380 vars.prevPhoto = secondHolder, 15381 vars.holder = firstHolder; 15382 15383 vars.nextPhoto.hide(); 15384 15385 vars.next = vars.next + 1, 15386 vars.prev = vars.current, 15387 vars.current = vars.current + 1; 15388 15389 if (opts.infinite) { 15390 if (vars.current > vars.total - 1) vars.current = 0; 15391 if (vars.current == vars.total - 1) vars.next = 0; 15392 if (vars.current == 0) vars.prev = vars.total - 1; 15393 } 15394 15395 iL.createUI(); 15396 15397 if (!iL.items[vars.next]) 15398 vars.nextLock = false; 15399 else 15400 iL.loadContent(iL.items[vars.next], 'next'); 15401 } else { 15402 vars.prevPhoto = lastHolder; 15403 vars.nextPhoto = secondHolder; 15404 vars.holder = firstHolder; 15405 15406 vars.prevPhoto.hide(); 15407 15408 vars.next = vars.current; 15409 vars.current = vars.prev; 15410 vars.prev = vars.current - 1; 15411 15412 if (opts.infinite) { 15413 if (vars.current == vars.total - 1) vars.next = 0; 15414 if (vars.current == 0) vars.prev = vars.total - 1; 15415 } 15416 15417 iL.createUI(); 15418 15419 if (!iL.items[vars.prev]) 15420 vars.prevLock = false; 15421 else 15422 iL.loadContent(iL.items[vars.prev], 'prev'); 15423 } 15424 15425 // Add iframe & video content for current slide 15426 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 15427 iL.loadContent(iL.items[vars.current], 'current'); 15428 } 15429 15430 if (opts.linkId) setTimeout(function() { 15431 vars.hashLock = false; 15432 }, 55); 15433 15434 // Configure arrow buttons 15435 if (!opts.infinite) { 15436 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15437 15438 if (vars.current == 0) 15439 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 15440 if (vars.current >= vars.total - 1) 15441 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 15442 } 15443 15444 iL.repositionPhoto(); 15445 15446 // Reset next cycle timeout 15447 iL.resetCycle(); 15448 15449 //Trigger the onAfterChange callback 15450 if (typeof opts.callback.onAfterChange == 'function') 15451 opts.callback.onAfterChange.call(iL, iL.ui); 15452 }); 15453 15454 top = (path == 'horizontal') ? getPixel(lastHolder, 'top') : ((side == "next") ? parseInt(-(winH / 2) - lastHolder.outerHeight()) : parseInt(top * 2)), 15455 left = (path == 'horizontal') ? ((side == "next") ? parseInt(-(winW / 2) - lastHolder.outerWidth()) : parseInt(left * 2)) : getPixel(lastHolder, 'left'); 15456 15457 lastHolder.css(transform, gpuAcceleration).animate({ 15458 top: top, 15459 left: left, 15460 opacity: opts.styles.nextOpacity 15461 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15462 lastHolder.css(transform, ''); 15463 }).addClass(secondClass); 15464 } 15465 }, 15466 15467 setCaption: function(obj, target) { 15468 var iL = this, 15469 caption = $('<div class="ilightbox-caption"></div>'); 15470 15471 if (obj.caption) { 15472 caption.html(obj.caption); 15473 $('div.ilightbox-container', target).append(caption); 15474 } 15475 }, 15476 15477 normalizeSocial: function(obj, url) { 15478 var iL = this, 15479 vars = iL.vars, 15480 opts = iL.options, 15481 baseURL = window.location.href; 15482 15483 $.each(obj, function(key, value) { 15484 if (!value) 15485 return true; 15486 15487 var item = key.toLowerCase(), 15488 source, text; 15489 15490 switch (item) { 15491 case 'facebook': 15492 source = "http://www.facebook.com/share.php?v=4&src=bm&u={URL}", 15493 text = "Share on Facebook"; 15494 break; 15495 case 'twitter': 15496 source = "http://twitter.com/home?status={URL}", 15497 text = "Share on Twitter"; 15498 break; 15499 case 'digg': 15500 source = "http://digg.com/submit?phase=2&url={URL}", 15501 text = "Share on Digg"; 15502 break; 15503 case 'reddit': 15504 source = "http://reddit.com/submit?url={URL}", 15505 text = "Share on reddit"; 15506 break; 15507 } 15508 15509 obj[key] = { 15510 URL: value.URL && absolutizeURI(baseURL, value.URL) || opts.linkId && window.location.href || typeof url !== 'string' && baseURL || url && absolutizeURI(baseURL, url) || baseURL, 15511 source: value.source || source || value.URL && absolutizeURI(baseURL, value.URL) || url && absolutizeURI(baseURL, url), 15512 text: value.text || text || "Share on " + key, 15513 width: (typeof(value.width) != 'undefined' && !isNaN(value.width)) ? parseInt(value.width) : 640, 15514 height: value.height || 360 15515 }; 15516 15517 }); 15518 15519 return obj; 15520 }, 15521 15522 setSocial: function(obj, url, target) { 15523 var iL = this, 15524 socialBar = $('<div class="ilightbox-social"></div>'), 15525 buttons = '<ul>'; 15526 15527 obj = iL.normalizeSocial(obj, url); 15528 15529 $.each(obj, function(key, value) { 15530 var item = key.toLowerCase(), 15531 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, '+')); 15532 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>'; 15533 }); 15534 15535 buttons += '</ul>'; 15536 15537 socialBar.html(buttons); 15538 $('div.ilightbox-container', target).append(socialBar); 15539 }, 15540 15541 fullScreenAction: function() { 15542 var iL = this, 15543 vars = iL.vars; 15544 15545 if (fullScreenApi.supportsFullScreen) { 15546 if (fullScreenApi.isFullScreen()) fullScreenApi.cancelFullScreen(document.documentElement); 15547 else fullScreenApi.requestFullScreen(document.documentElement); 15548 } else { 15549 iL.doFullscreen(); 15550 } 15551 }, 15552 15553 doFullscreen: function() { 15554 var iL = this, 15555 vars = iL.vars, 15556 viewport = getViewport(), 15557 opts = iL.options; 15558 15559 if (opts.fullAlone) { 15560 var currentHolder = vars.holder, 15561 current = iL.items[vars.current], 15562 windowWidth = viewport.width, 15563 windowHeight = viewport.height, 15564 elements = [currentHolder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.overlay, vars.toolbar, vars.thumbnails, vars.loader], 15565 hideElements = [vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 15566 15567 if (!vars.isInFullScreen) { 15568 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = true; 15569 vars.overlay.css({ 15570 opacity: 1 15571 }); 15572 15573 $.each(hideElements, function(i, element) { 15574 element.hide(); 15575 }); 15576 15577 vars.fullScreenButton.attr('title', opts.text.exitFullscreen); 15578 15579 if (opts.fullStretchTypes.indexOf(current.type) != -1) currentHolder.data({
15580 naturalWidthOld: currentHolder.data('naturalWidth'), 15581 naturalHeightOld: currentHolder.data('naturalHeight'), 15582 naturalWidth: windowWidth, 15583 naturalHeight: windowHeight 15584 }); 15585 else { 15586 var viewport = current.options.fullViewPort || opts.fullViewPort || '', 15587 newWidth = windowWidth, 15588 newHeight = windowHeight, 15589 width = currentHolder.data('naturalWidth'), 15590 height = currentHolder.data('naturalHeight'); 15591 15592 if (viewport.toLowerCase() == 'fill') { 15593 newHeight = (newWidth / width) * height; 15594 15595 if (newHeight < windowHeight) { 15596 newWidth = (windowHeight / height) * width, 15597 newHeight = windowHeight; 15598 } 15599 } else if (viewport.toLowerCase() == 'fit') { 15600 var dims = iL.getNewDimenstions(newWidth, newHeight, width, height, true); 15601 15602 newWidth = dims.width, 15603 newHeight = dims.height; 15604 } else if (viewport.toLowerCase() == 'stretch') { 15605 newWidth = newWidth, 15606 newHeight = newHeight; 15607 } else { 15608 var scale = (width > newWidth || height > newHeight) ? true : false, 15609 dims = iL.getNewDimenstions(newWidth, newHeight, width, height, scale); 15610 newWidth = dims.width, 15611 newHeight = dims.height; 15612 } 15613 15614 currentHolder.data({ 15615 naturalWidthOld: currentHolder.data('naturalWidth'), 15616 naturalHeightOld: currentHolder.data('naturalHeight'), 15617 naturalWidth: newWidth, 15618 naturalHeight: newHeight 15619 }); 15620 } 15621 15622 $.each(elements, function(key, val) { 15623 val.addClass('ilightbox-fullscreen'); 15624 }); 15625 15626 //Trigger the onEnterFullScreen callback 15627 if (typeof opts.callback.onEnterFullScreen == 'function') opts.callback.onEnterFullScreen.call(iL, iL.ui); 15628 } else { 15629 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = false; 15630 vars.overlay.css({ 15631 opacity: iL.options.overlay.opacity 15632 }); 15633 15634 $.each(hideElements, function(i, element) { 15635 element.show(); 15636 }); 15637 15638 vars.fullScreenButton.attr('title', opts.text.enterFullscreen); 15639 15640 currentHolder.data({ 15641 naturalWidth: currentHolder.data('naturalWidthOld'), 15642 naturalHeight: currentHolder.data('naturalHeightOld'), 15643 naturalWidthOld: null, 15644 naturalHeightOld: null 15645 }); 15646 15647 $.each(elements, function(key, val) { 15648 val.removeClass('ilightbox-fullscreen'); 15649 }); 15650 15651 //Trigger the onExitFullScreen callback 15652 if (typeof opts.callback.onExitFullScreen == 'function') opts.callback.onExitFullScreen.call(iL, iL.ui); 15653 } 15654 } else { 15655 if (!vars.isInFullScreen) vars.isInFullScreen = true; 15656 else vars.isInFullScreen = false; 15657 } 15658 iL.repositionPhoto(true); 15659 }, 15660 15661 closeAction: function() { 15662 var iL = this, 15663 vars = iL.vars, 15664 opts = iL.options; 15665 15666 $win.unbind('.iLightBox'); 15667 $doc.off('.iLightBox'); 15668 15669 if (vars.isInFullScreen) fullScreenApi.cancelFullScreen(document.documentElement); 15670 15671 $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails').off('.iLightBox'); 15672 15673 if (opts.hide.effect) vars.overlay.stop().fadeOut(opts.hide.speed, function() { 15674 vars.overlay.remove(); 15675 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 15676 }); 15677 else { 15678 vars.overlay.remove(); 15679 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 15680 } 15681 15682 var fadeOuts = [vars.toolbar, vars.holder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 15683 15684 $.each(fadeOuts, function(i, element) { 15685 element.removeAttr('style').remove(); 15686 }); 15687 15688 vars.dontGenerateThumbs = vars.isInFullScreen = false; 15689 15690 window.iLightBox = null; 15691 15692 if (opts.linkId) { 15693 vars.hashLock = true; 15694 removeHash(); 15695 setTimeout(function() { 15696 vars.hashLock = false; 15697 }, 55); 15698 } 15699 15700 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15701 15702 //Trigger the onHide callback 15703 if (typeof opts.callback.onHide == 'function') opts.callback.onHide.call(iL, iL.ui); 15704 }, 15705 15706 repositionPhoto: function() { 15707 var iL = this, 15708 vars = iL.vars, 15709 opts = iL.options, 15710 path = opts.path.toLowerCase(), 15711 viewport = getViewport(), 15712 winWidth = viewport.width, 15713 winHeight = viewport.height; 15714 15715 if (viewport.width < UNCODE.mediaQuery) opts.styles.nextOffsetX = 0; 15716 15717 var thumbsOffsetW = (vars.isInFullScreen && opts.fullAlone || vars.isMobile) ? 0 : ((path == 'horizontal') ? 0 : vars.thumbnails.outerWidth()), 15718 thumbsOffsetH = vars.isMobile ? vars.toolbar.outerHeight() : ((vars.isInFullScreen && opts.fullAlone) ? 0 : ((path == 'horizontal') ? vars.thumbnails.outerHeight() : 0)), 15719 width = (vars.isInFullScreen && opts.fullAlone) ? winWidth : (winWidth - (opts.styles.pageOffsetX)), 15720 height = (vars.isInFullScreen && opts.fullAlone) ? winHeight : (winHeight - (opts.styles.pageOffsetY)), 15721 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, 15722 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))); 15723 15724 var elObject = { 15725 type: 'current', 15726 width: width, 15727 height: height, 15728 item: iL.items[vars.current], 15729 offsetW: offsetW, 15730 offsetH: offsetH,
15731 thumbsOffsetW: thumbsOffsetW, 15732 thumbsOffsetH: thumbsOffsetH, 15733 animate: arguments.length, 15734 holder: vars.holder 15735 }; 15736 15737 iL.repositionEl(elObject); 15738 15739 if (iL.items[vars.next]) { 15740 elObject = $.extend(elObject, { 15741 type: 'next', 15742 item: iL.items[vars.next], 15743 offsetX: opts.styles.nextOffsetX, 15744 offsetY: opts.styles.nextOffsetY, 15745 holder: vars.nextPhoto 15746 }); 15747 15748 iL.repositionEl(elObject); 15749 } 15750 15751 if (iL.items[vars.prev]) { 15752 elObject = $.extend(elObject, { 15753 type: 'prev', 15754 item: iL.items[vars.prev], 15755 offsetX: opts.styles.nextOffsetX, 15756 offsetY: opts.styles.prevOffsetY, 15757 holder: vars.prevPhoto 15758 }); 15759 15760 iL.repositionEl(elObject); 15761 } 15762 15763 var loaderCss = (path == "horizontal") ? { 15764 left: parseInt((width / 2) - (vars.loader.outerWidth() / 2)) 15765 } : { 15766 top: parseInt((height / 2) - (vars.loader.outerHeight() / 2)) 15767 }; 15768 vars.loader.css(loaderCss); 15769 }, 15770 15771 repositionEl: function(obj) { 15772 var iL = this, 15773 vars = iL.vars, 15774 opts = iL.options, 15775 path = opts.path.toLowerCase(), 15776 widthAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.width : (obj.width - obj.offsetW)) : (obj.width - obj.offsetW), 15777 heightAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.height : (obj.height - obj.offsetH)) : (obj.height - obj.offsetH), 15778 itemParent = obj.item, 15779 item = obj.item.options, 15780 holder = obj.holder, 15781 offsetX = obj.offsetX || 0, 15782 offsetY = obj.offsetY || 0, 15783 //Uncode change ##START## 15784 toolbarHeight = $('.ilightbox-inner-toolbar', holder).length ? parseInt( $('.ilightbox-inner-toolbar', holder).outerHeight() ) : 0, 15785 //Uncode change ##END## 15786 thumbsOffsetW = obj.thumbsOffsetW, 15787 thumbsOffsetH = obj.thumbsOffsetH; 15788 15789 if (obj.type == 'current') { 15790 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); 15791 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); 15792 } else { 15793 if (typeof item.width == 'number' && item.width) widthAvail = (item.width > widthAvail) ? widthAvail : item.width; 15794 if (typeof item.height == 'number' && item.height) heightAvail = (item.height > heightAvail) ? heightAvail : item.height; 15795 } 15796 15797 15798 //Uncode change ##START## 15799 heightAvail = parseInt(heightAvail - toolbarHeight); 15800 // heightAvail = parseInt(heightAvail - $('.ilightbox-inner-toolbar', holder).outerHeight()); 15801 //Uncode change ##END## 15802 15803 var width = (typeof item.width == 'string' && item.width.indexOf('%') != -1) ? percentToValue(parseInt(item.width.replace('%', '')), obj.width) : holder.data('naturalWidth'), 15804 height = (typeof item.height == 'string' && item.height.indexOf('%') != -1) ? percentToValue(parseInt(item.height.replace('%', '')), obj.height) : holder.data('naturalHeight'); 15805 15806 var dims = ((typeof item.width == 'string' && item.width.indexOf('%') != -1 || typeof item.height == 'string' && item.height.indexOf('%') != -1) ? { 15807 width: width, 15808 height: height 15809 } : iL.getNewDimenstions(widthAvail, heightAvail, width, height)), 15810 newDims = $.extend({}, dims, {}); 15811 15812 if (obj.type == 'prev' || obj.type == 'next') 15813 width = parseInt(dims.width * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)), 15814 height = parseInt(dims.height * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)); 15815 else 15816 width = dims.width, 15817 height = dims.height; 15818 15819 var widthDiff = parseInt((getPixel(holder, 'padding-left') + getPixel(holder, 'padding-right') + getPixel(holder, 'border-left-width') + getPixel(holder, 'border-right-width')) / 2), 15820 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); 15821 15822 switch (obj.type) { 15823 case 'current': 15824 var top = parseInt((obj.height / 2) - (height / 2) - heightDiff - (thumbsOffsetH / 2)), 15825 left = parseInt((obj.width / 2) - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15826 break; 15827
15828 case 'next': 15829 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(obj.height - offsetX - heightDiff - (thumbsOffsetH / 2)), 15830 left = (path == 'horizontal') ? parseInt(obj.width - offsetX - widthDiff - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - (width / 2) - widthDiff - offsetY - (thumbsOffsetW / 2)); 15831 break; 15832 15833 case 'prev': 15834 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(offsetX - heightDiff - height - (thumbsOffsetH / 2)), 15835 left = (path == 'horizontal') ? parseInt(offsetX - widthDiff - width - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - offsetY - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15836 break; 15837 } 15838 15839 holder.data('offset', { 15840 top: top, 15841 left: left, 15842 newDims: newDims, 15843 diff: { 15844 W: widthDiff, 15845 H: heightDiff 15846 }, 15847 thumbsOffset: { 15848 W: thumbsOffsetW, 15849 H: thumbsOffsetH 15850 }, 15851 object: obj 15852 }); 15853 15854 var opacityMobile; 15855 if ( isMobile ) { 15856 opacityMobile = { 15857 opacity: 1, 15858 top: top, 15859 left: left 15860 }; 15861 } else { 15862 opacityMobile = { 15863 top: top, 15864 left: left 15865 }; 15866 } 15867 15868 if (obj.animate > 0 && opts.effects.reposition) { 15869 holder.css(transform, gpuAcceleration).stop().animate( 15870 opacityMobile, 15871 opts.effects.repositionSpeed, 'easeOutCirc', function() { 15872 holder.css(transform, ''); 15873 }); 15874 $('div.ilightbox-container', holder).stop().animate({ 15875 width: width, 15876 height: height 15877 }, opts.effects.repositionSpeed, 'easeOutCirc'); 15878 $('div.ilightbox-inner-toolbar', holder).stop().animate({ 15879 width: width 15880 }, opts.effects.repositionSpeed, 'easeOutCirc', function() { 15881 $(this).css('overflow', 'visible'); 15882 }); 15883 } else { 15884 holder.css(opacityMobile); 15885 $('div.ilightbox-container', holder).css({ 15886 width: width, 15887 height: height 15888 }); 15889 $('div.ilightbox-inner-toolbar', holder).css({ 15890 width: width 15891 }); 15892 } 15893 }, 15894 15895 15896 resume: function(priority) { 15897 var iL = this, 15898 vars = iL.vars, 15899 opts = iL.options; 15900 15901 if (!opts.slideshow.pauseTime || opts.controls.slideshow && vars.total <= 1 || priority < vars.isPaused) { 15902 return; 15903 } 15904 15905 vars.isPaused = 0; 15906 15907 if (vars.cycleID) { 15908 vars.cycleID = clearTimeout(vars.cycleID); 15909 } 15910 15911 vars.cycleID = setTimeout(function() { 15912 if (vars.current == vars.total - 1) iL.goTo(0); 15913 else iL.moveTo('next'); 15914 }, opts.slideshow.pauseTime); 15915 }, 15916 15917 pause: function(priority) { 15918 var iL = this, 15919 vars = iL.vars, 15920 opts = iL.options; 15921 15922 if (priority < vars.isPaused) { 15923 return; 15924 } 15925 15926 vars.isPaused = priority || 100; 15927 15928 if (vars.cycleID) { 15929 vars.cycleID = clearTimeout(vars.cycleID); 15930 } 15931 }, 15932 15933 resetCycle: function() { 15934 var iL = this, 15935 vars = iL.vars, 15936 opts = iL.options; 15937 15938 if (opts.controls.slideshow && vars.cycleID && !vars.isPaused) { 15939 iL.resume(); 15940 } 15941 }, 15942 15943 getNewDimenstions: function(width, height, width_old, height_old, thumb) { 15944 var iL = this; 15945 15946 if (!width) factor = height / height_old; 15947 else if (!height) factor = width / width_old; 15948 else factor = min(width / width_old, height / height_old); 15949 15950 if (!thumb) { 15951 if (factor > iL.options.maxScale) factor = iL.options.maxScale; 15952 else if (factor < iL.options.minScale) factor = iL.options.minScale; 15953 } 15954 15955 var final_width = (iL.options.keepAspectRatio) ? round(width_old * factor) : width, 15956 final_height = (iL.options.keepAspectRatio) ? round(height_old * factor) : height; 15957 15958 return { 15959 width: final_width, 15960 height: final_height, 15961 ratio: factor 15962 }; 15963 }, 15964 15965 setOption: function(options) { 15966 var iL = this; 15967 15968 iL.options = $.extend(true, iL.options, options || {}); 15969 iL.refresh(); 15970 }, 15971 15972 availPlugins: function() { 15973 var iL = this, 15974 testEl = document.createElement("video"); 15975 15976 iL.plugins = { 15977 flash: !isMobile, 15978 quicktime: (parseInt(PluginDetect.getVersion("QuickTime")) >= 0) ? true : false, 15979 html5H264: !!(testEl.canPlayType && testEl.canPlayType('video/mp4').replace(/no/, '')), 15980 html5WebM: !!(testEl.canPlayType && testEl.canPlayType('video/webm').replace(/no/, '')), 15981 html5Vorbis: !!(testEl.canPlayType && testEl.canPlayType('video/ogg').replace(/no/, '')), 15982 html5QuickTime: !!(testEl.canPlayType && testEl.canPlayType('video/quicktime').replace(/no/, '')) 15983 }; 15984 }, 15985 15986 addContent: function(element, obj) { 15987 var iL = this, 15988 el; 15989 15990 switch (obj.type) { 15991 case 'video': 15992 var HTML5 = false, 15993 videoType = obj.videoType, 15994 html5video = obj.options.html5video; 15995 15996 if (((videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v') || html5video.h264) && iL.plugins.html5H264) 15997 obj.ext = 'mp4', 15998 obj.URL = html5video.h264 || obj.URL; 15999 else if (html5video.webm && iL.plugins.html5WebM) 16000 obj.ext = 'webm', 16001 obj.URL = html5video.webm || obj.URL; 16002 else if (html5video.ogg && iL.plugins.html5Vorbis) 16003 obj.ext = 'ogv', 16004 obj.URL = html5video.ogg || obj.URL; 16005 16006 if (iL.plugins.html5H264 && (videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v')) HTML5 = true, videoType = "video/mp4"; 16007 else if (iL.plugins.html5WebM && (videoType == 'video/webm' || obj.ext == 'webm')) HTML5 = true, videoType = "video/webm"; 16008 else if (iL.plugins.html5Vorbis && (videoType == 'video/ogg' || obj.ext == 'ogv')) HTML5 = true, videoType = "video/ogg"; 16009 else if (iL.plugins.html5QuickTime && (videoType == 'video/quicktime' || obj.ext == 'mov' || obj.ext == 'qt')) HTML5 = true, videoType = "video/quicktime"; 16010 16011 if (HTML5) { 16012 el = $('<video />
16012', { 16013 "width": "100%", 16014 "height": "100%", 16015 "preload": html5video.preload, 16016 "autoplay": html5video.autoplay, 16017 "loop": html5video.loop, 16018 "poster": html5video.poster, 16019 "controls": html5video.controls, 16020 "controlslist": "nodownload" 16021 }).append($('<source />', { 16022 "src": obj.URL, 16023 "type": videoType 16024 })); 16025 } else { 16026 if (!iL.plugins.quicktime) el = $('<span />', { 16027 "class": "ilightbox-alert", 16028 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.quicktime).replace('{type}', 'QuickTime') 16029 }); 16030 else { 16031 16032 el = $('<object />', { 16033 "type": "video/quicktime", 16034 "pluginspage": pluginspages.quicktime 16035 }).attr({ 16036 "data": obj.URL, 16037 "width": "100%", 16038 "height": "100%" 16039 }).append($('<param />', { 16040 "name": "src", 16041 "value": obj.URL 16042 })).append($('<param />', { 16043 "name": "autoplay", 16044 "value": "false" 16045 })).append($('<param />', { 16046 "name": "loop", 16047 "value": "false" 16048 })).append($('<param />', { 16049 "name": "scale", 16050 "value": "tofit" 16051 })); 16052 16053 if (browser.msie) el = QT_GenerateOBJECTText(obj.URL, '100%', '100%', '', 'SCALE', 'tofit', 'AUTOPLAY', 'false', 'LOOP', 'false'); 16054 } 16055 } 16056 16057 break; 16058 16059 case 'flash': 16060 if (!iL.plugins.flash) el = $('<span />', { 16061 "class": "ilightbox-alert", 16062 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.flash).replace('{type}', 'Adobe Flash player') 16063 }); 16064 else { 16065 var flashvars = "", 16066 i = 0; 16067 16068 if (obj.options.flashvars) $.each(obj.options.flashvars, function(k, v) { 16069 if (i != 0) flashvars += "&"; 16070 flashvars += k + "=" + encodeURIComponent(v); 16071 i++; 16072 }); 16073 else flashvars = null; 16074 16075 el = $('<embed />').attr({ 16076 "type": "application/x-shockwave-flash", 16077 "src": obj.URL, 16078 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 16079 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 16080 "quality": "high", 16081 "bgcolor": "#000000", 16082 "play": "true", 16083 "loop": "true", 16084 "menu": "true", 16085 "wmode": "transparent", 16086 "scale": "showall", 16087 "allowScriptAccess": "always", 16088 "allowFullScreen": "true", 16089 "flashvars": flashvars, 16090 "fullscreen": "yes" 16091 }); 16092 } 16093 16094 break; 16095 16096 case 'iframe': 16097 el = $('<iframe />').attr({ 16098 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 16099 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 16100 src: obj.URL, 16101 frameborder: 0, 16102 'hspace': 0, 16103 'vspace': 0, 16104 'scrolling': supportTouch ? 'auto' : 'scroll', 16105 'webkitAllowFullScreen': '', 16106 'mozallowfullscreen': '', 16107 'allowFullScreen': '' 16108 }); 16109 16110 break; 16111 16112 case 'inline': 16113 el = $('<div class="ilightbox-wrapper"></div>').html($(obj.URL).clone(true)); 16114 16115 break; 16116 16117 case 'html': 16118 var object = obj.URL, 16119 el; 16120 16121 if (object[0].nodeName) { 16122 el = $('<div class="ilightbox-wrapper"></div>').html(object); 16123 } else { 16124 var dom = $(obj.URL), 16125 html = (dom.selector) ? $('<div>' + dom + '</div>') : dom; 16126 el = $('<div class="ilightbox-wrapper"></div>').html(html); 16127 } 16128 16129 break; 16130 } 16131 16132 $('div.ilightbox-container', element).empty().html(el); 16133 16134 // For fixing Chrome about just playing the video for first time 16135 if (el[0].tagName.toLowerCase() === 'video' && browser.webkit) setTimeout(function() { 16136 var src = el[0].currentSrc + '?' + floor(random() * 30000); 16137 el[0].currentSrc = src; 16138 el[0].src = src; 16139 }); 16140 16141 return el; 16142 }, 16143 16144 ogpRecognition: function(obj, callback) { 16145 var iL = this, 16146 url = obj.URL; 16147 16148 iL.showLoader(); 16149 doAjax(url, function(data) { 16150 iL.hideLoader(); 16151 if (data) { 16152 var object = new Object(); 16153 16154 object.length = false, 16155 object.url = data.url; 16156 16157 if (data.status == 200) { 16158 var result = data.results, 16159 type = result.type, 16160 source = result.source; 16161 16162 object.source = source.src, 16163 object.width = source.width && parseInt(source.width) || 0, 16164 object.height = source.height && parseInt(source.height) || 0, 16165 object.type = type, 16166 object.thumbnail = source.thumbnail || result.images && result.images[0], 16167 object.html5video = result.html5video || {}, 16168 object.length = true; 16169 16170 if (source.type == 'application/x-shockwave-flash') object.type = "flash"; 16171 else if (source.type.indexOf("video/") != -1) object.type = "video"; 16172 else if (source.type.indexOf("/html") != -1) object.type = "iframe"; 16173 else if (source.type.indexOf("image/") != -1) object.type = "image"; 16174 16175 } else if (typeof data.response != 'undefined') 16176 throw data.response; 16177 16178 callback.call(this, object.length ? object : false); 16179 } 16180 }); 16181 }, 16182 16183 hashChangeHandler: function(url) { 16184 var iL = this, 16185 vars = iL.vars, 16186 opts = iL.options, 16187 URL = url || window.location.href, 16188 hash = parseURI(URL).hash, 16189 split = hash.split('/'), 16190 index = split[1]; 16191 16192 if (vars.hashLock || ('#' + opts.linkId != split[0] && hash.length > 1)) return; 16193 16194 if (index) { 16195 var target = split[1] || 0; 16196 if (iL.items[target]) {
16197 var overlay = $('.ilightbox-overlay'); 16198 if (overlay.length && overlay.attr('linkid') == opts.linkId) { 16199 iL.goTo(target); 16200 } else { 16201 iL.itemsObject[target].trigger(ishybrid ? "itap click" : supportTouch ? 'itap' : 'click'); 16202 //iL.goTo(target); 16203 } 16204 } else { 16205 var overlay = $('.ilightbox-overlay'); 16206 if (overlay.length) iL.closeAction(); 16207 } 16208 } else { 16209 var overlay = $('.ilightbox-overlay'); 16210 if (overlay.length) iL.closeAction(); 16211 } 16212 } 16213 }; 16214 16215 /** 16216 * Parse style to pixels. 16217 * 16218 * @param {Object} $element jQuery object with element. 16219 * @param {Property} property CSS property to get the pixels from. 16220 * 16221 * @return {Int} 16222 */ 16223 function getPixel($element, property) { 16224 return parseInt($element.css(property), 10) || 0; 16225 } 16226 16227 /** 16228 * Make sure that number is within the limits. 16229 * 16230 * @param {Number} number 16231 * @param {Number} min 16232 * @param {Number} max 16233 * 16234 * @return {Number} 16235 */ 16236 function within(number, min, max) { 16237 return number < min ? min : number > max ? max : number; 16238 } 16239 16240 /** 16241 * Get viewport/window size (width and height). 16242 * 16243 * @return {Object} 16244 */ 16245 function getViewport() { 16246 var e = window, 16247 a = 'inner'; 16248 if (!('innerWidth' in window)) { 16249 a = 'client'; 16250 e = document.documentElement || document.body; 16251 } 16252 return { 16253 width: e[a + 'Width'], 16254 height: e[a + 'Height'] 16255 } 16256 } 16257 16258 /** 16259 * Remove hash tag from the URL 16260 * 16261 * @return {Void} 16262 */ 16263 function removeHash() { 16264 var scroll = getScrollXY(); 16265 16266 //UNCODE change 16267 // window.location.hash = ""; 16268 // history.pushState("", document.title, window.location.pathname + window.location.search); 16269 history.replaceState({}, document.title, window.location.pathname + window.location.search); 16270 16271 // Restore the scroll offset, should be flicker free 16272 window.scrollTo(scroll.x, scroll.y); 16273 } 16274 16275 /** 16276 * Do the ajax requests with callback. 16277 * 16278 * @param {String} url 16279 * @param {Function} callback 16280 * 16281 * @return {Void} 16282 */ 16283 function doAjax(url, callback) { 16284 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'); 16285 $.ajax({ 16286 url: url, 16287 dataType: 'jsonp' 16288 }); 16289 16290 iLCallback = function(data) { 16291 callback.call(this, data); 16292 }; 16293 } 16294 16295 /** 16296 * Find image from DOM elements 16297 * 16298 * @param {Element} element 16299 * 16300 * @return {Void} 16301 */ 16302 function findImageInElement(element) { 16303 var elements = $('*', element), 16304 imagesArr = new Array(); 16305 16306 elements.each(function() { 16307 var url = "", 16308 element = this; 16309 16310 if ($(element).css("background-image") != "none") { 16311 url = $(element).css("background-image"); 16312 } else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") { 16313 url = $(element).attr("src"); 16314 } 16315 16316 if (url.indexOf("gradient") == -1) { 16317 url = url.replace(/url\(\"/g, ""); 16318 url = url.replace(/url\(/g, ""); 16319 url = url.replace(/\"\)/g, ""); 16320 url = url.replace(/\)/g, ""); 16321 16322 var urls = url.split(","); 16323 16324 for (var i = 0; i < urls.length; i++) { 16325 if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) { 16326 var extra = ""; 16327 if (browser.msie && browser.version < 9) { 16328 extra = "?" + floor(random() * 3000); 16329 } 16330 imagesArr.push(urls[i] + extra); 16331 } 16332 } 16333 } 16334 }); 16335 16336 return imagesArr; 16337 } 16338 16339 /** 16340 * Get file extension. 16341 * 16342 * @param {String} URL 16343 * 16344 * @return {String} 16345 */ 16346 function getExtension(URL) { 16347 if (URL !== null) { 16348 //UNCODE: fix issue to detect media type with query strings 16349 var ext = URL.indexOf('?') !== -1 ? URL.split('?')[0] : URL; 16350 ext = ext.split('.').pop().toLowerCase(); 16351 16352 return ext; 16353 } 16354 } 16355 16356 /** 16357 * Get type via extension. 16358 * 16359 * @param {String} URL 16360 * 16361 * @return {String} 16362 */ 16363 function getTypeByExtension(URL) { 16364 var type, 16365 ext = getExtension(URL); 16366 16367 //Uncode addition ##START## 16368 if (URL == undefined) { 16369 return false; 16370 } 16371 //Uncode addition ##END## 16372 16373 if (extensions.image.indexOf(ext) !== -1) type = 'image'; 16374 else if (extensions.flash.indexOf(ext) !== -1) type = 'flash'; 16375 else if (extensions.video.indexOf(ext) !== -1) type = 'video'; 16376 else if (ext.substring(0, 1) == "#") type = 'inline'; //Uncode addition 16377 else type = 'iframe'; 16378 16379 return type; 16380 } 16381 16382 /** 16383 * Return value from percent of a number. 16384 * 16385 * @param {Number} percent 16386 * @param {Number} total 16387 * 16388 * @return {Number} 16389 */ 16390 function percentToValue(percent, total) { 16391 return parseInt((total / 100) * percent); 16392 } 16393 16394 /** 16395 * A JavaScript equivalent of PHPâs parse_url. 16396 * 16397 * @param {String} url The URL to parse. 16398 * 16399 * @return {Mixed} 16400 */ 16401 function parseURI(url) { 16402 var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); 16403 // authority = '//' + user + ':' + pass '@' + hostname + ':' port 16404 return (m ? { 16405 href: m[0] || '', 16406 protocol: m[1] || '', 16407 authority: m[2] || '', 16408 host: m[3] || '', 16409 hostname: m[4] || '', 16410 port: m[5] || '', 16411 pathname: m[6] || '', 16412 search: m[7] || '', 16413 hash: m[8] || '' 16414 } : null); 16415 } 16416 16417 /** 16418 * Gets the absolute URI. 16419 * 16420 * @param {String} href The relative URL. 16421 * @param {String} base The base URL. 16422 * 16423 * @return {String} The absolute URL. 16424 */ 16425 function absolutizeURI(base, href) { // RFC 3986 16426 var iL = this; 16427 16428 function removeDotSegments(input) { 16429 var output = []; 16430 input.replace(/^(\.\.?(\/|$))+/, '') 16431 .replace(/\/(\.(\/|$))+/g, '/') 16432 .replace(/\/\.\.$/, '/../') 16433 .replace(/\/?[^\/]*/g, function(p) { 16434 if (p === '/..') { 16435 output.pop(); 16436 } else { 16437 output.push(p); 16438 } 16439 }); 16440 return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); 16441 } 16442 16443 href = parseURI(href || ''); 16444 base = parseURI(base || ''); 16445 16446 return !href || !base ? null : (href.protocol || base.protocol) + 16447 (href.protocol || href.authority ? href.authority : base.authority) + 16448 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)) + 16449 (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) + 16450 href.hash; 16451 } 16452 16453 /** 16454 * A JavaScript equivalent of PHPâs version_compare. 16455 * 16456 * @param {String} v1 16457 * @param {String} v2 16458 * @param {String} operator
16459 * 16460 * @return {Boolean} 16461 */ 16462 function version_compare(v1, v2, operator) { 16463 this.php_js = this.php_js || {}; 16464 this.php_js.ENV = this.php_js.ENV || {}; 16465 var i = 0, 16466 x = 0, 16467 compare = 0, 16468 vm = { 16469 'dev': -6, 16470 'alpha': -5, 16471 'a': -5, 16472 'beta': -4, 16473 'b': -4, 16474 'RC': -3, 16475 'rc': -3, 16476 '#': -2, 16477 'p': 1, 16478 'pl': 1 16479 }, 16480 prepVersion = function(v) { 16481 v = ('' + v).replace(/[_\-+]/g, '.'); 16482 v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.'); 16483 return (!v.length ? [-8] : v.split('.')); 16484 }, 16485 numVersion = function(v) { 16486 return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10)); 16487 }; 16488 v1 = prepVersion(v1); 16489 v2 = prepVersion(v2); 16490 x = max(v1.length, v2.length); 16491 for (i = 0; i < x; i++) { 16492 if (v1[i] == v2[i]) { 16493 continue; 16494 } 16495 v1[i] = numVersion(v1[i]); 16496 v2[i] = numVersion(v2[i]); 16497 if (v1[i] < v2[i]) { 16498 compare = -1; 16499 break; 16500 } else if (v1[i] > v2[i]) { 16501 compare = 1; 16502 break; 16503 } 16504 } 16505 if (!operator) { 16506 return compare; 16507 } 16508 16509 switch (operator) { 16510 case '>': 16511 case 'gt': 16512 return (compare > 0); 16513 case '>=': 16514 case 'ge': 16515 return (compare >= 0); 16516 case '<=': 16517 case 'le': 16518 return (compare <= 0); 16519 case '==': 16520 case '=': 16521 case 'eq': 16522 return (compare === 0); 16523 case '<>': 16524 case '!=': 16525 case 'ne': 16526 return (compare !== 0); 16527 case '': 16528 case '<': 16529 case 'lt': 16530 return (compare < 0); 16531 default: 16532 return null; 16533 } 16534 } 16535 16536 16537 // Begin the iLightBox plugin 16538 $.fn.iLightBox = function() { 16539 16540 var args = arguments, 16541 opt = ($.isPlainObject(args[0])) ? args[0] : args[1], 16542 items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1]; 16543 16544 if (!opt) opt = {}; 16545 16546 // Default options. Play carefully. 16547 var options = $.extend(true, { 16548 attr: 'href', 16549 path: 'vertical', 16550 skin: 'dark', 16551 linkId: false, 16552 infinite: false, 16553 startFrom: 0, 16554 randomStart: false, 16555 keepAspectRatio: true, 16556 maxScale: 1, 16557 minScale: .2, 16558 innerToolbar: false, 16559 smartRecognition: false, 16560 mobileOptimizer: true, 16561 fullAlone: true, 16562 fullViewPort: null, 16563 fullStretchTypes: 'flash, video', 16564 overlay: { 16565 blur: true, 16566 opacity: .85 16567 }, 16568 controls: { 16569 arrows: false, 16570 slideshow: false, 16571 toolbar: true, 16572 fullscreen: true, 16573 thumbnail: true, 16574 keyboard: true, 16575 mousewheel: true, 16576 swipe: true 16577 }, 16578 keyboard: { 16579 left: true, // previous 16580 right: true, // next 16581 up: true, // previous 16582 down: true, // next 16583 esc: true, // close 16584 shift_enter: true // fullscreen 16585 }, 16586 show: { 16587 effect: true, 16588 speed: 300, 16589 title: true 16590 }, 16591 hide: { 16592 effect: true, 16593 speed: 300 16594 }, 16595 caption: { 16596 start: true, 16597 show: 'mouseenter', 16598 hide: 'mouseleave' 16599 }, 16600 social: { 16601 start: true, 16602 show: 'mouseenter', 16603 hide: 'mouseleave',
16604 buttons: false 16605 }, 16606 styles: { 16607 pageOffsetX: 0, 16608 pageOffsetY: 0, 16609 nextOffsetX: 45, 16610 nextOffsetY: 0, 16611 nextOpacity: 1, 16612 nextScale: 1, 16613 prevOffsetX: 45, 16614 prevOffsetY: 0, 16615 prevOpacity: 1, 16616 prevScale: 1 16617 }, 16618 thumbnails: { 16619 maxWidth: 120, 16620 maxHeight: 80, 16621 normalOpacity: 1, 16622 activeOpacity: .6 16623 }, 16624 effects: { 16625 reposition: true, 16626 repositionSpeed: 200, 16627 switchSpeed: 500, 16628 loadedFadeSpeed: 180, 16629 fadeSpeed: 200 16630 }, 16631 slideshow: { 16632 pauseTime: 5000, 16633 pauseOnHover: false, 16634 startPaused: true 16635 }, 16636 text: { 16637 close: "Press Esc to close", 16638 enterFullscreen: "Enter Fullscreen (Shift+Enter)", 16639 exitFullscreen: "Exit Fullscreen (Shift+Enter)", 16640 slideShow: "Slideshow", 16641 next: "Next", 16642 previous: "Previous" 16643 }, 16644 errors: { 16645 loadImage: "An error occurred when trying to load photo.", 16646 loadContents: "An error occurred when trying to load contents.", 16647 missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>." 16648 }, 16649 ajaxSetup: { 16650 url: '', 16651 beforeSend: function(jqXHR, settings) {}, 16652 cache: false, 16653 complete: function(jqXHR, textStatus) {}, 16654 crossDomain: false, 16655 error: function(jqXHR, textStatus, errorThrown) {}, 16656 success: function(data, textStatus, jqXHR) {}, 16657 global: true, 16658 ifModified: false, 16659 username: null, 16660 password: null, 16661 type: 'GET' 16662 }, 16663 callback: {} 16664 }, opt); 16665 16666 var instant = ($.isArray(items) || typeof items == 'string') ? true : false; 16667 16668 items = $.isArray(items) ? items : new Array(); 16669 16670 if (typeof args[0] == 'string') items[0] = args[0]; 16671 16672 if (version_compare($.fn.jquery, '1.8', '>=')) { 16673 var iLB = new iLightBox($(this), options, items, instant); 16674 return { 16675 close: function() { 16676 iLB.closeAction(); 16677 }, 16678 fullscreen: function() { 16679 iLB.fullScreenAction(); 16680 }, 16681 moveNext: function() { 16682 iLB.moveTo('next'); 16683 }, 16684 movePrev: function() { 16685 iLB.moveTo('prev'); 16686 }, 16687 goTo: function(index) { 16688 iLB.goTo(index); 16689 }, 16690 refresh: function() { 16691 iLB.refresh(); 16692 }, 16693 reposition: function() { 16694 (arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto(); 16695 }, 16696 setOption: function(options) { 16697 iLB.setOption(options); 16698 }, 16699 destroy: function() { 16700 iLB.closeAction(); 16701 iLB.dispatchItemsEvents(); 16702 } 16703 }; 16704 } else { 16705 throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+"; 16706 } 16707 16708 }; 16709 16710 16711 $.iLightBox = function() { 16712 return $.fn.iLightBox(arguments[0], arguments[1]); 16713 }; 16714 16715 function getScrollXY() { 16716 var scrOfX = 0, 16717 scrOfY = 0; 16718 if (typeof(window.pageYOffset) == 'number') { 16719 //Netscape compliant 16720 scrOfY = window.pageYOffset; 16721 scrOfX = window.pageXOffset; 16722 } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { 16723 //DOM compliant 16724 scrOfY = document.body.scrollTop; 16725 scrOfX = document.body.scrollLeft; 16726 } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) { 16727 //IE6 standards compliant mode 16728 scrOfY = document.documentElement.scrollTop; 16729 scrOfX = document.documentElement.scrollLeft; 16730 } 16731 return { 16732 x: scrOfX, 16733 y: scrOfY 16734 }; 16735 } 16736 16737 (function() { 16738 // add new event shortcuts 16739 $.each(("touchstart touchmove touchend " + 16740 "tap taphold " + 16741 "swipe swipeleft swiperight " + 16742 "scrollstart scrollstop").split(" "), function(i, name) { 16743 16744 $.fn[name] = function(fn) { 16745 return fn ? this.bind(name, fn) : this.trigger(name); 16746 }; 16747 16748 // jQuery < 1.8 16749 // if ($.attrFn) { 16750 // $.attrFn[name] = true; 16751 // } 16752 }); 16753 16754 var tapSettings = { 16755 startEvent: 'touchstart.iTap', 16756 endEvent: 'touchend.iTap' 16757 }; 16758 16759 // tap Event: 16760 $.event.special.itap = { 16761 setup: function() { 16762 16763 var self = this, 16764 $self = $(this), 16765 start, stop; 16766 16767 $self.bind(tapSettings.startEvent, function(event) { 16768 start = getScrollXY(); 16769 16770 $self.one(tapSettings.endEvent, function(event) { 16771 stop = getScrollXY(); 16772 16773 var orgEvent = event || window.event; 16774 event = $.event.fix(orgEvent); 16775 event.type = "itap"; 16776 16777 if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event); 16778 16779 start = stop = undefined; 16780 }); 16781 }); 16782 }, 16783 16784 teardown: function() { 16785 $(this).unbind(tapSettings.startEvent); 16786 } 16787 }; 16788 }()); 16789 16790 16791 //Fullscreen API 16792 (function() { 16793 fullScreenApi = { 16794 supportsFullScreen: false, 16795 isFullScreen: function() { 16796 return false;
16797 }, 16798 requestFullScreen: function() {}, 16799 cancelFullScreen: function() {}, 16800 fullScreenEventName: '', 16801 prefix: '' 16802 }, 16803 browserPrefixes = 'webkit moz o ms khtml'.split(' '); 16804 16805 // check for native support 16806 if (typeof document.cancelFullScreen != 'undefined') { 16807 fullScreenApi.supportsFullScreen = true; 16808 } else { 16809 // check for fullscreen support by vendor prefix 16810 for (var i = 0, il = browserPrefixes.length; i < il; i++) { 16811 fullScreenApi.prefix = browserPrefixes[i]; 16812 16813 if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') { 16814 fullScreenApi.supportsFullScreen = true; 16815 16816 break; 16817 } 16818 } 16819 } 16820 16821 // update methods to do something useful 16822 if (fullScreenApi.supportsFullScreen) { 16823 fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; 16824 16825 fullScreenApi.isFullScreen = function() { 16826 switch (this.prefix) { 16827 case '': 16828 return document.fullScreen; 16829 case 'webkit': 16830 return document.webkitIsFullScreen; 16831 default: 16832 return document[this.prefix + 'FullScreen']; 16833 } 16834 } 16835 fullScreenApi.requestFullScreen = function(el) { 16836 return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen'](); 16837 } 16838 fullScreenApi.cancelFullScreen = function(el) { 16839 return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen'](); 16840 } 16841 } 16842 }()); 16843 16844 // Browser detect 16845 (function() { 16846 function uaMatch(ua) { 16847 ua = ua.toLowerCase(); 16848 16849 var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 16850 /(webkit)[ \/]([\w.]+)/.exec(ua) || 16851 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 16852 /(msie) ([\w.]+)/.exec(ua) || 16853 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; 16854 16855 return { 16856 browser: match[1] || "", 16857 version: match[2] || "0" 16858 }; 16859 } 16860 16861 var matched = uaMatch(navigator.userAgent); 16862 browser = {}; 16863 16864 if (matched.browser) { 16865 browser[matched.browser] = true; 16866 browser.version = matched.version; 16867 } 16868 16869 // Chrome is Webkit, but Webkit is also Safari. 16870 if (browser.chrome) { 16871 browser.webkit = true; 16872 } else if (browser.webkit) { 16873 browser.safari = true; 16874 } 16875 }()); 16876 16877 // Feature detects 16878 (function() { 16879 var prefixes = ['', 'webkit', 'moz', 'ms', 'o']; 16880 var el = document.createElement('div'); 16881 16882 function testProp(prop) { 16883 for (var p = 0, pl = prefixes.length; p < pl; p++) { 16884 var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop; 16885 if (el.style[prefixedProp] !== undefined) { 16886 return prefixedProp; 16887 } 16888 } 16889 } 16890 16891 // Global support indicators 16892 transform = testProp('transform') || ''; 16893 gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : ''; 16894 }()); 16895 16896 16897 /* 16898 PluginDetect v0.7.9 16899 www.pinlady.net/PluginDetect/license/ 16900 [ getVersion onWindowLoaded BetterIE ] 16901 [ Flash QuickTime Shockwave ] 16902 */ 16903 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;
16903d++){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);
16903d.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)}
16903c.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;
16903if(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(); 16904 16905 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)}; 16906 16907 16908 /* 16909 jQuery hashchange event v1.3 16910 https://github.com/cowboy/jquery-hashchange 16911 Copyright (c) 2010 "Cowboy" Ben Alman 16912 Dual licensed under the MIT and GPL licenses. 16913 */ 16914 (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= 16915 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|| 16916 "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;
16916a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})(); 16917 16918 if (!Array.prototype.filter) { 16919 Array.prototype.filter = function(fun /*, thisp */ ) { 16920 "use strict"; 16921 16922 if (this == null) 16923 throw new TypeError(); 16924 16925 var t = Object(this); 16926 var len = t.length >>> 0; 16927 if (typeof fun != "function") 16928 throw new TypeError(); 16929 16930 var res = []; 16931 var thisp = arguments[1]; 16932 for (var i = 0; i < len; i++) { 16933 if (i in t) { 16934 var val = t[i]; // in case fun mutates this 16935 if (fun.call(thisp, val, i, t)) 16936 res.push(val); 16937 } 16938 } 16939 16940 return res; 16941 }; 16942 } 16943 16944 if (!Array.prototype.indexOf) { 16945 Array.prototype.indexOf = function(searchElement, fromIndex) { 16946 var k; 16947 16948 if (this == null) { 16949 throw new TypeError('"this" is null or not defined'); 16950 } 16951 16952 var O = Object(this); 16953 16954 var len = O.length >>> 0; 16955 16956 if (len === 0) { 16957 return -1; 16958 } 16959 16960 var n = +fromIndex || 0; 16961 16962 if (abs(n) === Infinity) { 16963 n = 0; 16964 } 16965 16966 if (n >= len) { 16967 return -1; 16968 } 16969 16970 k = max(n >= 0 ? n : len - abs(n), 0); 16971 16972 while (k < len) { 16973 var kValue; 16974 if (k in O && O[k] === searchElement) { 16975 return k; 16976 } 16977 k++; 16978 } 16979 return -1; 16980 }; 16981 } 16982 16983 if (!Array.prototype.lastIndexOf) { 16984 Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) { 16985 "use strict"; 16986 16987 if (this == null) 16988 throw new TypeError(); 16989 16990 var t = Object(this); 16991 var len = t.length >>> 0; 16992 if (len === 0) 16993 return -1; 16994 16995 var n = len; 16996 if (arguments.length > 1) { 16997 n = Number(arguments[1]); 16998 if (n != n) 16999 n = 0; 17000 else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) 17001 n = (n > 0 || -1) * floor(abs(n)); 17002 } 17003 17004 var k = n >= 0 ? min(n, len - 1) : len - abs(n); 17005 17006 for (; k >= 0; k--) { 17007 if (k in t && t[k] === searchElement) 17008 return k; 17009 } 17010 return -1; 17011 }; 17012 } 17013})(jQuery, this); 17014 17015/*! 17016 * lightgallery | 2.5.0 | June 13th 2022 17017 * http://www.lightgalleryjs.com/ 17018 * Copyright (c) 2020 Sachin Neravath; 17019 * @license GPLv3 17020 */ 17021 17022(function (global, factory) { 17023 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 17024 typeof define === 'function' && define.amd ? define(factory) : 17025 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lightGallery = factory()); 17026}(this, (function () { 'use strict'; 17027 17028 /*! ***************************************************************************** 17029 Copyright (c) Microsoft Corporation. 17030 17031 Permission to use, copy, modify, and/or distribute this software for any 17032 purpose with or without fee is hereby granted. 17033 17034 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 17035 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 17036 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 17037 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17038 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 17039 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17040 PERFORMANCE OF THIS SOFTWARE. 17041 ***************************************************************************** */ 17042 17043 var __assign = function() { 17044 __assign = Object.assign || function __assign(t) { 17045 for (var s, i = 1, n = arguments.length; i < n; i++) { 17046 s = arguments[i]; 17047 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 17048 } 17049 return t; 17050 }; 17051 return __assign.apply(this, arguments); 17052 }; 17053 17054 function __spreadArrays() { 17055 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 17056 for (var r = Array(s), k = 0, i = 0; i < il; i++) 17057 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 17058 r[k] = a[j]; 17059 return r; 17060 } 17061 17062 /** 17063 * List of lightGallery events 17064 * All events should be documented here 17065 * Below interfaces are used to build the website documentations 17066 * */ 17067 var lGEvents = { 17068 afterAppendSlide: 'lgAfterAppendSlide', 17069 init: 'lgInit', 17070 hasVideo: 'lgHasVideo', 17071 containerResize: 'lgContainerResize', 17072 updateSlides: 'lgUpdateSlides', 17073 afterAppendSubHtml: 'lgAfterAppendSubHtml', 17074 beforeOpen: 'lgBeforeOpen', 17075 afterOpen: 'lgAfterOpen', 17076 slideItemLoad: 'lgSlideItemLoad', 17077 beforeSlide: 'lgBeforeSlide', 17078 afterSlide: 'lgAfterSlide', 17079 posterClick: 'lgPosterClick', 17080 dragStart: 'lgDragStart', 17081 dragMove: 'lgDragMove', 17082 dragEnd: 'lgDragEnd', 17083 beforeNextSlide: 'lgBeforeNextSlide', 17084 beforePrevSlide: 'lgBeforePrevSlide', 17085 beforeClose: 'lgBeforeClose', 17086 afterClose: 'lgAfterClose', 17087 rotateLeft: 'lgRotateLeft', 17088 rotateRight: 'lgRotateRight', 17089 flipHorizontal: 'lgFlipHorizontal', 17090 flipVertical: 'lgFlipVertical', 17091 autoplay: 'lgAutoplay', 17092 autoplayStart: 'lgAutoplayStart', 17093 autoplayStop: 'lgAutoplayStop', 17094 }; 17095 17096 var lightGalleryCoreSettings = { 17097 mode: 'lg-slide', 17098 easing: 'ease', 17099 speed: 400, 17100 licenseKey: '0000-0000-000-0000', 17101 height: '100%', 17102 width: '100%', 17103 addClass: '', 17104 startClass: 'lg-start-zoom', 17105 backdropDuration: 300, 17106 container: '', 17107 startAnimationDuration: 400, 17108 zoomFromOrigin: true, 17109 hideBarsDelay: 0, 17110 showBarsAfter: 10000, 17111 slideDelay: 0, 17112 supportLegacyBrowser: true, 17113 allowMediaOverlap: false, 17114 videoMaxSize: '1280-720', 17115 loadYouTubePoster: true, 17116 defaultCaptionHeight: 0, 17117 ariaLabelledby: '', 17118 ariaDescribedby: '', 17119 resetScrollPosition: true, 17120 hideScrollbar: false, 17121 closable: true, 17122 swipeToClose: true, 17123 closeOnTap: true, 17124 showCloseIcon: true, 17125 showMaximizeIcon: false, 17126 loop: true, 17127 escKey: true, 17128 keyPress: true, 17129 trapFocus: true, 17130 controls: true, 17131 slideEndAnimation: true, 17132 hideControlOnEnd: false,
vendor: 15,066 bytes, lines 17133-17680
17133 mousewheel: false, 17134 getCaptionFromTitleOrAlt: true, 17135 appendSubHtmlTo: '.lg-sub-html', 17136 subHtmlSelectorRelative: false, 17137 preload: 2, 17138 numberOfSlideItemsInDom: 10, 17139 selector: '', 17140 selectWithin: '', 17141 nextHtml: '', 17142 prevHtml: '', 17143 index: 0, 17144 iframeWidth: '100%', 17145 iframeHeight: '100%', 17146 iframeMaxWidth: '100%', 17147 iframeMaxHeight: '100%', 17148 download: true, 17149 counter: true, 17150 appendCounterTo: '.lg-toolbar', 17151 swipeThreshold: 50, 17152 enableSwipe: true, 17153 enableDrag: true, 17154 dynamic: false, 17155 dynamicEl: [], 17156 extraProps: [], 17157 exThumbImage: '', 17158 isMobile: undefined, 17159 mobileSettings: { 17160 controls: false, 17161 showCloseIcon: false, 17162 download: false, 17163 }, 17164 plugins: [], 17165 strings: { 17166 closeGallery: 'Close gallery', 17167 toggleMaximize: 'Toggle maximize', 17168 previousSlide: 'Previous slide', 17169 nextSlide: 'Next slide', 17170 download: 'Download', 17171 playVideo: 'Play video', 17172 }, 17173 }; 17174 17175 function initLgPolyfills() { 17176 (function () { 17177 if (typeof window.CustomEvent === 'function') 17178 return false; 17179 function CustomEvent(event, params) { 17180 params = params || { 17181 bubbles: false, 17182 cancelable: false, 17183 detail: null, 17184 }; 17185 var evt = document.createEvent('CustomEvent'); 17186 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 17187 return evt; 17188 } 17189 window.CustomEvent = CustomEvent; 17190 })(); 17191 (function () { 17192 if (!Element.prototype.matches) { 17193 Element.prototype.matches = 17194 Element.prototype.msMatchesSelector || 17195 Element.prototype.webkitMatchesSelector; 17196 } 17197 })(); 17198 } 17199 var lgQuery = /** @class */ (function () { 17200 function lgQuery(selector) { 17201 this.cssVenderPrefixes = [ 17202 'TransitionDuration', 17203 'TransitionTimingFunction', 17204 'Transform', 17205 'Transition', 17206 ]; 17207 this.selector = this._getSelector(selector); 17208 this.firstElement = this._getFirstEl(); 17209 return this; 17210 } 17211 lgQuery.generateUUID = function () { 17212 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 17213 var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8; 17214 return v.toString(16); 17215 }); 17216 }; 17217 lgQuery.prototype._getSelector = function (selector, context) { 17218 if (context === void 0) { context = document; } 17219 if (typeof selector !== 'string') { 17220 return selector; 17221 } 17222 context = context || document; 17223 var fl = selector.substring(0, 1); 17224 if (fl === '#') { 17225 return context.querySelector(selector); 17226 } 17227 else { 17228 return context.querySelectorAll(selector); 17229 } 17230 }; 17231 lgQuery.prototype._each = function (func) { 17232 if (!this.selector) { 17233 return this; 17234 } 17235 if (this.selector.length !== undefined) { 17236 [].forEach.call(this.selector, func); 17237 } 17238 else { 17239 func(this.selector, 0); 17240 } 17241 return this; 17242 }; 17243 lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) { 17244 // prettier-ignore 17245 var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) { 17246 return group1.toUpperCase(); 17247 }); 17248 if (this.cssVenderPrefixes.indexOf(property) !== -1) { 17249 el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value; 17250 el.style['webkit' + property] = value; 17251 el.style['moz' + property] = value; 17252 el.style['ms' + property] = value; 17253 el.style['o' + property] = value; 17254 } 17255 else { 17256 el.style[property] = value; 17257 } 17258 }; 17259 lgQuery.prototype._getFirstEl = function () { 17260 if (this.selector && this.selector.length !== undefined) { 17261 return this.selector[0]; 17262 } 17263 else { 17264 return this.selector; 17265 } 17266 }; 17267 lgQuery.prototype.isEventMatched = function (event, eventName) { 17268 var eventNamespace = eventName.split('.'); 17269 return event 17270 .split('.') 17271 .filter(function (e) { return e; }) 17272 .every(function (e) { 17273 return eventNamespace.indexOf(e) !== -1; 17274 }); 17275 }; 17276 lgQuery.prototype.attr = function (attr, value) { 17277 if (value === undefined) { 17278 if (!this.firstElement) { 17279 return ''; 17280 } 17281 return this.firstElement.getAttribute(attr); 17282 } 17283 this._each(function (el) { 17284 el.setAttribute(attr, value); 17285 }); 17286 return this; 17287 }; 17288 lgQuery.prototype.find = function (selector) { 17289 return $LG(this._getSelector(selector, this.selector)); 17290 }; 17291 lgQuery.prototype.first = function () { 17292 if (this.selector && this.selector.length !== undefined) { 17293 return $LG(this.selector[0]); 17294 } 17295 else { 17296 return $LG(this.selector); 17297 } 17298 }; 17299 lgQuery.prototype.eq = function (index) { 17300 return $LG(this.selector[index]); 17301 }; 17302 lgQuery.prototype.parent = function () { 17303 return $LG(this.selector.parentElement); 17304 }; 17305 lgQuery.prototype.get = function () { 17306 return this._getFirstEl(); 17307 }; 17308 lgQuery.prototype.removeAttr = function (attributes) { 17309 var attrs = attributes.split(' '); 17310 this._each(function (el) { 17311 attrs.forEach(function (attr) { return el.removeAttribute(attr); }); 17312 }); 17313 return this; 17314 }; 17315 lgQuery.prototype.wrap = function (className) { 17316 if (!this.firstElement) { 17317 return this; 17318 } 17319 var wrapper = document.createElement('div'); 17320 wrapper.className = className; 17321 this.firstElement.parentNode.insertBefore(wrapper, this.firstElement); 17322 this.firstElement.parentNode.removeChild(this.firstElement); 17323 wrapper.appendChild(this.firstElement); 17324 return this; 17325 }; 17326 lgQuery.prototype.addClass = function (classNames) { 17327 if (classNames === void 0) { classNames = ''; } 17328 this._each(function (el) { 17329 // IE doesn't support multiple arguments 17330 classNames.split(' ').forEach(function (className) { 17331 if (className) { 17332 el.classList.add(className); 17333 } 17334 }); 17335 }); 17336 return this; 17337 }; 17338 lgQuery.prototype.removeClass = function (classNames) { 17339 this._each(function (el) { 17340 // IE doesn't support multiple arguments 17341 classNames.split(' ').forEach(function (className) { 17342 if (className) { 17343 el.classList.remove(className); 17344 } 17345 }); 17346 }); 17347 return this; 17348 }; 17349 lgQuery.prototype.hasClass = function (className) { 17350 if (!this.firstElement) { 17351 return false; 17352 } 17353 return this.firstElement.classList.contains(className); 17354 }; 17355 lgQuery.prototype.hasAttribute = function (attribute) { 17356 if (!this.firstElement) { 17357 return false; 17358 } 17359 return this.firstElement.hasAttribute(attribute); 17360 }; 17361 lgQuery.prototype.toggleClass = function (className) { 17362 if (!this.firstElement) { 17363 return this; 17364 } 17365 if (this.hasClass(className)) { 17366 this.removeClass(className); 17367 } 17368 else { 17369 this.addClass(className); 17370 } 17371 return this; 17372 }; 17373 lgQuery.prototype.css = function (property, value) { 17374 var _this = this; 17375 this._each(function (el) { 17376 _this._setCssVendorPrefix(el, property, value); 17377 }); 17378 return this; 17379 }; 17380 // Need to pass separate namespaces for separate elements 17381 lgQuery.prototype.on = function (events, listener) { 17382 var _this = this; 17383 if (!this.selector) { 17384 return this; 17385 } 17386 events.split(' ').forEach(function (event) { 17387 if (!Array.isArray(lgQuery.eventListeners[event])) { 17388 lgQuery.eventListeners[event] = []; 17389 } 17390 lgQuery.eventListeners[event].push(listener); 17391 _this.selector.addEventListener(event.split('.')[0], listener); 17392 }); 17393 return this; 17394 }; 17395 // @todo - test this 17396 lgQuery.prototype.once = function (event, listener) { 17397 var _this = this; 17398 this.on(event, function () { 17399 _this.off(event); 17400 listener(event); 17401 }); 17402 return this; 17403 }; 17404 lgQuery.prototype.off = function (event) { 17405 var _this = this; 17406 if (!this.selector) { 17407 return this; 17408 } 17409 Object.keys(lgQuery.eventListeners).forEach(function (eventName) { 17410 if (_this.isEventMatched(event, eventName)) { 17411 lgQuery.eventListeners[eventName].forEach(function (listener) { 17412 _this.selector.removeEventListener(eventName.split('.')[0], listener); 17413 }); 17414 lgQuery.eventListeners[eventName] = []; 17415 } 17416 }); 17417 return this; 17418 }; 17419 lgQuery.prototype.trigger = function (event, detail) { 17420 if (!this.firstElement) { 17421 return this; 17422 } 17423 var customEvent = new CustomEvent(event.split('.')[0], { 17424 detail: detail || null, 17425 }); 17426 this.firstElement.dispatchEvent(customEvent); 17427 return this; 17428 }; 17429 // Does not support IE 17430 lgQuery.prototype.load = function (url) { 17431 var _this = this; 17432 fetch(url) 17433 .then(function (res) { return res.text(); }) 17434 .then(function (html) { 17435 _this.selector.innerHTML = html; 17436 }); 17437 return this; 17438 }; 17439 lgQuery.prototype.html = function (html) { 17440 if (html === undefined) { 17441 if (!this.firstElement) { 17442 return ''; 17443 } 17444 return this.firstElement.innerHTML; 17445 } 17446 this._each(function (el) { 17447 el.innerHTML = html; 17448 }); 17449 return this; 17450 }; 17451 lgQuery.prototype.append = function (html) { 17452 this._each(function (el) { 17453 if (typeof html === 'string') { 17454 el.insertAdjacentHTML('beforeend', html); 17455 } 17456 else { 17457 el.appendChild(html); 17458 } 17459 }); 17460 return this; 17461 }; 17462 lgQuery.prototype.prepend = function (html) { 17463 this._each(function (el) { 17464 el.insertAdjacentHTML('afterbegin', html); 17465 }); 17466 return this; 17467 }; 17468 lgQuery.prototype.remove = function () { 17469 this._each(function (el) { 17470 el.parentNode.removeChild(el); 17471 }); 17472 return this; 17473 }; 17474 lgQuery.prototype.empty = function () { 17475 this._each(function (el) { 17476 el.innerHTML = ''; 17477 }); 17478 return this; 17479 }; 17480 lgQuery.prototype.scrollTop = function (scrollTop) { 17481 if (scrollTop !== undefined) { 17482 document.body.scrollTop = scrollTop; 17483 document.documentElement.scrollTop = scrollTop; 17484 return this; 17485 } 17486 else { 17487 return (window.pageYOffset || 17488 document.documentElement.scrollTop || 17489 document.body.scrollTop || 17490 0); 17491 } 17492 }; 17493 lgQuery.prototype.scrollLeft = function (scrollLeft) { 17494 if (scrollLeft !== undefined) { 17495 document.body.scrollLeft = scrollLeft; 17496 document.documentElement.scrollLeft = scrollLeft; 17497 return this; 17498 } 17499 else { 17500 return (window.pageXOffset || 17501 document.documentElement.scrollLeft || 17502 document.body.scrollLeft || 17503 0); 17504 } 17505 }; 17506 lgQuery.prototype.offset = function () { 17507 if (!this.firstElement) { 17508 return { 17509 left: 0, 17510 top: 0, 17511 }; 17512 } 17513 var rect = this.firstElement.getBoundingClientRect(); 17514 var bodyMarginLeft = $LG('body').style().marginLeft; 17515 // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value 17516 return { 17517 left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(), 17518 top: rect.top + this.scrollTop(), 17519 }; 17520 }; 17521 lgQuery.prototype.style = function () { 17522 if (!this.firstElement) { 17523 return {}; 17524 } 17525 return (this.firstElement.currentStyle || 17526 window.getComputedStyle(this.firstElement)); 17527 }; 17528 // Width without padding and border even if box-sizing is used. 17529 lgQuery.prototype.width = function () { 17530 var style = this.style(); 17531 return (this.firstElement.clientWidth - 17532 parseFloat(style.paddingLeft) - 17533 parseFloat(style.paddingRight)); 17534 }; 17535 // Height without padding and border even if box-sizing is used. 17536 lgQuery.prototype.height = function () { 17537 var style = this.style(); 17538 return (this.firstElement.clientHeight - 17539 parseFloat(style.paddingTop) - 17540 parseFloat(style.paddingBottom)); 17541 }; 17542 lgQuery.eventListeners = {}; 17543 return lgQuery; 17544 }()); 17545 function $LG(selector) { 17546 initLgPolyfills(); 17547 return new lgQuery(selector); 17548 } 17549 17550 var defaultDynamicOptions = [ 17551 'src', 17552 'sources', 17553 'subHtml', 17554 'subHtmlUrl', 17555 'html', 17556 'video', 17557 'poster', 17558 'slideName', 17559 'responsive', 17560 'srcset', 17561 'sizes', 17562 'iframe', 17563 'downloadUrl', 17564 'download', 17565 'width', 17566 'facebookShareUrl', 17567 'tweetText', 17568 'iframeTitle', 17569 'twitterShareUrl', 17570 'pinterestShareUrl', 17571 'pinterestText', 17572 'fbHtml', 17573 'disqusIdentifier', 17574 'disqusUrl', 17575 ]; 17576 // Convert html data-attribute to camalcase 17577 function convertToData(attr) { 17578 // FInd a way for lgsize 17579 if (attr === 'href') { 17580 return 'src'; 17581 } 17582 attr = attr.replace('data-', ''); 17583 attr = attr.charAt(0).toLowerCase() + attr.slice(1); 17584 attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); 17585 return attr; 17586 } 17587 var utils = { 17588 /** 17589 * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option 17590 */ 17591 //Uncode edit ##START## 17592 getSize: function (el, container, spacing, defaultLgSize, galleryItem) { 17593 // getSize: function (el, container, spacing, defaultLgSize) { 17594 //Uncode edit ##END## 17595 if (spacing === void 0) { spacing = 0; } 17596 var LGel = $LG(el); 17597 var lgSize = LGel.attr('data-lg-size') || defaultLgSize; 17598 //Uncode edit ##START## 17599 if ( typeof galleryItem.size && galleryItem.size != null ) { 17600 lgSize = galleryItem.size; 17601 } 17602 //Uncode edit ##END## 17603 if (!lgSize) { 17604 return; 17605 } 17606 var isResponsiveSizes = lgSize.split(','); 17607 // if at-least two viewport sizes are available 17608 if (isResponsiveSizes[1]) { 17609 var wWidth = window.innerWidth; 17610 for (var i = 0; i < isResponsiveSizes.length; i++) { 17611 var size_1 = isResponsiveSizes[i]; 17612 var responsiveWidth = parseInt(size_1.split('-')[2], 10); 17613 if (responsiveWidth > wWidth) { 17614 lgSize = size_1; 17615 break; 17616 } 17617 // take last item as last option 17618 if (i === isResponsiveSizes.length - 1) { 17619 lgSize = size_1; 17620 } 17621 } 17622 } 17623 var size = lgSize.split('-'); 17624 var width = parseInt(size[0], 10); 17625 var height = parseInt(size[1], 10); 17626 var cWidth = container.width(); 17627 var cHeight = container.height() - spacing; 17628 var maxWidth = Math.min(cWidth, width); 17629 var maxHeight = Math.min(cHeight, height); 17630 var ratio = Math.min(maxWidth / width, maxHeight / height); 17631 return { width: width * ratio, height: height * ratio }; 17632 }, 17633 /** 17634 * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option 17635 * @param {jQuery Element} 17636 * @returns {String} Transform CSS string 17637 */ 17638 getTransform: function (el, container, top, bottom, imageSize) { 17639 if (!imageSize) { 17640 return; 17641 } 17642 var LGel = $LG(el).find('img').first(); 17643 if (!LGel.get()) { 17644 return; 17645 } 17646 var containerRect = container.get().getBoundingClientRect(); 17647 var wWidth = containerRect.width; 17648 // using innerWidth to include mobile safari bottom bar 17649 var wHeight = container.height() - (top + bottom); 17650 var elWidth = LGel.width(); 17651 var elHeight = LGel.height(); 17652 var elStyle = LGel.style(); 17653 var x = (wWidth - elWidth) / 2 - 17654 LGel.offset().left + 17655 (parseFloat(elStyle.paddingLeft) || 0) + 17656 (parseFloat(elStyle.borderLeft) || 0) + 17657 $LG(window).scrollLeft() + 17658 containerRect.left; 17659 var y = (wHeight - elHeight) / 2 - 17660 LGel.offset().top + 17661 (parseFloat(elStyle.paddingTop) || 0) + 17662 (parseFloat(elStyle.borderTop) || 0) + 17663 $LG(window).scrollTop() + 17664 top; 17665 var scX = elWidth / imageSize.width; 17666 var scY = elHeight / imageSize.height; 17667 var transform = 'translate3d(' + 17668 (x *= -1) + 17669 'px, ' + 17670 (y *= -1) + 17671 'px, 0) scale3d(' + 17672 scX + 17673 ', ' + 17674 scY + 17675 ', 1)'; 17676 return transform; 17677 }, 17678 getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) { 17679 var title = iframeTitle ? 'title="' + iframeTitle + '"' : ''; 17680 return "<div class=\"lg-video-cont lg-has-iframe\" style=\"width:"
vendor: 2,803 bytes, lines 17680-17752
17680+ iframeWidth + "; max-width:" + iframeMaxWidth + "; height: " + iframeHeight + "; max-height:" + iframeMaxHeight + "\">\n <iframe class=\"lg-object\" frameborder=\"0\" " + title + " src=\"" + src + "\" allowfullscreen=\"true\"></iframe>\n </div>"; 17681 }, 17682 getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) { 17683 var srcsetAttr = srcset ? "srcset=\"" + srcset + "\"" : ''; 17684 var sizesAttr = sizes ? "sizes=\"" + sizes + "\"" : ''; 17685 var imgMarkup = "<img " + altAttr + " " + srcsetAttr + " " + sizesAttr + " class=\"lg-object lg-image\" data-index=\"" + index + "\" src=\"" + src + "\" />"; 17686 var sourceTag = ''; 17687 if (sources) { 17688 var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources; 17689 sourceTag = sourceObj.map(function (source) { 17690 var attrs = ''; 17691 Object.keys(source).forEach(function (key) { 17692 // Do not remove the first space as it is required to separate the attributes 17693 attrs += " " + key + "=\"" + source[key] + "\""; 17694 }); 17695 return "<source " + attrs + "></source>"; 17696 }); 17697 } 17698 return "" + sourceTag + imgMarkup; 17699 }, 17700 // Get src from responsive src 17701 getResponsiveSrc: function (srcItms) { 17702 var rsWidth = []; 17703 var rsSrc = []; 17704 var src = ''; 17705 for (var i = 0; i < srcItms.length; i++) { 17706 var _src = srcItms[i].split(' '); 17707 // Manage empty space 17708 if (_src[0] === '') { 17709 _src.splice(0, 1); 17710 } 17711 rsSrc.push(_src[0]); 17712 rsWidth.push(_src[1]); 17713 } 17714 var wWidth = window.innerWidth; 17715 for (var j = 0; j < rsWidth.length; j++) { 17716 if (parseInt(rsWidth[j], 10) > wWidth) { 17717 src = rsSrc[j]; 17718 break; 17719 } 17720 } 17721 return src; 17722 }, 17723 isImageLoaded: function (img) { 17724 if (!img) 17725 return false; 17726 // During the onload event, IE correctly identifies any images that 17727 // werenât downloaded as not complete. Others should too. Gecko-based 17728 // browsers act like NS4 in that they report this incorrectly. 17729 if (!img.complete) { 17730 return false; 17731 } 17732 // However, they do have two very useful properties: naturalWidth and 17733 // naturalHeight. These give the true size of the image. If it failed 17734 // to load, either of these should be zero. 17735 if (img.naturalWidth === 0) { 17736 return false; 17737 } 17738 // No other way of checking: assume itâs ok. 17739 return true; 17740 }, 17741 getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) { 17742 var videoClass = ''; 17743 if (_isVideo && _isVideo.youtube) { 17744 videoClass = 'lg-has-youtube'; 17745 } 17746 else if (_isVideo && _isVideo.vimeo) { 17747 videoClass = 'lg-has-vimeo'; 17748 } 17749 else { 17750 videoClass = 'lg-has-html5'; 17751 } 17752 return "<div class=\"lg-video-cont " + videoClass + "\" style=\"" + videoContStyle + "\">\n <div class=\"lg-video-play-button\">
vendor: 5,030 bytes, lines 17752-17863
17752\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>"; 17753 }, 17754 getFocusableElements: function (container) { 17755 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])'); 17756 var visibleElements = [].filter.call(elements, function (element) { 17757 var style = window.getComputedStyle(element); 17758 return style.display !== 'none' && style.visibility !== 'hidden'; 17759 }); 17760 return visibleElements; 17761 }, 17762 /** 17763 * @desc Create dynamic elements array from gallery items when dynamic option is false 17764 * It helps to avoid frequent DOM interaction 17765 * and avoid multiple checks for dynamic elments 17766 * 17767 * @returns {Array} dynamicEl 17768 */ 17769 getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) { 17770 var dynamicElements = []; 17771 var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps); 17772 [].forEach.call(items, function (item) { 17773 var dynamicEl = {}; 17774 for (var i = 0; i < item.attributes.length; i++) { 17775 var attr = item.attributes[i]; 17776 if (attr.specified) { 17777 var dynamicAttr = convertToData(attr.name); 17778 var label = ''; 17779 if (availableDynamicOptions.indexOf(dynamicAttr) > -1) { 17780 label = dynamicAttr; 17781 } 17782 if (label) { 17783 dynamicEl[label] = attr.value; 17784 } 17785 } 17786 } 17787 var currentItem = $LG(item); 17788 var alt = currentItem.find('img').first().attr('alt'); 17789 var title = currentItem.attr('title'); 17790 //Uncode edit ##START## 17791 // var thumb = exThumbImage 17792 var thumb = exThumbImage && currentItem.attr(exThumbImage) 17793 //Uncode edit ##END## 17794 ? currentItem.attr(exThumbImage) 17795 : currentItem.find('img').first().attr('src'); 17796 dynamicEl.thumb = thumb; 17797 //Uncode edit ##START## 17798 if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) { 17799 // dynamicEl.subHtml = title || alt || ''; 17800 dynamicEl.subHtml = title || ''; 17801 } 17802 // dynamicEl.alt = alt || title || ''; 17803 dynamicEl.alt = title || ''; 17804 var inlineType = currentItem.attr('data-type'); 17805 dynamicEl.type = inlineType; 17806 //Uncode edit ##END## 17807 dynamicElements.push(dynamicEl); 17808 }); 17809 return dynamicElements; 17810 }, 17811 isMobile: function () { 17812 return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); 17813 }, 17814 /** 17815 * @desc Check the given src is video 17816 * @param {String} src 17817 * @return {Object} video type 17818 * Ex:{ youtube : ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] } 17819 * 17820 * @todo - this information can be moved to dynamicEl to avoid frequent calls 17821 */ 17822 isVideo: function (src, isHTML5VIdeo, index) { 17823 if (!src || src.match(/\.(mp4|m4v|ogg|webm)$/) ) { 17824 if (isHTML5VIdeo) { 17825 return { 17826 html5: true, 17827 }; 17828 } 17829 else { 17830 console.warn('lightGallery :- data-src is not provided on slide item ' + 17831 (index + 1) + 17832 '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/'); 17833 return; 17834 } 17835 } 17836 var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)([\&|?][\S]*)*/i); 17837 var vimeo = src.match(/\/\/(?:www\.)?(?:player\.)?vimeo.com\/(?:video\/)?([0-9a-z\-_]+)(.*)?/i); 17838 var wistia = src.match(/https?:\/\/(.+)?(wistia\.com|wi\.st)\/(medias|embed)\/([0-9a-z\-_]+)(.*)/); 17839 if (youtube) { 17840 return { 17841 youtube: youtube, 17842 }; 17843 } 17844 else if (vimeo) { 17845 return { 17846 vimeo: vimeo, 17847 }; 17848 } 17849 else if (wistia) { 17850 return { 17851 wistia: wistia, 17852 }; 17853 } 17854 }, 17855 }; 17856 17857 // @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio 17858 // @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html 17859 // Unique id for each gallery 17860 var lgId = 0; 17861 var LightGallery = /** @class */ (function () { 17862 function LightGallery(element, options) { 17863 this.lgOpened = false;
vendor: 4,563 bytes, lines 17864-17998
17864 this.index = 0; 17865 // lightGallery modules 17866 this.plugins = []; 17867 // false when lightGallery load first slide content; 17868 this.lGalleryOn = false; 17869 // True when a slide animation is in progress 17870 this.lgBusy = false; 17871 this.currentItemsInDom = []; 17872 // Scroll top value before lightGallery is opened 17873 this.prevScrollTop = 0; 17874 this.bodyPaddingRight = 0; 17875 this.isDummyImageRemoved = false; 17876 this.dragOrSwipeEnabled = false; 17877 this.mediaContainerPosition = { 17878 top: 0, 17879 bottom: 0, 17880 }; 17881 if (!element) { 17882 return this; 17883 } 17884 lgId++; 17885 this.lgId = lgId; 17886 this.el = element; 17887 this.LGel = $LG(element); 17888 this.generateSettings(options); 17889 this.buildModules(); 17890 // When using dynamic mode, ensure dynamicEl is an array 17891 if (this.settings.dynamic && 17892 this.settings.dynamicEl !== undefined && 17893 !Array.isArray(this.settings.dynamicEl)) { 17894 throw 'When using dynamic mode, you must also define dynamicEl as an Array.'; 17895 } 17896 this.galleryItems = this.getItems(); 17897 this.normalizeSettings(); 17898 // Gallery items 17899 this.init(); 17900 //Uncode edit ##START## 17901 // this.validateLicense(); 17902 //Uncode edit ##END## 17903 return this; 17904 } 17905 LightGallery.prototype.generateSettings = function (options) { 17906 // lightGallery settings 17907 this.settings = __assign(__assign({}, lightGalleryCoreSettings), options); 17908 if (this.settings.isMobile && 17909 typeof this.settings.isMobile === 'function' 17910 ? this.settings.isMobile() 17911 : utils.isMobile()) { 17912 var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings); 17913 this.settings = __assign(__assign({}, this.settings), mobileSettings); 17914 } 17915 }; 17916 LightGallery.prototype.normalizeSettings = function () { 17917 if (this.settings.slideEndAnimation) { 17918 this.settings.hideControlOnEnd = false; 17919 } 17920 if (!this.settings.closable) { 17921 this.settings.swipeToClose = false; 17922 } 17923 // And reset it on close to get the correct value next time 17924 this.zoomFromOrigin = this.settings.zoomFromOrigin; 17925 // At the moment, Zoom from image doesn't support dynamic options 17926 // @todo add zoomFromOrigin support for dynamic images 17927 if (this.settings.dynamic) { 17928 this.zoomFromOrigin = false; 17929 } 17930 if (!this.settings.container) { 17931 this.settings.container = document.body; 17932 } 17933 // settings.preload should not be grater than $item.length 17934 this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length); 17935 }; 17936 LightGallery.prototype.init = function () { 17937 var _this = this; 17938 this.addSlideVideoInfo(this.galleryItems); 17939 this.buildStructure(); 17940 this.LGel.trigger(lGEvents.init, { 17941 instance: this, 17942 }); 17943 if (this.settings.keyPress) { 17944 this.keyPress(); 17945 } 17946 setTimeout(function () { 17947 _this.enableDrag(); 17948 _this.enableSwipe(); 17949 _this.triggerPosterClick(); 17950 }, 50); 17951 this.arrow(); 17952 if (this.settings.mousewheel) { 17953 this.mousewheel(); 17954 } 17955 if (!this.settings.dynamic) { 17956 this.openGalleryOnItemClick(); 17957 } 17958 }; 17959 LightGallery.prototype.openGalleryOnItemClick = function () { 17960 var _this = this; 17961 var _loop_1 = function (index) { 17962 var element = this_1.items[index]; 17963 var $element = $LG(element); 17964 // Using different namespace for click because click event should not unbind if selector is same object('this') 17965 // @todo manage all event listners - should have namespace that represent element 17966 var uuid = lgQuery.generateUUID(); 17967 $element 17968 .attr('data-lg-id', uuid) 17969 .on("click.lgcustom-item-" + uuid, function (e) { 17970 e.preventDefault(); 17971 var currentItemIndex = _this.settings.index || index; 17972 _this.openGallery(currentItemIndex, element); 17973 }); 17974 }; 17975 var this_1 = this; 17976 // Using for loop instead of using bubbling as the items can be any html element. 17977 for (var index = 0; index < this.items.length; index++) { 17978 _loop_1(index); 17979 } 17980 }; 17981 /** 17982 * Module constructor 17983 * Modules are build incrementally. 17984 * Gallery should be opened only once all the modules are initialized. 17985 * use moduleBuildTimeout to make sure this 17986 */ 17987 LightGallery.prototype.buildModules = function () { 17988 var _this = this; 17989 this.settings.plugins.forEach(function (plugin) { 17990 _this.plugins.push(new plugin(_this, $LG)); 17991 }); 17992 }; 17993 LightGallery.prototype.validateLicense = function () { 17994 if (!this.settings.licenseKey) { 17995 console.warn('Please provide a valid license key'); 17996 } 17997 else if (this.settings.licenseKey === '0000-0000-000-0000') { 17998 console.warn("lightGallery: " + this.settings.licenseKey + " license key is not val
vendor: 17,473 bytes, lines 17998-18412
17998id for production use"); 17999 } 18000 }; 18001 LightGallery.prototype.getSlideItem = function (index) { 18002 return $LG(this.getSlideItemId(index)); 18003 }; 18004 LightGallery.prototype.getSlideItemId = function (index) { 18005 return "#lg-item-" + this.lgId + "-" + index; 18006 }; 18007 LightGallery.prototype.getIdName = function (id) { 18008 return id + "-" + this.lgId; 18009 }; 18010 LightGallery.prototype.getElementById = function (id) { 18011 return $LG("#" + this.getIdName(id)); 18012 }; 18013 LightGallery.prototype.manageSingleSlideClassName = function () { 18014 if (this.galleryItems.length < 2) { 18015 this.outer.addClass('lg-single-item'); 18016 } 18017 else { 18018 this.outer.removeClass('lg-single-item'); 18019 } 18020 }; 18021 LightGallery.prototype.buildStructure = function () { 18022 var _this = this; 18023 var container = this.$container && this.$container.get(); 18024 if (container) { 18025 return; 18026 } 18027 var controls = ''; 18028 var subHtmlCont = ''; 18029 // Create controls 18030 if (this.settings.controls) { 18031 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>"; 18032 } 18033 if (this.settings.appendSubHtmlTo !== '.lg-item') { 18034 subHtmlCont = 18035 '<div class="lg-sub-html" role="status" aria-live="polite"></div>'; 18036 } 18037 var addClasses = ''; 18038 if (this.settings.allowMediaOverlap) { 18039 // Do not remove space before last single quote 18040 addClasses += 'lg-media-overlap '; 18041 } 18042 var ariaLabelledby = this.settings.ariaLabelledby 18043 ? 'aria-labelledby="' + this.settings.ariaLabelledby + '"' 18044 : ''; 18045 var ariaDescribedby = this.settings.ariaDescribedby 18046 ? 'aria-describedby="' + this.settings.ariaDescribedby + '"' 18047 : ''; 18048 var containerClassName = "lg-container " + this.settings.addClass + " " + (document.body !== this.settings.container ? 'lg-inline' : ''); 18049 var closeIcon = this.settings.closable && this.settings.showCloseIcon 18050 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['closeGallery'] + "\" id=\"" + this.getIdName('lg-close') + "\" class=\"lg-close lg-icon\"></button>" 18051 : ''; 18052 var maximizeIcon = this.settings.showMaximizeIcon 18053 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['toggleMaximize'] + "\" id=\"" + this.getIdName('lg-maximize') + "\" class=\"lg-maximize lg-icon\"></button>" 18054 : ''; 18055 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' 18056 ? subHtmlCont 18057 : '') + "\n <div id=\"" + this.getIdName('lg-components') + "\" class=\"lg-components\">\n " + (this.settings.appendSubHtmlTo === '.lg-sub-html' 18058 ? subHtmlCont 18059 : '') + "\n </div>\n </div>\n </div>\n "; 18060 $LG(this.settings.container).append(template); 18061 if (document.body !== this.settings.container) { 18062 $LG(this.settings.container).css('position', 'relative'); 18063 } 18064 this.outer = this.getElementById('lg-outer'); 18065 this.$lgComponents = this.getElementById('lg-components'); 18066 this.$backdrop = this.getElementById('lg-backdrop'); 18067 this.$container = this.getElementById('lg-container'); 18068 this.$inner = this.getElementById('lg-inner'); 18069 this.$content = this.getElementById('lg-content'); 18070 this.$toolbar = this.getElementById('lg-toolbar'); 18071 this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms'); 18072 var outerClassNames = this.settings.mode + " "; 18073 this.manageSingleSlideClassName(); 18074 if (this.settings.enableDrag) { 18075 outerClassNames += 'lg-grab '; 18076 } 18077 this.outer.addClass(outerClassNames); 18078 this.$inner.css('transition-timing-function', this.settings.easing); 18079 this.$inner.css('transition-duration', this.settings.speed + 'ms'); 18080 if (this.settings.download) { 18081 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>"); 18082 } 18083 this.counter(); 18084 $LG(window).on("resize.lg.global" + this.lgId + " orientationchange.lg.global" + this.lgId, function () { 18085 _this.refreshOnResize(); 18086 }); 18087 this.hideBars(); 18088 this.manageCloseGallery(); 18089 this.toggleMaximize(); 18090 this.initModules(); 18091 }; 18092 LightGallery.prototype.refreshOnResize = function () { 18093 if (this.lgOpened) { 18094 var currentGalleryItem = this.galleryItems[this.index]; 18095 var __slideVideoInfo = currentGalleryItem.__slideVideoInfo; 18096 this.mediaContainerPosition = this.getMediaContainerPosition(); 18097 var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom; 18098 //Uncode edit ##START## 18099 this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18100 // this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize); 18101 //Uncode edit ##END## 18102 if (__slideVideoInfo) { 18103 this.resizeVideoSlide(this.index, this.currentImageSize); 18104 } 18105 if (this.zoomFromOrigin && !this.isDummyImageRemoved) { 18106 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 18107 this.outer 18108 .find('.lg-current .lg-dummy-img') 18109 .first() 18110 .attr('style', imgStyle); 18111 } 18112 this.LGel.trigger(lGEvents.containerResize); 18113 } 18114 }; 18115 LightGallery.prototype.resizeVideoSlide = function (index, imageSize) { 18116 var lgVideoStyle = this.getVideoContStyle(imageSize); 18117 var currentSlide = this.getSlideItem(index); 18118 currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle); 18119 }; 18120 /** 18121 * Update slides dynamically. 18122 * Add, edit or delete slides dynamically when lightGallery is opened. 18123 * Modify the current gallery items and pass it via updateSlides method 18124 * @note 18125 * - Do not mutate existing lightGallery items directly. 18126 * - Always pass new list of gallery items 18127 * - You need to take care of thumbnails outside the gallery if any 18128 * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method. 18129 * @param items Gallery items 18130 * @param index After the update operation, which slide gallery should navigate to 18131 * @category lGPublicMethods 18132 * @example 18133 * const plugin = lightGallery(); 18134 * 18135 * // Adding slides dynamically 18136 * let galleryItems = [ 18137 * // Access existing lightGallery items 18138 * // galleryItems are automatically generated internally from the gallery HTML markup 18139 * // or directly from galleryItems when dynamic gallery is used 18140 * ...plugin.galleryItems, 18141 * ...[ 18142 * { 18143 * src: 'img/img-1.png', 18144 * thumb: 'img/thumb1.png', 18145 * }, 18146 * ], 18147 * ]; 18148 * plugin.updateSlides( 18149 * galleryItems, 18150 * plugin.index, 18151 * ); 18152 * 18153 * 18154 * // Remove slides dynamically 18155 * galleryItems = JSON.parse( 18156 * JSON.stringify(updateSlideInstance.galleryItems), 18157 * ); 18158 * galleryItems.shift(); 18159 * updateSlideInstance.updateSlides(galleryItems, 1); 18160 * @see <a href="/demos/update-slides/">Demo</a> 18161 */ 18162 LightGallery.prototype.updateSlides = function (items, index) { 18163 if (this.index > items.length - 1) { 18164 this.index = items.length - 1; 18165 } 18166 if (items.length === 1) { 18167 this.index = 0; 18168 } 18169 if (!items.length) { 18170 this.closeGallery(); 18171 return; 18172 } 18173 var currentSrc = this.galleryItems[index].src; 18174 this.galleryItems = items; 18175 this.updateControls(); 18176 this.$inner.empty(); 18177 this.currentItemsInDom = []; 18178 var _index = 0; 18179 // Find the current index based on source value of the slide 18180 this.galleryItems.some(function (galleryItem, itemIndex) { 18181 if (galleryItem.src === currentSrc) { 18182 _index = itemIndex; 18183 return true; 18184 } 18185 return false; 18186 }); 18187 this.currentItemsInDom = this.organizeSlideItems(_index, -1); 18188 this.loadContent(_index, true); 18189 this.getSlideItem(_index).addClass('lg-current'); 18190 this.index = _index; 18191 this.updateCurrentCounter(_index); 18192 this.LGel.trigger(lGEvents.updateSlides); 18193 }; 18194 // Get gallery items based on multiple conditions 18195 LightGallery.prototype.getItems = function () { 18196 // Gallery items 18197 this.items = []; 18198 if (!this.settings.dynamic) { 18199 if (this.settings.selector === 'this') { 18200 this.items.push(this.el); 18201 } 18202 else if (this.settings.selector) { 18203 if (typeof this.settings.selector === 'string') { 18204 if (this.settings.selectWithin) { 18205 var selectWithin = $LG(this.settings.selectWithin); 18206 this.items = selectWithin 18207 .find(this.settings.selector) 18208 .get(); 18209 } 18210 else { 18211 this.items = this.el.querySelectorAll(this.settings.selector); 18212 } 18213 } 18214 else { 18215 this.items = this.settings.selector; 18216 } 18217 } 18218 else { 18219 this.items = this.el.children; 18220 } 18221 return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage); 18222 } 18223 else { 18224 return this.settings.dynamicEl || []; 18225 } 18226 }; 18227 LightGallery.prototype.shouldHideScrollbar = function () { 18228 return (this.settings.hideScrollbar && 18229 document.body === this.settings.container); 18230 }; 18231 LightGallery.prototype.hideScrollbar = function () { 18232 if (!this.shouldHideScrollbar()) { 18233 return; 18234 } 18235 this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight); 18236 var bodyRect = document.documentElement.getBoundingClientRect(); 18237 var scrollbarWidth = window.innerWidth - bodyRect.width; 18238 $LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px'); 18239 $LG(document.body).addClass('lg-overlay-open'); 18240 }; 18241 LightGallery.prototype.resetScrollBar = function () { 18242 if (!this.shouldHideScrollbar()) { 18243 return; 18244 } 18245 $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px'); 18246 $LG(document.body).removeClass('lg-overlay-open'); 18247 }; 18248 /** 18249 * Open lightGallery. 18250 * Open gallery with specific slide by passing index of the slide as parameter. 18251 * @category lGPublicMethods 18252 * @param {Number} index - index of the slide 18253 * @param {HTMLElement} element - Which image lightGallery should zoom from 18254 * 18255 * @example 18256 * const $dynamicGallery = document.getElementById('dynamic-gallery-demo'); 18257 * const dynamicGallery = lightGallery($dynamicGallery, { 18258 * dynamic: true, 18259 * dynamicEl: [ 18260 * { 18261 * src: 'img/1.jpg', 18262 * thumb: 'img/thumb-1.jpg', 18263 * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>', 18264 * }, 18265 * ... 18266 * ], 18267 * }); 18268 * $dynamicGallery.addEventListener('click', function () { 18269 * // Starts with third item.(Optional). 18270 * // This is useful if you want use dynamic mode with 18271 * // custom thumbnails (thumbnails outside gallery), 18272 * dynamicGallery.openGallery(2); 18273 * }); 18274 * 18275 */ 18276 LightGallery.prototype.openGallery = function (index, element) { 18277 var _this = this; 18278 if (index === void 0) { index = this.settings.index; } 18279 // prevent accidental double execution 18280 if (this.lgOpened) 18281 return; 18282 this.lgOpened = true; 18283 this.outer.removeClass('lg-hide-items'); 18284 this.hideScrollbar(); 18285 // Add display block, but still has opacity 0 18286 this.$container.addClass('lg-show'); 18287 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index); 18288 this.currentItemsInDom = itemsToBeInsertedToDom; 18289 var items = ''; 18290 itemsToBeInsertedToDom.forEach(function (item) { 18291 items = items + ("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 18292 }); 18293 this.$inner.append(items); 18294 this.addHtml(index); 18295 var transform = ''; 18296 this.mediaContainerPosition = this.getMediaContainerPosition(); 18297 var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 18298 if (!this.settings.allowMediaOverlap) { 18299 this.setMediaContainerPosition(top, bottom); 18300 } 18301 var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo; 18302 if (this.zoomFromOrigin && element) { 18303 //Uncode edit ##START## 18304 this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18305 // this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize); 18306 //Uncode edit ##END## 18307 transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize); 18308 } 18309 if (!this.zoomFromOrigin || !transform) { 18310 this.outer.addClass(this.settings.startClass); 18311 this.getSlideItem(index).removeClass('lg-complete'); 18312 } 18313 var timeout = this.settings.zoomFromOrigin 18314 ? 100 18315 : this.settings.backdropDuration; 18316 setTimeout(function () { 18317 _this.outer.addClass('lg-components-open'); 18318 }, timeout); 18319 this.index = index; 18320 //Uncode edit ##START## 18321 // this.LGel.trigger(lGEvents.beforeOpen); 18322 this.LGel.trigger(lGEvents.beforeOpen, { 18323 galleryItems: this.galleryItems, 18324 items: this.items, 18325 outer: this.outer, 18326 }); 18327 //Uncode edit ##END## 18328 // add class lg-current to remove initial transition 18329 this.getSlideItem(index).addClass('lg-current'); 18330 this.lGalleryOn = false; 18331 // Store the current scroll top value to scroll back after closing the gallery.. 18332 this.prevScrollTop = $LG(window).scrollTop(); 18333 setTimeout(function () { 18334 // Need to check both zoomFromOrigin and transform values as we need to set set the 18335 // default opening animation if user missed to add the lg-size attribute 18336 if (_this.zoomFromOrigin && transform) { 18337 var currentSlide_1 = _this.getSlideItem(index); 18338 currentSlide_1.css('transform', transform); 18339 setTimeout(function () { 18340 currentSlide_1 18341 .addClass('lg-start-progress lg-start-end-progress') 18342 .css('transition-duration', _this.settings.startAnimationDuration + 'ms'); 18343 _this.outer.addClass('lg-zoom-from-image'); 18344 }); 18345 setTimeout(function () { 18346 currentSlide_1.css('transform', 'translate3d(0, 0, 0)'); 18347 }, 100); 18348 } 18349 setTimeout(function () { 18350 _this.$backdrop.addClass('in'); 18351 _this.$container.addClass('lg-show-in'); 18352 }, 10); 18353 setTimeout(function () { 18354 if (_this.settings.trapFocus && 18355 document.body === _this.settings.container) { 18356 _this.trapFocus(); 18357 } 18358 }, _this.settings.backdropDuration + 50); 18359 // lg-visible class resets gallery opacity to 1 18360 if (!_this.zoomFromOrigin || !transform) { 18361 setTimeout(function () { 18362 _this.outer.addClass('lg-visible'); 18363 }, _this.settings.backdropDuration); 18364 } 18365 // initiate slide function 18366 _this.slide(index, false, false, false); 18367 _this.LGel.trigger(lGEvents.afterOpen); 18368 }); 18369 if (document.body === this.settings.container) { 18370 $LG('html').addClass('lg-on'); 18371 } 18372 }; 18373 /** 18374 * Note - Changing the position of the media on every slide transition creates a flickering effect. 18375 * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption. 18376 * if you have dynamic captions for each media, 18377 * you can provide an appropriate height for the captions via allowMediaOverlap option 18378 */ 18379 LightGallery.prototype.getMediaContainerPosition = function () { 18380 if (this.settings.allowMediaOverlap) { 18381 return { 18382 top: 0, 18383 bottom: 0, 18384 }; 18385 } 18386 var top = this.$toolbar.get().clientHeight || 0; 18387 var subHtml = this.outer.find('.lg-components .lg-sub-html').get(); 18388 var captionHeight = this.settings.defaultCaptionHeight || 18389 (subHtml && subHtml.clientHeight) || 18390 0; 18391 var thumbContainer = this.outer.find('.lg-thumb-outer').get(); 18392 var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0; 18393 var bottom = thumbHeight + captionHeight; 18394 //Uncode edit ##START## 18395 bottom = bottom < 55 ? 55 : bottom; 18396 //Uncode edit ##END## 18397 return { 18398 top: top, 18399 bottom: bottom, 18400 }; 18401 }; 18402 LightGallery.prototype.setMediaContainerPosition = function (top, bottom) { 18403 if (top === void 0) { top = 0; } 18404 if (bottom === void 0) { bottom = 0; } 18405 this.$content.css('top', top + 'px').css('bottom', bottom + 'px'); 18406 }; 18407 LightGallery.prototype.hideBars = function () { 18408 var _this = this; 18409 // Hide controllers if mouse doesn't move for some period 18410 setTimeout(function () { 18411 _this.outer.removeClass('lg-hide-items'); 18412 if (_this.settings.hideBarsDelay > 0) {
vendor: 4,223 bytes, lines 18413-18543
18413 _this.outer.on('mousemove.lg click.lg touchstart.lg', function () { 18414 _this.outer.removeClass('lg-hide-items'); 18415 clearTimeout(_this.hideBarTimeout); 18416 // Timeout will be cleared on each slide movement also 18417 _this.hideBarTimeout = setTimeout(function () { 18418 _this.outer.addClass('lg-hide-items'); 18419 }, _this.settings.hideBarsDelay); 18420 }); 18421 _this.outer.trigger('mousemove.lg'); 18422 } 18423 }, this.settings.showBarsAfter); 18424 }; 18425 LightGallery.prototype.initPictureFill = function ($img) { 18426 if (this.settings.supportLegacyBrowser) { 18427 try { 18428 picturefill({ 18429 elements: [$img.get()], 18430 }); 18431 } 18432 catch (e) { 18433 console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.'); 18434 } 18435 } 18436 }; 18437 /** 18438 * @desc Create image counter 18439 * Ex: 1/10 18440 */ 18441 LightGallery.prototype.counter = function () { 18442 if (this.settings.counter) { 18443 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>"; 18444 this.outer.find(this.settings.appendCounterTo).append(counterHtml); 18445 } 18446 }; 18447 /** 18448 * @desc add sub-html into the slide 18449 * @param {Number} index - index of the slide 18450 */ 18451 LightGallery.prototype.addHtml = function (index) { 18452 var subHtml; 18453 var subHtmlUrl; 18454 if (this.galleryItems[index].subHtmlUrl) { 18455 subHtmlUrl = this.galleryItems[index].subHtmlUrl; 18456 } 18457 else { 18458 subHtml = this.galleryItems[index].subHtml; 18459 } 18460 if (!subHtmlUrl) { 18461 if (subHtml) { 18462 // get first letter of sub-html 18463 // if first letter starts with . or # get the html form the jQuery object 18464 var fL = subHtml.substring(0, 1); 18465 if (fL === '.' || fL === '#') { 18466 if (this.settings.subHtmlSelectorRelative && 18467 !this.settings.dynamic) { 18468 subHtml = $LG(this.items) 18469 .eq(index) 18470 .find(subHtml) 18471 .first() 18472 .html(); 18473 } 18474 else { 18475 subHtml = $LG(subHtml).first().html(); 18476 } 18477 } 18478 } 18479 else { 18480 subHtml = ''; 18481 } 18482 } 18483 if (this.settings.appendSubHtmlTo !== '.lg-item') { 18484 if (subHtmlUrl) { 18485 this.outer.find('.lg-sub-html').load(subHtmlUrl); 18486 } 18487 else { 18488 this.outer.find('.lg-sub-html').html(subHtml); 18489 } 18490 } 18491 else { 18492 var currentSlide = $LG(this.getSlideItemId(index)); 18493 if (subHtmlUrl) { 18494 currentSlide.load(subHtmlUrl); 18495 } 18496 else { 18497 currentSlide.append("<div class=\"lg-sub-html\">" + subHtml + "</div>"); 18498 } 18499 } 18500 // Add lg-empty-html class if title doesn't exist 18501 if (typeof subHtml !== 'undefined' && subHtml !== null) { 18502 if (subHtml === '') { 18503 this.outer 18504 .find(this.settings.appendSubHtmlTo) 18505 .addClass('lg-empty-html'); 18506 } 18507 else { 18508 this.outer 18509 .find(this.settings.appendSubHtmlTo) 18510 .removeClass('lg-empty-html'); 18511 } 18512 } 18513 this.LGel.trigger(lGEvents.afterAppendSubHtml, { 18514 index: index, 18515 }); 18516 }; 18517 /** 18518 * @desc Preload slides 18519 * @param {Number} index - index of the slide 18520 * @todo preload not working for the first slide, Also, should work for the first and last slide as well 18521 */ 18522 LightGallery.prototype.preload = function (index) { 18523 for (var i = 1; i <= this.settings.preload; i++) { 18524 if (i >= this.galleryItems.length - index) { 18525 break; 18526 } 18527 this.loadContent(index + i, false); 18528 } 18529 for (var j = 1; j <= this.settings.preload; j++) { 18530 if (index - j < 0) { 18531 break; 18532 } 18533 this.loadContent(index - j, false); 18534 } 18535 }; 18536 LightGallery.prototype.getDummyImgStyles = function (imageSize) { 18537 if (!imageSize) 18538 return ''; 18539 return "width:" + imageSize.width + "px;\n margin-left: -" + imageSize.width / 2 + "px;\n margin-top: -" + imageSize.height / 2 + "px;\n height:" + imageSize.height + "px"; 18540 }; 18541 LightGallery.prototype.getVideoContStyle = function (imageSize) { 18542 if (!imageSize) 18543 return '';
18544 return "width:" + imageSize.width + "px;\n height:" + imageSize.height + "px"; 18545 }; 18546 LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) { 18547 var $currentItem; 18548 if (!this.settings.dynamic) { 18549 $currentItem = $LG(this.items).eq(index); 18550 } 18551 if ($currentItem) { 18552 var _dummyImgSrc = void 0; 18553 if (!this.settings.exThumbImage) { 18554 _dummyImgSrc = $currentItem.find('img').first().attr('src'); 18555 } 18556 else { 18557 _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage); 18558 } 18559 if (!_dummyImgSrc) 18560 return ''; 18561 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 18562 var dummyImgContent = "<img " + alt + " style=\"" + imgStyle + "\" class=\"lg-dummy-img\" src=\"" + _dummyImgSrc + "\" />"; 18563 $currentSlide.addClass('lg-first-slide'); 18564 this.outer.addClass('lg-first-slide-loading'); 18565 return dummyImgContent; 18566 } 18567 return ''; 18568 }; 18569 LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) { 18570 var currentGalleryItem = this.galleryItems[index]; 18571 var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 18572 // Use the thumbnail as dummy image which will be resized to actual image size and 18573 // displayed on top of actual image 18574 var imgContent = ''; 18575 var altAttr = alt ? 'alt="' + alt + '"' : ''; 18576 if (this.isFirstSlideWithZoomAnimation()) { 18577 imgContent = this.getDummyImageContent($currentSlide, index, altAttr); 18578 } 18579 else { 18580 imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources); 18581 } 18582 var imgMarkup = "<picture class=\"lg-img-wrap\"> " + imgContent + "</picture>"; 18583 $currentSlide.prepend(imgMarkup); 18584 }; 18585 LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) { 18586 var mediaObject = $slide.find('.lg-object').first(); 18587 if (utils.isImageLoaded(mediaObject.get()) || 18588 isHTML5VideoWithoutPoster) { 18589 onLoad(); 18590 } 18591 else { 18592 mediaObject.on('load.lg error.lg', function () { 18593 onLoad && onLoad(); 18594 }); 18595 mediaObject.on('error.lg', function () { 18596 onError && onError(); 18597 }); 18598 } 18599 }; 18600 /** 18601 * 18602 * @param $el Current slide item 18603 * @param index 18604 * @param delay Delay is 0 except first time 18605 * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin 18606 * @param isFirstSlide 18607 */ 18608 LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) { 18609 var _this = this; 18610 //Uncode edit ##START## 18611 var $item = _this.galleryItems[index], 18612 type = $item.type; 18613 18614 if ( typeof $item.src !== 'undefined' ) { 18615 var inline_id = $item.src.replace('#', ''), 18616 $inline = document.getElementById(inline_id), 18617 inline_html; 18618 18619 if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) { 18620 inline_html = $inline.innerHTML; 18621 } else { 18622 inline_html = ''; 18623 } 18624 } 18625 //Uncode edit ##END## 18626 this.onSlideObjectLoad(currentSlide, true, function () { 18627 _this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide); 18628 }, function () { 18629 currentSlide.addClass('lg-complete lg-complete_'); 18630 //Uncode edit ##START## 18631 // currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 18632 if ( inline_html !== '' ) { 18633 currentSlide.html(inline_html); 18634 } else { 18635 currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 18636 } 18637 //Uncode edit ##END## 18638 }); 18639 }; 18640 LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) { 18641 var _this = this; 18642 var currentGalleryItem = this.galleryItems[index]; 18643 // Adding delay for video slides without poster for better performance and user experience 18644 // Videos should start playing once once the gallery is completely loaded 18645 var _speed = isFirstSlide &&
vendor: 37,617 bytes, lines 18646-19728
18646 this.getSlideType(currentGalleryItem) === 'video' && 18647 !currentGalleryItem.poster 18648 ? speed 18649 : 0; 18650 setTimeout(function () { 18651 $currentSlide.addClass('lg-complete lg-complete_'); 18652 _this.LGel.trigger(lGEvents.slideItemLoad, { 18653 index: index, 18654 delay: delay || 0, 18655 isFirstSlide: isFirstSlide, 18656 }); 18657 }, _speed); 18658 }; 18659 LightGallery.prototype.isFirstSlideWithZoomAnimation = function () { 18660 return !!(!this.lGalleryOn && 18661 this.zoomFromOrigin && 18662 this.currentImageSize); 18663 }; 18664 // Add video slideInfo 18665 LightGallery.prototype.addSlideVideoInfo = function (items) { 18666 var _this = this; 18667 items.forEach(function (element, index) { 18668 element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index); 18669 if (element.__slideVideoInfo && 18670 _this.settings.loadYouTubePoster && 18671 !element.poster && 18672 element.__slideVideoInfo.youtube) { 18673 element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg"; 18674 } 18675 }); 18676 }; 18677 /** 18678 * Load slide content into slide. 18679 * This is used to load content into slides that is not visible too 18680 * @param {Number} index - index of the slide. 18681 * @param {Boolean} rec - if true call loadcontent() function again. 18682 */ 18683 LightGallery.prototype.loadContent = function (index, rec) { 18684 var _this = this; 18685 var currentGalleryItem = this.galleryItems[index]; 18686 var $currentSlide = $LG(this.getSlideItemId(index)); 18687 var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 18688 var src = currentGalleryItem.src; 18689 var video = currentGalleryItem.video; 18690 var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video; 18691 if (currentGalleryItem.responsive) { 18692 var srcDyItms = currentGalleryItem.responsive.split(','); 18693 src = utils.getResponsiveSrc(srcDyItms) || src; 18694 } 18695 var videoInfo = currentGalleryItem.__slideVideoInfo; 18696 var lgVideoStyle = ''; 18697 var iframe = !!currentGalleryItem.iframe; 18698 var isFirstSlide = !this.lGalleryOn; 18699 // delay for adding complete class. it is 0 except first time. 18700 var delay = 0; 18701 if (isFirstSlide) { 18702 if (this.zoomFromOrigin && this.currentImageSize) { 18703 delay = this.settings.startAnimationDuration + 10; 18704 } 18705 else { 18706 delay = this.settings.backdropDuration + 10; 18707 } 18708 } 18709 if (!$currentSlide.hasClass('lg-loaded')) { 18710 if (videoInfo) { 18711 var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom; 18712 //Uncode edit ##START## 18713 var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18714 // var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize); 18715 //Uncode edit ##END## 18716 lgVideoStyle = this.getVideoContStyle(videoSize); 18717 } 18718 if (iframe) { 18719 var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle); 18720 $currentSlide.prepend(markup); 18721 } 18722 else if (poster) { 18723 var dummyImg = ''; 18724 var hasStartAnimation = isFirstSlide && 18725 this.zoomFromOrigin && 18726 this.currentImageSize; 18727 if (hasStartAnimation) { 18728 dummyImg = this.getDummyImageContent($currentSlide, index, ''); 18729 } 18730 var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo); 18731 $currentSlide.prepend(markup); 18732 } 18733 //Uncode edit ##START## 18734 // else if (videoInfo) { 18735 else if (videoInfo || this.getSlideType(currentGalleryItem) === 'audio') { 18736 if (! _html5Video) { 18737 var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>"; 18738 } 18739 //Uncode edit ##END## 18740 $currentSlide.prepend(markup); 18741 } 18742 else { 18743 this.setImgMarkup(src, $currentSlide, index); 18744 if (srcset || sources) { 18745 var $img = $currentSlide.find('.lg-object'); 18746 this.initPictureFill($img); 18747 } 18748 } 18749 if (poster || videoInfo) { 18750 this.LGel.trigger(lGEvents.hasVideo, { 18751 index: index, 18752 src: src, 18753 html5Video: _html5Video, 18754 hasPoster: !!poster, 18755 }); 18756 } 18757 this.LGel.trigger(lGEvents.afterAppendSlide, { index: index }); 18758 if (this.lGalleryOn && 18759 this.settings.appendSubHtmlTo === '.lg-item') { 18760 this.addHtml(index); 18761 } 18762 } 18763 // For first time add some delay for displaying the start animation. 18764 var _speed = 0; 18765 // Do not change the delay value because it is required for zoom plugin. 18766 // If gallery opened from direct url (hash) speed value should be 0 18767 if (delay && !$LG(document.body).hasClass('lg-from-hash')) { 18768 _speed = delay; 18769 } 18770 // Only for first slide and zoomFromOrigin is enabled 18771 if (this.isFirstSlideWithZoomAnimation()) { 18772 setTimeout(function () { 18773 $currentSlide 18774 .removeClass('lg-start-end-progress lg-start-progress') 18775 .removeAttr('style'); 18776 }, this.settings.startAnimationDuration + 100); 18777 if (!$currentSlide.hasClass('lg-loaded')) { 18778 setTimeout(function () { 18779 if (_this.getSlideType(currentGalleryItem) === 'image') { 18780 var alt = currentGalleryItem.alt; 18781 var altAttr = alt ? 'alt="' + alt + '"' : ''; 18782 $currentSlide 18783 .find('.lg-img-wrap') 18784 .append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources)); 18785 if (srcset || sources) { 18786 var $img = $currentSlide.find('.lg-object'); 18787 _this.initPictureFill($img); 18788 } 18789 } 18790 if (_this.getSlideType(currentGalleryItem) === 'image' || 18791 (_this.getSlideType(currentGalleryItem) === 'video' && 18792 poster)) { 18793 _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false); 18794 // load remaining slides once the slide is completely loaded 18795 _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () { 18796 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18797 }, function () { 18798 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18799 }); 18800 } 18801 }, this.settings.startAnimationDuration + 100); 18802 } 18803 } 18804 // SLide content has been added to dom 18805 $currentSlide.addClass('lg-loaded'); 18806 if (!this.isFirstSlideWithZoomAnimation() || 18807 (this.getSlideType(currentGalleryItem) === 'video' && !poster)) { 18808 //Uncode edit ##START## 18809 // this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster)); 18810 this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!( (videoInfo && videoInfo.html5 && !poster) || this.getSlideType(currentGalleryItem) === 'audio')); 18811 //Uncode edit ##END## 18812 } 18813 // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling 18814 if ((!this.zoomFromOrigin || !this.currentImageSize) && 18815 $currentSlide.hasClass('lg-complete_') && 18816 !this.lGalleryOn) { 18817 setTimeout(function () { 18818 $currentSlide.addClass('lg-complete'); 18819 }, this.settings.backdropDuration); 18820 } 18821 // Content loaded 18822 // Need to set lGalleryOn before calling preload function 18823 this.lGalleryOn = true; 18824 if (rec === true) { 18825 if (!$currentSlide.hasClass('lg-complete_')) { 18826 $currentSlide 18827 .find('.lg-object') 18828 .first() 18829 .on('load.lg error.lg', function () { 18830 _this.preload(index); 18831 }); 18832 } 18833 else { 18834 this.preload(index); 18835 } 18836 } 18837 }; 18838 /** 18839 * @desc Remove dummy image content and load next slides 18840 * Called only for the first time if zoomFromOrigin animation is enabled 18841 * @param index 18842 * @param $currentSlide 18843 * @param speed 18844 */ 18845 LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) { 18846 var _this = this; 18847 setTimeout(function () { 18848 $currentSlide.find('.lg-dummy-img').remove(); 18849 $currentSlide.removeClass('lg-first-slide'); 18850 _this.outer.removeClass('lg-first-slide-loading'); 18851 _this.isDummyImageRemoved = true; 18852 _this.preload(index); 18853 }, speed + 300); 18854 }; 18855 LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) { 18856 var _this = this; 18857 if (numberOfItems === void 0) { numberOfItems = 0; } 18858 var itemsToBeInsertedToDom = []; 18859 // Minimum 2 items should be there 18860 var possibleNumberOfItems = Math.max(numberOfItems, 3); 18861 possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length); 18862 var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex; 18863 if (this.galleryItems.length <= 3) { 18864 this.galleryItems.forEach(function (_element, index) { 18865 itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index); 18866 }); 18867 return itemsToBeInsertedToDom; 18868 } 18869 if (index < (this.galleryItems.length - 1) / 2) { 18870 for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) { 18871 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18872 } 18873 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18874 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18875 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1)); 18876 } 18877 } 18878 else { 18879 for (var idx = index; idx <= this.galleryItems.length - 1 && 18880 idx < index + possibleNumberOfItems / 2; idx++) { 18881 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18882 } 18883 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18884 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18885 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1)); 18886 } 18887 } 18888 if (this.settings.loop) { 18889 if (index === this.galleryItems.length - 1) { 18890 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0); 18891 } 18892 else if (index === 0) { 18893 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1)); 18894 } 18895 } 18896 if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) { 18897 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex); 18898 } 18899 return itemsToBeInsertedToDom; 18900 }; 18901 LightGallery.prototype.organizeSlideItems = function (index, prevIndex) { 18902 var _this = this; 18903 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom); 18904 itemsToBeInsertedToDom.forEach(function (item) { 18905 if (_this.currentItemsInDom.indexOf(item) === -1) { 18906 _this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 18907 } 18908 }); 18909 this.currentItemsInDom.forEach(function (item) { 18910 if (itemsToBeInsertedToDom.indexOf(item) === -1) { 18911 $LG("#" + item).remove(); 18912 } 18913 }); 18914 return itemsToBeInsertedToDom; 18915 }; 18916 /** 18917 * Get previous index of the slide 18918 */ 18919 LightGallery.prototype.getPreviousSlideIndex = function () { 18920 var prevIndex = 0; 18921 try { 18922 var currentItemId = this.outer 18923 .find('.lg-current') 18924 .first() 18925 .attr('id'); 18926 prevIndex = parseInt(currentItemId.split('-')[3]) || 0; 18927 } 18928 catch (error) { 18929 prevIndex = 0; 18930 } 18931 return prevIndex; 18932 }; 18933 LightGallery.prototype.setDownloadValue = function (index) { 18934 if (this.settings.download) { 18935 var currentGalleryItem = this.galleryItems[index]; 18936 var hideDownloadBtn = currentGalleryItem.downloadUrl === false || 18937 currentGalleryItem.downloadUrl === 'false'; 18938 if (hideDownloadBtn) { 18939 this.outer.addClass('lg-hide-download'); 18940 } 18941 else { 18942 var $download = this.getElementById('lg-download'); 18943 this.outer.removeClass('lg-hide-download'); 18944 $download.attr('href', currentGalleryItem.downloadUrl || 18945 currentGalleryItem.src); 18946 if (currentGalleryItem.download) { 18947 //Uncode edit ##START## 18948 var download_url = currentGalleryItem.downloadUrl || currentGalleryItem.src, 18949 download_name = download_url.substring(download_url.lastIndexOf('/')+1); 18950 $download.attr('download', download_name); 18951 // $download.attr('download', currentGalleryItem.download); 18952 //Uncode edit ##END## 18953 } 18954 } 18955 } 18956 }; 18957 LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) { 18958 var _this = this; 18959 if (this.lGalleryOn) { 18960 previousSlideItem.addClass('lg-slide-progress'); 18961 } 18962 setTimeout(function () { 18963 // remove all transitions 18964 _this.outer.addClass('lg-no-trans'); 18965 _this.outer 18966 .find('.lg-item') 18967 .removeClass('lg-prev-slide lg-next-slide'); 18968 if (direction === 'prev') { 18969 //prevslide 18970 currentSlideItem.addClass('lg-prev-slide'); 18971 previousSlideItem.addClass('lg-next-slide'); 18972 } 18973 else { 18974 // next slide 18975 currentSlideItem.addClass('lg-next-slide'); 18976 previousSlideItem.addClass('lg-prev-slide'); 18977 } 18978 // give 50 ms for browser to add/remove class 18979 setTimeout(function () { 18980 _this.outer.find('.lg-item').removeClass('lg-current'); 18981 currentSlideItem.addClass('lg-current'); 18982 // reset all transitions 18983 _this.outer.removeClass('lg-no-trans'); 18984 }, 50); 18985 }, this.lGalleryOn ? this.settings.slideDelay : 0); 18986 }; 18987 /** 18988 * Goto a specific slide. 18989 * @param {Number} index - index of the slide 18990 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag 18991 * @param {Boolean} fromThumb - true if slide function called via thumbnail click 18992 * @param {String} direction - Direction of the slide(next/prev) 18993 * @category lGPublicMethods 18994 * @example 18995 * const plugin = lightGallery(); 18996 * // to go to 3rd slide 18997 * plugin.slide(2); 18998 * 18999 */ 19000 LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) { 19001 var _this = this; 19002 var prevIndex = this.getPreviousSlideIndex(); 19003 this.currentItemsInDom = this.organizeSlideItems(index, prevIndex); 19004 // Prevent multiple call, Required for hsh plugin 19005 if (this.lGalleryOn && prevIndex === index) { 19006 return; 19007 } 19008 var numberOfGalleryItems = this.galleryItems.length; 19009 if (!this.lgBusy) { 19010 if (this.settings.counter) { 19011 this.updateCurrentCounter(index); 19012 } 19013 var currentSlideItem = this.getSlideItem(index); 19014 var previousSlideItem_1 = this.getSlideItem(prevIndex); 19015 var currentGalleryItem = this.galleryItems[index]; 19016 var videoInfo = currentGalleryItem.__slideVideoInfo; 19017 this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem)); 19018 this.setDownloadValue(index); 19019 if (videoInfo) { 19020 var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom; 19021 //Uncode edit ##START## 19022 var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 19023 // var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize); 19024 //Uncode edit ##END## 19025 this.resizeVideoSlide(index, videoSize); 19026 } 19027 this.LGel.trigger(lGEvents.beforeSlide, { 19028 prevIndex: prevIndex, 19029 index: index, 19030 fromTouch: !!fromTouch, 19031 fromThumb: !!fromThumb, 19032 //Uncode edit ##START## 19033 currentSlide: currentSlideItem, 19034 previousSlide: previousSlideItem_1, 19035 info: currentGalleryItem, 19036 item: this.items[index] 19037 //Uncode edit ##END## 19038 }); 19039 this.lgBusy = true; 19040 clearTimeout(this.hideBarTimeout); 19041 this.arrowDisable(index); 19042 if (!direction) { 19043 if (index < prevIndex) { 19044 direction = 'prev'; 19045 } 19046 else if (index > prevIndex) { 19047 direction = 'next'; 19048 } 19049 } 19050 if (!fromTouch) { 19051 this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1); 19052 } 19053 else { 19054 this.outer 19055 .find('.lg-item') 19056 .removeClass('lg-prev-slide lg-current lg-next-slide'); 19057 var touchPrev = void 0; 19058 var touchNext = void 0; 19059 if (numberOfGalleryItems > 2) { 19060 touchPrev = index - 1; 19061 touchNext = index + 1; 19062 if (index === 0 && prevIndex === numberOfGalleryItems - 1) { 19063 // next slide 19064 touchNext = 0; 19065 touchPrev = numberOfGalleryItems - 1; 19066 } 19067 else if (index === numberOfGalleryItems - 1 && 19068 prevIndex === 0) { 19069 // prev slide 19070 touchNext = 0; 19071 touchPrev = numberOfGalleryItems - 1; 19072 } 19073 } 19074 else { 19075 touchPrev = 0; 19076 touchNext = 1; 19077 } 19078 if (direction === 'prev') { 19079 this.getSlideItem(touchNext).addClass('lg-next-slide'); 19080 } 19081 else { 19082 this.getSlideItem(touchPrev).addClass('lg-prev-slide'); 19083 } 19084 currentSlideItem.addClass('lg-current'); 19085 } 19086 // Do not put load content in set timeout as it needs to load immediately when the gallery is opened 19087 if (!this.lGalleryOn) { 19088 this.loadContent(index, true); 19089 } 19090 else { 19091 setTimeout(function () { 19092 _this.loadContent(index, true); 19093 // Add title if this.settings.appendSubHtmlTo === lg-sub-html 19094 if (_this.settings.appendSubHtmlTo !== '.lg-item') { 19095 _this.addHtml(index); 19096 } 19097 }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay)); 19098 } 19099 setTimeout(function () { 19100 _this.lgBusy = false; 19101 previousSlideItem_1.removeClass('lg-slide-progress'); 19102 _this.LGel.trigger(lGEvents.afterSlide, { 19103 prevIndex: prevIndex, 19104 index: index, 19105 fromTouch: fromTouch, 19106 fromThumb: fromThumb, 19107 }); 19108 }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay)); 19109 } 19110 this.index = index; 19111 }; 19112 LightGallery.prototype.updateCurrentCounter = function (index) { 19113 this.getElementById('lg-counter-current').html(index + 1 + ''); 19114 }; 19115 LightGallery.prototype.updateCounterTotal = function () { 19116 this.getElementById('lg-counter-all').html(this.galleryItems.length + ''); 19117 }; 19118 LightGallery.prototype.getSlideType = function (item) { 19119 if (item.__slideVideoInfo) { 19120 return 'video'; 19121 } 19122 else if (item.iframe) { 19123 return 'iframe'; 19124 } 19125 //Uncode edit ##START## 19126 else if (typeof item.src !== '' && item.src.search(/.mp3|.m4a/i) > -1) { 19127 return 'audio'; 19128 } 19129 //Uncode edit ##END## 19130 else { 19131 return 'image'; 19132 } 19133 }; 19134 LightGallery.prototype.touchMove = function (startCoords, endCoords, e) { 19135 var distanceX = endCoords.pageX - startCoords.pageX; 19136 var distanceY = endCoords.pageY - startCoords.pageY; 19137 var allowSwipe = false; 19138 if (this.swipeDirection) { 19139 allowSwipe = true; 19140 } 19141 else { 19142 if (Math.abs(distanceX) > 15) { 19143 this.swipeDirection = 'horizontal'; 19144 allowSwipe = true; 19145 } 19146 else if (Math.abs(distanceY) > 15) { 19147 this.swipeDirection = 'vertical'; 19148 allowSwipe = true; 19149 } 19150 } 19151 if (!allowSwipe) { 19152 return; 19153 } 19154 var $currentSlide = this.getSlideItem(this.index); 19155 if (this.swipeDirection === 'horizontal') { 19156 e === null || e === void 0 ? void 0 : e.preventDefault(); 19157 // reset opacity and transition duration 19158 this.outer.addClass('lg-dragging'); 19159 // move current slide 19160 this.setTranslate($currentSlide, distanceX, 0); 19161 // move next and prev slide with current slide 19162 var width = $currentSlide.get().offsetWidth; 19163 var slideWidthAmount = (width * 15) / 100; 19164 var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100); 19165 this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0); 19166 this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0); 19167 } 19168 else if (this.swipeDirection === 'vertical') { 19169 if (this.settings.swipeToClose) { 19170 e === null || e === void 0 ? void 0 : e.preventDefault(); 19171 this.$container.addClass('lg-dragging-vertical'); 19172 var opacity = 1 - Math.abs(distanceY) / window.innerHeight; 19173 this.$backdrop.css('opacity', opacity); 19174 var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2); 19175 this.setTranslate($currentSlide, 0, distanceY, scale, scale); 19176 if (Math.abs(distanceY) > 100) { 19177 this.outer 19178 .addClass('lg-hide-items') 19179 .removeClass('lg-components-open'); 19180 } 19181 } 19182 } 19183 }; 19184 LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) { 19185 var _this = this; 19186 var distance; 19187 // keep slide animation for any mode while dragg/swipe 19188 if (this.settings.mode !== 'lg-slide') { 19189 this.outer.addClass('lg-slide'); 19190 } 19191 // set transition duration 19192 setTimeout(function () { 19193 _this.$container.removeClass('lg-dragging-vertical'); 19194 _this.outer 19195 .removeClass('lg-dragging lg-hide-items') 19196 .addClass('lg-components-open'); 19197 var triggerClick = true; 19198 if (_this.swipeDirection === 'horizontal') { 19199 distance = endCoords.pageX - startCoords.pageX; 19200 var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX); 19201 if (distance < 0 && 19202 distanceAbs > _this.settings.swipeThreshold) { 19203 _this.goToNextSlide(true); 19204 triggerClick = false; 19205 } 19206 else if (distance > 0 && 19207 distanceAbs > _this.settings.swipeThreshold) { 19208 _this.goToPrevSlide(true); 19209 triggerClick = false; 19210 } 19211 } 19212 else if (_this.swipeDirection === 'vertical') { 19213 distance = Math.abs(endCoords.pageY - startCoords.pageY); 19214 if (_this.settings.closable && 19215 _this.settings.swipeToClose && 19216 distance > 100) { 19217 _this.closeGallery(); 19218 return; 19219 } 19220 else { 19221 _this.$backdrop.css('opacity', 1); 19222 } 19223 } 19224 _this.outer.find('.lg-item').removeAttr('style'); 19225 if (triggerClick && 19226 Math.abs(endCoords.pageX - startCoords.pageX) < 5) { 19227 // Trigger click if distance is less than 5 pix 19228 var target = $LG(event.target); 19229 if (_this.isPosterElement(target)) { 19230 _this.LGel.trigger(lGEvents.posterClick); 19231 } 19232 } 19233 _this.swipeDirection = undefined; 19234 }); 19235 // remove slide class once drag/swipe is completed if mode is not slide 19236 setTimeout(function () { 19237 if (!_this.outer.hasClass('lg-dragging') && 19238 _this.settings.mode !== 'lg-slide') { 19239 _this.outer.removeClass('lg-slide'); 19240 } 19241 }, this.settings.speed + 100); 19242 }; 19243 LightGallery.prototype.enableSwipe = function () { 19244 var _this = this; 19245 var startCoords = {}; 19246 var endCoords = {}; 19247 var isMoved = false; 19248 var isSwiping = false; 19249 if (this.settings.enableSwipe) { 19250 this.$inner.on('touchstart.lg', function (e) { 19251 _this.dragOrSwipeEnabled = true; 19252 var $item = _this.getSlideItem(_this.index); 19253 if (($LG(e.target).hasClass('lg-item') || 19254 $item.get().contains(e.target)) && 19255 !_this.outer.hasClass('lg-zoomed') && 19256 !_this.lgBusy && 19257 e.targetTouches.length === 1) { 19258 isSwiping = true; 19259 _this.touchAction = 'swipe'; 19260 _this.manageSwipeClass(); 19261 startCoords = { 19262 pageX: e.targetTouches[0].pageX, 19263 pageY: e.targetTouches[0].pageY, 19264 }; 19265 } 19266 }); 19267 this.$inner.on('touchmove.lg', function (e) { 19268 if (isSwiping && 19269 _this.touchAction === 'swipe' && 19270 e.targetTouches.length === 1) { 19271 endCoords = { 19272 pageX: e.targetTouches[0].pageX, 19273 pageY: e.targetTouches[0].pageY, 19274 }; 19275 _this.touchMove(startCoords, endCoords, e); 19276 isMoved = true; 19277 } 19278 }); 19279 this.$inner.on('touchend.lg', function (event) { 19280 if (_this.touchAction === 'swipe') { 19281 if (isMoved) { 19282 isMoved = false; 19283 _this.touchEnd(endCoords, startCoords, event); 19284 } 19285 else if (isSwiping) { 19286 var target = $LG(event.target); 19287 if (_this.isPosterElement(target)) { 19288 _this.LGel.trigger(lGEvents.posterClick); 19289 } 19290 } 19291 _this.touchAction = undefined; 19292 isSwiping = false; 19293 } 19294 }); 19295 } 19296 }; 19297 LightGallery.prototype.enableDrag = function () { 19298 var _this = this; 19299 var startCoords = {}; 19300 var endCoords = {}; 19301 var isDraging = false; 19302 var isMoved = false; 19303 if (this.settings.enableDrag) { 19304 this.outer.on('mousedown.lg', function (e) { 19305 _this.dragOrSwipeEnabled = true; 19306 var $item = _this.getSlideItem(_this.index); 19307 if ($LG(e.target).hasClass('lg-item') || 19308 $item.get().contains(e.target)) { 19309 if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) { 19310 e.preventDefault(); 19311 if (!_this.lgBusy) { 19312 _this.manageSwipeClass(); 19313 startCoords = { 19314 pageX: e.pageX, 19315 pageY: e.pageY, 19316 }; 19317 isDraging = true; 19318 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 19319 _this.outer.get().scrollLeft += 1; 19320 _this.outer.get().scrollLeft -= 1; 19321 // * 19322 _this.outer 19323 .removeClass('lg-grab') 19324 .addClass('lg-grabbing'); 19325 _this.LGel.trigger(lGEvents.dragStart); 19326 } 19327 } 19328 } 19329 }); 19330 $LG(window).on("mousemove.lg.global" + this.lgId, function (e) { 19331 if (isDraging && _this.lgOpened) { 19332 isMoved = true; 19333 endCoords = { 19334 pageX: e.pageX, 19335 pageY: e.pageY, 19336 }; 19337 _this.touchMove(startCoords, endCoords); 19338 _this.LGel.trigger(lGEvents.dragMove); 19339 } 19340 }); 19341 $LG(window).on("mouseup.lg.global" + this.lgId, function (event) { 19342 if (!_this.lgOpened) { 19343 return; 19344 } 19345 var target = $LG(event.target); 19346 if (isMoved) { 19347 isMoved = false; 19348 _this.touchEnd(endCoords, startCoords, event); 19349 _this.LGel.trigger(lGEvents.dragEnd); 19350 } 19351 else if (_this.isPosterElement(target)) { 19352 _this.LGel.trigger(lGEvents.posterClick); 19353 } 19354 // Prevent execution on click 19355 if (isDraging) { 19356 isDraging = false; 19357 _this.outer.removeClass('lg-grabbing').addClass('lg-grab'); 19358 } 19359 }); 19360 } 19361 }; 19362 LightGallery.prototype.triggerPosterClick = function () { 19363 var _this = this; 19364 this.$inner.on('click.lg', function (event) { 19365 if (!_this.dragOrSwipeEnabled && 19366 _this.isPosterElement($LG(event.target))) { 19367 _this.LGel.trigger(lGEvents.posterClick); 19368 } 19369 }); 19370 }; 19371 LightGallery.prototype.manageSwipeClass = function () { 19372 var _touchNext = this.index + 1; 19373 var _touchPrev = this.index - 1; 19374 if (this.settings.loop && this.galleryItems.length > 2) { 19375 if (this.index === 0) { 19376 _touchPrev = this.galleryItems.length - 1; 19377 } 19378 else if (this.index === this.galleryItems.length - 1) { 19379 _touchNext = 0; 19380 } 19381 } 19382 this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide'); 19383 if (_touchPrev > -1) { 19384 this.getSlideItem(_touchPrev).addClass('lg-prev-slide'); 19385 } 19386 this.getSlideItem(_touchNext).addClass('lg-next-slide'); 19387 }; 19388 /** 19389 * Go to next slide 19390 * @param {Boolean} fromTouch - true if slide function called via touch event 19391 * @category lGPublicMethods 19392 * @example 19393 * const plugin = lightGallery(); 19394 * plugin.goToNextSlide(); 19395 * @see <a href="/demos/methods/">Demo</a> 19396 */ 19397 LightGallery.prototype.goToNextSlide = function (fromTouch) { 19398 var _this = this; 19399 var _loop = this.settings.loop; 19400 if (fromTouch && this.galleryItems.length < 3) { 19401 _loop = false; 19402 } 19403 if (!this.lgBusy) { 19404 if (this.index + 1 < this.galleryItems.length) { 19405 this.index++; 19406 this.LGel.trigger(lGEvents.beforeNextSlide, { 19407 index: this.index, 19408 }); 19409 this.slide(this.index, !!fromTouch, false, 'next'); 19410 } 19411 else { 19412 if (_loop) { 19413 this.index = 0; 19414 this.LGel.trigger(lGEvents.beforeNextSlide, { 19415 index: this.index, 19416 }); 19417 this.slide(this.index, !!fromTouch, false, 'next'); 19418 } 19419 else if (this.settings.slideEndAnimation && !fromTouch) { 19420 this.outer.addClass('lg-right-end'); 19421 setTimeout(function () { 19422 _this.outer.removeClass('lg-right-end'); 19423 }, 400); 19424 } 19425 } 19426 } 19427 }; 19428 /** 19429 * Go to previous slides 19430 * @param {Boolean} fromTouch - true if slide function called via touch event 19431 * @category lGPublicMethods 19432 * @example 19433 * const plugin = lightGallery({}); 19434 * plugin.goToPrevSlide(); 19435 * @see <a href="/demos/methods/">Demo</a> 19436 * 19437 */ 19438 LightGallery.prototype.goToPrevSlide = function (fromTouch) { 19439 var _this = this; 19440 var _loop = this.settings.loop; 19441 if (fromTouch && this.galleryItems.length < 3) { 19442 _loop = false; 19443 } 19444 if (!this.lgBusy) { 19445 if (this.index > 0) { 19446 this.index--; 19447 this.LGel.trigger(lGEvents.beforePrevSlide, { 19448 index: this.index, 19449 fromTouch: fromTouch, 19450 }); 19451 this.slide(this.index, !!fromTouch, false, 'prev'); 19452 } 19453 else { 19454 if (_loop) { 19455 this.index = this.galleryItems.length - 1; 19456 this.LGel.trigger(lGEvents.beforePrevSlide, { 19457 index: this.index, 19458 fromTouch: fromTouch, 19459 }); 19460 this.slide(this.index, !!fromTouch, false, 'prev'); 19461 } 19462 else if (this.settings.slideEndAnimation && !fromTouch) { 19463 this.outer.addClass('lg-left-end'); 19464 setTimeout(function () { 19465 _this.outer.removeClass('lg-left-end'); 19466 }, 400); 19467 } 19468 } 19469 } 19470 }; 19471 LightGallery.prototype.keyPress = function () { 19472 var _this = this; 19473 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 19474 if (_this.lgOpened && 19475 _this.settings.escKey === true && 19476 e.keyCode === 27) { 19477 e.preventDefault(); 19478 if (_this.settings.allowMediaOverlap && 19479 _this.outer.hasClass('lg-can-toggle') && 19480 _this.outer.hasClass('lg-components-open')) { 19481 _this.outer.removeClass('lg-components-open'); 19482 } 19483 else { 19484 _this.closeGallery(); 19485 } 19486 } 19487 if (_this.lgOpened && _this.galleryItems.length > 1) { 19488 if (e.keyCode === 37) { 19489 e.preventDefault(); 19490 _this.goToPrevSlide(); 19491 } 19492 if (e.keyCode === 39) { 19493 e.preventDefault(); 19494 _this.goToNextSlide(); 19495 } 19496 } 19497 }); 19498 }; 19499 LightGallery.prototype.arrow = function () { 19500 var _this = this; 19501 this.getElementById('lg-prev').on('click.lg', function () { 19502 _this.goToPrevSlide(); 19503 }); 19504 this.getElementById('lg-next').on('click.lg', function () { 19505 _this.goToNextSlide(); 19506 }); 19507 }; 19508 LightGallery.prototype.arrowDisable = function (index) { 19509 // Disable arrows if settings.hideControlOnEnd is true 19510 if (!this.settings.loop && this.settings.hideControlOnEnd) { 19511 var $prev = this.getElementById('lg-prev'); 19512 var $next = this.getElementById('lg-next'); 19513 if (index + 1 === this.galleryItems.length) { 19514 $next.attr('disabled', 'disabled').addClass('disabled'); 19515 } 19516 else { 19517 $next.removeAttr('disabled').removeClass('disabled'); 19518 } 19519 if (index === 0) { 19520 $prev.attr('disabled', 'disabled').addClass('disabled'); 19521 } 19522 else { 19523 $prev.removeAttr('disabled').removeClass('disabled'); 19524 } 19525 } 19526 }; 19527 LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) { 19528 if (scaleX === void 0) { scaleX = 1; } 19529 if (scaleY === void 0) { scaleY = 1; } 19530 $el.css('transform', 'translate3d(' + 19531 xValue + 19532 'px, ' + 19533 yValue + 19534 'px, 0px) scale3d(' + 19535 scaleX + 19536 ', ' + 19537 scaleY + 19538 ', 1)'); 19539 }; 19540 LightGallery.prototype.mousewheel = function () { 19541 var _this = this; 19542 var lastCall = 0; 19543 this.outer.on('wheel.lg', function (e) { 19544 if (!e.deltaY || _this.galleryItems.length < 2) { 19545 return; 19546 } 19547 e.preventDefault(); 19548 var now = new Date().getTime(); 19549 if (now - lastCall < 1000) { 19550 return; 19551 } 19552 lastCall = now; 19553 if (e.deltaY > 0) { 19554 _this.goToNextSlide(); 19555 } 19556 else if (e.deltaY < 0) { 19557 _this.goToPrevSlide(); 19558 } 19559 }); 19560 }; 19561 LightGallery.prototype.isSlideElement = function (target) { 19562 return (target.hasClass('lg-outer') || 19563 target.hasClass('lg-item') || 19564 target.hasClass('lg-img-wrap')); 19565 }; 19566 LightGallery.prototype.isPosterElement = function (target) { 19567 var playButton = this.getSlideItem(this.index) 19568 .find('.lg-video-play-button') 19569 .get(); 19570 return (target.hasClass('lg-video-poster') || 19571 target.hasClass('lg-video-play-button') || 19572 (playButton && playButton.contains(target.get()))); 19573 }; 19574 /** 19575 * Maximize minimize inline gallery. 19576 * @category lGPublicMethods 19577 */ 19578 LightGallery.prototype.toggleMaximize = function () { 19579 var _this = this; 19580 this.getElementById('lg-maximize').on('click.lg', function () { 19581 _this.$container.toggleClass('lg-inline'); 19582 _this.refreshOnResize(); 19583 }); 19584 }; 19585 LightGallery.prototype.invalidateItems = function () { 19586 for (var index = 0; index < this.items.length; index++) { 19587 var element = this.items[index]; 19588 var $element = $LG(element); 19589 $element.off("click.lgcustom-item-" + $element.attr('data-lg-id')); 19590 } 19591 }; 19592 LightGallery.prototype.trapFocus = function () { 19593 var _this = this; 19594 this.$container.get().focus({ 19595 preventScroll: true, 19596 }); 19597 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 19598 if (!_this.lgOpened) { 19599 return; 19600 } 19601 var isTabPressed = e.key === 'Tab' || e.keyCode === 9; 19602 if (!isTabPressed) { 19603 return; 19604 } 19605 var focusableEls = utils.getFocusableElements(_this.$container.get()); 19606 var firstFocusableEl = focusableEls[0]; 19607 var lastFocusableEl = focusableEls[focusableEls.length - 1]; 19608 if (e.shiftKey) { 19609 if (document.activeElement === firstFocusableEl) { 19610 lastFocusableEl.focus(); 19611 e.preventDefault(); 19612 } 19613 } 19614 else { 19615 if (document.activeElement === lastFocusableEl) { 19616 firstFocusableEl.focus(); 19617 e.preventDefault(); 19618 } 19619 } 19620 }); 19621 }; 19622 LightGallery.prototype.manageCloseGallery = function () { 19623 var _this = this; 19624 if (!this.settings.closable) 19625 return; 19626 var mousedown = false; 19627 this.getElementById('lg-close').on('click.lg', function () { 19628 _this.closeGallery(); 19629 }); 19630 if (this.settings.closeOnTap) { 19631 // If you drag the slide and release outside gallery gets close on chrome 19632 // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer 19633 this.outer.on('mousedown.lg', function (e) { 19634 var target = $LG(e.target); 19635 if (_this.isSlideElement(target)) { 19636 mousedown = true; 19637 } 19638 else { 19639 mousedown = false; 19640 } 19641 }); 19642 this.outer.on('mousemove.lg', function () { 19643 mousedown = false; 19644 }); 19645 this.outer.on('mouseup.lg', function (e) { 19646 var target = $LG(e.target); 19647 if (_this.isSlideElement(target) && mousedown) { 19648 if (!_this.outer.hasClass('lg-dragging')) { 19649 _this.closeGallery(); 19650 } 19651 } 19652 }); 19653 } 19654 }; 19655 /** 19656 * Close lightGallery if it is opened. 19657 * 19658 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery 19659 * @return returns the estimated time to close gallery completely including the close animation duration 19660 * @category lGPublicMethods 19661 * @example 19662 * const plugin = lightGallery(); 19663 * plugin.closeGallery(); 19664 * 19665 */ 19666 LightGallery.prototype.closeGallery = function (force) { 19667 var _this = this; 19668 if (!this.lgOpened || (!this.settings.closable && !force)) { 19669 return 0; 19670 } 19671 this.LGel.trigger(lGEvents.beforeClose); 19672 if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) { 19673 $LG(window).scrollTop(this.prevScrollTop); 19674 } 19675 var currentItem = this.items[this.index]; 19676 var transform; 19677 if (this.zoomFromOrigin && currentItem) { 19678 var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom; 19679 var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster; 19680 //Uncode edit ##START## 19681 var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize, this.galleryItems[this.index]); 19682 // var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize); 19683 //Uncode edit ##END## 19684 transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize); 19685 } 19686 if (this.zoomFromOrigin && transform) { 19687 this.outer.addClass('lg-closing lg-zoom-from-image'); 19688 this.getSlideItem(this.index) 19689 .addClass('lg-start-end-progress') 19690 .css('transition-duration', this.settings.startAnimationDuration + 'ms') 19691 .css('transform', transform); 19692 } 19693 else { 19694 this.outer.addClass('lg-hide-items'); 19695 // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true 19696 // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts 19697 this.outer.removeClass('lg-zoom-from-image'); 19698 } 19699 // Unbind all events added by lightGallery 19700 // @todo 19701 //this.$el.off('.lg.tm'); 19702 this.destroyModules(); 19703 this.lGalleryOn = false; 19704 this.isDummyImageRemoved = false; 19705 this.zoomFromOrigin = this.settings.zoomFromOrigin; 19706 clearTimeout(this.hideBarTimeout); 19707 this.hideBarTimeout = false; 19708 $LG('html').removeClass('lg-on'); 19709 this.outer.removeClass('lg-visible lg-components-open'); 19710 // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity. 19711 this.$backdrop.removeClass('in').css('opacity', 0); 19712 var removeTimeout = this.zoomFromOrigin && transform 19713 ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration) 19714 : this.settings.backdropDuration; 19715 this.$container.removeClass('lg-show-in'); 19716 // Once the closign animation is completed and gallery is invisible 19717 setTimeout(function () { 19718 if (_this.zoomFromOrigin && transform) { 19719 _this.outer.removeClass('lg-zoom-from-image'); 19720 } 19721 _this.$container.removeClass('lg-show'); 19722 // Reset scrollbar 19723 _this.resetScrollBar(); 19724 // Need to remove inline opacity as it is used in the stylesheet as well 19725 _this.$backdrop 19726 .removeAttr('style') 19727 .css('transition-duration', _this.settings.backdropDuration + 'ms'); 19728 _this.outer.removeClass("lg-closing " + _this.settings.startClass);
vendor: 6,259 bytes, lines 19729-19932
19729 _this.getSlideItem(_this.index).removeClass('lg-start-end-progress'); 19730 _this.$inner.empty(); 19731 if (_this.lgOpened) { 19732 _this.LGel.trigger(lGEvents.afterClose, { 19733 instance: _this, 19734 }); 19735 } 19736 if (_this.$container.get()) { 19737 _this.$container.get().blur(); 19738 } 19739 _this.lgOpened = false; 19740 }, removeTimeout + 100); 19741 return removeTimeout + 100; 19742 }; 19743 LightGallery.prototype.initModules = function () { 19744 this.plugins.forEach(function (module) { 19745 try { 19746 module.init(); 19747 } 19748 catch (err) { 19749 console.warn("lightGallery:- make sure lightGallery module is properly initiated"); 19750 } 19751 }); 19752 }; 19753 LightGallery.prototype.destroyModules = function (destroy) { 19754 this.plugins.forEach(function (module) { 19755 try { 19756 if (destroy) { 19757 module.destroy(); 19758 } 19759 else { 19760 module.closeGallery && module.closeGallery(); 19761 } 19762 } 19763 catch (err) { 19764 console.warn("lightGallery:- make sure lightGallery module is properly destroyed"); 19765 } 19766 }); 19767 }; 19768 /** 19769 * Refresh lightGallery with new set of children. 19770 * 19771 * @description This is useful to update the gallery when the child elements are changed without calling destroy method. 19772 * 19773 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery 19774 * @see <a href="/demos/dynamic-mode/">Demo</a> 19775 * @category lGPublicMethods 19776 * @example 19777 * const plugin = lightGallery(); 19778 * // Delete or add children, then call 19779 * plugin.refresh(); 19780 * 19781 */ 19782 LightGallery.prototype.refresh = function (galleryItems) { 19783 if (!this.settings.dynamic) { 19784 this.invalidateItems(); 19785 } 19786 if (galleryItems) { 19787 this.galleryItems = galleryItems; 19788 } 19789 else { 19790 this.galleryItems = this.getItems(); 19791 } 19792 this.updateControls(); 19793 this.openGalleryOnItemClick(); 19794 this.LGel.trigger(lGEvents.updateSlides); 19795 }; 19796 LightGallery.prototype.updateControls = function () { 19797 this.addSlideVideoInfo(this.galleryItems); 19798 this.updateCounterTotal(); 19799 this.manageSingleSlideClassName(); 19800 }; 19801 /** 19802 * Destroy lightGallery. 19803 * Destroy lightGallery and its plugin instances completely 19804 * 19805 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance. 19806 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed. 19807 * You can use refresh method most of the times. 19808 * @category lGPublicMethods 19809 * @example 19810 * const plugin = lightGallery(); 19811 * plugin.destroy(); 19812 * 19813 */ 19814 LightGallery.prototype.destroy = function () { 19815 var _this = this; 19816 var closeTimeout = this.closeGallery(true); 19817 setTimeout(function () { 19818 _this.destroyModules(true); 19819 if (!_this.settings.dynamic) { 19820 _this.invalidateItems(); 19821 } 19822 $LG(window).off(".lg.global" + _this.lgId); 19823 _this.LGel.off('.lg'); 19824 _this.$container.remove(); 19825 }, closeTimeout); 19826 return closeTimeout; 19827 }; 19828 return LightGallery; 19829 }()); 19830 19831 function lightGallery(el, options) { 19832 return new LightGallery(el, options); 19833 } 19834 19835 return lightGallery; 19836 19837}))); 19838 19839/*! 19840 * lightgallery | 2.5.0 | June 13th 2022 19841 * http://www.lightgalleryjs.com/ 19842 * Copyright (c) 2020 Sachin Neravath; 19843 * @license GPLv3 19844 */ 19845 19846(function (global, factory) { 19847 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 19848 typeof define === 'function' && define.amd ? define(factory) : 19849 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgZoom = factory()); 19850}(this, (function () { 'use strict'; 19851 19852 /*! ***************************************************************************** 19853 Copyright (c) Microsoft Corporation. 19854 19855 Permission to use, copy, modify, and/or distribute this software for any 19856 purpose with or without fee is hereby granted. 19857 19858 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 19859 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19860 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 19861 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 19862 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 19863 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19864 PERFORMANCE OF THIS SOFTWARE. 19865 ***************************************************************************** */ 19866 19867 var __assign = function() { 19868 __assign = Object.assign || function __assign(t) { 19869 for (var s, i = 1, n = arguments.length; i < n; i++) { 19870 s = arguments[i]; 19871 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 19872 } 19873 return t; 19874 }; 19875 return __assign.apply(this, arguments); 19876 }; 19877 19878 var zoomSettings = { 19879 scale: 1, 19880 zoom: true, 19881 actualSize: true, 19882 showZoomInOutIcons: false, 19883 actualSizeIcons: { 19884 zoomIn: 'lg-zoom-in', 19885 zoomOut: 'lg-zoom-out', 19886 }, 19887 enableZoomAfter: 300, 19888 zoomPluginStrings: { 19889 zoomIn: 'Zoom in', 19890 zoomOut: 'Zoom out', 19891 viewActualSize: 'View actual size', 19892 }, 19893 }; 19894 19895 /** 19896 * List of lightGallery events 19897 * All events should be documented here 19898 * Below interfaces are used to build the website documentations 19899 * */ 19900 var lGEvents = { 19901 afterAppendSlide: 'lgAfterAppendSlide', 19902 init: 'lgInit', 19903 hasVideo: 'lgHasVideo', 19904 containerResize: 'lgContainerResize', 19905 updateSlides: 'lgUpdateSlides', 19906 afterAppendSubHtml: 'lgAfterAppendSubHtml', 19907 beforeOpen: 'lgBeforeOpen', 19908 afterOpen: 'lgAfterOpen', 19909 slideItemLoad: 'lgSlideItemLoad', 19910 beforeSlide: 'lgBeforeSlide', 19911 afterSlide: 'lgAfterSlide', 19912 posterClick: 'lgPosterClick', 19913 dragStart: 'lgDragStart', 19914 dragMove: 'lgDragMove', 19915 dragEnd: 'lgDragEnd', 19916 beforeNextSlide: 'lgBeforeNextSlide', 19917 beforePrevSlide: 'lgBeforePrevSlide', 19918 beforeClose: 'lgBeforeClose', 19919 afterClose: 'lgAfterClose', 19920 rotateLeft: 'lgRotateLeft', 19921 rotateRight: 'lgRotateRight', 19922 flipHorizontal: 'lgFlipHorizontal', 19923 flipVertical: 'lgFlipVertical', 19924 autoplay: 'lgAutoplay', 19925 autoplayStart: 'lgAutoplayStart', 19926 autoplayStop: 'lgAutoplayStop', 19927 }; 19928 19929 var Zoom = /** @class */ (function () { 19930 function Zoom(instance, $LG) { 19931 // get lightGallery core plugin instance 19932 this.core = instance;
19933 this.$LG = $LG; 19934 this.settings = __assign(__assign({}, zoomSettings), this.core.settings); 19935 return this; 19936 } 19937 // Append Zoom controls. Actual size, Zoom-in, Zoom-out 19938 Zoom.prototype.buildTemplates = function () { 19939 var zoomIcons = this.settings.showZoomInOutIcons 19940 ? "<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>" 19941 : ''; 19942 if (this.settings.actualSize) { 19943 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>"; 19944 } 19945 this.core.outer.addClass('lg-use-transition-for-zoom'); 19946 this.core.$toolbar.first().append(zoomIcons); 19947 }; 19948 /** 19949 * @desc Enable zoom option only once the image is completely loaded 19950 * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted 19951 * 19952 * Zoom styles are defined under lg-zoomable CSS class. 19953 */ 19954 Zoom.prototype.enableZoom = function (event) { 19955 var _this = this; 19956 // delay will be 0 except first time 19957 var _speed = this.settings.enableZoomAfter + event.detail.delay; 19958 // set _speed value 0 if gallery opened from direct url and if it is first slide 19959 if (this.$LG('body').first().hasClass('lg-from-hash') && 19960 event.detail.delay) { 19961 // will execute only once 19962 _speed = 0; 19963 } 19964 else { 19965 // Remove lg-from-hash to enable starting animation. 19966 this.$LG('body').first().removeClass('lg-from-hash'); 19967 } 19968 this.zoomableTimeout = setTimeout(function () { 19969 if (!_this.isImageSlide()) { 19970 return; 19971 } 19972 _this.core.getSlideItem(event.detail.index).addClass('lg-zoomable'); 19973 if (event.detail.index === _this.core.index) { 19974 _this.setZoomEssentials(); 19975 } 19976 }, _speed + 30); 19977 }; 19978 Zoom.prototype.enableZoomOnSlideItemLoad = function () { 19979 // Add zoomable class 19980 this.core.LGel.on(lGEvents.slideItemLoad + ".zoom", this.enableZoom.bind(this)); 19981 }; 19982 Zoom.prototype.getModifier = function (rotateValue, axis, el) { 19983 var originalRotate = rotateValue; 19984 rotateValue = Math.abs(rotateValue); 19985 var transformValues = this.getCurrentTransform(el); 19986 if (!transformValues) { 19987 return 1; 19988 } 19989 var modifier = 1; 19990 if (axis === 'X') { 19991 var flipHorizontalValue = Math.sign(parseFloat(transformValues[0])); 19992 if (rotateValue === 0 || rotateValue === 180) { 19993 modifier = 1; 19994 } 19995 else if (rotateValue === 90) { 19996 if ((originalRotate === -90 && flipHorizontalValue === 1) || 19997 (originalRotate === 90 && flipHorizontalValue === -1)) { 19998 modifier = -1; 19999 } 20000 else { 20001 modifier = 1; 20002 } 20003 } 20004 modifier = modifier * flipHorizontalValue; 20005 } 20006 else { 20007 var flipVerticalValue = Math.sign(parseFloat(transformValues[3])); 20008 if (rotateValue === 0 || rotateValue === 180) { 20009 modifier = 1; 20010 } 20011 else if (rotateValue === 90) { 20012 var sinX = parseFloat(transformValues[1]); 20013 var sinMinusX = parseFloat(transformValues[2]); 20014 modifier = Math.sign(sinX * sinMinusX * originalRotate * flipVerticalValue); 20015 } 20016 modifier = modifier * flipVerticalValue; 20017 } 20018 return modifier; 20019 }; 20020 Zoom.prototype.getImageSize = function ($image, rotateValue, axis) { 20021 var imageSizes = { 20022 y: 'offsetHeight', 20023 x: 'offsetWidth', 20024 }; 20025 if (Math.abs(rotateValue) === 90) { 20026 // Swap axis 20027 if (axis === 'x') { 20028 axis = 'y'; 20029 } 20030 else { 20031 axis = 'x'; 20032 } 20033 } 20034 return $image[imageSizes[axis]]; 20035 }; 20036 Zoom.prototype.getDragCords = function (e, rotateValue) { 20037 if (rotateValue === 90) { 20038 return { 20039 x: e.pageY, 20040 y: e.pageX, 20041 }; 20042 } 20043 else { 20044 return { 20045 x: e.pageX, 20046 y: e.pageY, 20047 }; 20048 } 20049 }; 20050 Zoom.prototype.getSwipeCords = function (e, rotateValue) { 20051 var x = e.targetTouches[0].pageX; 20052 var y = e.targetTouches[0].pageY; 20053 if (rotateValue === 90) { 20054 return { 20055 x: y, 20056 y: x, 20057 }; 20058 } 20059 else { 20060 return { 20061 x: x, 20062 y: y, 20063 }; 20064 } 20065 }; 20066 Zoom.prototype.getDragAllowedAxises = function (rotateValue, scale) { 20067 scale = scale || this.scale || 1; 20068 var allowY = this.imageYSize * scale > this.containerRect.height; 20069 var allowX = this.imageXSize * scale > this.containerRect.width; 20070 if (rotateValue === 90) { 20071 return { 20072 allowX: allowY, 20073 allowY: allowX, 20074 }; 20075 } 20076 else { 20077 return { 20078 allowX: allowX, 20079 allowY: allowY, 20080 }; 20081 } 20082 }; 20083 /** 20084 * 20085 * @param {Element} el 20086 * @return matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0); 20087 * Get the current transform value 20088 */ 20089 Zoom.prototype.getCurrentTransform = function (el) { 20090 if (!el) { 20091 return; 20092 } 20093 var st = window.getComputedStyle(el, null); 20094 var tm = st.getPropertyValue('-webkit-transform') || 20095 st.getPropertyValue('-moz-transform') || 20096 st.getPropertyValue('-ms-transform') || 20097 st.getPropertyValue('-o-transform') || 20098 st.getPropertyValue('transform') || 20099 'none'; 20100 if (tm !== 'none') { 20101 return tm.split('(')[1].split(')')[0].split(','); 20102 } 20103 return; 20104 }; 20105 Zoom.prototype.getCurrentRotation = function (el) { 20106 if (!el) { 20107 return 0; 20108 } 20109 var values = this.getCurrentTransform(el); 20110 if (values) { 20111 return Math.round(Math.atan2(parseFloat(values[1]), parseFloat(values[0])) * 20112 (180 / Math.PI)); 20113 // If you want rotate in 360 20114 //return (angle < 0 ? angle + 360 : angle); 20115 } 20116 return 0; 20117 }; 20118 Zoom.prototype.setZoomEssentials = function () { 20119 var $image = this.core 20120 .getSlideItem(this.core.index) 20121 .find('.lg-image') 20122 .first(); 20123 var rotateEl = this.core 20124 .getSlideItem(this.core.index) 20125 .find('.lg-img-rotate') 20126 .first() 20127 .get(); 20128 this.rotateValue = this.getCurrentRotation(rotateEl); 20129 this.imageYSize = this.getImageSize($image.get(), this.rotateValue, 'y'); 20130 this.imageXSize = this.getImageSize($image.get(), this.rotateValue, 'x'); 20131 this.containerRect = this.core.outer.get().getBoundingClientRect(); 20132 this.modifierX = this.getModifier(this.rotateValue, 'X', rotateEl); 20133 this.modifierY = this.getModifier(this.rotateValue, 'Y', rotateEl); 20134 }; 20135 /** 20136 * @desc Image zoom 20137 * Translate the wrap and scale the image to get better user experience 20138 * 20139 * @param {String} scale - Zoom decrement/increment value 20140 */ 20141 Zoom.prototype.zoomImage = function (scale) { 20142 // Find offset manually to avoid issue after zoom 20143 var offsetX = (this.containerRect.width - this.imageXSize) / 2 + 20144 this.containerRect.left; 20145 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 20146 var topBottomSpacing = Math.abs(top - bottom) / 2; 20147 var offsetY = (this.containerRect.height - 20148 this.imageYSize - 20149 topBottomSpacing * this.modifierX) / 20150 2 + 20151 this.scrollTop + 20152 this.containerRect.top; 20153 var originalX; 20154 var originalY; 20155 if (scale === 1) { 20156 this.positionChanged = false;
20157 } 20158 var dragAllowedAxises = this.getDragAllowedAxises(Math.abs(this.rotateValue), scale); 20159 var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX; 20160 if (this.positionChanged) { 20161 originalX = this.left / (this.scale - 1); 20162 originalY = this.top / (this.scale - 1); 20163 this.pageX = Math.abs(originalX) + offsetX; 20164 this.pageY = Math.abs(originalY) + offsetY; 20165 this.positionChanged = false; 20166 } 20167 var possibleSwipeCords = this.getPossibleSwipeDragCords(this.rotateValue, scale); 20168 var _x = offsetX - this.pageX; 20169 var _y = offsetY - this.pageY; 20170 var x = (scale - 1) * _x; 20171 var y = (scale - 1) * _y; 20172 if (allowX) { 20173 if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) { 20174 x = possibleSwipeCords.minX; 20175 } 20176 else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) { 20177 x = possibleSwipeCords.maxX; 20178 } 20179 } 20180 else { 20181 if (scale > 1) { 20182 if (x < possibleSwipeCords.minX) { 20183 x = possibleSwipeCords.minX; 20184 } 20185 else if (x > possibleSwipeCords.maxX) { 20186 x = possibleSwipeCords.maxX; 20187 } 20188 } 20189 }
20190 if (allowY) { 20191 if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) { 20192 y = possibleSwipeCords.minY; 20193 } 20194 else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) { 20195 y = possibleSwipeCords.maxY; 20196 } 20197 } 20198 else { 20199 // If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out 20200 if (scale > 1) { 20201 //If image goes beyond viewport top, use the minim possible translate value 20202 if (y < possibleSwipeCords.minY) { 20203 y = possibleSwipeCords.minY; 20204 } 20205 else if (y > possibleSwipeCords.maxY) { 20206 y = possibleSwipeCords.maxY; 20207 } 20208 } 20209 } 20210 this.setZoomStyles({ 20211 x: x, 20212 y: y, 20213 scale: scale, 20214 }); 20215 }; 20216 /** 20217 * @desc apply scale3d to image and translate to image wrap 20218 * @param {style} X,Y and scale 20219 */ 20220 Zoom.prototype.setZoomStyles = function (style) { 20221 var $image = this.core 20222 .getSlideItem(this.core.index) 20223 .find('.lg-image') 20224 .first(); 20225 var $dummyImage = this.core.outer 20226 .find('.lg-current .lg-dummy-img') 20227 .first(); 20228 var $imageWrap = $image.parent(); 20229 this.scale = style.scale; 20230 $image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 20231 $dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 20232 var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)'; 20233 $imageWrap.css('transform', transform); 20234 this.left = style.x; 20235 this.top = style.y; 20236 }; 20237 /** 20238 * @param index - Index of the current slide 20239 * @param event - event will be available only if the function is called on clicking/taping the imags 20240 */ 20241 Zoom.prototype.setActualSize = function (index, event) { 20242 var _this = this; 20243 // Allow zoom only on image 20244 if (!this.isImageSlide() || 20245 this.core.outer.hasClass('lg-first-slide-loading')) { 20246 return; 20247 } 20248 var scale = this.getCurrentImageActualSizeScale(); 20249 if (this.core.outer.hasClass('lg-zoomed')) { 20250 this.scale = 1; 20251 } 20252 else { 20253 this.scale = this.getScale(scale); 20254 } 20255 this.setPageCords(event); 20256 this.beginZoom(this.scale); 20257 this.zoomImage(this.scale); 20258 setTimeout(function () { 20259 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20260 }, 10); 20261 }; 20262 Zoom.prototype.getNaturalWidth = function (index) { 20263 var $image = this.core.getSlideItem(index).find('.lg-image').first(); 20264 var naturalWidth = this.core.galleryItems[index].width; 20265 return naturalWidth 20266 ? parseFloat(naturalWidth) 20267 : $image.get().naturalWidth; 20268 }; 20269 Zoom.prototype.getActualSizeScale = function (naturalWidth, width) { 20270 var _scale; 20271 var scale;
20272 if (naturalWidth > width) { 20273 _scale = naturalWidth / width; 20274 scale = _scale || 2; 20275 } 20276 else { 20277 scale = 1; 20278 } 20279 return scale; 20280 }; 20281 Zoom.prototype.getCurrentImageActualSizeScale = function () { 20282 var $image = this.core 20283 .getSlideItem(this.core.index) 20284 .find('.lg-image') 20285 .first(); 20286 var width = $image.get().offsetWidth; 20287 var naturalWidth = this.getNaturalWidth(this.core.index) || width; 20288 return this.getActualSizeScale(naturalWidth, width); 20289 }; 20290 Zoom.prototype.getPageCords = function (event) { 20291 var cords = {}; 20292 if (event) { 20293 cords.x = event.pageX || event.targetTouches[0].pageX; 20294 cords.y = event.pageY || event.targetTouches[0].pageY; 20295 } 20296 else { 20297 var containerRect = this.core.outer.get().getBoundingClientRect(); 20298 cords.x = containerRect.width / 2 + containerRect.left; 20299 cords.y = 20300 containerRect.height / 2 + this.scrollTop + containerRect.top; 20301 } 20302 return cords; 20303 }; 20304 Zoom.prototype.setPageCords = function (event) { 20305 var pageCords = this.getPageCords(event); 20306 this.pageX = pageCords.x; 20307 this.pageY = pageCords.y; 20308 }; 20309 // If true, zoomed - in else zoomed out 20310 Zoom.prototype.beginZoom = function (scale) { 20311 this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 20312 if (scale > 1) { 20313 this.core.outer.addClass('lg-zoomed'); 20314 var $actualSize = this.core.getElementById('lg-actual-size'); 20315 $actualSize 20316 .removeClass(this.settings.actualSizeIcons.zoomIn) 20317 .addClass(this.settings.actualSizeIcons.zoomOut); 20318 } 20319 else { 20320 this.resetZoom(); 20321 } 20322 return scale > 1; 20323 }; 20324 Zoom.prototype.getScale = function (scale) { 20325 var actualSizeScale = this.getCurrentImageActualSizeScale(); 20326 if (scale < 1) { 20327 scale = 1; 20328 } 20329 else if (scale > actualSizeScale) { 20330 scale = actualSizeScale; 20331 } 20332 return scale; 20333 }; 20334 Zoom.prototype.init = function () { 20335 var _this = this; 20336 if (!this.settings.zoom) { 20337 return; 20338 } 20339 this.buildTemplates(); 20340 this.enableZoomOnSlideItemLoad(); 20341 var tapped = null; 20342 this.core.outer.on('dblclick.lg', function (event) { 20343 if (!_this.$LG(event.target).hasClass('lg-image')) { 20344 return; 20345 } 20346 _this.setActualSize(_this.core.index, event); 20347 }); 20348 this.core.outer.on('touchstart.lg', function (event) { 20349 var $target = _this.$LG(event.target); 20350 if (event.targetTouches.length === 1 && 20351 $target.hasClass('lg-image')) { 20352 if (!tapped) { 20353 tapped = setTimeout(function () { 20354 tapped = null; 20355 }, 300); 20356 } 20357 else { 20358 clearTimeout(tapped); 20359 tapped = null; 20360 event.preventDefault(); 20361 _this.setActualSize(_this.core.index, event); 20362 } 20363 } 20364 }); 20365 // Update zoom on resize and orientationchange 20366 this.core.LGel.on(lGEvents.containerResize + ".zoom " + lGEvents.rotateRight + ".zoom " + lGEvents.rotateLeft + ".zoom " + lGEvents.flipHorizontal + ".zoom " + lGEvents.flipVertical + ".zoom", function () { 20367 if (!_this.core.lgOpened || !_this.isImageSlide()) 20368 return; 20369 _this.setPageCords(); 20370 _this.setZoomEssentials(); 20371 _this.zoomImage(_this.scale); 20372 }); 20373 // Update zoom on resize and orientationchange 20374 this.$LG(window).on("scroll.lg.zoom.global" + this.core.lgId, function () { 20375 if (!_this.core.lgOpened) 20376 return; 20377 _this.scrollTop = _this.$LG(window).scrollTop(); 20378 }); 20379 this.core.getElementById('lg-zoom-out').on('click.lg', function () { 20380 if (_this.core.outer.find('.lg-current .lg-image').get()) { 20381 _this.scale -= _this.settings.scale; 20382 _this.scale = _this.getScale(_this.scale); 20383 _this.beginZoom(_this.scale); 20384 _this.zoomImage(_this.scale); 20385 } 20386 }); 20387 this.core.getElementById('lg-zoom-in').on('click.lg', function () { 20388 _this.zoomIn(); 20389 }); 20390 this.core.getElementById('lg-actual-size').on('click.lg', function () { 20391 _this.setActualSize(_this.core.index); 20392 }); 20393 this.core.LGel.on(lGEvents.beforeOpen + ".zoom", function () { 20394 _this.core.outer.find('.lg-item').removeClass('lg-zoomable'); 20395 }); 20396 this.core.LGel.on(lGEvents.afterOpen + ".zoom", function () { 20397 _this.scrollTop = _this.$LG(window).scrollTop(); 20398 // Set the initial value center 20399 _this.pageX = _this.core.outer.width() / 2;
20400 _this.pageY = _this.core.outer.height() / 2 + _this.scrollTop; 20401 _this.scale = 1; 20402 }); 20403 // Reset zoom on slide change 20404 this.core.LGel.on(lGEvents.afterSlide + ".zoom", function (event) { 20405 var prevIndex = event.detail.prevIndex; 20406 _this.scale = 1; 20407 _this.positionChanged = false; 20408 _this.resetZoom(prevIndex); 20409 if (_this.isImageSlide()) { 20410 _this.setZoomEssentials(); 20411 } 20412 }); 20413 // Drag option after zoom 20414 this.zoomDrag(); 20415 this.pinchZoom(); 20416 this.zoomSwipe(); 20417 // Store the zoomable timeout value just to clear it while closing 20418 this.zoomableTimeout = false; 20419 this.positionChanged = false; 20420 }; 20421 Zoom.prototype.zoomIn = function (scale) { 20422 // Allow zoom only on image 20423 if (!this.isImageSlide()) { 20424 return; 20425 } 20426 if (scale) { 20427 this.scale = scale; 20428 } 20429 else { 20430 this.scale += this.settings.scale; 20431 } 20432 this.scale = this.getScale(this.scale); 20433 this.beginZoom(this.scale); 20434 this.zoomImage(this.scale); 20435 }; 20436 // Reset zoom effect 20437 Zoom.prototype.resetZoom = function (index) { 20438 this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition'); 20439 var $actualSize = this.core.getElementById('lg-actual-size'); 20440 var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index); 20441 $actualSize 20442 .removeClass(this.settings.actualSizeIcons.zoomOut) 20443 .addClass(this.settings.actualSizeIcons.zoomIn); 20444 $item.find('.lg-img-wrap').first().removeAttr('style'); 20445 $item.find('.lg-image').first().removeAttr('style'); 20446 this.scale = 1; 20447 this.left = 0; 20448 this.top = 0; 20449 // Reset pagx pagy values to center 20450 this.setPageCords(); 20451 }; 20452 Zoom.prototype.getTouchDistance = function (e) { 20453 return Math.sqrt((e.targetTouches[0].pageX - e.targetTouches[1].pageX) * 20454 (e.targetTouches[0].pageX - e.targetTouches[1].pageX) + 20455 (e.targetTouches[0].pageY - e.targetTouches[1].pageY) * 20456 (e.targetTouches[0].pageY - e.targetTouches[1].pageY)); 20457 }; 20458 Zoom.prototype.pinchZoom = function () { 20459 var _this = this; 20460 var startDist = 0; 20461 var pinchStarted = false; 20462 var initScale = 1; 20463 var $item = this.core.getSlideItem(this.core.index); 20464 this.core.$inner.on('touchstart.lg', function (e) { 20465 $item = _this.core.getSlideItem(_this.core.index); 20466 if (!_this.isImageSlide()) { 20467 return; 20468 } 20469 if (e.targetTouches.length === 2 && 20470 !_this.core.outer.hasClass('lg-first-slide-loading') && 20471 (_this.$LG(e.target).hasClass('lg-item') || 20472 $item.get().contains(e.target))) { 20473 initScale = _this.scale || 1; 20474 _this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 20475 _this.core.touchAction = 'pinch'; 20476 startDist = _this.getTouchDistance(e); 20477 } 20478 }); 20479 this.core.$inner.on('touchmove.lg', function (e) { 20480 if (e.targetTouches.length === 2 && 20481 _this.core.touchAction === 'pinch' && 20482 (_this.$LG(e.target).hasClass('lg-item') || 20483 $item.get().contains(e.target))) { 20484 e.preventDefault(); 20485 var endDist = _this.getTouchDistance(e); 20486 var distance = startDist - endDist; 20487 if (!pinchStarted && Math.abs(distance) > 5) { 20488 pinchStarted = true; 20489 } 20490 if (pinchStarted) { 20491 _this.scale = Math.max(1, initScale + -distance * 0.008); 20492 _this.zoomImage(_this.scale); 20493 } 20494 } 20495 }); 20496 this.core.$inner.on('touchend.lg', function (e) { 20497 if (_this.core.touchAction === 'pinch' && 20498 (_this.$LG(e.target).hasClass('lg-item') || 20499 $item.get().contains(e.target))) { 20500 pinchStarted = false; 20501 startDist = 0; 20502 if (_this.scale <= 1) { 20503 _this.resetZoom(); 20504 } 20505 else { 20506 _this.scale = _this.getScale(_this.scale); 20507 _this.zoomImage(_this.scale); 20508 _this.core.outer.addClass('lg-zoomed'); 20509 } 20510 _this.core.touchAction = undefined; 20511 } 20512 }); 20513 }; 20514 Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration, rotateValue) { 20515 var distanceXnew = endCoords.x - startCoords.x; 20516 var distanceYnew = endCoords.y - startCoords.y; 20517 var speedX = Math.abs(distanceXnew) / touchDuration + 1; 20518 var speedY = Math.abs(distanceYnew) / touchDuration + 1; 20519 if (speedX > 2) { 20520 speedX += 1; 20521 } 20522 if (speedY > 2) { 20523 speedY += 1; 20524 } 20525 distanceXnew = distanceXnew * speedX; 20526 distanceYnew = distanceYnew * speedY; 20527 var _LGel = this.core 20528 .getSlideItem(this.core.index) 20529 .find('.lg-img-wrap') 20530 .first(); 20531 var distance = {}; 20532 distance.x = this.left + distanceXnew * this.modifierX; 20533 distance.y = this.top + distanceYnew * this.modifierY; 20534 var possibleSwipeCords = this.getPossibleSwipeDragCords(rotateValue); 20535 if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) { 20536 if (allowY) { 20537 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 20538 distance.y = possibleSwipeCords.minY; 20539 } 20540 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 20541 distance.y = possibleSwipeCords.maxY; 20542 } 20543 } 20544 if (allowX) { 20545 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 20546 distance.x = possibleSwipeCords.minX; 20547 } 20548 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 20549 distance.x = possibleSwipeCords.maxX; 20550 } 20551 } 20552 if (allowY) { 20553 this.top = distance.y; 20554 } 20555 else { 20556 distance.y = this.top; 20557 } 20558 if (allowX) { 20559 this.left = distance.x; 20560 } 20561 else { 20562 distance.x = this.left; 20563 } 20564 this.setZoomSwipeStyles(_LGel, distance); 20565 this.positionChanged = true; 20566 } 20567 }; 20568 Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) { 20569 var distance = {}; 20570 if (allowY) { 20571 distance.y = 20572 this.top + (endCoords.y - startCoords.y) * this.modifierY; 20573 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 20574 var diffMinY = possibleSwipeCords.minY - distance.y; 20575 distance.y = possibleSwipeCords.minY - diffMinY / 6; 20576 } 20577 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 20578 var diffMaxY = distance.y - possibleSwipeCords.maxY; 20579 distance.y = possibleSwipeCords.maxY + diffMaxY / 6; 20580 } 20581 } 20582 else { 20583 distance.y = this.top; 20584 }
20585 if (allowX) { 20586 distance.x = 20587 this.left + (endCoords.x - startCoords.x) * this.modifierX; 20588 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 20589 var diffMinX = possibleSwipeCords.minX - distance.x; 20590 distance.x = possibleSwipeCords.minX - diffMinX / 6; 20591 } 20592 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 20593 var difMaxX = distance.x - possibleSwipeCords.maxX; 20594 distance.x = possibleSwipeCords.maxX + difMaxX / 6; 20595 } 20596 } 20597 else { 20598 distance.x = this.left; 20599 } 20600 return distance; 20601 }; 20602 Zoom.prototype.isBeyondPossibleLeft = function (x, minX) { 20603 return x >= minX; 20604 }; 20605 Zoom.prototype.isBeyondPossibleRight = function (x, maxX) { 20606 return x <= maxX; 20607 }; 20608 Zoom.prototype.isBeyondPossibleTop = function (y, minY) { 20609 return y >= minY; 20610 }; 20611 Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) { 20612 return y <= maxY; 20613 }; 20614 Zoom.prototype.isImageSlide = function () { 20615 var currentItem = this.core.galleryItems[this.core.index]; 20616 return this.core.getSlideType(currentItem) === 'image'; 20617 }; 20618 Zoom.prototype.getPossibleSwipeDragCords = function (rotateValue, scale) { 20619 var dataScale = scale || this.scale || 1; 20620 var elDataScale = Math.abs(dataScale); 20621 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 20622 var topBottomSpacing = Math.abs(top - bottom) / 2; 20623 var minY = (this.imageYSize - this.containerRect.height) / 2 + 20624 topBottomSpacing * this.modifierX; 20625 var maxY = this.containerRect.height - this.imageYSize * elDataScale + minY; 20626 var minX = (this.imageXSize - this.containerRect.width) / 2; 20627 var maxX = this.containerRect.width - this.imageXSize * elDataScale + minX; 20628 var possibleSwipeCords = { 20629 minY: minY, 20630 maxY: maxY, 20631 minX: minX, 20632 maxX: maxX, 20633 }; 20634 if (Math.abs(rotateValue) === 90) { 20635 possibleSwipeCords = { 20636 minY: minX, 20637 maxY: maxX, 20638 minX: minY, 20639 maxX: maxY, 20640 }; 20641 } 20642 return possibleSwipeCords; 20643 }; 20644 Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) { 20645 LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)'); 20646 }; 20647 Zoom.prototype.zoomSwipe = function () { 20648 var _this = this; 20649 var startCoords = {}; 20650 var endCoords = {}; 20651 var isMoved = false; 20652 // Allow x direction drag 20653 var allowX = false; 20654 // Allow Y direction drag 20655 var allowY = false; 20656 var startTime = new Date(); 20657 var endTime = new Date(); 20658 var possibleSwipeCords; 20659 var _LGel; 20660 var $item = this.core.getSlideItem(this.core.index); 20661 this.core.$inner.on('touchstart.lg', function (e) { 20662 // Allow zoom only on image 20663 if (!_this.isImageSlide()) { 20664 return; 20665 } 20666 $item = _this.core.getSlideItem(_this.core.index); 20667 if ((_this.$LG(e.target).hasClass('lg-item') || 20668 $item.get().contains(e.target)) && 20669 e.targetTouches.length === 1 && 20670 _this.core.outer.hasClass('lg-zoomed')) { 20671 e.preventDefault(); 20672 startTime = new Date(); 20673 _this.core.touchAction = 'zoomSwipe'; 20674 _LGel = _this.core 20675 .getSlideItem(_this.core.index) 20676 .find('.lg-img-wrap') 20677 .first(); 20678 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 20679 allowY = dragAllowedAxises.allowY; 20680 allowX = dragAllowedAxises.allowX; 20681 if (allowX || allowY) { 20682 startCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 20683 } 20684 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20685 // reset opacity and transition duration 20686 _this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition'); 20687 } 20688 }); 20689 this.core.$inner.on('touchmove.lg', function (e) { 20690 if (e.targetTouches.length === 1 && 20691 _this.core.touchAction === 'zoomSwipe' && 20692 (_this.$LG(e.target).hasClass('lg-item') || 20693 $item.get().contains(e.target))) { 20694 e.preventDefault(); 20695 _this.core.touchAction = 'zoomSwipe'; 20696 endCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 20697 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20698 if (Math.abs(endCoords.x - startCoords.x) > 15 || 20699 Math.abs(endCoords.y - startCoords.y) > 15) { 20700 isMoved = true; 20701 _this.setZoomSwipeStyles(_LGel, distance); 20702 } 20703 } 20704 }); 20705 this.core.$inner.on('touchend.lg', function (e) { 20706 if (_this.core.touchAction === 'zoomSwipe' && 20707 (_this.$LG(e.target).hasClass('lg-item') || 20708 $item.get().contains(e.target))) { 20709 _this.core.touchAction = undefined; 20710 _this.core.outer.removeClass('lg-zoom-dragging'); 20711 if (!isMoved) { 20712 return; 20713 } 20714 isMoved = false;
20715 endTime = new Date(); 20716 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20717 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20718 } 20719 }); 20720 }; 20721 Zoom.prototype.zoomDrag = function () { 20722 var _this = this; 20723 var startCoords = {}; 20724 var endCoords = {}; 20725 var isDragging = false; 20726 var isMoved = false; 20727 // Allow x direction drag 20728 var allowX = false; 20729 // Allow Y direction drag 20730 var allowY = false; 20731 var startTime; 20732 var endTime; 20733 var possibleSwipeCords; 20734 var _LGel; 20735 this.core.outer.on('mousedown.lg.zoom', function (e) { 20736 // Allow zoom only on image 20737 if (!_this.isImageSlide()) { 20738 return; 20739 } 20740 var $item = _this.core.getSlideItem(_this.core.index); 20741 if (_this.$LG(e.target).hasClass('lg-item') || 20742 $item.get().contains(e.target)) { 20743 startTime = new Date(); 20744 _LGel = _this.core 20745 .getSlideItem(_this.core.index) 20746 .find('.lg-img-wrap') 20747 .first(); 20748 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 20749 allowY = dragAllowedAxises.allowY; 20750 allowX = dragAllowedAxises.allowX; 20751 if (_this.core.outer.hasClass('lg-zoomed')) { 20752 if (_this.$LG(e.target).hasClass('lg-object') && 20753 (allowX || allowY)) { 20754 e.preventDefault(); 20755 startCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20756 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20757 isDragging = true; 20758 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 20759 _this.core.outer.get().scrollLeft += 1; 20760 _this.core.outer.get().scrollLeft -= 1; 20761 _this.core.outer 20762 .removeClass('lg-grab') 20763 .addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging'); 20764 // reset opacity and transition duration 20765 } 20766 } 20767 } 20768 }); 20769 this.$LG(window).on("mousemove.lg.zoom.global" + this.core.lgId, function (e) { 20770 if (isDragging) { 20771 isMoved = true; 20772 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20773 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20774 _this.setZoomSwipeStyles(_LGel, distance); 20775 } 20776 }); 20777 this.$LG(window).on("mouseup.lg.zoom.global" + this.core.lgId, function (e) { 20778 if (isDragging) { 20779 endTime = new Date(); 20780 isDragging = false; 20781 _this.core.outer.removeClass('lg-zoom-dragging'); 20782 // Fix for chrome mouse move on click 20783 if (isMoved && 20784 (startCoords.x !== endCoords.x || 20785 startCoords.y !== endCoords.y)) { 20786 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20787 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20788 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20789 } 20790 isMoved = false; 20791 } 20792 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20793 }); 20794 }; 20795 Zoom.prototype.closeGallery = function () { 20796 this.resetZoom(); 20797 }; 20798 Zoom.prototype.destroy = function () { 20799 // Unbind all events added by lightGallery zoom plugin 20800 this.$LG(window).off(".lg.zoom.global" + this.core.lgId); 20801 this.core.LGel.off('.lg.zoom'); 20802 this.core.LGel.off('.zoom'); 20803 clearTimeout(this.zoomableTimeout); 20804 this.zoomableTimeout = false; 20805 }; 20806 return Zoom; 20807 }()); 20808 20809 return Zoom; 20810 20811}))); 20812/*! 20813 * lightgallery | 2.5.0 | June 13th 2022 20814 * http://www.lightgalleryjs.com/ 20815 * Copyright (c) 2020 Sachin Neravath; 20816 * @license GPLv3 20817 */ 20818 20819(function (global, factory) { 20820 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20821 typeof define === 'function' && define.amd ? define(factory) : 20822 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgFullscreen = factory()); 20823}(this, (function () { 'use strict'; 20824 20825 /*! ***************************************************************************** 20826 Copyright (c) Microsoft Corporation. 20827 20828 Permission to use, copy, modify, and/or distribute this software for any 20829 purpose with or without fee is hereby granted. 20830 20831 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20832 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20833 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20834 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20835 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20836 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20837 PERFORMANCE OF THIS SOFTWARE. 20838 ***************************************************************************** */ 20839 20840 var __assign = function() { 20841 __assign = Object.assign || function __assign(t) { 20842 for (var s, i = 1, n = arguments.length; i < n; i++) { 20843 s = arguments[i]; 20844 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20845 } 20846 return t; 20847 }; 20848 return __assign.apply(this, arguments); 20849 }; 20850 20851 var fullscreenSettings = { 20852 fullScreen: true, 20853 fullscreenPluginStrings: { 20854 toggleFullscreen: 'Toggle Fullscreen', 20855 }, 20856 }; 20857 20858 var FullScreen = /** @class */ (function () { 20859 function FullScreen(instance, $LG) { 20860 // get lightGallery core plugin instance 20861 this.core = instance;
20862 this.$LG = $LG; 20863 // extend module default settings with lightGallery core settings 20864 this.settings = __assign(__assign({}, fullscreenSettings), this.core.settings); 20865 return this; 20866 } 20867 FullScreen.prototype.init = function () { 20868 var fullScreen = ''; 20869 if (this.settings.fullScreen) { 20870 // check for fullscreen browser support 20871 if (!document.fullscreenEnabled && 20872 !document.webkitFullscreenEnabled && 20873 !document.mozFullScreenEnabled && 20874 !document.msFullscreenEnabled) { 20875 return; 20876 } 20877 else { 20878 fullScreen = "<button type=\"button\" aria-label=\"" + this.settings.fullscreenPluginStrings['toggleFullscreen'] + "\" class=\"lg-fullscreen lg-icon\"></button>"; 20879 this.core.$toolbar.append(fullScreen); 20880 this.fullScreen(); 20881 } 20882 } 20883 }; 20884 FullScreen.prototype.isFullScreen = function () { 20885 return (document.fullscreenElement || 20886 document.mozFullScreenElement || 20887 document.webkitFullscreenElement || 20888 document.msFullscreenElement); 20889 }; 20890 FullScreen.prototype.requestFullscreen = function () { 20891 var el = document.documentElement; 20892 if (el.requestFullscreen) { 20893 el.requestFullscreen(); 20894 } 20895 else if (el.msRequestFullscreen) { 20896 el.msRequestFullscreen(); 20897 } 20898 else if (el.mozRequestFullScreen) { 20899 el.mozRequestFullScreen(); 20900 } 20901 else if (el.webkitRequestFullscreen) { 20902 el.webkitRequestFullscreen(); 20903 } 20904 }; 20905 FullScreen.prototype.exitFullscreen = function () { 20906 if (document.exitFullscreen) { 20907 document.exitFullscreen(); 20908 } 20909 else if (document.msExitFullscreen) { 20910 document.msExitFullscreen(); 20911 } 20912 else if (document.mozCancelFullScreen) { 20913 document.mozCancelFullScreen(); 20914 } 20915 else if (document.webkitExitFullscreen) { 20916 document.webkitExitFullscreen(); 20917 } 20918 }; 20919 // https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode 20920 FullScreen.prototype.fullScreen = function () { 20921 var _this = this; 20922 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 () { 20923 if (!_this.core.lgOpened) 20924 return; 20925 _this.core.outer.toggleClass('lg-fullscreen-on'); 20926 }); 20927 this.core.outer 20928 .find('.lg-fullscreen') 20929 .first() 20930 .on('click.lg', function () { 20931 if (_this.isFullScreen()) { 20932 _this.exitFullscreen(); 20933 } 20934 else { 20935 _this.requestFullscreen(); 20936 } 20937 }); 20938 }; 20939 FullScreen.prototype.closeGallery = function () { 20940 // exit from fullscreen if activated 20941 if (this.isFullScreen()) { 20942 this.exitFullscreen(); 20943 } 20944 }; 20945 FullScreen.prototype.destroy = function () { 20946 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); 20947 }; 20948 return FullScreen; 20949 }()); 20950 20951 return FullScreen; 20952 20953}))); 20954 20955/*! 20956 * lightgallery | 2.5.0 | June 13th 2022 20957 * http://www.lightgalleryjs.com/ 20958 * Copyright (c) 2020 Sachin Neravath; 20959 * @license GPLv3 20960 */ 20961 20962(function (global, factory) { 20963 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20964 typeof define === 'function' && define.amd ? define(factory) : 20965 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgHash = factory()); 20966}(this, (function () { 'use strict'; 20967 20968 /*! ***************************************************************************** 20969 Copyright (c) Microsoft Corporation. 20970 20971 Permission to use, copy, modify, and/or distribute this software for any 20972 purpose with or without fee is hereby granted. 20973 20974 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20975 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20976 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20977 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20978 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20979 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20980 PERFORMANCE OF THIS SOFTWARE. 20981 ***************************************************************************** */ 20982 20983 var __assign = function() { 20984 __assign = Object.assign || function __assign(t) { 20985 for (var s, i = 1, n = arguments.length; i < n; i++) { 20986 s = arguments[i]; 20987 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20988 } 20989 return t; 20990 }; 20991 return __assign.apply(this, arguments); 20992 }; 20993 20994 /** 20995 * List of lightGallery events 20996 * All events should be documented here 20997 * Below interfaces are used to build the website documentations 20998 * */ 20999 var lGEvents = { 21000 afterAppendSlide: 'lgAfterAppendSlide', 21001 init: 'lgInit', 21002 hasVideo: 'lgHasVideo', 21003 containerResize: 'lgContainerResize', 21004 updateSlides: 'lgUpdateSlides', 21005 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21006 beforeOpen: 'lgBeforeOpen', 21007 afterOpen: 'lgAfterOpen', 21008 slideItemLoad: 'lgSlideItemLoad', 21009 beforeSlide: 'lgBeforeSlide', 21010 afterSlide: 'lgAfterSlide', 21011 posterClick: 'lgPosterClick', 21012 dragStart: 'lgDragStart', 21013 dragMove: 'lgDragMove', 21014 dragEnd: 'lgDragEnd', 21015 beforeNextSlide: 'lgBeforeNextSlide', 21016 beforePrevSlide: 'lgBeforePrevSlide', 21017 beforeClose: 'lgBeforeClose', 21018 afterClose: 'lgAfterClose', 21019 rotateLeft: 'lgRotateLeft', 21020 rotateRight: 'lgRotateRight', 21021 flipHorizontal: 'lgFlipHorizontal', 21022 flipVertical: 'lgFlipVertical', 21023 autoplay: 'lgAutoplay', 21024 autoplayStart: 'lgAutoplayStart', 21025 autoplayStop: 'lgAutoplayStop', 21026 }; 21027 21028 var hashSettings = { 21029 hash: true, 21030 galleryId: '1', 21031 customSlideName: false, 21032 }; 21033 21034 var Hash = /** @class */ (function () { 21035 function Hash(instance, $LG) { 21036 // get lightGallery core plugin instance 21037 this.core = instance;
21038 this.$LG = $LG; 21039 // extend module default settings with lightGallery core settings 21040 this.settings = __assign(__assign({}, hashSettings), this.core.settings); 21041 return this; 21042 } 21043 Hash.prototype.init = function () { 21044 var _this = this; 21045 if (!this.settings.hash) { 21046 return; 21047 } 21048 this.oldHash = window.location.hash; 21049 setTimeout(function () { 21050 _this.buildFromHash(); 21051 }, 100); 21052 // Change hash value on after each slide transition 21053 this.core.LGel.on(lGEvents.afterSlide + ".hash", this.onAfterSlide.bind(this)); 21054 this.core.LGel.on(lGEvents.afterClose + ".hash", this.onCloseAfter.bind(this)); 21055 // Listen hash change and change the slide according to slide value 21056 this.$LG(window).on("hashchange.lg.hash.global" + this.core.lgId, this.onHashchange.bind(this)); 21057 }; 21058 Hash.prototype.onAfterSlide = function (event) { 21059 var slideName = this.core.galleryItems[event.detail.index].slideName; 21060 slideName = this.settings.customSlideName 21061 ? slideName || event.detail.index 21062 : event.detail.index; 21063 if (history.replaceState) { 21064 history.replaceState(null, '', window.location.pathname + 21065 window.location.search + 21066 '#lg=' + 21067 this.settings.galleryId + 21068 '&slide=' + 21069 slideName); 21070 } 21071 else { 21072 window.location.hash = 21073 'lg=' + this.settings.galleryId + '&slide=' + slideName; 21074 } 21075 }; 21076 /** 21077 * Get index of the slide from custom slideName. Has to be a public method. Used in hash plugin 21078 * @param {String} hash 21079 * @returns {Number} Index of the slide. 21080 */ 21081 Hash.prototype.getIndexFromUrl = function (hash) { 21082 if (hash === void 0) { hash = window.location.hash; } 21083 var slideName = hash.split('&slide=')[1]; 21084 var _idx = 0; 21085 if (this.settings.customSlideName) { 21086 for (var index = 0; index < this.core.galleryItems.length; index++) { 21087 var dynamicEl = this.core.galleryItems[index]; 21088 if (dynamicEl.slideName === slideName) { 21089 _idx = index; 21090 break; 21091 } 21092 } 21093 } 21094 else { 21095 _idx = parseInt(slideName, 10); 21096 } 21097 return isNaN(_idx) ? 0 : _idx; 21098 }; 21099 // Build Gallery if gallery id exist in the URL 21100 Hash.prototype.buildFromHash = function () { 21101 // if dynamic option is enabled execute immediately 21102 var _hash = window.location.hash; 21103 //Uncode edit ##START## 21104 // if (_hash.indexOf('lg=' + this.settings.galleryId) > 0) { 21105 if (_hash.indexOf('lg=' + this.settings.galleryId + '&') > 0) { 21106 //Uncode edit ##END## 21107 // This class is used to remove the initial animation if galleryId present in the URL 21108 this.$LG(document.body).addClass('lg-from-hash'); 21109 var index = this.getIndexFromUrl(_hash); 21110 this.core.openGallery(index); 21111 return true; 21112 } 21113 }; 21114 Hash.prototype.onCloseAfter = function () { 21115 // Reset to old hash value 21116 if (this.oldHash && 21117 this.oldHash.indexOf('lg=' + this.settings.galleryId) < 0) { 21118 if (history.replaceState) { 21119 history.replaceState(null, '', this.oldHash); 21120 } 21121 else { 21122 window.location.hash = this.oldHash; 21123 } 21124 } 21125 else { 21126 if (history.replaceState) { 21127 history.replaceState(null, document.title, window.location.pathname + window.location.search); 21128 } 21129 else { 21130 window.location.hash = ''; 21131 } 21132 } 21133 }; 21134 Hash.prototype.onHashchange = function () { 21135 if (!this.core.lgOpened) 21136 return; 21137 var _hash = window.location.hash; 21138 var index = this.getIndexFromUrl(_hash); 21139 // it galleryId doesn't exist in the url close the gallery 21140 if (_hash.indexOf('lg=' + this.settings.galleryId) > -1) { 21141 this.core.slide(index, false, false); 21142 } 21143 else if (this.core.lGalleryOn) { 21144 this.core.closeGallery(); 21145 } 21146 }; 21147 Hash.prototype.closeGallery = function () { 21148 if (this.settings.hash) { 21149 this.$LG(document.body).removeClass('lg-from-hash'); 21150 } 21151 }; 21152 Hash.prototype.destroy = function () { 21153 this.core.LGel.off('.lg.hash'); 21154 this.core.LGel.off('.hash'); 21155 this.$LG(window).off("hashchange.lg.hash.global" + this.core.lgId); 21156 }; 21157 return Hash; 21158 }()); 21159 21160 return Hash; 21161 21162}))); 21163/*! 21164 * lightgallery | 2.5.0 | June 13th 2022 21165 * http://www.lightgalleryjs.com/ 21166 * Copyright (c) 2020 Sachin Neravath; 21167 * @license GPLv3 21168 */ 21169 21170(function (global, factory) { 21171 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21172 typeof define === 'function' && define.amd ? define(factory) : 21173 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgShare = factory()); 21174}(this, (function () { 'use strict'; 21175 21176 /*! ***************************************************************************** 21177 Copyright (c) Microsoft Corporation. 21178 21179 Permission to use, copy, modify, and/or distribute this software for any 21180 purpose with or without fee is hereby granted. 21181 21182 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21183 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21184 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21185 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21186 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21187 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21188 PERFORMANCE OF THIS SOFTWARE. 21189 ***************************************************************************** */ 21190 21191 var __assign = function() { 21192 __assign = Object.assign || function __assign(t) { 21193 for (var s, i = 1, n = arguments.length; i < n; i++) { 21194 s = arguments[i]; 21195 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21196 } 21197 return t; 21198 }; 21199 return __assign.apply(this, arguments); 21200 }; 21201 21202 function __spreadArrays() { 21203 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 21204 for (var r = Array(s), k = 0, i = 0; i < il; i++) 21205 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 21206 r[k] = a[j]; 21207 return r; 21208 } 21209 21210 var shareSettings = { 21211 share: true, 21212 facebook: true, 21213 facebookDropdownText: 'Facebook', 21214 twitter: true, 21215 twitterDropdownText: 'Twitter', 21216 pinterest: true, 21217 pinterestDropdownText: 'Pinterest', 21218 additionalShareOptions: [], 21219 sharePluginStrings: { share: 'Share' }, 21220 }; 21221 21222 function getFacebookShareLink(galleryItem) { 21223 var facebookBaseUrl = '//www.facebook.com/sharer/sharer.php?u='; 21224 return (facebookBaseUrl + 21225 encodeURIComponent(galleryItem.facebookShareUrl || window.location.href)); 21226 } 21227 21228 function getTwitterShareLink(galleryItem) { 21229 var twitterBaseUrl = '//twitter.com/intent/tweet?text='; 21230 var url = encodeURIComponent(galleryItem.twitterShareUrl || window.location.href); 21231 var text = galleryItem.tweetText;
21232 return twitterBaseUrl + text + '&url=' + url; 21233 } 21234 21235 function getPinterestShareLink(galleryItem) { 21236 var pinterestBaseUrl = 'http://www.pinterest.com/pin/create/button/?url='; 21237 var description = galleryItem.pinterestText; 21238 var media = encodeURIComponent(galleryItem.src); 21239 var url = encodeURIComponent(galleryItem.pinterestShareUrl || window.location.href); 21240 return (pinterestBaseUrl + 21241 url + 21242 '&media=' + 21243 media + 21244 '&description=' + 21245 description); 21246 } 21247 21248 /** 21249 * List of lightGallery events 21250 * All events should be documented here 21251 * Below interfaces are used to build the website documentations 21252 * */ 21253 var lGEvents = { 21254 afterAppendSlide: 'lgAfterAppendSlide', 21255 init: 'lgInit', 21256 hasVideo: 'lgHasVideo', 21257 containerResize: 'lgContainerResize', 21258 updateSlides: 'lgUpdateSlides', 21259 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21260 beforeOpen: 'lgBeforeOpen', 21261 afterOpen: 'lgAfterOpen', 21262 slideItemLoad: 'lgSlideItemLoad', 21263 beforeSlide: 'lgBeforeSlide', 21264 afterSlide: 'lgAfterSlide', 21265 posterClick: 'lgPosterClick', 21266 dragStart: 'lgDragStart', 21267 dragMove: 'lgDragMove', 21268 dragEnd: 'lgDragEnd', 21269 beforeNextSlide: 'lgBeforeNextSlide', 21270 beforePrevSlide: 'lgBeforePrevSlide', 21271 beforeClose: 'lgBeforeClose', 21272 afterClose: 'lgAfterClose', 21273 rotateLeft: 'lgRotateLeft', 21274 rotateRight: 'lgRotateRight', 21275 flipHorizontal: 'lgFlipHorizontal', 21276 flipVertical: 'lgFlipVertical', 21277 autoplay: 'lgAutoplay', 21278 autoplayStart: 'lgAutoplayStart', 21279 autoplayStop: 'lgAutoplayStop', 21280 }; 21281 21282 var Share = /** @class */ (function () { 21283 function Share(instance) { 21284 this.shareOptions = []; 21285 // get lightGallery core plugin instance 21286 this.core = instance; 21287 // extend module default settings with lightGallery core settings 21288 this.settings = __assign(__assign({}, shareSettings), this.core.settings); 21289 return this; 21290 } 21291 Share.prototype.init = function () { 21292 if (!this.settings.share) { 21293 return; 21294 } 21295 this.shareOptions = __spreadArrays(this.getDefaultShareOptions(), this.settings.additionalShareOptions); 21296 this.setLgShareMarkup(); 21297 this.core.outer 21298 .find('.lg-share .lg-dropdown') 21299 .append(this.getShareListHtml()); 21300 this.core.LGel.on(lGEvents.afterSlide + ".share", this.onAfterSlide.bind(this)); 21301 }; 21302 Share.prototype.getShareListHtml = function () { 21303 var shareHtml = ''; 21304 this.shareOptions.forEach(function (shareOption) { 21305 shareHtml += shareOption.dropdownHTML; 21306 }); 21307 return shareHtml; 21308 }; 21309 Share.prototype.setLgShareMarkup = function () { 21310 var _this = this; 21311 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>"); 21312 this.core.outer.append('<div class="lg-dropdown-overlay"></div>'); 21313 var $shareButton = this.core.outer.find('.lg-share'); 21314 $shareButton.first().on('click.lg', function () { 21315 _this.core.outer.toggleClass('lg-dropdown-active'); 21316 if (_this.core.outer.hasClass('lg-dropdown-active')) { 21317 _this.core.outer.attr('aria-expanded', true); 21318 } 21319 else { 21320 _this.core.outer.attr('aria-expanded', false); 21321 } 21322 }); 21323 this.core.outer 21324 .find('.lg-dropdown-overlay') 21325 .first() 21326 .on('click.lg', function () { 21327 _this.core.outer.removeClass('lg-dropdown-active'); 21328 _this.core.outer.attr('aria-expanded', false); 21329 }); 21330 }; 21331 Share.prototype.onAfterSlide = function (event) { 21332 var _this = this; 21333 var index = event.detail.index; 21334 var currentItem = this.core.galleryItems[index]; 21335 setTimeout(function () { 21336 _this.shareOptions.forEach(function (shareOption) { 21337 var selector = shareOption.selector; 21338 _this.core.outer 21339 .find(selector) 21340 .attr('href', shareOption.generateLink(currentItem)); 21341 }); 21342 }, 100); 21343 }; 21344 Share.prototype.getShareListItemHTML = function (type, text) { 21345 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>"; 21346 }; 21347 Share.prototype.getDefaultShareOptions = function () { 21348 return __spreadArrays((this.settings.facebook 21349 ? [ 21350 { 21351 type: 'facebook', 21352 generateLink: getFacebookShareLink,
21353 dropdownHTML: this.getShareListItemHTML('facebook', this.settings.facebookDropdownText), 21354 selector: '.lg-share-facebook', 21355 }, 21356 ] 21357 : []), (this.settings.twitter 21358 ? [ 21359 { 21360 type: 'twitter', 21361 generateLink: getTwitterShareLink, 21362 dropdownHTML: this.getShareListItemHTML('twitter', this.settings.twitterDropdownText), 21363 selector: '.lg-share-twitter', 21364 }, 21365 ] 21366 : []), (this.settings.pinterest 21367 ? [ 21368 { 21369 type: 'pinterest', 21370 generateLink: getPinterestShareLink, 21371 dropdownHTML: this.getShareListItemHTML('pinterest', this.settings.pinterestDropdownText), 21372 selector: '.lg-share-pinterest', 21373 }, 21374 ] 21375 : [])); 21376 }; 21377 Share.prototype.destroy = function () { 21378 this.core.outer.find('.lg-dropdown-overlay').remove(); 21379 this.core.outer.find('.lg-share').remove(); 21380 this.core.LGel.off('.lg.share'); 21381 this.core.LGel.off('.share'); 21382 }; 21383 return Share; 21384 }()); 21385 21386 return Share; 21387 21388}))); 21389/*! 21390 * lightgallery | 2.5.0 | June 13th 2022 21391 * http://www.lightgalleryjs.com/ 21392 * Copyright (c) 2020 Sachin Neravath; 21393 * @license GPLv3 21394 */ 21395 21396(function (global, factory) { 21397 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21398 typeof define === 'function' && define.amd ? define(factory) : 21399 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgThumbnail = factory()); 21400}(this, (function () { 'use strict'; 21401 21402 /*! ***************************************************************************** 21403 Copyright (c) Microsoft Corporation. 21404 21405 Permission to use, copy, modify, and/or distribute this software for any 21406 purpose with or without fee is hereby granted. 21407 21408 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21409 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21410 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21411 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21412 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21413 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21414 PERFORMANCE OF THIS SOFTWARE. 21415 ***************************************************************************** */ 21416 21417 var __assign = function() { 21418 __assign = Object.assign || function __assign(t) { 21419 for (var s, i = 1, n = arguments.length; i < n; i++) { 21420 s = arguments[i]; 21421 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21422 } 21423 return t; 21424 }; 21425 return __assign.apply(this, arguments); 21426 }; 21427 21428 var thumbnailsSettings = { 21429 thumbnail: true, 21430 animateThumb: true, 21431 currentPagerPosition: 'middle', 21432 alignThumbnails: 'middle', 21433 thumbWidth: 100, 21434 thumbHeight: '80px', 21435 thumbMargin: 5, 21436 appendThumbnailsTo: '.lg-components', 21437 toggleThumb: false, 21438 enableThumbDrag: true, 21439 enableThumbSwipe: true, 21440 thumbnailSwipeThreshold: 10, 21441 loadYouTubeThumbnail: true, 21442 youTubeThumbSize: 1, 21443 thumbnailPluginStrings: { 21444 toggleThumbnails: 'Toggle thumbnails', 21445 }, 21446 }; 21447 21448 /** 21449 * List of lightGallery events 21450 * All events should be documented here 21451 * Below interfaces are used to build the website documentations 21452 * */ 21453 var lGEvents = { 21454 afterAppendSlide: 'lgAfterAppendSlide', 21455 init: 'lgInit', 21456 hasVideo: 'lgHasVideo', 21457 containerResize: 'lgContainerResize', 21458 updateSlides: 'lgUpdateSlides', 21459 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21460 beforeOpen: 'lgBeforeOpen', 21461 afterOpen: 'lgAfterOpen', 21462 slideItemLoad: 'lgSlideItemLoad', 21463 beforeSlide: 'lgBeforeSlide', 21464 afterSlide: 'lgAfterSlide', 21465 posterClick: 'lgPosterClick', 21466 dragStart: 'lgDragStart', 21467 dragMove: 'lgDragMove', 21468 dragEnd: 'lgDragEnd', 21469 beforeNextSlide: 'lgBeforeNextSlide', 21470 beforePrevSlide: 'lgBeforePrevSlide', 21471 beforeClose: 'lgBeforeClose', 21472 afterClose: 'lgAfterClose', 21473 rotateLeft: 'lgRotateLeft', 21474 rotateRight: 'lgRotateRight', 21475 flipHorizontal: 'lgFlipHorizontal', 21476 flipVertical: 'lgFlipVertical', 21477 autoplay: 'lgAutoplay', 21478 autoplayStart: 'lgAutoplayStart', 21479 autoplayStop: 'lgAutoplayStop', 21480 }; 21481 21482 var Thumbnail = /** @class */ (function () { 21483 function Thumbnail(instance, $LG) { 21484 this.thumbOuterWidth = 0; 21485 this.thumbTotalWidth = 0; 21486 this.translateX = 0; 21487 this.thumbClickable = false;
21488 // get lightGallery core plugin instance 21489 this.core = instance; 21490 this.$LG = $LG; 21491 return this; 21492 } 21493 Thumbnail.prototype.init = function () { 21494 // extend module default settings with lightGallery core settings 21495 this.settings = __assign(__assign({}, thumbnailsSettings), this.core.settings); 21496 this.thumbOuterWidth = 0; 21497 this.thumbTotalWidth = 21498 this.core.galleryItems.length * 21499 (this.settings.thumbWidth + this.settings.thumbMargin); 21500 // Thumbnail animation value 21501 this.translateX = 0; 21502 this.setAnimateThumbStyles(); 21503 if (!this.core.settings.allowMediaOverlap) { 21504 this.settings.toggleThumb = false; 21505 } 21506 if (this.settings.thumbnail) { 21507 this.build(); 21508 if (this.settings.animateThumb) { 21509 if (this.settings.enableThumbDrag) { 21510 this.enableThumbDrag(); 21511 } 21512 if (this.settings.enableThumbSwipe) { 21513 this.enableThumbSwipe(); 21514 } 21515 this.thumbClickable = false; 21516 } 21517 else { 21518 this.thumbClickable = true; 21519 } 21520 this.toggleThumbBar(); 21521 this.thumbKeyPress(); 21522 } 21523 }; 21524 Thumbnail.prototype.build = function () { 21525 var _this = this; 21526 this.setThumbMarkup(); 21527 this.manageActiveClassOnSlideChange(); 21528 this.$lgThumb.first().on('click.lg touchend.lg', function (e) { 21529 var $target = _this.$LG(e.target); 21530 if (!$target.hasAttribute('data-lg-item-id')) { 21531 return; 21532 } 21533 setTimeout(function () { 21534 // In IE9 and bellow touch does not support 21535 // Go to slide if browser does not support css transitions 21536 if (_this.thumbClickable && !_this.core.lgBusy) { 21537 var index = parseInt($target.attr('data-lg-item-id')); 21538 _this.core.slide(index, false, true, false); 21539 } 21540 }, 50); 21541 }); 21542 //Uncode edit ##START## 21543 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 21544 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 21545 //Uncode edit ##END## 21546 var index = event.detail.index; 21547 _this.animateThumb(index); 21548 }); 21549 //Uncode edit ##START## 21550 // this.core.LGel.on(lGEvents.beforeOpen + ".thumb", function () { 21551 this.core.LGel.on(lGEvents.beforeOpen, function () { 21552 //Uncode edit ##END## 21553 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21554 }); 21555 //Uncode edit ##START## 21556 // this.core.LGel.on(lGEvents.updateSlides + ".thumb", function () { 21557 this.core.LGel.on(lGEvents.updateSlides, function () { 21558 //Uncode edit ##END## 21559 _this.rebuildThumbnails(); 21560 }); 21561 //Uncode edit ##START## 21562 // this.core.LGel.on(lGEvents.containerResize + ".thumb", function () { 21563 this.core.LGel.on(lGEvents.containerResize, function () { 21564 //Uncode edit ##END## 21565 if (!_this.core.lgOpened) 21566 return; 21567 setTimeout(function () { 21568 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21569 _this.animateThumb(_this.core.index); 21570 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21571 }, 50); 21572 }); 21573 }; 21574 Thumbnail.prototype.setThumbMarkup = function () { 21575 var thumbOuterClassNames = 'lg-thumb-outer '; 21576 if (this.settings.alignThumbnails) { 21577 thumbOuterClassNames += "lg-thumb-align-" + this.settings.alignThumbnails; 21578 } 21579 var html = "<div class=\"" + thumbOuterClassNames + "\">\n <div class=\"lg-thumb lg-group\">\n </div>\n </div>"; 21580 this.core.outer.addClass('lg-has-thumb'); 21581 if (this.settings.appendThumbnailsTo === '.lg-components') { 21582 this.core.$lgComponents.append(html); 21583 } 21584 else { 21585 this.core.outer.append(html); 21586 } 21587 this.$thumbOuter = this.core.outer.find('.lg-thumb-outer').first(); 21588 this.$lgThumb = this.core.outer.find('.lg-thumb').first(); 21589 if (this.settings.animateThumb) { 21590 this.core.outer 21591 .find('.lg-thumb') 21592 .css('transition-duration', this.core.settings.speed + 'ms') 21593 .css('width', this.thumbTotalWidth + 'px') 21594 .css('position', 'relative'); 21595 } 21596 this.setThumbItemHtml(this.core.galleryItems); 21597 }; 21598 Thumbnail.prototype.enableThumbDrag = function () { 21599 var _this = this; 21600 var thumbDragUtils = { 21601 cords: { 21602 startX: 0, 21603 endX: 0, 21604 }, 21605 isMoved: false, 21606 newTranslateX: 0, 21607 startTime: new Date(), 21608 endTime: new Date(), 21609 touchMoveTime: 0, 21610 }; 21611 var isDragging = false;
21612 this.$thumbOuter.addClass('lg-grab'); 21613 this.core.outer 21614 .find('.lg-thumb') 21615 .first() 21616 .on('mousedown.lg.thumb', function (e) { 21617 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21618 // execute only on .lg-object 21619 e.preventDefault(); 21620 thumbDragUtils.cords.startX = e.pageX; 21621 thumbDragUtils.startTime = new Date(); 21622 _this.thumbClickable = false; 21623 isDragging = true; 21624 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 21625 _this.core.outer.get().scrollLeft += 1; 21626 _this.core.outer.get().scrollLeft -= 1; 21627 // * 21628 _this.$thumbOuter 21629 .removeClass('lg-grab') 21630 .addClass('lg-grabbing'); 21631 } 21632 }); 21633 this.$LG(window).on("mousemove.lg.thumb.global" + this.core.lgId, function (e) { 21634 if (!_this.core.lgOpened) 21635 return; 21636 if (isDragging) { 21637 thumbDragUtils.cords.endX = e.pageX; 21638 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 21639 } 21640 }); 21641 this.$LG(window).on("mouseup.lg.thumb.global" + this.core.lgId, function () { 21642 if (!_this.core.lgOpened) 21643 return; 21644 if (thumbDragUtils.isMoved) { 21645 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 21646 } 21647 else { 21648 _this.thumbClickable = true; 21649 } 21650 if (isDragging) { 21651 isDragging = false; 21652 _this.$thumbOuter.removeClass('lg-grabbing').addClass('lg-grab'); 21653 } 21654 }); 21655 }; 21656 Thumbnail.prototype.enableThumbSwipe = function () { 21657 var _this = this; 21658 var thumbDragUtils = { 21659 cords: { 21660 startX: 0, 21661 endX: 0, 21662 }, 21663 isMoved: false, 21664 newTranslateX: 0, 21665 startTime: new Date(), 21666 endTime: new Date(), 21667 touchMoveTime: 0, 21668 }; 21669 this.$lgThumb.on('touchstart.lg', function (e) { 21670 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21671 e.preventDefault(); 21672 thumbDragUtils.cords.startX = e.targetTouches[0].pageX; 21673 _this.thumbClickable = false; 21674 thumbDragUtils.startTime = new Date(); 21675 } 21676 }); 21677 this.$lgThumb.on('touchmove.lg', function (e) { 21678 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21679 e.preventDefault(); 21680 thumbDragUtils.cords.endX = e.targetTouches[0].pageX; 21681 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 21682 } 21683 }); 21684 this.$lgThumb.on('touchend.lg', function () { 21685 if (thumbDragUtils.isMoved) { 21686 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 21687 } 21688 else { 21689 _this.thumbClickable = true; 21690 } 21691 }); 21692 }; 21693 // Rebuild thumbnails 21694 Thumbnail.prototype.rebuildThumbnails = function () { 21695 var _this = this; 21696 // Remove transitions 21697 this.$thumbOuter.addClass('lg-rebuilding-thumbnails'); 21698 setTimeout(function () { 21699 _this.thumbTotalWidth = 21700 _this.core.galleryItems.length * 21701 (_this.settings.thumbWidth + _this.settings.thumbMargin); 21702 _this.$lgThumb.css('width', _this.thumbTotalWidth + 'px'); 21703 _this.$lgThumb.empty(); 21704 _this.setThumbItemHtml(_this.core.galleryItems); 21705 _this.animateThumb(_this.core.index); 21706 }, 50); 21707 setTimeout(function () { 21708 _this.$thumbOuter.removeClass('lg-rebuilding-thumbnails'); 21709 }, 200); 21710 }; 21711 // @ts-check 21712 Thumbnail.prototype.setTranslate = function (value) { 21713 this.$lgThumb.css('transform', 'translate3d(-' + value + 'px, 0px, 0px)'); 21714 }; 21715 Thumbnail.prototype.getPossibleTransformX = function (left) { 21716 if (left > this.thumbTotalWidth - this.thumbOuterWidth) { 21717 left = this.thumbTotalWidth - this.thumbOuterWidth; 21718 } 21719 if (left < 0) { 21720 left = 0; 21721 } 21722 return left; 21723 }; 21724 Thumbnail.prototype.animateThumb = function (index) { 21725 this.$lgThumb.css('transition-duration', this.core.settings.speed + 'ms'); 21726 if (this.settings.animateThumb) { 21727 var position = 0; 21728 switch (this.settings.currentPagerPosition) { 21729 case 'left': 21730 position = 0; 21731 break; 21732 case 'middle': 21733 position = 21734 this.thumbOuterWidth / 2 - this.settings.thumbWidth / 2; 21735 break; 21736 case 'right': 21737 position = this.thumbOuterWidth - this.settings.thumbWidth; 21738 } 21739 this.translateX = 21740 (this.settings.thumbWidth + this.settings.thumbMargin) * index - 21741 1 - 21742 position; 21743 if (this.translateX > this.thumbTotalWidth - this.thumbOuterWidth) { 21744 this.translateX = this.thumbTotalWidth - this.thumbOuterWidth; 21745 } 21746 if (this.translateX < 0) { 21747 this.translateX = 0; 21748 } 21749 this.setTranslate(this.translateX); 21750 } 21751 };
21752 Thumbnail.prototype.onThumbTouchMove = function (thumbDragUtils) { 21753 thumbDragUtils.newTranslateX = this.translateX; 21754 thumbDragUtils.isMoved = true; 21755 thumbDragUtils.touchMoveTime = new Date().valueOf(); 21756 thumbDragUtils.newTranslateX -= 21757 thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21758 thumbDragUtils.newTranslateX = this.getPossibleTransformX(thumbDragUtils.newTranslateX); 21759 // move current slide 21760 this.setTranslate(thumbDragUtils.newTranslateX); 21761 this.$thumbOuter.addClass('lg-dragging'); 21762 return thumbDragUtils; 21763 }; 21764 Thumbnail.prototype.onThumbTouchEnd = function (thumbDragUtils) { 21765 thumbDragUtils.isMoved = false; 21766 thumbDragUtils.endTime = new Date(); 21767 this.$thumbOuter.removeClass('lg-dragging'); 21768 var touchDuration = thumbDragUtils.endTime.valueOf() - 21769 thumbDragUtils.startTime.valueOf(); 21770 var distanceXnew = thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21771 var speedX = Math.abs(distanceXnew) / touchDuration; 21772 // Some magical numbers 21773 // Can be improved 21774 if (speedX > 0.15 && 21775 thumbDragUtils.endTime.valueOf() - thumbDragUtils.touchMoveTime < 30) { 21776 speedX += 1; 21777 if (speedX > 2) { 21778 speedX += 1; 21779 } 21780 speedX = 21781 speedX + 21782 speedX * (Math.abs(distanceXnew) / this.thumbOuterWidth); 21783 this.$lgThumb.css('transition-duration', Math.min(speedX - 1, 2) + 'settings'); 21784 distanceXnew = distanceXnew * speedX; 21785 this.translateX = this.getPossibleTransformX(this.translateX - distanceXnew); 21786 this.setTranslate(this.translateX); 21787 } 21788 else { 21789 this.translateX = thumbDragUtils.newTranslateX; 21790 } 21791 if (Math.abs(thumbDragUtils.cords.endX - thumbDragUtils.cords.startX) < 21792 this.settings.thumbnailSwipeThreshold) { 21793 this.thumbClickable = true; 21794 } 21795 return thumbDragUtils; 21796 }; 21797 Thumbnail.prototype.getThumbHtml = function (thumb, index) { 21798 var slideVideoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 21799 var thumbImg; 21800 if (slideVideoInfo.youtube) { 21801 if (this.settings.loadYouTubeThumbnail) { 21802 thumbImg = 21803 '//img.youtube.com/vi/' + 21804 slideVideoInfo.youtube[1] + 21805 '/' + 21806 this.settings.youTubeThumbSize + 21807 '.jpg'; 21808 } 21809 else { 21810 thumbImg = thumb; 21811 } 21812 } 21813 else { 21814 thumbImg = thumb; 21815 } 21816 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 + "\" src=\"" + thumbImg + "\" />\n </div>"; 21817 }; 21818 Thumbnail.prototype.getThumbItemHtml = function (items) { 21819 var thumbList = ''; 21820 for (var i = 0; i < items.length; i++) { 21821 thumbList += this.getThumbHtml(items[i].thumb, i); 21822 } 21823 return thumbList; 21824 }; 21825 Thumbnail.prototype.setThumbItemHtml = function (items) { 21826 var thumbList = this.getThumbItemHtml(items); 21827 this.$lgThumb.html(thumbList); 21828 }; 21829 Thumbnail.prototype.setAnimateThumbStyles = function () { 21830 if (this.settings.animateThumb) { 21831 this.core.outer.addClass('lg-animate-thumb'); 21832 } 21833 }; 21834 // Manage thumbnail active calss
21835 Thumbnail.prototype.manageActiveClassOnSlideChange = function () { 21836 var _this = this; 21837 // manage active class for thumbnail 21838 //Uncode edit ##START## 21839 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 21840 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 21841 //Uncode edit ##END## 21842 var $thumb = _this.core.outer.find('.lg-thumb-item'); 21843 var index = event.detail.index; 21844 $thumb.removeClass('active'); 21845 $thumb.eq(index).addClass('active'); 21846 }); 21847 }; 21848 // Toggle thumbnail bar 21849 Thumbnail.prototype.toggleThumbBar = function () { 21850 var _this = this; 21851 if (this.settings.toggleThumb) { 21852 this.core.outer.addClass('lg-can-toggle'); 21853 this.core.$toolbar.append('<button type="button" aria-label="' + 21854 this.settings.thumbnailPluginStrings['toggleThumbnails'] + 21855 '" class="lg-toggle-thumb lg-icon"></button>'); 21856 this.core.outer 21857 .find('.lg-toggle-thumb') 21858 .first() 21859 .on('click.lg', function () { 21860 _this.core.outer.toggleClass('lg-components-open'); 21861 }); 21862 } 21863 }; 21864 Thumbnail.prototype.thumbKeyPress = function () { 21865 var _this = this; 21866 this.$LG(window).on("keydown.lg.thumb.global" + this.core.lgId, function (e) { 21867 if (!_this.core.lgOpened || !_this.settings.toggleThumb) 21868 return; 21869 if (e.keyCode === 38) { 21870 e.preventDefault(); 21871 _this.core.outer.addClass('lg-components-open'); 21872 } 21873 else if (e.keyCode === 40) { 21874 e.preventDefault(); 21875 _this.core.outer.removeClass('lg-components-open'); 21876 } 21877 }); 21878 }; 21879 Thumbnail.prototype.destroy = function () { 21880 if (this.settings.thumbnail) { 21881 this.$LG(window).off(".lg.thumb.global" + this.core.lgId); 21882 this.core.LGel.off('.lg.thumb'); 21883 this.core.LGel.off('.thumb'); 21884 this.$thumbOuter.remove(); 21885 this.core.outer.removeClass('lg-has-thumb'); 21886 } 21887 }; 21888 return Thumbnail; 21889 }()); 21890 21891 return Thumbnail; 21892 21893}))); 21894/*! 21895 * lightgallery | 2.5.0 | June 13th 2022 21896 * http://www.lightgalleryjs.com/ 21897 * Copyright (c) 2020 Sachin Neravath; 21898 * @license GPLv3 21899 */ 21900 21901(function (global, factory) { 21902 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21903 typeof define === 'function' && define.amd ? define(factory) : 21904 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgVideo = factory()); 21905}(this, (function () { 'use strict'; 21906 21907 /*! ***************************************************************************** 21908 Copyright (c) Microsoft Corporation. 21909 21910 Permission to use, copy, modify, and/or distribute this software for any 21911 purpose with or without fee is hereby granted. 21912 21913 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21914 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21915 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21916 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21917 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21918 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21919 PERFORMANCE OF THIS SOFTWARE. 21920 ***************************************************************************** */ 21921 21922 var __assign = function() { 21923 __assign = Object.assign || function __assign(t) { 21924 for (var s, i = 1, n = arguments.length; i < n; i++) { 21925 s = arguments[i]; 21926 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21927 } 21928 return t; 21929 }; 21930 return __assign.apply(this, arguments); 21931 }; 21932 21933 var videoSettings = { 21934 autoplayFirstVideo: true, 21935 youTubePlayerParams: false, 21936 vimeoPlayerParams: false, 21937 wistiaPlayerParams: false, 21938 gotoNextSlideOnVideoEnd: true, 21939 autoplayVideoOnSlide: false, 21940 videojs: false, 21941 videojsTheme: '', 21942 videojsOptions: {}, 21943 }; 21944 21945 /** 21946 * List of lightGallery events 21947 * All events should be documented here 21948 * Below interfaces are used to build the website documentations 21949 * */ 21950 var lGEvents = { 21951 afterAppendSlide: 'lgAfterAppendSlide', 21952 init: 'lgInit', 21953 hasVideo: 'lgHasVideo', 21954 containerResize: 'lgContainerResize', 21955 updateSlides: 'lgUpdateSlides', 21956 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21957 beforeOpen: 'lgBeforeOpen', 21958 afterOpen: 'lgAfterOpen', 21959 slideItemLoad: 'lgSlideItemLoad', 21960 beforeSlide: 'lgBeforeSlide', 21961 afterSlide: 'lgAfterSlide', 21962 posterClick: 'lgPosterClick', 21963 dragStart: 'lgDragStart', 21964 dragMove: 'lgDragMove', 21965 dragEnd: 'lgDragEnd', 21966 beforeNextSlide: 'lgBeforeNextSlide', 21967 beforePrevSlide: 'lgBeforePrevSlide', 21968 beforeClose: 'lgBeforeClose', 21969 afterClose: 'lgAfterClose', 21970 rotateLeft: 'lgRotateLeft', 21971 rotateRight: 'lgRotateRight', 21972 flipHorizontal: 'lgFlipHorizontal', 21973 flipVertical: 'lgFlipVertical', 21974 autoplay: 'lgAutoplay', 21975 autoplayStart: 'lgAutoplayStart', 21976 autoplayStop: 'lgAutoplayStop', 21977 }; 21978 21979 var param = function (obj) { 21980 return Object.keys(obj) 21981 .map(function (k) { 21982 return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); 21983 }) 21984 .join('&'); 21985 }; 21986 var getVimeoURLParams = function (defaultParams, videoInfo) { 21987 if (!videoInfo || !videoInfo.vimeo) 21988 return '';
21989 var urlParams = videoInfo.vimeo[2] || ''; 21990 var defaultPlayerParams = defaultParams && Object.keys(defaultParams).length !== 0 21991 ? '&' + param(defaultParams) 21992 : ''; 21993 // Support private video 21994 var urlWithHash = videoInfo.vimeo[0].split('/').pop() || ''; 21995 var urlWithHashWithParams = urlWithHash.split('?')[0] || ''; 21996 var hash = urlWithHashWithParams.split('#')[0]; 21997 var isPrivate = videoInfo.vimeo[1] !== hash; 21998 if (isPrivate) { 21999 urlParams = urlParams.replace("/" + hash, ''); 22000 } 22001 urlParams = 22002 urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || ''; 22003 // For vimeo last params gets priority if duplicates found 22004 // Uncode edit ##START## 22005 var vimeoPlayerParams = '?autoplay=0'; 22006 if ( videoInfo.autoplay !== '' ) { 22007 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 22008 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay(&|$)'), '$1$2' ); 22009 } else { 22010 if ( typeof SiteParameters !== 'undefined' && typeof SiteParameters.vimeoPlayerParams !== 'undefined' && SiteParameters.vimeoPlayerParams !== '' ) { 22011 vimeoPlayerParams = SiteParameters.vimeoPlayerParams; 22012 } 22013 } 22014 if ( videoInfo.muted !== '' ) { 22015 vimeoPlayerParams += '&muted=' + (videoInfo.muted === 'yes'); 22016 } else { 22017 if ( urlParams.indexOf('muted=') < 0 && vimeoPlayerParams.indexOf('muted=') < 0 ) { 22018 vimeoPlayerParams += '&muted=1'; 22019 } 22020 } 22021 // var vimeoPlayerParams = "?autoplay=0&muted=1" + (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 22022 vimeoPlayerParams += (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 22023 // Uncode edit ##END## 22024 return vimeoPlayerParams; 22025 }; 22026 22027 /** 22028 * Video module for lightGallery 22029 * Supports HTML5, YouTube, Vimeo, wistia videos 22030 * 22031 * 22032 * @ref Wistia 22033 * https://wistia.com/support/integrations/wordpress(How to get url) 22034 * https://wistia.com/support/developers/embed-options#using-embed-options 22035 * https://wistia.com/support/developers/player-api 22036 * https://wistia.com/support/developers/construct-an-embed-code 22037 * http://jsfiddle.net/xvnm7xLm/ 22038 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video 22039 * https://wistia.com/support/embed-and-share/sharing-videos 22040 * https://private-sharing.wistia.com/medias/mwhrulrucj 22041 * 22042 * @ref Youtube 22043 * https://developers.google.com/youtube/player_parameters#enablejsapi 22044 * https://developers.google.com/youtube/iframe_api_reference 22045 * https://developer.chrome.com/blog/autoplay/#iframe-delegation 22046 * 22047 * @ref Vimeo 22048 * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url 22049 * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode 22050 * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters 22051 */ 22052 var Video = /** @class */ (function () { 22053 function Video(instance) { 22054 // get lightGallery core plugin instance 22055 this.core = instance; 22056 this.settings = __assign(__assign({}, videoSettings), this.core.settings); 22057 return this; 22058 } 22059 Video.prototype.init = function () { 22060 var _this = this; 22061 /** 22062 * Event triggered when video url found without poster 22063 * Append video HTML 22064 * Play if autoplayFirstVideo is true 22065 */ 22066 this.core.LGel.on(lGEvents.hasVideo + ".video", this.onHasVideo.bind(this)); 22067 this.core.LGel.on(lGEvents.posterClick + ".video", function () { 22068 var $el = _this.core.getSlideItem(_this.core.index); 22069 _this.loadVideoOnPosterClick($el); 22070 }); 22071 this.core.LGel.on(lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this)); 22072 // @desc fired immediately before each slide transition. 22073 this.core.LGel.on(lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this)); 22074 // @desc fired immediately after each slide transition. 22075 this.core.LGel.on(lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this)); 22076 }; 22077 /** 22078 * @desc Event triggered when a slide is completely loaded 22079 * 22080 * @param {Event} event - lightGalley custom event 22081 */ 22082 Video.prototype.onSlideItemLoad = function (event) { 22083 var _this = this; 22084 var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index; 22085 // Should check the active slide as well as user may have moved to different slide before the first slide is loaded 22086 if (this.settings.autoplayFirstVideo && 22087 isFirstSlide && 22088 index === this.core.index) { 22089 // Delay is just for the transition effect on video load 22090 setTimeout(function () { 22091 _this.loadAndPlayVideo(index); 22092 }, 200); 22093 } 22094 // Should not call on first slide. should check only if the slide is active 22095 if (!isFirstSlide && 22096 this.settings.autoplayVideoOnSlide && 22097 index === this.core.index) { 22098 setTimeout(function () { 22099 _this.loadAndPlayVideo(index); 22100 }, 500); 22101 } 22102 }; 22103 /** 22104 * @desc Event triggered when video url or poster found 22105 * Append video HTML is poster is not given 22106 * Play if autoplayFirstVideo is true 22107 * 22108 * @param {Event} event - Javascript Event object. 22109 */ 22110 Video.prototype.onHasVideo = function (event) { 22111 var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster; 22112 if (!hasPoster) { 22113 // All functions are called separately if poster exist in loadVideoOnPosterClick function 22114 this.appendVideos(this.core.getSlideItem(index), { 22115 src: src, 22116 addClass: 'lg-object', 22117 index: index, 22118 html5Video: html5Video, 22119 // Uncode edit ##START## 22120 autoplay: event.target.getAttribute('data-lb-autoplay'), 22121 muted: event.target.getAttribute('data-lb-muted'), 22122 // Uncode edit ##END## 22123 }); 22124 // Automatically navigate to next slide once video reaches the end. 22125 this.gotoNextSlideOnVideoEnd(src, index); 22126 } 22127 }; 22128 /** 22129 * @desc fired immediately before each slide transition. 22130 * Pause the previous video 22131 * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos. 22132 * 22133 * @param {Event} event - Javascript Event object. 22134 * @param {number} prevIndex - Previous index of the slide. 22135 * @param {number} index - Current index of the slide 22136 */ 22137 Video.prototype.onBeforeSlide = function (event) { 22138 if (this.core.lGalleryOn) { 22139 var prevIndex = event.detail.prevIndex; 22140 this.pauseVideo(prevIndex); 22141 } 22142 // Uncode edit ##START## 22143 var _a = event.detail, index = _a.index; 22144 var $slide = this.core.getSlideItem(index); 22145
22146 var iframe = $slide.selector.querySelector('iframe'); 22147 if ( iframe != null ) { 22148 22149 var data_play = iframe.getAttribute('data-autoplay'); 22150 if ( typeof data_play !== 'undefined' && data_play === '1' ) { 22151 this.loadAndPlayVideo(index); 22152 22153 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}, 22154 $videoElement = this.core.getSlideItem(index).find('.lg-video-object').first(); 22155 if (videoInfo.vimeo) { 22156 var vimeoPlayer = new Vimeo.Player($videoElement.get()); 22157 vimeoPlayer.on('play', function () { 22158 vimeoPlayer.setCurrentTime(0); 22159 }); 22160 } else if ( videoInfo.youtube ) { 22161 try { 22162 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"seekTo\",\"args\":[0, true]}", '*'); 22163 } 22164 catch (e) { 22165 console.warn(e); 22166 } 22167 } 22168 } 22169 } 22170 // Uncode edit ##END## 22171 }; 22172 /** 22173 * @desc fired immediately after each slide transition. 22174 * Play video if autoplayVideoOnSlide option is enabled. 22175 * 22176 * @param {Event} event - Javascript Event object. 22177 * @param {number} prevIndex - Previous index of the slide. 22178 * @param {number} index - Current index of the slide 22179 * @todo should check on onSlideLoad as well if video is not loaded on after slide 22180 */ 22181 Video.prototype.onAfterSlide = function (event) { 22182 var _this = this; 22183 var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex; 22184 // Do not call on first slide 22185 var $slide = this.core.getSlideItem(index); 22186 if (this.settings.autoplayVideoOnSlide && index !== prevIndex) { 22187 if ($slide.hasClass('lg-complete')) { 22188 setTimeout(function () { 22189 _this.loadAndPlayVideo(index); 22190 }, 100); 22191 } 22192 } 22193 }; 22194 Video.prototype.loadAndPlayVideo = function (index) { 22195 var $slide = this.core.getSlideItem(index); 22196 var currentGalleryItem = this.core.galleryItems[index]; 22197 if (currentGalleryItem.poster) { 22198 this.loadVideoOnPosterClick($slide, true); 22199 } 22200 else { 22201 //Uncode edit ##START## 22202 // this.playVideo(index); 22203 var iframe = $slide.selector.querySelector('iframe'); 22204 if ( iframe != null ) { 22205 var data_play = iframe.getAttribute('data-autoplay'); 22206 if ( typeof data_play !== 'undefined' ) { 22207 if ( data_play === '1' && this.core.index == index ) { 22208 this.playVideo(index); 22209 } else { 22210 this.pauseVideo(index); 22211 } 22212 } 22213 } 22214 //Uncode edit ##END## 22215 } 22216 }; 22217 /** 22218 * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 22219 * @param {number} index - Index of the slide 22220 */ 22221 Video.prototype.playVideo = function (index) { 22222 this.controlVideo(index, 'play'); 22223 }; 22224 /** 22225 * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 22226 * @param {number} index - Index of the slide 22227 */ 22228 Video.prototype.pauseVideo = function (index) { 22229 this.controlVideo(index, 'pause'); 22230 }; 22231 // Uncode edit ##START## 22232 //Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) { 22233 Video.prototype.getVideoHtml = function (src, addClass, index, html5Video, autoplay, muted) { 22234 // Uncode edit ##END## 22235 var video = ''; 22236 var videoInfo = this.core.galleryItems[index] 22237 .__slideVideoInfo || {}; 22238 var currentGalleryItem = this.core.galleryItems[index]; 22239 var videoTitle = currentGalleryItem.title || currentGalleryItem.alt; 22240 videoTitle = videoTitle ? 'title="' + videoTitle + '"' : ''; 22241 var commonIframeProps = "allowtransparency=\"true\"\n frameborder=\"0\"\n scrolling=\"no\"\n allowfullscreen\n mozallowfullscreen\n webkitallowfullscreen\n oallowfullscreen\n msallowfullscreen"; 22242 if (videoInfo.youtube) { 22243 var videoId = 'lg-youtube' + index; 22244 var slideUrlParams = videoInfo.youtube[2] 22245 ? videoInfo.youtube[2] + '&' 22246 : ''; 22247 // For youtube first parms gets priority if duplicates found 22248 // Uncode edit ##START## 22249 // var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&autoplay=0&mute=1&enablejsapi=1"; 22250 var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&enablejsapi=1"; 22251 if ( ( slideUrlParams.indexOf('autoplay=') < 0 && youTubePlayerParams.indexOf('autoplay=') < 0 ) ) { 22252 youTubePlayerParams += '&autoplay=0'; 22253 } 22254 if ( slideUrlParams.indexOf('mute=') < 0 && youTubePlayerParams.indexOf('mute=') < 0 ) { 22255 youTubePlayerParams += '&mute=1'; 22256 } 22257 var data_video = ''; 22258 if ( autoplay !== '' ) { 22259 //youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1autoplay=' + (autoplay === 'yes' ? 1 : 0) + '$3' ); 22260 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 22261 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay'), '$1' ); 22262 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 22263 } 22264 // if ( muted !== '' ) { 22265 // youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1mute=' + (muted === 'yes' ? 1 : 0) + '$3' ); 22266 // } 22267 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1$3' ); 22268 22269 youTubePlayerParams = youTubePlayerParams.replace('??', '?'); 22270 // Uncode edit ##END## 22271 var playerParams = youTubePlayerParams + 22272 (this.settings.youTubePlayerParams 22273 ? '&' + param(this.settings.youTubePlayerParams) 22274 : ''); 22275 // Uncode edit ##START## 22276 // 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>"; 22277 video = "<iframe allow=\"autoplay\"" + data_video + " id=" + videoId + " class=\"lg-video-object lg-youtube " + addClass + "\" " + videoTitle + " src=\"//www.youtube.com/embed/" + (videoInfo.youtube[1] + playerParams) + "\" " + commonIframeProps + "></iframe>"; 22278 var tag = document.createElement('script'); 22279 tag.src = "//www.youtube.com/player_api"; 22280 var firstScriptTag = document.getElementsByTagName('script')[0]; 22281 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 22282 22283 // Replace the 'ytplayer' element with an <iframe> and 22284 // YouTube player after the API code downloads. 22285 var ytIframeplayer, 22286 setMute = muted === 'yes' ? 0 : 100; 22287 window.onYouTubePlayerAPIReady = function() { 22288 ytIframeplayer = new YT.Player(videoId, { 22289 videoId: videoInfo.youtube[1], 22290 events: { 22291 'onReady': function (event) { 22292 event.target.setVolume(setMute); 22293 } 22294 } 22295 }); 22296 } 22297 // Uncode edit ##END## 22298 } 22299 else if (videoInfo.vimeo) { 22300 var videoId = 'lg-vimeo' + index; 22301 // Uncode edit ##START## 22302 videoInfo.autoplay = autoplay; 22303 videoInfo.muted = muted; 22304 // Uncode edit ##END## 22305 var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo); 22306 // Uncode edit ##START## 22307 // 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>"; 22308 var data_video = ''; 22309 if ( autoplay !== '' ) { 22310 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 22311 } 22312 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>"; 22313 // Uncode edit ##END## 22314 } 22315 else if (videoInfo.wistia) { 22316 var wistiaId = 'lg-wistia' + index; 22317 var playerParams = param(this.settings.wistiaPlayerParams); 22318 playerParams = playerParams ? '?' + playerParams : ''; 22319 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>"; 22320 } 22321 else if (videoInfo.html5) { 22322 var html5VideoMarkup = ''; 22323 for (var i = 0; i < html5Video.source.length; i++) { 22324 html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">"; 22325 } 22326 if (html5Video.tracks) { 22327 var _loop_1 = function (i) { 22328 var trackAttributes = ''; 22329 var track = html5Video.tracks[i]; 22330 Object.keys(track || {}
22330).forEach(function (key) { 22331 trackAttributes += key + "=\"" + track[key] + "\" "; 22332 }); 22333 html5VideoMarkup += "<track " + trackAttributes + ">"; 22334 }; 22335 for (var i = 0; i < html5Video.tracks.length; i++) { 22336 _loop_1(i); 22337 } 22338 } 22339 var html5VideoAttrs_1 = ''; 22340 var videoAttributes_1 = html5Video.attributes || {}; 22341 Object.keys(videoAttributes_1 || {}).forEach(function (key) { 22342 html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" "; 22343 }); 22344 video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs && this.settings.videojsTheme 22345 ? this.settings.videojsTheme + ' ' 22346 : '') + " " + (this.settings.videojs ? ' video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n " + html5VideoMarkup + "\n Your browser does not support HTML5 video.\n </video>"; 22347 } 22348 return video; 22349 }; 22350 /** 22351 * @desc - Append videos to the slide 22352 * 22353 * @param {HTMLElement} el - slide element 22354 * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo 22355 */ 22356 Video.prototype.appendVideos = function (el, videoParams) { 22357 var _a; 22358 // Uncode edit ##START## 22359 // var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video); 22360 var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video, videoParams.autoplay, videoParams.muted); 22361 // Uncode edit ##END## 22362 el.find('.lg-video-cont').append(videoHtml); 22363 var $videoElement = el.find('.lg-video-object').first(); 22364 if (videoParams.html5Video) { 22365 $videoElement.on('mousedown.lg.video', function (e) { 22366 e.stopPropagation(); 22367 }); 22368 } 22369 if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) { 22370 try { 22371 return videojs($videoElement.get(), this.settings.videojsOptions); 22372 } 22373 catch (e) { 22374 console.warn('lightGallery:- Make sure you have included videojs'); 22375 } 22376 } 22377 }; 22378 Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) { 22379 var _this = this; 22380 var $videoElement = this.core 22381 .getSlideItem(index) 22382 .find('.lg-video-object') 22383 .first(); 22384 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 22385 if (this.settings.gotoNextSlideOnVideoEnd) { 22386 if (videoInfo.html5) { 22387 $videoElement.on('ended', function () { 22388 _this.core.goToNextSlide(); 22389 }); 22390 } 22391 else if (videoInfo.vimeo) { 22392 try { 22393 // https://github.com/vimeo/player.js/#ended 22394 new Vimeo.Player($videoElement.get()).on('ended', function () { 22395 _this.core.goToNextSlide(); 22396 }); 22397 } 22398 catch (e) { 22399 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 22400 } 22401 } 22402 else if (videoInfo.wistia) { 22403 try { 22404 window._wq = window._wq || []; 22405 // @todo Event is gettign triggered multiple times 22406 window._wq.push({ 22407 id: $videoElement.attr('id'), 22408 onReady: function (video) { 22409 video.bind('end', function () { 22410 _this.core.goToNextSlide(); 22411 }); 22412 }, 22413 }); 22414 } 22415 catch (e) { 22416 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 22417 } 22418 } 22419 } 22420 }; 22421 Video.prototype.controlVideo = function (index, action) { 22422 var $videoElement = this.core 22423 .getSlideItem(index) 22424 .find('.lg-video-object') 22425 .first(); 22426 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 22427 if (!$videoElement.get()) 22428 return; 22429 if (videoInfo.youtube) { 22430 try { 22431 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*'); 22432 } 22433 catch (e) { 22434 console.warn("lightGallery:- " + e); 22435 } 22436 } 22437 else if (videoInfo.vimeo) { 22438 try { 22439 new Vimeo.Player($videoElement.get())[action](); 22440 } 22441 catch (e) { 22442 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 22443 } 22444 } 22445 else if (videoInfo.html5) { 22446 if (this.settings.videojs) { 22447 try { 22448 videojs($videoElement.get())[action](); 22449 } 22450 catch (e) { 22451 console.warn('lightGallery:- Make sure you have included videojs'); 22452 } 22453 } 22454 else { 22455 $videoElement.get()[action](); 22456 } 22457 } 22458 else if (videoInfo.wistia) { 22459 try { 22460 window._wq = window._wq || []; 22461 // @todo Find a way to destroy wistia player instance 22462 window._wq.push({ 22463 id: $videoElement.attr('id'), 22464 onReady: function (video) { 22465 video[action](); 22466 }, 22467 }); 22468 } 22469 catch (e) { 22470 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 22471 } 22472 } 22473 }; 22474 Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) { 22475 var _this = this; 22476 // check slide has poster 22477 if (!$el.hasClass('lg-video-loaded')) { 22478 // check already video element present
22479 if (!$el.hasClass('lg-has-video')) { 22480 $el.addClass('lg-has-video'); 22481 var _html = void 0; 22482 var _src = this.core.galleryItems[this.core.index].src; 22483 var video = this.core.galleryItems[this.core.index].video; 22484 if (video) { 22485 _html = 22486 typeof video === 'string' ? JSON.parse(video) : video; 22487 } 22488 var videoJsPlayer_1 = this.appendVideos($el, { 22489 src: _src, 22490 addClass: '', 22491 index: this.core.index, 22492 html5Video: _html, 22493 }); 22494 this.gotoNextSlideOnVideoEnd(_src, this.core.index); 22495 var $tempImg = $el.find('.lg-object').first().get(); 22496 // @todo make sure it is working 22497 $el.find('.lg-video-cont').first().append($tempImg); 22498 $el.addClass('lg-video-loading'); 22499 videoJsPlayer_1 && 22500 videoJsPlayer_1.ready(function () { 22501 videoJsPlayer_1.on('loadedmetadata', function () { 22502 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 22503 }); 22504 }); 22505 $el.find('.lg-video-object') 22506 .first() 22507 .on('load.lg error.lg loadedmetadata.lg', function () { 22508 setTimeout(function () { 22509 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 22510 }, 50); 22511 }); 22512 } 22513 else { 22514 this.playVideo(this.core.index); 22515 } 22516 } 22517 else if (forcePlay) { 22518 this.playVideo(this.core.index); 22519 } 22520 }; 22521 Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) { 22522 $el.addClass('lg-video-loaded'); 22523 this.playVideo(index); 22524 }; 22525 Video.prototype.destroy = function () { 22526 this.core.LGel.off('.lg.video'); 22527 this.core.LGel.off('.video'); 22528 }; 22529 return Video; 22530 }()); 22531 22532 return Video; 22533 22534}))); 22535 22536 22537/*! @vimeo/player v2.17.1 | (c) 2022 Vimeo | MIT License | https://github.com/vimeo/player.js */ 22538!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:{}}
22538),p.exports),g=new WeakMap;function w(e,t,n){var r=g.get(e.element)||{};t in r||(r[t]=[]),r[t].push(n),g.set(e.element,r)}function b(e,t){return(g.get(e.element)||{})[t]||[]}function k(e,t,n){var r=g.get(e.element)||{};if(!r[t])return!0;if(!n)return r[t]=[],g.set(e.element,r),!0;var o=r[t].indexOf(n);return-1!==o&&r[t].splice(o,1),g.set(e.element,r),r[t]&&0===r[t].length}function E(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){return console.warn(e),{}}return e}function T(e,t,n){var r,o;e.element.contentWindow&&e.element.contentWindow.postMessage&&(r={method:t},void 0!==n&&(r.value=n),8<=(o=parseFloat(navigator.userAgent.toLowerCase().replace(/^.*msie (\d+).*$/,"$1")))&&o<10&&(r=JSON.stringify(r)),e.element.contentWindow.postMessage(r,e.origin))}function P(n,r){var t,e,o=[];(r=E(r)).event?("error"===r.event&&b(n,r.data.method).forEach(function(e){var t=new Error(r.data.message);t.name=r.data.name,e.reject(t),k(n,r.data.method,e)}),o=b(n,"event:".concat(r.event)),t=r.data):!r.method||(e=function(e,t){var n=b(e,t);if(n.length<1)return!1;var r=n.shift();return k(e,t,r),r}(n,r.method))&&(o.push(e),t=r.value),o.forEach(function(e){try{if("function"==typeof e)return void e.call(n,t);e.resolve(t)}catch(e){}})}var M=["autopause","autoplay","background","byline","color","controls","dnt","height","id","interactive_params","keyboard","loop","maxheight","maxwidth","muted","playsinline","portrait","responsive","speed","texttrack","title","transparent","url","width"];function _(r,e){var t=1<arguments.length&&void 0!==e?e:{};return M.reduce(function(e,t){var n=r.getAttribute("data-vimeo-".concat(t));return!n&&""!==n||(e[t]=""===n?1:n),e},t)}function N(e,t){var n=e.html;if(!t)throw new TypeError("An element must be provided");if(null!==t.getAttribute("data-vimeo-initialized"))return t.querySelector("iframe");var r=document.createElement("div");return r.innerHTML=n,t.appendChild(r.firstChild),t.setAttribute("data-vimeo-initialized","true"),t.querySelector("iframe")}function F(i,e,t){var a=1<arguments.length&&void 0!==e?e:{},u=2<arguments.length?t:void 0;return new Promise(function(t,n){if(!c(i))throw new TypeError("â".concat(i,"â is not a vimeo.com url."));var e="https://vimeo.com/api/oembed.json?url=".concat(encodeURIComponent(i));for(var r in a)a.hasOwnProperty(r)&&(e+="&".concat(r,"=").concat(encodeURIComponent(a[r])));var o=new("XDomainRequest"in window?XDomainRequest:XMLHttpRequest);o.open("GET",e,!0),o.onload=function(){if(404!==o.status)if(403!==o.status)try{var e=JSON.parse(o.responseText);if(403===e.domain_status_code)return N(e,u),void n(new Error("â".concat(i,"â is not embeddable.")));t(e)}catch(e){n(e)}else n(new Error("â".concat(i,"â is not embeddable.")));else n(new Error("â".concat(i,"â was not found.")))},o.onerror=function(){var e=o.status?" (".concat(o.status,")"):"";n(new Error("There was an error fetching the embed code from Vimeo".concat(e,".")))},o.send()})}var x,C,j,A=new WeakMap,S=new WeakMap,q={},Player=function(){function Player(u){var e,t,l=this,n=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};if(!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,Player),window.jQuery&&u instanceof jQuery&&(1<u.length&&window.console&&console.warn&&console.warn("A jQuery object with multiple elements was passed, using the first element."),u=u[0]),"undefined"!=typeof document&&"string"==typeof u&&(u=document.getElementById(u)),e=u,!Boolean(e&&1===e.nodeType&&"nodeName"in e&&e.ownerDocument&&e.ownerDocument.defaultView))throw new TypeError("You must pass either a valid element or a valid id.");if("IFRAME"===u.nodeName||(t=u.querySelector("iframe"))&&(u=t),"IFRAME"===u.nodeName&&!c(u.getAttribute("src")||""))throw new Error("The player element passed isnât a Vimeo embed.");if(A.has(u))return A.get(u);this._window=u.ownerDocument.defaultView,this.element=u,this.origin="*";var r,o=new y(function(i,a){var e;l._onMessage=function(e){if(c(e.origin)&&l.element.contentWindow===e.source){"*"===l.origin&&(l.origin=e.origin);var t=E(e.data);if(t&&"error"===t.event&&t.data&&"ready"===t.data.method){var n=new Error(t.data.message);return n.name=t.data.name,void a(n)}
vendor: 5,252 bytes, line 22538
22538var 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)}
22538},{key:"getDuration",value:function(){return this.get("duration")}},{key:"getEnded",value:function(){return this.get("ended")}},{key:"getLoop",value:function(){return this.get("loop")}},{key:"setLoop",value:function(e){return this.set("loop",e)}},{key:"setMuted",value:function(e){return this.set("muted",e)}},{key:"getMuted",value:function(){return this.get("muted")}},{key:"getPaused",value:function(){return this.get("paused")}},{key:"getPlaybackRate",value:function(){return this.get("playbackRate")}},{key:"setPlaybackRate",value:function(e){return this.set("playbackRate",e)}},{key:"getPlayed",value:function(){return this.get("played")}},{key:"getQualities",value:function(){return this.get("qualities")}},{key:"getQuality",value:function(){return this.get("quality")}},{key:"setQuality",value:function(e){return this.set("quality",e)}},{key:"getSeekable",value:function(){return this.get("seekable")}},{key:"getSeeking",value:function(){return this.get("seeking")}},{key:"getTextTracks",value:function(){return this.get("textTracks")}},{key:"getVideoEmbedCode",value:function(){return this.get("videoEmbedCode")}},{key:"getVideoId",value:function(){return this.get("videoId")}},{key:"getVideoTitle",value:function(){return this.get("videoTitle")}},{key:"getVideoWidth",value:function(){return this.get("videoWidth")}},{key:"getVideoHeight",value:function(){return this.get("videoHeight")}},{key:"getVideoUrl",value:function(){return this.get("videoUrl")}},{key:"getVolume",value:function(){return this.get("volume")}},{key:"setVolume",value:function(e){return this.set("volume",e)}}])&&r(e.prototype,t),n&&r(e,n),Player}();return e||(x=function(){for(var e,t=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],n=0,r=t.length,o={};n<r;n++)if((e=t[n])&&e[1]in document){for(n=0;n<e.length;n++)o[t[0][n]]=e[n];return o}return!1}(),C={fullscreenchange:x.fullscreenchange,fullscreenerror:x.fullscreenerror},j={request:function(o){return new Promise(function(e,t){function n(){j.off("fullscreenchange",n),e()}j.on("fullscreenchange",n);var r=(o=o||document.documentElement)[x.requestFullscreen]();r instanceof Promise&&r.then(n).catch(t)})},exit:function(){return new Promise(function(t,e){var n,r;j.isFullscreen?(n=function e(){j.off("fullscreenchange",e),t()},j.on("fullscreenchange",n),(r=document[x.exitFullscreen]())instanceof Promise&&r.then(n).catch(e)):t()})},on:function(e,t){var n=C[e];n&&document.addEventListener(n,t)},off:function(e,t){var n=C[e];n&&document.removeEventListener(n,t)}},Object.defineProperties(j,{isFullscreen:{get:function(){return Boolean(document[x.fullscreenElement])}},element:{enumerable:!0,get:function(){return document[x.fullscreenElement]}},isEnabled:{enumerable:!0,get:function(){return Boolean(document[x.fullscreenEnabled])}}}),q=j,function(e){function n(e){"console"in window&&console.error&&console.error("There was an error creating an embed: ".concat(e))}var t=0<arguments.length&&void 0!==e?e:document;[].slice.call(t.querySelectorAll("[data-vimeo-id], [data-vimeo-url]")).forEach(function(t){try{if(null!==t.getAttribute("data-vimeo-defer"))return;var e=_(t);F(s(e),e,t).then(function(e){return N(e,t)}).catch(n)}catch(e){n(e)}})}(),function(e){var r=0<arguments.length&&void 0!==e?e:document;window.VimeoPlayerResizeEmbeds_||(window.VimeoPlayerResizeEmbeds_=!0,window.addEventListener("message",function(e){if(c(e.origin)&&e.data&&"spacechange"===e.data.event)for(var t=r.querySelectorAll("iframe"),n=0;n<t.length;n++)if(t[n].contentWindow===e.source){t[n].parentElement.style.paddingBottom="".concat(e.data.data[0].bottom,"px");break}}
vendor: 31,994 bytes, lines 22538-23745
22538))}(),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}); 22539 22540/** 22541 * Owl carousel 22542 * @version 2.0.0-beta.3 22543 * @author Bartosz Wojciechowski 22544 * @license The MIT License (MIT) 22545 * @todo Lazy Load Icon 22546 * @todo prevent animationend bubling 22547 * @todo itemsScaleUp 22548 * @todo Test Zepto 22549 * @todo stagePadding calculate wrong active classes 22550 */ 22551;(function($, window, document, undefined) { 22552 22553 /** 22554 * Creates a carousel. 22555 * @class The Owl Carousel. 22556 * @public 22557 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 22558 * @param {Object} [options] - The options 22559 */ 22560 function Owl(element, options) { 22561 22562 /** 22563 * Current settings for the carousel. 22564 * @public 22565 */ 22566 this.settings = null; 22567 22568 /** 22569 * Current options set by the caller including defaults. 22570 * @public 22571 */ 22572 this.options = $.extend({}, Owl.Defaults, options); 22573 22574 /** 22575 * Plugin element. 22576 * @public 22577 */ 22578 this.$element = $(element); 22579 22580 /** 22581 * Proxied event handlers. 22582 * @protected 22583 */ 22584 this._handlers = {}; 22585 22586 /** 22587 * References to the running plugins of this carousel. 22588 * @protected 22589 */ 22590 this._plugins = {}; 22591 22592 /** 22593 * Currently suppressed events to prevent them from beeing retriggered. 22594 * @protected 22595 */ 22596 this._supress = {}; 22597 22598 /** 22599 * Absolute current position. 22600 * @protected 22601 */ 22602 this._current = null; 22603 22604 /** 22605 * Animation speed in milliseconds. 22606 * @protected 22607 */ 22608 this._speed = null; 22609 22610 /** 22611 * Coordinates of all items in pixel. 22612 * @todo The name of this member is missleading. 22613 * @protected 22614 */ 22615 this._coordinates = []; 22616 22617 /** 22618 * Current breakpoint. 22619 * @todo Real media queries would be nice. 22620 * @protected 22621 */ 22622 this._breakpoint = null; 22623 22624 /** 22625 * Current width of the plugin element. 22626 */ 22627 this._width = null; 22628 22629 /** 22630 * All real items. 22631 * @protected 22632 */ 22633 this._items = []; 22634 22635 /** 22636 * All cloned items. 22637 * @protected 22638 */ 22639 this._clones = []; 22640 22641 /** 22642 * Merge values of all items. 22643 * @todo Maybe this could be part of a plugin. 22644 * @protected 22645 */ 22646 this._mergers = []; 22647 22648 /** 22649 * Widths of all items. 22650 */ 22651 this._widths = []; 22652 22653 /** 22654 * Invalidated parts within the update process. 22655 * @protected 22656 */ 22657 this._invalidated = {}; 22658 22659 /** 22660 * Ordered list of workers for the update process. 22661 * @protected 22662 */ 22663 this._pipe = []; 22664 22665 /** 22666 * Current state information for the drag operation. 22667 * @todo #261 22668 * @protected 22669 */ 22670 this._drag = { 22671 time: null, 22672 target: null, 22673 pointer: null, 22674 stage: { 22675 start: null, 22676 current: null 22677 }, 22678 direction: null 22679 }; 22680 22681 /** 22682 * Current state information and their tags. 22683 * @type {Object} 22684 * @protected 22685 */ 22686 this._states = { 22687 current: {}, 22688 tags: { 22689 'initializing': [ 'busy' ], 22690 'animating': [ 'busy' ], 22691 'dragging': [ 'interacting' ] 22692 } 22693 }; 22694 22695 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 22696 this._handlers[handler] = $.proxy(this[handler], this); 22697 }, this)); 22698 22699 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 22700 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 22701 = new plugin(this); 22702 }, this)); 22703 22704 $.each(Owl.Workers, $.proxy(function(priority, worker) { 22705 this._pipe.push({ 22706 'filter': worker.filter, 22707 'run': $.proxy(worker.run, this) 22708 }); 22709 }, this)); 22710 22711 this.setup(); 22712 this.initialize(); 22713 } 22714 22715 /** 22716 * Default options for the carousel. 22717 * @public 22718 */ 22719 Owl.Defaults = { 22720 items: 3, 22721 loop: false, 22722 center: false, 22723 rewind: false, 22724 22725 mouseDrag: true, 22726 touchDrag: true, 22727 pullDrag: true, 22728 freeDrag: false, 22729 22730 margin: 0, 22731 stagePadding: 0, 22732 22733 merge: false, 22734 mergeFit: true, 22735 autoWidth: false, 22736 22737 startPosition: 0, 22738 rtl: false, 22739 22740 smartSpeed: 250, 22741 fluidSpeed: false, 22742 dragEndSpeed: false, 22743 22744 responsive: {}, 22745 responsiveRefreshRate: 200, 22746 responsiveBaseElement: window, 22747 22748 fallbackEasing: 'swing', 22749 22750 info: false, 22751 22752 nestedItemSelector: false, 22753 itemElement: 'div', 22754 stageElement: 'div', 22755 22756 refreshClass: 'owl-refresh', 22757 loadedClass: 'owl-loaded', 22758 loadingClass: 'owl-loading', 22759 rtlClass: 'owl-rtl', 22760 responsiveClass: 'owl-responsive', 22761 dragClass: 'owl-drag', 22762 itemClass: 'owl-item', 22763 stageClass: 'owl-stage', 22764 stageOuterClass: 'owl-stage-outer', 22765 grabClass: 'owl-grab' 22766 }; 22767 22768 /** 22769 * Enumeration for width. 22770 * @public 22771 * @readonly 22772 * @enum {String} 22773 */ 22774 Owl.Width = { 22775 Default: 'default', 22776 Inner: 'inner', 22777 Outer: 'outer' 22778 }; 22779 22780 /** 22781 * Enumeration for types. 22782 * @public 22783 * @readonly 22784 * @enum {String} 22785 */ 22786 Owl.Type = { 22787 Event: 'event', 22788 State: 'state' 22789 }; 22790 22791 /** 22792 * Contains all registered plugins. 22793 * @public 22794 */ 22795 Owl.Plugins = {}; 22796 22797 /** 22798 * List of workers involved in the update process. 22799 */ 22800 Owl.Workers = [ { 22801 filter: [ 'width', 'settings' ], 22802 run: function() { 22803 this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width(); 22804 //this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12); 22805 } 22806 }, { 22807 filter: [ 'width', 'items', 'settings' ], 22808 run: function(cache) { 22809 cache.current = this._items && this._items[this.relative(this._current)]; 22810 } 22811 }, { 22812 filter: [ 'items', 'settings' ], 22813 run: function() { 22814 this.$stage.children('.cloned').remove(); 22815 } 22816 }, { 22817 filter: [ 'width', 'items', 'settings' ], 22818 run: function(cache) { 22819 var margin = this.settings.margin || '', 22820 grid = !this.settings.autoWidth, 22821 rtl = this.settings.rtl, 22822 css = { 22823 'width': 'auto', 22824 'margin-left': rtl ? margin : '', 22825 'margin-right': rtl ? '' : margin 22826 }; 22827 22828 !grid && this.$stage.children().css(css); 22829 22830 cache.css = css; 22831 } 22832 }, { 22833 filter: [ 'width', 'items', 'settings' ], 22834 run: function(cache) { 22835 //UNCODE edit to fix Chrome stage padding issue 22836 var width = Math.round((this.width() / this.settings.items).toFixed(3) - this.settings.margin), 22837 merge = null, 22838 iterator = this._items.length, 22839 grid = !this.settings.autoWidth, 22840 widths = []; 22841 22842 cache.items = { 22843 merge: false, 22844 width: width 22845 }; 22846 22847 while (iterator--) { 22848 merge = this._mergers[iterator]; 22849 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 22850 22851 cache.items.merge = merge > 1 || cache.items.merge; 22852 22853 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 22854 } 22855 22856 this._widths = widths; 22857 } 22858 }, { 22859 filter: [ 'items', 'settings' ], 22860 run: function() { 22861 var clones = [], 22862 items = this._items, 22863 settings = this.settings, 22864 view = Math.max(settings.items * 2, 4), 22865 size = Math.ceil(items.length / 2) * 2, 22866 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 22867 append = '', 22868 prepend = ''; 22869 22870 repeat /= 2; 22871 22872 while (repeat--) { 22873 clones.push(this.normalize(clones.length / 2, true)); 22874 append = append + items[clones[clones.length - 1]][0].outerHTML; 22875 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 22876 prepend = items[clones[clones.length - 1]][0].outerHTML + prepend; 22877 } 22878 22879 this._clones = clones; 22880 22881 // var appendVideo = $(append).find('.uncode-video-container'); 22882 // if (appendVideo.length) { 22883 // appendVideo.attr('data-id', Math.round(Math.random() * 100000)); 22884 // } 22885 // var prependVideo = $(prepend).find('.uncode-video-container'); 22886 // if (prependVideo.length) { 22887 // prependVideo.attr('data-id', Math.round(Math.random() * 100000)); 22888 // } 22889 $(append).addClass('cloned').appendTo(this.$stage); 22890 $(prepend).addClass('cloned').prependTo(this.$stage); 22891 } 22892 }, { 22893 filter: [ 'width', 'items', 'settings' ], 22894 run: function() { 22895 var rtl = this.settings.rtl ? 1 : -1, 22896 size = this._clones.length + this._items.length, 22897 iterator = -1, 22898 previous = 0, 22899 current = 0, 22900 coordinates = []; 22901 22902 while (++iterator < size) { 22903 previous = coordinates[iterator - 1] || 0; 22904 current = this._widths[this.relative(iterator)] + this.settings.margin; 22905 coordinates.push(previous + current * rtl); 22906 } 22907 22908 this._coordinates = coordinates; 22909 } 22910 }, { 22911 filter: [ 'width', 'items', 'settings' ], 22912 run: function() { 22913 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 22914 padding = stagePadding, 22915 coordinates = this._coordinates, 22916 css = { 22917 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 22918 'padding-left': padding || '', 22919 'padding-right': padding || '' 22920 }; 22921 22922 this.$stage.css(css); 22923 } 22924 }, { 22925 filter: [ 'width', 'items', 'settings' ], 22926 run: function(cache) { 22927 var iterator = this._coordinates.length, 22928 grid = !this.settings.autoWidth, 22929 items = this.$stage.children(); 22930 22931 if (grid && cache.items.merge) { 22932 while (iterator--) { 22933 cache.css.width = this._widths[this.relative(iterator)]; 22934 items.eq(iterator).css(cache.css); 22935 } 22936 } else if (grid) { 22937 cache.css.width = cache.items.width; 22938 items.css(cache.css); 22939 } 22940 } 22941 }, { 22942 filter: [ 'items' ], 22943 run: function() { 22944 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 22945 } 22946 }, { 22947 filter: [ 'width', 'items', 'settings' ], 22948 run: function(cache) { 22949 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 22950 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 22951 this.reset(cache.current); 22952 } 22953 }, { 22954 filter: [ 'position' ], 22955 run: function() { 22956 this.animate(this.coordinates(this._current)); 22957 } 22958 }, { 22959 filter: [ 'width', 'position', 'items', 'settings' ], 22960 run: function() { 22961 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 22962 rtl = this.settings.rtl ? 1 : -1, 22963 padding = this.settings.stagePadding * 2, 22964 begin = this.coordinates(this.current()) + padding, 22965 end = begin + this.width() * rtl, 22966 inner, outer, matches = [], i, n; 22967 22968 for (i = 0, n = this._coordinates.length; i < n; i++) { 22969 inner = this._coordinates[i - 1] || 0; 22970 outer = Math.abs(this._coordinates[i]) + padding * rtl; 22971 22972 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 22973 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 22974 matches.push(i); 22975 } 22976 } 22977 22978 this.$stage.children('.active').removeClass('active'); 22979 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 22980 22981 if (this.settings.center) { 22982 this.$stage.children('.center').removeClass('center'); 22983 this.$stage.children().eq(this.current()).addClass('center'); 22984 } 22985 } 22986 } ]; 22987 22988 /** 22989 * Initializes the carousel. 22990 * @protected 22991 */ 22992 Owl.prototype.initialize = function() { 22993 this.enter('initializing'); 22994 this.trigger('initialize'); 22995 22996 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 22997 22998 if (this.settings.autoWidth && !this.is('pre-loading')) { 22999 var imgs, nestedSelector, width; 23000 imgs = this.$element.find('img'); 23001 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 23002 width = this.$element.children(nestedSelector).width(); 23003 23004 if (imgs.length && width <= 0) { 23005 this.preloadAutoWidthImages(imgs); 23006 } 23007 } 23008 23009 this.$element.addClass(this.options.loadingClass); 23010 23011 // create stage 23012 this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>') 23013 .wrap('<div class="' + this.settings.stageOuterClass + '"/>'); 23014 23015 // append stage 23016 this.$element.append(this.$stage.parent()); 23017 23018 // append content 23019 this.replace(this.$element.children().not(this.$stage.parent())); 23020 23021 // check visibility 23022 if (this.$element.is(':visible')) { 23023 // update view 23024 this.refresh(); 23025 } else { 23026 // invalidate width 23027 this.invalidate('width'); 23028 } 23029 23030 this.$element 23031 .removeClass(this.options.loadingClass) 23032 .addClass(this.options.loadedClass); 23033 23034 // register event handlers 23035 this.registerEventHandlers(); 23036 23037 this.leave('initializing'); 23038 this.trigger('initialized'); 23039 }; 23040 23041 /** 23042 * Setups the current settings. 23043 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 23044 * @todo Support for media queries by using `matchMedia` would be nice. 23045 * @public 23046 */ 23047 Owl.prototype.setup = function() { 23048 var viewport = this.viewport(), 23049 overwrites = this.options.responsive, 23050 match = -1, 23051 settings = null; 23052 23053 if (!overwrites) { 23054 settings = $.extend({}, this.options); 23055 } else { 23056 $.each(overwrites, function(breakpoint) { 23057 if (breakpoint <= viewport && breakpoint > match) { 23058 match = Number(breakpoint); 23059 } 23060 }); 23061 23062 settings = $.extend({}, this.options, overwrites[match]); 23063 delete settings.responsive; 23064 23065 // responsive class 23066 if (settings.responsiveClass) { 23067 this.$element.attr('class', 23068 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 23069 ); 23070 } 23071 } 23072 23073 if (this.settings === null || this._breakpoint !== match) { 23074 this.trigger('change', { property: { name: 'settings', value: settings } }); 23075 this._breakpoint = match; 23076 this.settings = settings; 23077 this.invalidate('settings'); 23078 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 23079 } 23080 }; 23081 23082 /** 23083 * Updates option logic if necessery. 23084 * @protected 23085 */ 23086 Owl.prototype.optionsLogic = function() { 23087 if (this.settings.autoWidth) { 23088 this.settings.stagePadding = false; 23089 this.settings.merge = false; 23090 } 23091 }; 23092 23093 /** 23094 * Prepares an item before add. 23095 * @todo Rename event parameter `content` to `item`. 23096 * @protected 23097 * @returns {jQuery|HTMLElement} - The item container. 23098 */ 23099 Owl.prototype.prepare = function(item, index) { 23100 var event = this.trigger('prepare', { content: item }); 23101 if (!event.data) { 23102 event.data = $('<' + this.settings.itemElement + '/>') 23103 .addClass(this.options.itemClass).attr('data-index', index + 1).append(item) 23104 } 23105 23106 this.trigger('prepared', { content: event.data }); 23107 23108 return event.data; 23109 }; 23110 23111 /** 23112 * Updates the view. 23113 * @public 23114 */ 23115 Owl.prototype.update = function() { 23116 var i = 0, 23117 n = this._pipe.length, 23118 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 23119 cache = {}; 23120 23121 while (i < n) { 23122 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 23123 this._pipe[i].run(cache); 23124 } 23125 i++; 23126 } 23127 23128 this._invalidated = {}; 23129 23130 !this.is('valid') && this.enter('valid'); 23131 }; 23132 23133 /** 23134 * Gets the width of the view. 23135 * @public 23136 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 23137 * @returns {Number} - The width of the view in pixel. 23138 */ 23139 Owl.prototype.width = function(dimension) { 23140 dimension = dimension || Owl.Width.Default; 23141 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200; 23142 switch (dimension) { 23143 case Owl.Width.Inner: 23144 case Owl.Width.Outer: 23145 return this._width; 23146 default: 23147 return this._width - stagePadding * 2 + this.settings.margin; 23148 } 23149 }; 23150 23151 /** 23152 * Refreshes the carousel primarily for adaptive purposes. 23153 * @public 23154 */ 23155 Owl.prototype.refresh = function() { 23156 this.enter('refreshing'); 23157 this.trigger('refresh'); 23158 23159 this.setup(); 23160 23161 this.optionsLogic(); 23162 23163 this.$element.addClass(this.options.refreshClass); 23164 23165 this.update(); 23166 23167 this.$element.removeClass(this.options.refreshClass); 23168 23169 this.leave('refreshing'); 23170 this.trigger('refreshed'); 23171 }; 23172 23173 /** 23174 * Checks window `resize` event. 23175 * @protected 23176 */ 23177 Owl.prototype.onThrottledResize = function() { 23178 window.clearTimeout(this.resizeTimer); 23179 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 23180 }; 23181 23182 /** 23183 * Checks window `resize` event. 23184 * @protected 23185 */ 23186 Owl.prototype.onResize = function() { 23187 if (!this._items.length) { 23188 return false; 23189 } 23190 23191 if (this._width === this.$element.width()) { 23192 return false; 23193 } 23194 23195 if (!this.$element.is(':visible')) { 23196 return false; 23197 } 23198 23199 this.enter('resizing'); 23200 23201 if (this.trigger('resize').isDefaultPrevented()) { 23202 this.leave('resizing'); 23203 return false; 23204 } 23205 23206 this.invalidate('width'); 23207 23208 this.refresh(); 23209 23210 this.leave('resizing'); 23211 this.trigger('resized'); 23212 }; 23213 23214 /** 23215 * Registers event handlers. 23216 * @todo Check `msPointerEnabled` 23217 * @todo #261 23218 * @protected 23219 */ 23220 Owl.prototype.registerEventHandlers = function() { 23221 if ($.support.transition) { 23222 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 23223 } 23224 23225 if (this.settings.responsive !== false) { 23226 this.on(window, 'resize', this._handlers.onThrottledResize); 23227 } 23228 23229 if (this.settings.mouseDrag) { 23230 this.$element.addClass(this.options.dragClass); 23231 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 23232 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 23233 } 23234 23235 if (this.settings.touchDrag){ 23236 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 23237 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 23238 } 23239 }; 23240 23241 /** 23242 * Handles `touchstart` and `mousedown` events. 23243 * @todo Horizontal swipe threshold as option 23244 * @todo #261 23245 * @protected 23246 * @param {Event} event - The event arguments. 23247 */ 23248 Owl.prototype.onDragStart = function(event) { 23249 var stage = null; 23250 23251 if (event.which === 3) { 23252 return; 23253 } 23254 23255 if ($.support.transform) { 23256 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 23257 stage = { 23258 x: stage[stage.length === 16 ? 12 : 4], 23259 y: stage[stage.length === 16 ? 13 : 5] 23260 }; 23261 } else { 23262 stage = this.$stage.position(); 23263 stage = { 23264 x: this.settings.rtl ? 23265 stage.left + this.$stage.width() - this.width() + this.settings.margin : 23266 stage.left, 23267 y: stage.top 23268 }; 23269 } 23270 23271 if (this.is('animating')) { 23272 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 23273 this.invalidate('position'); 23274 } 23275 23276 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 23277 23278 this.speed(0); 23279 23280 this._drag.time = new Date().getTime(); 23281 this._drag.target = $(event.target); 23282 this._drag.stage.start = stage; 23283 this._drag.stage.current = stage; 23284 this._drag.pointer = this.pointer(event); 23285 23286 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 23287 23288 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 23289 var delta = this.difference(this._drag.pointer, this.pointer(event)); 23290 23291 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 23292 23293 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 23294 return; 23295 } 23296 23297 event.preventDefault(); 23298 23299 this.enter('dragging'); 23300 this.trigger('drag'); 23301 }, this)); 23302 }; 23303 23304 /** 23305 * Handles the `touchmove` and `mousemove` events. 23306 * @todo #261 23307 * @protected 23308 * @param {Event} event - The event arguments. 23309 */ 23310 Owl.prototype.onDragMove = function(event) { 23311 var minimum = null, 23312 maximum = null, 23313 pull = null, 23314 delta = this.difference(this._drag.pointer, this.pointer(event)), 23315 stage = this.difference(this._drag.stage.start, delta); 23316 23317 if (!this.is('dragging')) { 23318 return; 23319 } 23320 23321 event.preventDefault(); 23322 23323 if (this.settings.loop) { 23324 minimum = this.coordinates(this.minimum()); 23325 maximum = this.coordinates(this.maximum() + 1) - minimum; 23326 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 23327 } else { 23328 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 23329 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 23330 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 23331 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 23332 } 23333 23334 this._drag.stage.current = stage; 23335 23336 this.animate(stage.x); 23337 }; 23338 23339 /** 23340 * Handles the `touchend` and `mouseup` events. 23341 * @todo #261 23342 * @todo Threshold for click event 23343 * @protected 23344 * @param {Event} event - The event arguments. 23345 */ 23346 Owl.prototype.onDragEnd = function(event) { 23347 var delta = this.difference(this._drag.pointer, this.pointer(event)), 23348 stage = this._drag.stage.current, 23349 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 23350 23351 $(document).off('.owl.core'); 23352 23353 this.$element.removeClass(this.options.grabClass); 23354 23355 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 23356 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 23357 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 23358 this.invalidate('position'); 23359 this.update(); 23360 23361 this._drag.direction = direction; 23362 23363 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 23364 this._drag.target.one('click.owl.core', function() { return false; }); 23365 } 23366 } 23367 23368 if (!this.is('dragging')) { 23369 return; 23370 } 23371 23372 this.leave('dragging'); 23373 this.trigger('dragged'); 23374 }; 23375 23376 /** 23377 * Gets absolute position of the closest item for a coordinate. 23378 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 23379 * @protected 23380 * @param {Number} coordinate - The coordinate in pixel. 23381 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 23382 * @return {Number} - The absolute position of the closest item. 23383 */ 23384 Owl.prototype.closest = function(coordinate, direction) { 23385 var position = -1, 23386 pull = 30, 23387 width = this.width(), 23388 coordinates = this.coordinates(); 23389 23390 if (!this.settings.freeDrag) { 23391 // check closest item 23392 $.each(coordinates, $.proxy(function(index, value) { 23393 if (coordinate > value - pull && coordinate < value + pull) { 23394 position = index; 23395 } else if (this.op(coordinate, '<', value) 23396 && this.op(coordinate, '>', coordinates[index + 1] || value - width)) { 23397 position = direction === 'left' ? index + 1 : index; 23398 } 23399 return position === -1; 23400 }, this)); 23401 } 23402 23403 if (!this.settings.loop) { 23404 // non loop boundries 23405 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 23406 position = coordinate = this.minimum(); 23407 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 23408 position = coordinate = this.maximum(); 23409 } 23410 } 23411 23412 return position; 23413 }; 23414 23415 /** 23416 * Animates the stage. 23417 * @todo #270 23418 * @public 23419 * @param {Number} coordinate - The coordinate in pixels. 23420 */ 23421 Owl.prototype.animate = function(coordinate) { 23422 var animate = this.speed() > 0; 23423 23424 this.is('animating') && this.onTransitionEnd(); 23425 23426 if (animate) { 23427 this.enter('animating'); 23428 this.trigger('translate'); 23429 } 23430 23431 if ($.support.transform3d && $.support.transition) { 23432 this.$stage.css({ 23433 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 23434 transition: (this.speed() / 1000) + 's' 23435 }); 23436 } else if (animate) { 23437 this.$stage.animate({ 23438 left: coordinate + 'px' 23439 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 23440 } else { 23441 this.$stage.css({ 23442 left: coordinate + 'px' 23443 }); 23444 } 23445 }; 23446 23447 /** 23448 * Checks whether the carousel is in a specific state or not. 23449 * @param {String} state - The state to check. 23450 * @returns {Boolean} - The flag which indicates if the carousel is busy. 23451 */ 23452 Owl.prototype.is = function(state) { 23453 return this._states.current[state] && this._states.current[state] > 0; 23454 }; 23455 23456 /** 23457 * Sets the absolute position of the current item. 23458 * @public 23459 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 23460 * @returns {Number} - The absolute position of the current item. 23461 */ 23462 Owl.prototype.current = function(position) { 23463 if (position === undefined) { 23464 return this._current; 23465 } 23466 23467 if (this._items.length === 0) { 23468 return undefined; 23469 } 23470 23471 position = this.normalize(position); 23472 23473 if (this._current !== position) { 23474 var event = this.trigger('change', { property: { name: 'position', value: position } }); 23475 23476 if (event.data !== undefined) { 23477 position = this.normalize(event.data); 23478 } 23479 23480 this._current = position; 23481 23482 this.invalidate('position'); 23483 23484 this.trigger('changed', { property: { name: 'position', value: this._current } }); 23485 } 23486 23487 return this._current; 23488 }; 23489 23490 /** 23491 * Invalidates the given part of the update routine. 23492 * @param {String} [part] - The part to invalidate. 23493 * @returns {Array.<String>} - The invalidated parts. 23494 */ 23495 Owl.prototype.invalidate = function(part) { 23496 if ($.type(part) === 'string') { 23497 this._invalidated[part] = true; 23498 this.is('valid') && this.leave('valid'); 23499 } 23500 return $.map(this._invalidated, function(v, i) { return i }); 23501 }; 23502 23503 /** 23504 * Resets the absolute position of the current item. 23505 * @public 23506 * @param {Number} position - The absolute position of the new item. 23507 */ 23508 Owl.prototype.reset = function(position) { 23509 position = this.normalize(position); 23510 23511 if (position === undefined) { 23512 return; 23513 } 23514 23515 this._speed = 0; 23516 this._current = position; 23517 23518 this.suppress([ 'translate', 'translated' ]); 23519 23520 this.animate(this.coordinates(position)); 23521 23522 this.release([ 'translate', 'translated' ]); 23523 }; 23524 23525 /** 23526 * Normalizes an absolute or a relative position of an item. 23527 * @public 23528 * @param {Number} position - The absolute or relative position to normalize. 23529 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 23530 * @returns {Number} - The normalized position. 23531 */ 23532 Owl.prototype.normalize = function(position, relative) { 23533 var n = this._items.length, 23534 m = relative ? 0 : this._clones.length; 23535 23536 if (!$.isNumeric(position) || n < 1) { 23537 position = undefined; 23538 } else if (position < 0 || position >= n + m) { 23539 position = ((position - m / 2) % n + n) % n + m / 2; 23540 } 23541 23542 return position; 23543 }; 23544 23545 /** 23546 * Converts an absolute position of an item into a relative one. 23547 * @public 23548 * @param {Number} position - The absolute position to convert. 23549 * @returns {Number} - The converted position. 23550 */ 23551 Owl.prototype.relative = function(position) { 23552 position -= this._clones.length / 2; 23553 return this.normalize(position, true); 23554 }; 23555 23556 /** 23557 * Gets the maximum position for the current item. 23558 * @public 23559 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 23560 * @returns {Number} 23561 */ 23562 Owl.prototype.maximum = function(relative) { 23563 var settings = this.settings, 23564 maximum = this._coordinates.length, 23565 boundary = Math.abs(this._coordinates[maximum - 1]) - this._width, 23566 i = -1, j; 23567 23568 if (settings.loop) { 23569 maximum = this._clones.length / 2 + this._items.length - 1; 23570 } else if (settings.autoWidth || settings.merge) { 23571 // binary search 23572 while (maximum - i > 1) { 23573 Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary 23574 ? i = j : maximum = j; 23575 } 23576 } else if (settings.center) { 23577 maximum = this._items.length - 1; 23578 } else { 23579 maximum = this._items.length - settings.items; 23580 } 23581 23582 if (relative) { 23583 maximum -= this._clones.length / 2; 23584 } 23585 23586 return Math.max(maximum, 0); 23587 }; 23588 23589 /** 23590 * Gets the minimum position for the current item. 23591 * @public 23592 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 23593 * @returns {Number} 23594 */ 23595 Owl.prototype.minimum = function(relative) { 23596 return relative ? 0 : this._clones.length / 2; 23597 }; 23598 23599 /** 23600 * Gets an item at the specified relative position. 23601 * @public 23602 * @param {Number} [position] - The relative position of the item. 23603 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 23604 */ 23605 Owl.prototype.items = function(position) { 23606 if (position === undefined) { 23607 return this._items.slice(); 23608 } 23609 23610 position = this.normalize(position, true); 23611 return this._items[position]; 23612 }; 23613 23614 /** 23615 * Gets an item at the specified relative position. 23616 * @public 23617 * @param {Number} [position] - The relative position of the item. 23618 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 23619 */ 23620 Owl.prototype.mergers = function(position) { 23621 if (position === undefined) { 23622 return this._mergers.slice(); 23623 } 23624 23625 position = this.normalize(position, true); 23626 return this._mergers[position]; 23627 }; 23628 23629 /** 23630 * Gets the absolute positions of clones for an item. 23631 * @public 23632 * @param {Number} [position] - The relative position of the item. 23633 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 23634 */ 23635 Owl.prototype.clones = function(position) { 23636 var odd = this._clones.length / 2, 23637 even = odd + this._items.length, 23638 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 23639 23640 if (position === undefined) { 23641 return $.map(this._clones, function(v, i) { return map(i) }); 23642 } 23643 23644 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 23645 }; 23646 23647 /** 23648 * Sets the current animation speed. 23649 * @public 23650 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 23651 * @returns {Number} - The current animation speed in milliseconds. 23652 */ 23653 Owl.prototype.speed = function(speed) { 23654 if (speed !== undefined) { 23655 this._speed = speed; 23656 } 23657 23658 return this._speed; 23659 }; 23660 23661 /** 23662 * Gets the coordinate of an item. 23663 * @todo The name of this method is missleanding. 23664 * @public 23665 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 23666 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 23667 */ 23668 Owl.prototype.coordinates = function(position) { 23669 var coordinate = null; 23670 23671 if (position === undefined) { 23672 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 23673 return this.coordinates(index); 23674 }, this)); 23675 } 23676 23677 if (this.settings.center) { 23678 coordinate = this._coordinates[position]; 23679 coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1); 23680 } else { 23681 coordinate = this._coordinates[position - 1] || 0; 23682 } 23683 23684 return coordinate; 23685 }; 23686 23687 /** 23688 * Calculates the speed for a translation. 23689 * @protected 23690 * @param {Number} from - The absolute position of the start item. 23691 * @param {Number} to - The absolute position of the target item. 23692 * @param {Number} [factor=undefined] - The time factor in milliseconds. 23693 * @returns {Number} - The time in milliseconds for the translation. 23694 */ 23695 Owl.prototype.duration = function(from, to, factor) { 23696 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 23697 }; 23698 23699 /** 23700 * Slides to the specified item. 23701 * @public 23702 * @param {Number} position - The position of the item. 23703 * @param {Number} [speed] - The time in milliseconds for the transition. 23704 */ 23705 Owl.prototype.to = function(position, speed) { 23706 var current = this.current(), 23707 revert = null, 23708 distance = position - this.relative(current), 23709 direction = (distance > 0) - (distance < 0), 23710 items = this._items.length, 23711 minimum = this.minimum(), 23712 maximum = this.maximum(); 23713 23714 if (this.settings.loop) { 23715 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 23716 distance += direction * -1 * items; 23717 } 23718 23719 position = current + distance; 23720 revert = ((position - minimum) % items + items) % items + minimum; 23721 23722 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 23723 current = revert - distance; 23724 position = revert; 23725 this.reset(current); 23726 } 23727 } else if (this.settings.rewind) { 23728 maximum += 1; 23729 position = (position % maximum + maximum) % maximum; 23730 } else { 23731 position = Math.max(minimum, Math.min(maximum, position)); 23732 } 23733 23734 this.speed(this.duration(current, position, speed)); 23735 this.current(position); 23736 23737 if (this.$element.is(':visible')) { 23738 this.update(); 23739 } 23740 }; 23741 23742 /** 23743 * Slides to the next item. 23744 * @public 23745 * @param {Number}
vendor: 12,284 bytes, lines 23745-24165
23745 [speed] - The time in milliseconds for the transition. 23746 */ 23747 Owl.prototype.next = function(speed) { 23748 speed = speed || false; 23749 this.to(this.relative(this.current()) + 1, speed); 23750 }; 23751 23752 /** 23753 * Slides to the previous item. 23754 * @public 23755 * @param {Number} [speed] - The time in milliseconds for the transition. 23756 */ 23757 Owl.prototype.prev = function(speed) { 23758 speed = speed || false; 23759 this.to(this.relative(this.current()) - 1, speed); 23760 }; 23761 23762 /** 23763 * Handles the end of an animation. 23764 * @protected 23765 * @param {Event} event - The event arguments. 23766 */ 23767 Owl.prototype.onTransitionEnd = function(event) { 23768 23769 // if css2 animation then event object is undefined 23770 if (event !== undefined) { 23771 event.stopPropagation(); 23772 23773 // Catch only owl-stage transitionEnd event 23774 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 23775 return false; 23776 } 23777 } 23778 23779 this.leave('animating'); 23780 this.trigger('translated'); 23781 }; 23782 23783 /** 23784 * Gets viewport width. 23785 * @protected 23786 * @return {Number} - The width in pixel. 23787 */ 23788 Owl.prototype.viewport = function() { 23789 var width; 23790 if (this.options.responsiveBaseElement !== window) { 23791 width = $(this.options.responsiveBaseElement).width(); 23792 } else if (window.innerWidth) { 23793 width = window.innerWidth; 23794 } else if (document.documentElement && document.documentElement.clientWidth) { 23795 width = document.documentElement.clientWidth; 23796 } else { 23797 throw 'Can not detect viewport width.'; 23798 } 23799 23800 return width; 23801 }; 23802 23803 /** 23804 * Replaces the current content. 23805 * @public 23806 * @param {HTMLElement|jQuery|String} content - The new content. 23807 */ 23808 Owl.prototype.replace = function(content) { 23809 this.$stage.empty(); 23810 this._items = []; 23811 23812 if (content) { 23813 content = (content instanceof jQuery) ? content : $(content); 23814 } 23815 23816 if (this.settings.nestedItemSelector) { 23817 content = content.find('.' + this.settings.nestedItemSelector); 23818 } 23819 23820 content.filter(function() { 23821 return this.nodeType === 1; 23822 }).each($.proxy(function(index, item) { 23823 item = this.prepare(item, index); 23824 this.$stage.append(item); 23825 this._items.push(item); 23826 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 23827 }, this)); 23828 23829 this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 23830 23831 this.invalidate('items'); 23832 }; 23833 23834 /** 23835 * Adds an item. 23836 * @todo Use `item` instead of `content` for the event arguments. 23837 * @public 23838 * @param {HTMLElement|jQuery|String} content - The item content to add. 23839 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 23840 */ 23841 Owl.prototype.add = function(content, position) { 23842 var current = this.relative(this._current); 23843 23844 position = position === undefined ? this._items.length : this.normalize(position, true); 23845 content = content instanceof jQuery ? content : $(content); 23846 23847 this.trigger('add', { content: content, position: position }); 23848 23849 content = this.prepare(content, this._items[current].index()); 23850 23851 if (this._items.length === 0 || position === this._items.length) { 23852 this._items.length === 0 && this.$stage.append(content); 23853 this._items.length !== 0 && this._items[position - 1].after(content); 23854 this._items.push(content); 23855 this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23856 } else { 23857 this._items[position].before(content); 23858 this._items.splice(position, 0, content); 23859 this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23860 } 23861 23862 this._items[current] && this.reset(this._items[current].index()); 23863 23864 this.invalidate('items'); 23865 23866 this.trigger('added', { content: content, position: position }); 23867 }; 23868 23869 /** 23870 * Removes an item by its position. 23871 * @todo Use `item` instead of `content` for the event arguments. 23872 * @public 23873 * @param {Number} position - The relative position of the item to remove. 23874 */ 23875 Owl.prototype.remove = function(position) { 23876 position = this.normalize(position, true); 23877 23878 if (position === undefined) { 23879 return; 23880 } 23881 23882 this.trigger('remove', { content: this._items[position], position: position }); 23883 23884 this._items[position].remove(); 23885 this._items.splice(position, 1); 23886 this._mergers.splice(position, 1); 23887 23888 this.invalidate('items'); 23889 23890 this.trigger('removed', { content: null, position: position }); 23891 }; 23892 23893 /** 23894 * Preloads images with auto width. 23895 * @todo Replace by a more generic approach 23896 * @protected 23897 */ 23898 Owl.prototype.preloadAutoWidthImages = function(images) { 23899 images.each($.proxy(function(i, element) { 23900 this.enter('pre-loading'); 23901 element = $(element); 23902 $(new Image()).one('load', $.proxy(function(e) { 23903 element.attr('src', e.target.src); 23904 element.css('opacity', 1); 23905 this.leave('pre-loading'); 23906 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 23907 }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina')); 23908 }, this)); 23909 }; 23910 23911 /** 23912 * Destroys the carousel. 23913 * @public 23914 */ 23915 Owl.prototype.destroy = function() { 23916 23917 this.$element.off('.owl.core'); 23918 this.$stage.off('.owl.core'); 23919 $(document).off('.owl.core'); 23920 23921 if (this.settings.responsive !== false) { 23922 window.clearTimeout(this.resizeTimer); 23923 this.off(window, 'resize', this._handlers.onThrottledResize); 23924 } 23925 23926 for (var i in this._plugins) { 23927 this._plugins[i].destroy(); 23928 } 23929 23930 this.$stage.children('.cloned').remove(); 23931 23932 this.$stage.unwrap(); 23933 this.$stage.children().contents().unwrap(); 23934 this.$stage.children().unwrap(); 23935 23936 this.$element 23937 .removeClass(this.options.refreshClass) 23938 .removeClass(this.options.loadingClass) 23939 .removeClass(this.options.loadedClass) 23940 .removeClass(this.options.rtlClass) 23941 .removeClass(this.options.dragClass) 23942 .removeClass(this.options.grabClass) 23943 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 23944 .removeData('owl.carousel'); 23945 }; 23946 23947 /** 23948 * Operators to calculate right-to-left and left-to-right. 23949 * @protected 23950 * @param {Number} [a] - The left side operand. 23951 * @param {String} [o] - The operator. 23952 * @param {Number} [b] - The right side operand. 23953 */ 23954 Owl.prototype.op = function(a, o, b) { 23955 var rtl = this.settings.rtl; 23956 switch (o) { 23957 case '<': 23958 return rtl ? a > b : a < b; 23959 case '>': 23960 return rtl ? a < b : a > b; 23961 case '>=': 23962 return rtl ? a <= b : a >= b; 23963 case '<=': 23964 return rtl ? a >= b : a <= b; 23965 default: 23966 break; 23967 } 23968 }; 23969 23970 /** 23971 * Attaches to an internal event. 23972 * @protected 23973 * @param {HTMLElement} element - The event source. 23974 * @param {String} event - The event name. 23975 * @param {Function} listener - The event handler to attach. 23976 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. 23977 */ 23978 Owl.prototype.on = function(element, event, listener, capture) { 23979 if (element.addEventListener) { 23980 element.addEventListener(event, listener, capture); 23981 } else if (element.attachEvent) { 23982 element.attachEvent('on' + event, listener); 23983 } 23984 }; 23985 23986 /** 23987 * Detaches from an internal event. 23988 * @protected 23989 * @param {HTMLElement} element - The event source. 23990 * @param {String} event - The event name. 23991 * @param {Function} listener - The attached event handler to detach. 23992 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 23993 */ 23994 Owl.prototype.off = function(element, event, listener, capture) { 23995 if (element.removeEventListener) { 23996 element.removeEventListener(event, listener, capture); 23997 } else if (element.detachEvent) { 23998 element.detachEvent('on' + event, listener); 23999 } 24000 }; 24001 24002 /** 24003 * Triggers a public event. 24004 * @todo Remove `status`, `relatedTarget` should be used instead. 24005 * @protected 24006 * @param {String} name - The event name. 24007 * @param {*} [data=null] - The event data. 24008 * @param {String} [namespace=carousel] - The event namespace. 24009 * @param {String} [state] - The state which is associated with the event. 24010 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 24011 * @returns {Event} - The event arguments. 24012 */ 24013 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 24014 var status = { 24015 item: { count: this._items.length, index: this.current() } 24016 }, handler = $.camelCase( 24017 $.grep([ 'on', name, namespace ], function(v) { return v }) 24018 .join('-').toLowerCase() 24019 ), event = $.Event( 24020 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 24021 $.extend({ relatedTarget: this }, status, data) 24022 ); 24023 24024 if (!this._supress[name]) { 24025 $.each(this._plugins, function(name, plugin) { 24026 if (plugin.onTrigger) { 24027 plugin.onTrigger(event); 24028 } 24029 }); 24030 24031 this.register({ type: Owl.Type.Event, name: name }); 24032 this.$element.trigger(event); 24033 24034 if (this.settings && typeof this.settings[handler] === 'function') { 24035 this.settings[handler].call(this, event); 24036 } 24037 } 24038 24039 return event; 24040 }; 24041 24042 /** 24043 * Enters a state. 24044 * @param name - The state name. 24045 */ 24046 Owl.prototype.enter = function(name) { 24047 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 24048 if (this._states.current[name] === undefined) { 24049 this._states.current[name] = 0; 24050 } 24051 24052 this._states.current[name]++; 24053 }, this)); 24054 }; 24055 24056 /** 24057 * Leaves a state. 24058 * @param name - The state name. 24059 */ 24060 Owl.prototype.leave = function(name) { 24061 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 24062 this._states.current[name]--; 24063 }, this)); 24064 }; 24065 24066 /** 24067 * Registers an event or state. 24068 * @public 24069 * @param {Object} object - The event or state to register. 24070 */ 24071 Owl.prototype.register = function(object) { 24072 if (object.type === Owl.Type.Event) { 24073 if (!$.event.special[object.name]) { 24074 $.event.special[object.name] = {}; 24075 } 24076 24077 if (!$.event.special[object.name].owl) { 24078 var _default = $.event.special[object.name]._default; 24079 $.event.special[object.name]._default = function(e) { 24080 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 24081 return _default.apply(this, arguments); 24082 } 24083 return e.namespace && e.namespace.indexOf('owl') > -1; 24084 }; 24085 $.event.special[object.name].owl = true; 24086 } 24087 } else if (object.type === Owl.Type.State) { 24088 if (!this._states.tags[object.name]) { 24089 this._states.tags[object.name] = object.tags; 24090 } else { 24091 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 24092 } 24093 24094 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 24095 return $.inArray(tag, this._states.tags[object.name]) === i; 24096 }, this)); 24097 } 24098 }; 24099 24100 /** 24101 * Suppresses events. 24102 * @protected 24103 * @param {Array.<String>} events - The events to suppress. 24104 */ 24105 Owl.prototype.suppress = function(events) { 24106 $.each(events, $.proxy(function(index, event) { 24107 this._supress[event] = true; 24108 }, this)); 24109 }; 24110 24111 /** 24112 * Releases suppressed events. 24113 * @protected 24114 * @param {Array.<String>} events - The events to release. 24115 */ 24116 Owl.prototype.release = function(events) { 24117 $.each(events, $.proxy(function(index, event) { 24118 delete this._supress[event]; 24119 }, this)); 24120 }; 24121 24122 /** 24123 * Gets unified pointer coordinates from event. 24124 * @todo #261 24125 * @protected 24126 * @param {Event} - The `mousedown` or `touchstart` event. 24127 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 24128 */ 24129 Owl.prototype.pointer = function(event) { 24130 var result = { x: null, y: null }; 24131 24132 event = event.originalEvent || event || window.event; 24133 24134 event = event.touches && event.touches.length ? 24135 event.touches[0] : event.changedTouches && event.changedTouches.length ? 24136 event.changedTouches[0] : event; 24137 24138 if (event.pageX) { 24139 result.x = event.pageX; 24140 result.y = event.pageY; 24141 } else { 24142 result.x = event.clientX; 24143 result.y = event.clientY; 24144 } 24145 24146 return result; 24147 }; 24148 24149 /** 24150 * Gets the difference of two vectors. 24151 * @todo #261 24152 * @protected 24153 * @param {Object} - The first vector. 24154 * @param {Object} - The second vector. 24155 * @returns {Object} - The difference. 24156 */ 24157 Owl.prototype.difference = function(first, second) { 24158 return { 24159 x: first.x - second.x, 24160 y: first.y - second.y 24161 }; 24162 }; 24163 24164 /** 24165 * The jQuery Plugin for the Owl Carousel
vendor: 32,216 bytes, lines 24166-25448
24166 * @todo Navigation plugin `next` and `prev` 24167 * @public 24168 */ 24169 $.fn.owlCarousel = function(option) { 24170 var args = Array.prototype.slice.call(arguments, 1); 24171 24172 return this.each(function() { 24173 var $this = $(this), 24174 data = $this.data('owl.carousel'); 24175 24176 if (!data) { 24177 data = new Owl(this, typeof option == 'object' && option); 24178 $this.data('owl.carousel', data); 24179 24180 $.each([ 24181 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 24182 ], function(i, event) { 24183 data.register({ type: Owl.Type.Event, name: event }); 24184 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 24185 if (e.namespace && e.relatedTarget !== this) { 24186 this.suppress([ event ]); 24187 data[event].apply(this, [].slice.call(arguments, 1)); 24188 this.release([ event ]); 24189 } 24190 }, data)); 24191 }); 24192 } 24193 24194 if (typeof option == 'string' && option.charAt(0) !== '_') { 24195 data[option].apply(data, args); 24196 } 24197 }); 24198 }; 24199 24200 /** 24201 * The constructor for the jQuery Plugin 24202 * @public 24203 */ 24204 $.fn.owlCarousel.Constructor = Owl; 24205 24206})(window.Zepto || window.jQuery, window, document); 24207 24208/** 24209 * AutoRefresh Plugin 24210 * @version 2.0.0-beta.3 24211 * @author Artus Kolanowski 24212 * @license The MIT License (MIT) 24213 */ 24214;(function($, window, document, undefined) { 24215 24216 /** 24217 * Creates the auto refresh plugin. 24218 * @class The Auto Refresh Plugin 24219 * @param {Owl} carousel - The Owl Carousel 24220 */ 24221 var AutoRefresh = function(carousel) { 24222 /** 24223 * Reference to the core. 24224 * @protected 24225 * @type {Owl} 24226 */ 24227 this._core = carousel; 24228 24229 /** 24230 * Refresh interval. 24231 * @protected 24232 * @type {number} 24233 */ 24234 this._interval = null; 24235 24236 /** 24237 * Whether the element is currently visible or not. 24238 * @protected 24239 * @type {Boolean} 24240 */ 24241 this._visible = null; 24242 24243 /** 24244 * All event handlers. 24245 * @protected 24246 * @type {Object} 24247 */ 24248 this._handlers = { 24249 'initialized.owl.carousel': $.proxy(function(e) { 24250 if (e.namespace && this._core.settings.autoRefresh) { 24251 this.watch(); 24252 } 24253 }, this) 24254 }; 24255 24256 // set default options 24257 this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options); 24258 24259 // register event handlers 24260 this._core.$element.on(this._handlers); 24261 }; 24262 24263 /** 24264 * Default options. 24265 * @public 24266 */ 24267 AutoRefresh.Defaults = { 24268 autoRefresh: true, 24269 autoRefreshInterval: 500 24270 }; 24271 24272 /** 24273 * Watches the element. 24274 */ 24275 AutoRefresh.prototype.watch = function() { 24276 if (this._interval) { 24277 return; 24278 } 24279 24280 this._visible = this._core.$element.is(':visible'); 24281 this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval); 24282 }; 24283 24284 /** 24285 * Refreshes the element. 24286 */ 24287 AutoRefresh.prototype.refresh = function() { 24288 if (this._core.$element.is(':visible') === this._visible) { 24289 return; 24290 } 24291 24292 this._visible = !this._visible; 24293 24294 this._core.$element.toggleClass('owl-hidden', !this._visible); 24295 24296 this._visible && (this._core.invalidate('width') && this._core.refresh()); 24297 }; 24298 24299 /** 24300 * Destroys the plugin. 24301 */ 24302 AutoRefresh.prototype.destroy = function() { 24303 var handler, property; 24304 24305 window.clearInterval(this._interval); 24306 24307 for (handler in this._handlers) { 24308 this._core.$element.off(handler, this._handlers[handler]); 24309 } 24310 for (property in Object.getOwnPropertyNames(this)) { 24311 typeof this[property] != 'function' && (this[property] = null); 24312 } 24313 }; 24314 24315 $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; 24316 24317})(window.Zepto || window.jQuery, window, document); 24318 24319/** 24320 * Lazy Plugin 24321 * @version 2.0.0-beta.3 24322 * @author Bartosz Wojciechowski 24323 * @license The MIT License (MIT) 24324 */ 24325;(function($, window, document, undefined) { 24326 24327 /** 24328 * Creates the lazy plugin. 24329 * @class The Lazy Plugin 24330 * @param {Owl} carousel - The Owl Carousel 24331 */ 24332 var Lazy = function(carousel) { 24333 24334 /** 24335 * Reference to the core. 24336 * @protected 24337 * @type {Owl} 24338 */ 24339 this._core = carousel; 24340 24341 /** 24342 * Already loaded items. 24343 * @protected 24344 * @type {Array.<jQuery>} 24345 */ 24346 this._loaded = []; 24347 24348 /** 24349 * Event handlers. 24350 * @protected 24351 * @type {Object} 24352 */ 24353 this._handlers = { 24354 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) { 24355 if (!e.namespace) { 24356 return; 24357 } 24358 24359 if (!this._core.settings || !this._core.settings.lazyLoad) { 24360 return; 24361 } 24362 24363 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 24364 var settings = this._core.settings, 24365 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 24366 i = ((settings.center && n * -1) || 0), 24367 position = ((e.property && e.property.value) || this._core.current()) + i, 24368 clones = this._core.clones().length, 24369 load = $.proxy(function(i, v) { this.load(v) }, this); 24370 24371 while (i++ < n) { 24372 this.load(clones / 2 + this._core.relative(position)); 24373 clones && $.each(this._core.clones(this._core.relative(position)), load); 24374 position++; 24375 } 24376 } 24377 }, this) 24378 }; 24379 24380 // set the default options 24381 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 24382 24383 // register event handler 24384 this._core.$element.on(this._handlers); 24385 } 24386 24387 /** 24388 * Default options. 24389 * @public 24390 */ 24391 Lazy.Defaults = { 24392 lazyLoad: false 24393 } 24394 24395 /** 24396 * Loads all resources of an item at the specified position. 24397 * @param {Number} position - The absolute position of the item. 24398 * @protected 24399 */ 24400 Lazy.prototype.load = function(position) { 24401 var $item = this._core.$stage.children().eq(position), 24402 $elements = $item && $item.find('.owl-lazy'); 24403 24404 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 24405 return; 24406 } 24407 24408 $elements.each($.proxy(function(index, element) { 24409 var $element = $(element), image, 24410 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src'); 24411 24412 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 24413 24414 if ($element.is('img')) { 24415 $element.one('load.owl.lazy', $.proxy(function() { 24416 $element.css('opacity', 1); 24417 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 24418 }, this)).attr('src', url); 24419 } else { 24420 image = new Image(); 24421 image.onload = $.proxy(function() { 24422 $element.css({ 24423 'background-image': 'url(' + url + ')', 24424 'opacity': '1' 24425 }); 24426 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 24427 }, this); 24428 image.src = url; 24429 } 24430 }, this)); 24431 24432 this._loaded.push($item.get(0)); 24433 } 24434 24435 /** 24436 * Destroys the plugin. 24437 * @public 24438 */ 24439 Lazy.prototype.destroy = function() { 24440 var handler, property; 24441 24442 for (handler in this.handlers) { 24443 this._core.$element.off(handler, this.handlers[handler]); 24444 } 24445 for (property in Object.getOwnPropertyNames(this)) { 24446 typeof this[property] != 'function' && (this[property] = null); 24447 } 24448 }; 24449 24450 $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; 24451 24452})(window.Zepto || window.jQuery, window, document); 24453 24454/** 24455 * AutoHeight Plugin 24456 * @version 2.0.0-beta.3 24457 * @author Bartosz Wojciechowski 24458 * @license The MIT License (MIT) 24459 */ 24460;(function($, window, document, undefined) { 24461 24462 /** 24463 * Creates the auto height plugin. 24464 * @class The Auto Height Plugin 24465 * @param {Owl} carousel - The Owl Carousel 24466 */ 24467 var AutoHeight = function(carousel) { 24468 /** 24469 * Reference to the core. 24470 * @protected 24471 * @type {Owl} 24472 */ 24473 this._core = carousel; 24474 24475 /** 24476 * All event handlers. 24477 * @protected 24478 * @type {Object} 24479 */ 24480 this._handlers = { 24481 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { 24482 if (e.namespace && this._core.settings.autoHeight) { 24483 this.update(); 24484 } 24485 }, this), 24486 'changed.owl.carousel': $.proxy(function(e) { 24487 if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){ 24488 this.update(); 24489 } 24490 }, this), 24491 'loaded.owl.lazy': $.proxy(function(e) { 24492 if (e.namespace && this._core.settings.autoHeight 24493 && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) { 24494 this.update(); 24495 } 24496 }, this) 24497 }; 24498 24499 // set default options 24500 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 24501 24502 // register event handlers 24503 this._core.$element.on(this._handlers); 24504 }; 24505 24506 /** 24507 * Default options. 24508 * @public 24509 */ 24510 AutoHeight.Defaults = { 24511 autoHeight: false, 24512 autoHeightClass: 'owl-height' 24513 }; 24514 24515 /** 24516 * Updates the view. 24517 */ 24518 AutoHeight.prototype.update = function() { 24519 var start = this._core._current, 24520 end = start + this._core.settings.items, 24521 visible = this._core.$stage.children().toArray().slice(start, end); 24522 heights = [], 24523 maxheight = 0; 24524 24525 $.each(visible, function(index, item) { 24526 heights.push($(item).height()); 24527 }); 24528 24529 maxheight = Math.max.apply(null, heights); 24530 24531 this._core.$stage.parent() 24532 .height(maxheight) 24533 .addClass(this._core.settings.autoHeightClass); 24534 }; 24535 24536 AutoHeight.prototype.destroy = function() { 24537 var handler, property; 24538 24539 for (handler in this._handlers) { 24540 this._core.$element.off(handler, this._handlers[handler]); 24541 } 24542 for (property in Object.getOwnPropertyNames(this)) { 24543 typeof this[property] != 'function' && (this[property] = null); 24544 } 24545 }; 24546 24547 $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; 24548 24549})(window.Zepto || window.jQuery, window, document); 24550 24551/** 24552 * Video Plugin 24553 * @version 2.0.0-beta.3 24554 * @author Bartosz Wojciechowski 24555 * @license The MIT License (MIT) 24556 */ 24557;(function($, window, document, undefined) { 24558 24559 /** 24560 * Creates the video plugin. 24561 * @class The Video Plugin 24562 * @param {Owl} carousel - The Owl Carousel 24563 */ 24564 var Video = function(carousel) { 24565 /** 24566 * Reference to the core. 24567 * @protected 24568 * @type {Owl} 24569 */ 24570 this._core = carousel; 24571 24572 /** 24573 * Cache all video URLs. 24574 * @protected 24575 * @type {Object} 24576 */ 24577 this._videos = {}; 24578 24579 /** 24580 * Current playing item. 24581 * @protected 24582 * @type {jQuery} 24583 */ 24584 this._playing = null; 24585 24586 /** 24587 * All event handlers. 24588 * @todo The cloned content removale is too late 24589 * @protected 24590 * @type {Object} 24591 */ 24592 this._handlers = { 24593 'initialized.owl.carousel': $.proxy(function(e) { 24594 if (e.namespace) { 24595 this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] }); 24596 } 24597 }, this), 24598 'resize.owl.carousel': $.proxy(function(e) { 24599 if (e.namespace && this._core.settings.video && this.isInFullScreen()) { 24600 e.preventDefault(); 24601 } 24602 }, this), 24603 'refreshed.owl.carousel': $.proxy(function(e) { 24604 if (e.namespace && this._core.is('resizing')) { 24605 this._core.$stage.find('.cloned .owl-video-frame').remove(); 24606 } 24607 }, this), 24608 'changed.owl.carousel': $.proxy(function(e) { 24609 if (e.namespace && e.property.name === 'position' && this._playing) { 24610 this.stop(); 24611 } 24612 }, this), 24613 'prepared.owl.carousel': $.proxy(function(e) { 24614 if (!e.namespace) { 24615 return; 24616 } 24617 24618 var $element = $(e.content).find('.owl-video'); 24619 24620 if ($element.length) { 24621 $element.css('display', 'none'); 24622 this.fetch($element, $(e.content)); 24623 } 24624 }, this) 24625 }; 24626 24627 // set default options 24628 this._core.options = $.extend({}, Video.Defaults, this._core.options); 24629 24630 // register event handlers 24631 this._core.$element.on(this._handlers); 24632 24633 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 24634 this.play(e); 24635 }, this)); 24636 }; 24637 24638 /** 24639 * Default options. 24640 * @public 24641 */ 24642 Video.Defaults = { 24643 video: false, 24644 videoHeight: false, 24645 videoWidth: false 24646 }; 24647 24648 /** 24649 * Gets the video ID and the type (YouTube/Vimeo only). 24650 * @protected 24651 * @param {jQuery} target - The target containing the video data. 24652 * @param {jQuery} item - The item containing the video. 24653 */ 24654 Video.prototype.fetch = function(target, item) { 24655 var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube', 24656 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'), 24657 width = target.attr('data-width') || this._core.settings.videoWidth, 24658 height = target.attr('data-height') || this._core.settings.videoHeight, 24659 url = target.attr('href'); 24660 24661 if (url) { 24662 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+)?/); 24663 24664 if (id[3].indexOf('youtu') > -1) { 24665 type = 'youtube'; 24666 } else if (id[3].indexOf('vimeo') > -1) { 24667 type = 'vimeo'; 24668 } else { 24669 throw new Error('Video URL not supported.'); 24670 } 24671 id = id[6]; 24672 } else { 24673 throw new Error('Missing video URL.'); 24674 } 24675 24676 this._videos[url] = { 24677 type: type, 24678 id: id, 24679 width: width, 24680 height: height 24681 }; 24682 24683 item.attr('data-video', url); 24684 24685 this.thumbnail(target, this._videos[url]); 24686 }; 24687 24688 /** 24689 * Creates video thumbnail. 24690 * @protected 24691 * @param {jQuery} target - The target containing the video data. 24692 * @param {Object} info - The video info object. 24693 * @see `fetch` 24694 */ 24695 Video.prototype.thumbnail = function(target, video) { 24696 var tnLink, 24697 icon, 24698 path, 24699 dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '', 24700 customTn = target.find('img'), 24701 srcType = 'src', 24702 lazyClass = '', 24703 settings = this._core.settings, 24704 create = function(path) { 24705 icon = '<div class="owl-video-play-icon"></div>'; 24706 24707 if (settings.lazyLoad) { 24708 tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>'; 24709 } else { 24710 tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>'; 24711 } 24712 target.after(tnLink); 24713 target.after(icon); 24714 }; 24715 24716 // wrap video content into owl-video-wrapper div 24717 target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>'); 24718 24719 if (this._core.settings.lazyLoad) { 24720 srcType = 'data-src'; 24721 lazyClass = 'owl-lazy'; 24722 } 24723 24724 // custom thumbnail 24725 if (customTn.length) { 24726 create(customTn.attr(srcType)); 24727 customTn.remove(); 24728 return false; 24729 } 24730 24731 if (video.type === 'youtube') { 24732 path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 24733 create(path); 24734 } else if (video.type === 'vimeo') { 24735 $.ajax({ 24736 type: 'GET', 24737 url: '//vimeo.com/api/v2/video/' + video.id + '.json', 24738 jsonp: 'callback', 24739 dataType: 'jsonp', 24740 success: function(data) { 24741 path = data[0].thumbnail_large; 24742 create(path); 24743 } 24744 }); 24745 } 24746 }; 24747 24748 /** 24749 * Stops the current video. 24750 * @public 24751 */ 24752 Video.prototype.stop = function() { 24753 this._core.trigger('stop', null, 'video'); 24754 this._playing.find('.owl-video-frame').remove(); 24755 this._playing.removeClass('owl-video-playing'); 24756 this._playing = null; 24757 this._core.leave('playing'); 24758 this._core.trigger('stopped', null, 'video'); 24759 }; 24760 24761 /** 24762 * Starts the current video. 24763 * @public 24764 * @param {Event} event - The event arguments. 24765 */ 24766 Video.prototype.play = function(event) { 24767 var target = $(event.target), 24768 item = target.closest('.' + this._core.settings.itemClass), 24769 video = this._videos[item.attr('data-video')], 24770 width = video.width || '100%', 24771 height = video.height || this._core.$stage.height(), 24772 html; 24773 24774 if (this._playing) { 24775 return; 24776 } 24777 24778 this._core.enter('playing'); 24779 this._core.trigger('play', null, 'video'); 24780 24781 item = this._core.items(this._core.relative(item.index())); 24782 24783 this._core.reset(item.index()); 24784 24785 if (video.type === 'youtube') { 24786 html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' + 24787 video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>'; 24788 } else if (video.type === 'vimeo') { 24789 html = '<iframe src="//player.vimeo.com/video/' + video.id + 24790 '?autoplay=1" width="' + width + '" height="' + height + 24791 '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; 24792 } 24793 24794 $('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video')); 24795 24796 this._playing = item.addClass('owl-video-playing'); 24797 }; 24798 24799 /** 24800 * Checks whether an video is currently in full screen mode or not. 24801 * @todo Bad style because looks like a readonly method but changes members. 24802 * @protected 24803 * @returns {Boolean} 24804 */ 24805 Video.prototype.isInFullScreen = function() { 24806 var element = document.fullscreenElement || document.mozFullScreenElement || 24807 document.webkitFullscreenElement; 24808 24809 return element && $(element).parent().hasClass('owl-video-frame'); 24810 }; 24811 24812 /** 24813 * Destroys the plugin. 24814 */ 24815 Video.prototype.destroy = function() { 24816 var handler, property; 24817 24818 this._core.$element.off('click.owl.video'); 24819 24820 for (handler in this._handlers) { 24821 this._core.$element.off(handler, this._handlers[handler]); 24822 } 24823 for (property in Object.getOwnPropertyNames(this)) { 24824 typeof this[property] != 'function' && (this[property] = null); 24825 } 24826 }; 24827 24828 $.fn.owlCarousel.Constructor.Plugins.Video = Video; 24829 24830})(window.Zepto || window.jQuery, window, document); 24831 24832/** 24833 * Animate Plugin 24834 * @version 2.0.0-beta.3 24835 * @author Bartosz Wojciechowski 24836 * @license The MIT License (MIT) 24837 */ 24838;(function($, window, document, undefined) { 24839 24840 /** 24841 * Creates the animate plugin. 24842 * @class The Navigation Plugin 24843 * @param {Owl} scope - The Owl Carousel 24844 */ 24845 var Animate = function(scope) { 24846 this.core = scope; 24847 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 24848 this.swapping = true; 24849 this.previous = undefined; 24850 this.next = undefined; 24851 24852 this.handlers = { 24853 'change.owl.carousel': $.proxy(function(e) { 24854 if (e.namespace && e.property.name == 'position') { 24855 this.previous = this.core.current(); 24856 this.next = e.property.value; 24857 } 24858 }, this), 24859 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 24860 if (e.namespace) { 24861 this.swapping = e.type == 'translated'; 24862 } 24863 }, this), 24864 'translate.owl.carousel': $.proxy(function(e) { 24865 if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 24866 this.swap(); 24867 } 24868 }, this) 24869 }; 24870 24871 this.core.$element.on(this.handlers); 24872 }; 24873 24874 /** 24875 * Default options. 24876 * @public 24877 */ 24878 Animate.Defaults = { 24879 animateOut: false, 24880 animateIn: false 24881 }; 24882 24883 /** 24884 * Toggles the animation classes whenever an translations starts. 24885 * @protected 24886 * @returns {Boolean|undefined} 24887 */ 24888 Animate.prototype.swap = function() { 24889 24890 if (this.core.settings.items !== 1) { 24891 return; 24892 } 24893 24894 if (!$.support.animation || !$.support.transition) { 24895 return; 24896 } 24897 24898 this.core.speed(0); 24899 24900 var left, 24901 clear = $.proxy(this.clear, this), 24902 previous = this.core.$stage.children().eq(this.previous), 24903 next = this.core.$stage.children().eq(this.next), 24904 incoming = this.core.settings.animateIn, 24905 outgoing = this.core.settings.animateOut; 24906 24907 if (this.core.current() === this.previous) { 24908 return; 24909 } 24910 24911 if (outgoing) { 24912 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 24913 previous.css( { 'left': left + 'px' } ) 24914 .addClass('animated owl-animated-out') 24915 .addClass(outgoing) 24916 .on($.support.animation.end, clear); 24917 } 24918 24919 if (incoming) { 24920 next.addClass('animated owl-animated-in') 24921 .addClass(incoming) 24922 .on($.support.animation.end, clear); 24923 } 24924 }; 24925 24926 Animate.prototype.clear = function(e) { 24927 if ($(e.target).hasClass('animated')) { 24928 $(e.target).css( { 'left': '' } ) 24929 .removeClass('animated owl-animated-out owl-animated-in') 24930 .removeClass(this.core.settings.animateIn) 24931 .removeClass(this.core.settings.animateOut); 24932 this.core.onTransitionEnd(); 24933 } 24934 }; 24935 24936 /** 24937 * Destroys the plugin. 24938 * @public 24939 */ 24940 Animate.prototype.destroy = function() { 24941 var handler, property; 24942 24943 for (handler in this.handlers) { 24944 this.core.$element.off(handler, this.handlers[handler]); 24945 } 24946 for (property in Object.getOwnPropertyNames(this)) { 24947 typeof this[property] != 'function' && (this[property] = null); 24948 } 24949 }; 24950 24951 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 24952 24953})(window.Zepto || window.jQuery, window, document); 24954 24955/** 24956 * Autoplay Plugin 24957 * @version 2.0.0-beta.3 24958 * @author Bartosz Wojciechowski 24959 * @author Artus Kolanowski 24960 * @license The MIT License (MIT) 24961 */ 24962;(function($, window, document, undefined) { 24963 24964 /** 24965 * Creates the autoplay plugin. 24966 * @class The Autoplay Plugin 24967 * @param {Owl} scope - The Owl Carousel 24968 */ 24969 var Autoplay = function(carousel) { 24970 /** 24971 * Reference to the core. 24972 * @protected 24973 * @type {Owl} 24974 */ 24975 this._core = carousel; 24976 24977 /** 24978 * The autoplay interval. 24979 * @type {Number} 24980 */ 24981 this._interval = null; 24982 24983 /** 24984 * Indicates whenever the autoplay is paused. 24985 * @type {Boolean} 24986 */ 24987 this._paused = false; 24988 24989 /** 24990 * All event handlers. 24991 * @protected 24992 * @type {Object} 24993 */ 24994 this._handlers = { 24995 'changed.owl.carousel': $.proxy(function(e) { 24996 if (e.namespace && e.property.name === 'settings') { 24997 if (this._core.settings.autoplay) { 24998 this.play(); 24999 } else { 25000 this.stop(); 25001 } 25002 } 25003 }, this), 25004 'initialized.owl.carousel': $.proxy(function(e) { 25005 if (e.namespace && this._core.settings.autoplay) { 25006 this.play(); 25007 } 25008 }, this), 25009 'play.owl.autoplay': $.proxy(function(e, t, s) { 25010 if (e.namespace) { 25011 this.play(t, s); 25012 } 25013 }, this), 25014 'stop.owl.autoplay': $.proxy(function(e) { 25015 if (e.namespace) { 25016 this.stop(); 25017 } 25018 }, this), 25019 'mouseover.owl.autoplay': $.proxy(function() { 25020 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 25021 this.pause(); 25022 } 25023 }, this), 25024 'mouseleave.owl.autoplay': $.proxy(function() { 25025 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 25026 this.play(); 25027 } 25028 }, this) 25029 }; 25030 25031 // register event handlers 25032 this._core.$element.on(this._handlers); 25033 25034 // set default options 25035 this._core.options = $.extend({}, Autoplay.Defaults, this._core.options); 25036 }; 25037 25038 /** 25039 * Default options. 25040 * @public 25041 */ 25042 Autoplay.Defaults = { 25043 autoplay: false, 25044 autoplayTimeout: 5000, 25045 autoplayHoverPause: false, 25046 autoplaySpeed: false 25047 }; 25048 25049 /** 25050 * Starts the autoplay. 25051 * @public 25052 * @param {Number} [timeout] - The interval before the next animation starts. 25053 * @param {Number} [speed] - The animation speed for the animations. 25054 */ 25055 Autoplay.prototype.play = function(timeout, speed) { 25056 this._paused = false; 25057 25058 if (this._core.is('rotating')) { 25059 return; 25060 } 25061 25062 this._core.enter('rotating'); 25063 25064 this._interval = window.setInterval($.proxy(function() { 25065 if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) { 25066 return; 25067 } 25068 this._core.next(speed || this._core.settings.autoplaySpeed); 25069 }, this), timeout || this._core.settings.autoplayTimeout); 25070 }; 25071 25072 /** 25073 * Stops the autoplay. 25074 * @public 25075 */ 25076 Autoplay.prototype.stop = function() { 25077 if (!this._core.is('rotating')) { 25078 return; 25079 } 25080 25081 window.clearInterval(this._interval); 25082 this._core.leave('rotating'); 25083 }; 25084 25085 /** 25086 * Stops the autoplay. 25087 * @public 25088 */ 25089 Autoplay.prototype.pause = function() { 25090 if (!this._core.is('rotating')) { 25091 return; 25092 } 25093 25094 this._paused = true; 25095 }; 25096 25097 /** 25098 * Destroys the plugin. 25099 */ 25100 Autoplay.prototype.destroy = function() { 25101 var handler, property; 25102 25103 this.stop(); 25104 25105 for (handler in this._handlers) { 25106 this._core.$element.off(handler, this._handlers[handler]); 25107 } 25108 for (property in Object.getOwnPropertyNames(this)) { 25109 typeof this[property] != 'function' && (this[property] = null); 25110 } 25111 }; 25112 25113 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 25114 25115})(window.Zepto || window.jQuery, window, document); 25116 25117/** 25118 * Navigation Plugin 25119 * @version 2.0.0-beta.3 25120 * @author Artus Kolanowski 25121 * @license The MIT License (MIT) 25122 */ 25123;(function($, window, document, undefined) { 25124 'use strict'; 25125 25126 /** 25127 * Creates the navigation plugin. 25128 * @class The Navigation Plugin 25129 * @param {Owl} carousel - The Owl Carousel. 25130 */ 25131 var Navigation = function(carousel) { 25132 /** 25133 * Reference to the core. 25134 * @protected 25135 * @type {Owl} 25136 */ 25137 this._core = carousel; 25138 25139 /** 25140 * Indicates whether the plugin is initialized or not. 25141 * @protected 25142 * @type {Boolean} 25143 */ 25144 this._initialized = false; 25145 25146 /** 25147 * The current paging indexes. 25148 * @protected 25149 * @type {Array} 25150 */ 25151 this._pages = []; 25152 25153 /** 25154 * All DOM elements of the user interface. 25155 * @protected 25156 * @type {Object} 25157 */ 25158 this._controls = {}; 25159 25160 /** 25161 * Markup for an indicator. 25162 * @protected 25163 * @type {Array.<String>} 25164 */ 25165 this._templates = []; 25166 25167 /** 25168 * The carousel element. 25169 * @type {jQuery} 25170 */ 25171 this.$element = this._core.$element; 25172 25173 /** 25174 * Overridden methods of the carousel. 25175 * @protected 25176 * @type {Object} 25177 */ 25178 this._overrides = { 25179 next: this._core.next, 25180 prev: this._core.prev, 25181 to: this._core.to 25182 }; 25183 25184 /** 25185 * All event handlers. 25186 * @protected 25187 * @type {Object} 25188 */ 25189 this._handlers = { 25190 'prepared.owl.carousel': $.proxy(function(e) { 25191 if (e.namespace && this._core.settings.dotsData) { 25192 this._templates.push('<div class="' + this._core.settings.dotClass + '">' + 25193 $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>'); 25194 } 25195 }, this), 25196 'added.owl.carousel': $.proxy(function(e) { 25197 if (e.namespace && this._core.settings.dotsData) { 25198 this._templates.splice(e.position, 0, this._templates.pop()); 25199 } 25200 }, this), 25201 'remove.owl.carousel': $.proxy(function(e) { 25202 if (e.namespace && this._core.settings.dotsData) { 25203 this._templates.splice(e.position, 1); 25204 } 25205 }, this), 25206 'changed.owl.carousel': $.proxy(function(e) { 25207 if (e.namespace && e.property.name == 'position') { 25208 this.draw(); 25209 } 25210 }, this), 25211 'initialized.owl.carousel': $.proxy(function(e) { 25212 if (e.namespace && !this._initialized) { 25213 this._core.trigger('initialize', null, 'navigation'); 25214 this.initialize(); 25215 this.update(); 25216 this.draw(); 25217 this._initialized = true; 25218 this._core.trigger('initialized', null, 'navigation'); 25219 } 25220 }, this), 25221 'refreshed.owl.carousel': $.proxy(function(e) { 25222 if (e.namespace && this._initialized) { 25223 this._core.trigger('refresh', null, 'navigation'); 25224 this.update(); 25225 this.draw(); 25226 this._core.trigger('refreshed', null, 'navigation'); 25227 } 25228 }, this) 25229 }; 25230 25231 // set default options 25232 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 25233 25234 // register event handlers 25235 this.$element.on(this._handlers); 25236 }; 25237 25238 /** 25239 * Default options. 25240 * @public 25241 * @todo Rename `slideBy` to `navBy` 25242 */ 25243 Navigation.Defaults = { 25244 nav: false, 25245 navText: [ 'prev', 'next' ], 25246 navSpeed: false, 25247 navElement: 'div', 25248 navContainer: false, 25249 navContainerClass: 'owl-nav', 25250 navClass: [ 'owl-prev', 'owl-next' ], 25251 slideBy: 1, 25252 dotClass: 'owl-dot', 25253 dotsClass: 'owl-dots', 25254 dots: true, 25255 dotsEach: false, 25256 dotsData: false, 25257 dotsSpeed: false, 25258 dotsContainer: false 25259 }; 25260 25261 /** 25262 * Initializes the layout of the plugin and extends the carousel. 25263 * @protected 25264 */ 25265 Navigation.prototype.initialize = function() { 25266 var override, 25267 settings = this._core.settings; 25268 25269 // create DOM structure for relative navigation 25270 this._controls.$relative = (settings.navContainer ? $(settings.navContainer) 25271 : $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled'); 25272 25273 this._controls.$previous = $('<' + settings.navElement + '>') 25274 .addClass(settings.navClass[0]) 25275 .html(settings.navText[0]) 25276 .prependTo(this._controls.$relative) 25277 .on('click', $.proxy(function(e) { 25278 this.prev(settings.navSpeed); 25279 }, this)); 25280 this._controls.$next = $('<' + settings.navElement + '>') 25281 .addClass(settings.navClass[1]) 25282 .html(settings.navText[1]) 25283 .appendTo(this._controls.$relative) 25284 .on('click', $.proxy(function(e) { 25285 this.next(settings.navSpeed); 25286 }, this)); 25287 25288 // create DOM structure for absolute navigation 25289 if (!settings.dotsData) { 25290 this._templates = [ $('<div>') 25291 .addClass(settings.dotClass) 25292 .append($('<span>')) 25293 .prop('outerHTML') ]; 25294 } 25295 25296 this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer) 25297 : $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled'); 25298 25299 this._controls.$absolute.on('click', 'div', $.proxy(function(e) { 25300 var index = $(e.target).parent().is(this._controls.$absolute) 25301 ? $(e.target).index() : $(e.target).parent().index(); 25302 25303 e.preventDefault(); 25304 25305 this.to(index, settings.dotsSpeed); 25306 }, this)); 25307 25308 // override public methods of the carousel 25309 for (override in this._overrides) { 25310 this._core[override] = $.proxy(this[override], this); 25311 } 25312 }; 25313 25314 /** 25315 * Destroys the plugin. 25316 * @protected 25317 */ 25318 Navigation.prototype.destroy = function() { 25319 var handler, control, property, override; 25320 25321 for (handler in this._handlers) { 25322 this.$element.off(handler, this._handlers[handler]); 25323 } 25324 for (control in this._controls) { 25325 this._controls[control].remove(); 25326 } 25327 for (override in this.overides) { 25328 this._core[override] = this._overrides[override]; 25329 } 25330 for (property in Object.getOwnPropertyNames(this)) { 25331 typeof this[property] != 'function' && (this[property] = null); 25332 } 25333 }; 25334 25335 /** 25336 * Updates the internal state. 25337 * @protected 25338 */ 25339 Navigation.prototype.update = function() { 25340 var i, j, k, 25341 lower = this._core.clones().length / 2, 25342 upper = lower + this._core.items().length, 25343 maximum = this._core.maximum(true), 25344 settings = this._core.settings, 25345 size = settings.center || settings.autoWidth || settings.dotsData 25346 ? 1 : settings.dotsEach || settings.items; 25347 25348 if (settings.slideBy !== 'page') { 25349 settings.slideBy = Math.min(settings.slideBy, settings.items); 25350 } 25351 25352 if (settings.dots || settings.slideBy == 'page') { 25353 this._pages = []; 25354 25355 for (i = lower, j = 0, k = 0; i < upper; i++) { 25356 if (j >= size || j === 0) { 25357 this._pages.push({ 25358 start: Math.min(maximum, i - lower), 25359 end: i - lower + size - 1 25360 }); 25361 if (Math.min(maximum, i - lower) === maximum) { 25362 break; 25363 } 25364 j = 0, ++k; 25365 } 25366 j += this._core.mergers(this._core.relative(i)); 25367 } 25368 } 25369 }; 25370 25371 /** 25372 * Draws the user interface. 25373 * @todo The option `dotsData` wont work. 25374 * @protected 25375 */ 25376 Navigation.prototype.draw = function() { 25377 var difference, 25378 settings = this._core.settings, 25379 disabled = this._core.items().length <= settings.items, 25380 index = this._core.relative(this._core.current()), 25381 loop = settings.loop || settings.rewind; 25382 25383 this._controls.$relative.toggleClass('disabled', !settings.nav || disabled); 25384 25385 if (settings.nav) { 25386 this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true)); 25387 this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true)); 25388 } 25389 25390 this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled); 25391 25392 if (settings.dots) { 25393 difference = this._pages.length - this._controls.$absolute.children().length; 25394 25395 if (settings.dotsData && difference !== 0) { 25396 this._controls.$absolute.html(this._templates.join('')); 25397 } else if (difference > 0) { 25398 this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0])); 25399 } else if (difference < 0) { 25400 this._controls.$absolute.children().slice(difference).remove(); 25401 } 25402 25403 this._controls.$absolute.find('.active').removeClass('active'); 25404 this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 25405 } 25406 }; 25407 25408 /** 25409 * Extends event data. 25410 * @protected 25411 * @param {Event} event - The event object which gets thrown. 25412 */ 25413 Navigation.prototype.onTrigger = function(event) { 25414 var settings = this._core.settings; 25415 25416 event.page = { 25417 index: $.inArray(this.current(), this._pages), 25418 count: this._pages.length, 25419 size: settings && (settings.center || settings.autoWidth || settings.dotsData 25420 ? 1 : settings.dotsEach || settings.items) 25421 }; 25422 }; 25423 25424 /** 25425 * Gets the current page position of the carousel. 25426 * @protected 25427 * @returns {Number} 25428 */ 25429 Navigation.prototype.current = function() { 25430 var current = this._core.relative(this._core.current()); 25431 return $.grep(this._pages, $.proxy(function(page, index) { 25432 return page.start <= current && page.end >= current; 25433 }, this)).pop(); 25434 }; 25435 25436 /** 25437 * Gets the current succesor/predecessor position. 25438 * @protected 25439 * @returns {Number} 25440 */ 25441 Navigation.prototype.getPosition = function(successor) { 25442 var position, length, 25443 settings = this._core.settings; 25444 25445 if (settings.slideBy == 'page') { 25446 position = $.inArray(this.current(), this._pages); 25447 length = this._pages.length; 25448 successor ? ++position : --position;
vendor: 5,678 bytes, lines 25449-25673
25449 position = this._pages[((position % length) + length) % length].start; 25450 } else { 25451 position = this._core.relative(this._core.current()); 25452 length = this._core.items().length; 25453 successor ? position += settings.slideBy : position -= settings.slideBy; 25454 } 25455 25456 return position; 25457 }; 25458 25459 /** 25460 * Slides to the next item or page. 25461 * @public 25462 * @param {Number} [speed=false] - The time in milliseconds for the transition. 25463 */ 25464 Navigation.prototype.next = function(speed) { 25465 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 25466 }; 25467 25468 /** 25469 * Slides to the previous item or page. 25470 * @public 25471 * @param {Number} [speed=false] - The time in milliseconds for the transition. 25472 */ 25473 Navigation.prototype.prev = function(speed) { 25474 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 25475 }; 25476 25477 /** 25478 * Slides to the specified item or page. 25479 * @public 25480 * @param {Number} position - The position of the item or page. 25481 * @param {Number} [speed] - The time in milliseconds for the transition. 25482 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 25483 */ 25484 Navigation.prototype.to = function(position, speed, standard) { 25485 var length; 25486 25487 if (!standard) { 25488 length = this._pages.length; 25489 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 25490 } else { 25491 $.proxy(this._overrides.to, this._core)(position, speed); 25492 } 25493 }; 25494 25495 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 25496 25497})(window.Zepto || window.jQuery, window, document); 25498 25499/** 25500 * Hash Plugin 25501 * @version 2.0.0-beta.3 25502 * @author Artus Kolanowski 25503 * @license The MIT License (MIT) 25504 */ 25505;(function($, window, document, undefined) { 25506 'use strict'; 25507 25508 /** 25509 * Creates the hash plugin. 25510 * @class The Hash Plugin 25511 * @param {Owl} carousel - The Owl Carousel 25512 */ 25513 var Hash = function(carousel) { 25514 /** 25515 * Reference to the core. 25516 * @protected 25517 * @type {Owl} 25518 */ 25519 this._core = carousel; 25520 25521 /** 25522 * Hash index for the items. 25523 * @protected 25524 * @type {Object} 25525 */ 25526 this._hashes = {}; 25527 25528 /** 25529 * The carousel element. 25530 * @type {jQuery} 25531 */ 25532 this.$element = this._core.$element; 25533 25534 /** 25535 * All event handlers. 25536 * @protected 25537 * @type {Object} 25538 */ 25539 this._handlers = { 25540 /*'initialized.owl.carousel': $.proxy(function(e) { 25541 if (e.namespace && this._core.settings.startPosition === 'URLHash') { 25542 $(window).trigger('hashchange.owl.navigation'); 25543 } 25544 }, this),*/ 25545 'prepared.owl.carousel': $.proxy(function(e) { 25546 if (e.namespace) { 25547 var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash'); 25548 25549 if (!hash) { 25550 return; 25551 } 25552 25553 this._hashes[hash] = e.content; 25554 } 25555 }, this), 25556 'changed.owl.carousel': $.proxy(function(e) { 25557 if (e.namespace && e.property.name === 'position') { 25558 var current = this._core.items(this._core.relative(this._core.current())), 25559 hash = $.map(this._hashes, function(item, hash) { 25560 return item === current ? hash : null; 25561 }).join(); 25562 25563 if (!hash || window.location.hash.slice(1) === hash) { 25564 return; 25565 } 25566 25567 window.location.hash = hash; 25568 } 25569 }, this) 25570 }; 25571 25572 // set default options 25573 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 25574 25575 // register the event handlers 25576 this.$element.on(this._handlers); 25577 25578 // register event listener for hash navigation 25579 /*$(window).on('hashchange.owl.navigation', $.proxy(function(e) { 25580 var hash = window.location.hash.substring(1), 25581 items = this._core.$stage.children(), 25582 position = this._hashes[hash] && items.index(this._hashes[hash]); 25583 25584 if (position === undefined || position === this._core.current()) { 25585 return; 25586 } 25587 25588 this._core.to(this._core.relative(position), false, true); 25589 }, this));*/ 25590 }; 25591 25592 /** 25593 * Default options. 25594 * @public 25595 */ 25596 Hash.Defaults = { 25597 URLhashListener: false 25598 }; 25599 25600 /** 25601 * Destroys the plugin. 25602 * @public 25603 */ 25604 Hash.prototype.destroy = function() { 25605 var handler, property; 25606 25607 $(window).off('hashchange.owl.navigation'); 25608 25609 for (handler in this._handlers) { 25610 this._core.$element.off(handler, this._handlers[handler]); 25611 } 25612 for (property in Object.getOwnPropertyNames(this)) { 25613 typeof this[property] != 'function' && (this[property] = null); 25614 } 25615 }; 25616 25617 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 25618 25619})(window.Zepto || window.jQuery, window, document); 25620 25621/** 25622 * Support Plugin 25623 * 25624 * @version 2.0.0-beta.3 25625 * @author Vivid Planet Software GmbH 25626 * @author Artus Kolanowski 25627 * @license The MIT License (MIT) 25628 */ 25629;(function($, window, document, undefined) { 25630 25631 var style = $('<support>').get(0).style, 25632 prefixes = 'Webkit Moz O ms'.split(' '), 25633 events = { 25634 transition: { 25635 end: { 25636 WebkitTransition: 'webkitTransitionEnd', 25637 MozTransition: 'transitionend', 25638 OTransition: 'oTransitionEnd', 25639 transition: 'transitionend' 25640 } 25641 }, 25642 animation: { 25643 end: { 25644 WebkitAnimation: 'webkitAnimationEnd', 25645 MozAnimation: 'animationend', 25646 OAnimation: 'oAnimationEnd', 25647 animation: 'animationend' 25648 } 25649 } 25650 }, 25651 tests = { 25652 csstransforms: function() { 25653 return !!test('transform'); 25654 }, 25655 csstransforms3d: function() { 25656 return !!test('perspective'); 25657 }, 25658 csstransitions: function() { 25659 return !!test('transition'); 25660 }, 25661 cssanimations: function() { 25662 return !!test('animation'); 25663 } 25664 }; 25665 25666 function test(property, prefixed) { 25667 var result = false, 25668 upper = property.charAt(0).toUpperCase() + property.slice(1); 25669 25670 $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) { 25671 if (style[property] !== undefined) { 25672 result = prefixed ? property : true; 25673 return false;
25674 } 25675 }); 25676 25677 return result; 25678 } 25679 25680 function prefixed(property) { 25681 return test(property, true); 25682 } 25683 25684 if (tests.csstransitions()) { 25685 /* jshint -W053 */ 25686 $.support.transition = new String(prefixed('transition')) 25687 $.support.transition.end = events.transition.end[ $.support.transition ]; 25688 } 25689 25690 if (tests.cssanimations()) { 25691 /* jshint -W053 */ 25692 $.support.animation = new String(prefixed('animation')) 25693 $.support.animation.end = events.animation.end[ $.support.animation ]; 25694 } 25695 25696 if (tests.csstransforms()) { 25697 /* jshint -W053 */ 25698 $.support.transform = new String(prefixed('transform')); 25699 $.support.transform3d = tests.csstransforms3d(); 25700 } 25701 25702})(window.Zepto || window.jQuery, window, document); 25703 25704(function(window, document, undefined) { 25705 25706 /** 25707 * Find the absolute position of an element 25708 */ 25709 var absPos = function(element) { 25710 var offsetLeft, offsetTop; 25711 offsetLeft = offsetTop = 0; 25712 if (element.offsetParent) { 25713 do { 25714 offsetLeft += element.offsetLeft; 25715 offsetTop += element.offsetTop; 25716 } while (element = element.offsetParent); 25717 } 25718 return [offsetLeft, offsetTop]; 25719 }; 25720 25721 /** 25722 * @constructor Progress Circle class 25723 * @param params.canvas Canvas on which the circles will be drawn. 25724 * @param params.minRadius Inner radius of the innermost circle, in px. 25725 * @param params.arcWidth Width of each circle(to be more accurate, ring). 25726 * @param params.gapWidth Space between each circle. 25727 * @param params.centerX X coordinate of the center of circles. 25728 * @param params.centerY Y coordinate of the center of circles. 25729 * @param params.infoLineBaseAngle Base angle of the info line. 25730 * @param params.infoLineAngleInterval Angles between the info lines. 25731 */ 25732 var ProgressCircle = function(params) { 25733 this.canvas = params.canvas; 25734 this.minRadius = params.minRadius || 15; 25735 this.arcWidth = params.arcWidth || 5; 25736 this.gapWidth = params.gapWidth || 3; 25737 this.centerX = params.centerX || this.canvas.width / 2; 25738 this.centerY = params.centerY || this.canvas.height / 2;
25739 this.infoLineLength = params.infoLineLength || 60; 25740 this.horizLineLength = params.horizLineLength || 10; 25741 this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8; 25742 this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6; 25743 25744 this.context = this.canvas.getContext('2d'); 25745 25746 this.width = this.canvas.width; 25747 this.height = this.canvas.height; 25748 25749 this.circles = []; 25750 this.runningCount = 0; 25751 }; 25752 25753 ProgressCircle.prototype = { 25754 constructor: ProgressCircle, 25755 25756 /** 25757 * @method Adds an progress monitor entry. 25758 * @param params.fillColor Color to fill in the circle. 25759 * @param params.outlineColor Color to outline the circle. 25760 * @param params.progressListener Callback function to fetch the progress. 25761 * @param params.infoListener Callback function to fetch the info. 25762 * @returns this 25763 */ 25764 addEntry: function(params) { 25765 this.circles.push(new Circle({ 25766 canvas: this.canvas, 25767 context: this.context, 25768 centerX: this.centerX, 25769 centerY: this.centerY, 25770 innerRadius: this.minRadius + this.circles.length * 25771 (this.gapWidth + this.arcWidth), 25772 arcWidth: this.arcWidth,
25773 infoLineLength: this.infoLineLength, 25774 horizLineLength: this.horizLineLength, 25775 25776 id: this.circles.length, 25777 fillColor: params.fillColor, 25778 outlineColor: params.outlineColor, 25779 progressListener: params.progressListener, 25780 infoListener: params.infoListener, 25781 infoLineAngle: this.infoLineBaseAngle + 25782 this.circles.length * this.infoLineAngleInterval, 25783 })); 25784 25785 return this; 25786 }, 25787 25788 /** 25789 * @method Starts the monitor and updates with the given interval. 25790 * @param interval Interval between updates, in millisecond. 25791 * @returns this 25792 */ 25793 start: function(interval) { 25794 var self = this; 25795 this.timer = setInterval(function() { 25796 self._update(); 25797 }, interval || 33); 25798 25799 return this; 25800 }, 25801 25802 /** 25803 * @method Stop the animation. 25804 */ 25805 stop: function() { 25806 clearTimeout(this.timer); 25807 }, 25808 25809 /** 25810 * @private 25811 * @method Call update on each circle and redraw them. 25812 * @returns this 25813 */ 25814 _update: function() { 25815 this._clear(); 25816 this.circles.forEach(function(circle, idx, array) { 25817 circle.update(); 25818 }); 25819 25820 return this; 25821 }, 25822 25823 /** 25824 * @private 25825 * @method Clear the canvas. 25826 * @returns this 25827 */ 25828 _clear: function() { 25829 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); 25830 25831 return this; 25832 }, 25833 25834 }; 25835 25836 /** 25837 * @private 25838 * @class Individual progress circle. 25839 * @param params.canvas Canvas on which the circle will be drawn. 25840 * @param params.context Context of the canvas. 25841 * @param params.innerRadius Inner radius of the circle, in px. 25842 * @param params.arcWidth Width of each arc(circle). 25843 * @param params.gapWidth Distance between each arc. 25844 * @param params.centerX X coordinate of the center of circles. 25845 * @param params.centerY Y coordinate of the center of circles. 25846 * @param params.fillColor Color to fill in the circle. 25847 * @param params.outlineColor Color to outline the circle. 25848 * @param params.progressListener Callback function to fetch the progress. 25849 * @param params.infoListener Callback function to fetch the info. 25850 * @param params.infoLineAngle Angle of info line. 25851 */ 25852 var Circle = function(params) { 25853 this.id = params.id; 25854 this.canvas = params.canvas; 25855 this.context = params.context; 25856 this.centerX = params.centerX; 25857 this.centerY = params.centerY; 25858 this.arcWidth = params.arcWidth; 25859 this.innerRadius = params.innerRadius || 0; 25860 this.fillColor = params.fillColor || '#fff'; 25861 this.outlineColor = params.outlineColor || this.fillColor; 25862 this.progressListener = params.progressListener;
25863 this.infoLineLength = params.infoLineLength || 250; 25864 this.horizLineLength = params.horizLineLength || 50; 25865 this.infoListener = params.infoListener; 25866 this.infoLineAngle = params.infoLineAngle; 25867 25868 this.outerRadius = this.innerRadius + this.arcWidth; 25869 25870 // If the info listener is not registered, then don't calculate 25871 // the related coordinates 25872 if (!this.infoListener) return; 25873 25874 // calculate the info-line turning points 25875 var angle = this.infoLineAngle, 25876 arcDistance = (this.innerRadius + this.outerRadius) / 2, 25877 25878 sinA = Math.sin(angle), 25879 cosA = Math.cos(angle); 25880 25881 this.infoLineStartX = this.centerX + sinA * arcDistance; 25882 this.infoLineStartY = this.centerY - cosA * arcDistance; 25883 25884 this.infoLineMidX = this.centerX + sinA * this.infoLineLength; 25885 this.infoLineMidY = this.centerY - cosA * this.infoLineLength; 25886 25887 this.infoLineEndX = this.infoLineMidX + 25888 (sinA < 0 ? -this.horizLineLength : this.horizLineLength); 25889 this.infoLineEndY = this.infoLineMidY; 25890 25891 var infoText = document.createElement('div'), 25892 style = infoText.style; 25893 25894 style.color = this.fillColor; 25895 style.position = 'absolute'; 25896 style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px'; 25897 // style.top will be calculated in the `drawInfo` method. Since 25898 // user may want to change the size of the font, so the top offset 25899 // must be updated in each loop. 25900 infoText.className = 'ProgressCircleInfo'; // For css styling 25901 infoText.id = 'progress_circle_info_' + this.id; 25902 document.body.appendChild(infoText); 25903 this.infoText = infoText; 25904 }; 25905 25906 Circle.prototype = { 25907 constructor: Circle, 25908 25909 update: function() { 25910 this.progress = this.progressListener(); 25911 this._draw(); 25912 25913 if (this.infoListener) { 25914 this.info = this.infoListener(); 25915 this._drawInfo(); 25916 } 25917 }, 25918 25919 /** 25920 * @private 25921 * @method Draw the circle on the canvas. 25922 * @returns this 25923 */ 25924 _draw: function() { 25925 var ctx = this.context, 25926 25927 ANGLE_OFFSET = -Math.PI / 2, 25928 25929 startAngle = 0 + ANGLE_OFFSET, 25930 endAngle= startAngle + this.progress * Math.PI * 2, 25931 25932 x = this.centerX, 25933 y = this.centerY, 25934 25935 innerRadius = this.innerRadius - this.arcWidth - 1, 25936 outerRadius = this.outerRadius - this.arcWidth - 1; 25937 25938 if ( innerRadius < 0 ) 25939 return; 25940 25941 ctx.fillStyle = this.fillColor; 25942 ctx.strokeStyle = this.outlineColor; 25943 25944 ctx.beginPath(); 25945 ctx.arc(x, y, innerRadius, startAngle, endAngle, false); 25946 ctx.arc(x, y, outerRadius, endAngle, startAngle, true); 25947 ctx.closePath(); 25948 ctx.stroke(); 25949 ctx.fill(); 25950 25951 return this; 25952 }, 25953 25954 /** 25955 * @private 25956 * @method Draw the info lines and info text. 25957 * @returns this 25958 */ 25959 _drawInfo: function() { 25960 25961 var pointList, lineHeight; 25962 25963 pointList = [ 25964 [this.infoLineStartX, this.infoLineStartY], 25965 [this.infoLineMidX, this.infoLineMidY], 25966 [this.infoLineEndX, this.infoLineEndY], 25967 ]; 25968 this._drawSegments(pointList, false); 25969 25970 this.infoText.innerHTML = this.info; 25971 25972 lineHeight = this.infoText.offsetHeight; 25973 this.infoText.style.top = this.infoLineEndY + 25974 absPos(this.canvas)[1] - lineHeight / 2 + 'px'; 25975 25976 return this; 25977 }, 25978 25979 /** 25980 * @private 25981 * @method Helper function to draw the segments 25982 * @param pointList An array of points in the form of [x, y]. 25983 * @param close Whether to connect the first and last point. 25984 */ 25985 _drawSegments: function(pointList, close) { 25986 var ctx = this.context; 25987 25988 ctx.beginPath(); 25989 ctx.moveTo(pointList[0][0], pointList[0][1]); 25990 for (var i = 1; i < pointList.length; ++i) { 25991 ctx.lineTo(pointList[i][0], pointList[i][1]); 25992 } 25993 25994 if (close) { 25995 ctx.closePath(); 25996 } 25997 ctx.stroke(); 25998 }, 25999 }; 26000 26001 window.ProgressCircle = ProgressCircle; 26002 26003})(window, document); 26004 26005 26006 26007 26008/* ========================================================= 26009 * jquery.vc_chart.js v1.0 26010 * ========================================================= 26011 * Copyright 2013 Wpbakery 26012 * 26013 * Jquery chart plugin for the Visual Composer. 26014 * ========================================================= */ 26015(function($){ 26016 /** 26017 * Pie chart animated. 26018 * @param element - DOM element 26019 * @param options - settings object. 26020 * @constructor 26021 */ 26022 var VcChart = function(element, options) { 26023 this.el = element; 26024 this.$el = $(this.el); 26025 var $this = this; 26026 $this.options = $.extend({ 26027 color: 'wpb_button', 26028 units: '', 26029 width: '', 26030 label_selector: '.vc_pie_chart_value', 26031 back_selector: '.vc_pie_chart_back', 26032 responsive: true 26033 }, options); 26034 $this.init(); 26035 }; 26036 VcChart.prototype = { 26037 constructor: VcChart, 26038 _progress_v: 0, 26039 animated: false, 26040 colors: { 26041 'wpb_button': 'rgba(247, 247, 247, 1)', 26042 'btn-primary': 'rgba(0, 136, 204, 1)', 26043 'btn-info': 'rgba(88, 185, 218, 1)', 26044 'btn-success': 'rgba(106, 177, 101, 1)', 26045 'btn-warning': 'rgba(255, 153, 0, 1)', 26046 'btn-danger': 'rgba(255, 103, 91, 1)', 26047 'btn-inverse': 'rgba(85, 85, 85, 1)' 26048 }, 26049 init: function() { 26050 this.setupColor(); 26051 this.value = this.$el.data('pie-value')/100; 26052 this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value'); 26053 this.$wrapper = $('.vc_pie_wrapper', this.$el); 26054 this.$label = $(this.options.label_selector, this.$el); 26055 this.$back = $(this.options.back_selector, this.$el); 26056 this.$canvas = this.$el.find('canvas'); 26057 this.arcWidth = this.$el.data('pie-width') * 2; 26058 this.draw(); 26059 this.setWayPoint(); 26060 if(this.options.responsive === true) this.setResponsive(); 26061 if (UNCODE.isMobile) this._progress_v = this.value; 26062 }, 26063 setupColor: function() { 26064 // if(typeof this.colors[this.options.color] !== 'undefined') { 26065 // this.color = this.colors[this.options.color]; 26066 // } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) { 26067 // this.color = this.options.color; 26068 // } else { 26069 // this.color = 'rgba(247, 247, 247, 0.2)'; 26070 // } 26071 if(typeof this.options.color !== 'undefined') { 26072 this.color = this.options.color; 26073 } else this.color = 'rgba(247, 247, 247, 0.2)'; 26074 26075 }, 26076 setResponsive: function() { 26077 var that = this; 26078 if (!UNCODE.isMobile) { 26079 $(window).resize(function(){ 26080 if(that.animated === true) that.circle.stop(); 26081 that.draw(true); 26082 }); 26083 } 26084 }, 26085 draw: function(redraw) { 26086 var w = this.$el.addClass('vc_ready').width() * 2, 26087 border_w = this.arcWidth, 26088 radius; 26089 if(!w) w = this.$el.parents(':visible').first().width()-2; 26090 //w = Math.round(w/100*80); 26091 //if (w < 250) w = 250; 26092 radius = w/2; 26093 this.$wrapper.css({"width" : (w / 2) + "px"}); 26094 this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"}); 26095 this.$back.css({"width" : (w / 2), "height" : (w / 2)}); 26096 this.$canvas.attr({"width" : w + "px", "height" : w + "px"}); 26097 this.$el.addClass('vc_ready'); 26098 this.circle = new ProgressCircle({ 26099 canvas: this.$canvas.get(0), 26100 minRadius: radius, 26101 arcWidth: border_w 26102 }); 26103 if(redraw === true && this.animated === true) { 26104 this._progress_v = this.value; 26105 this.circle.addEntry({ 26106 fillColor: this.color, 26107 progressListener: $.proxy(this.setProgress, this) 26108 }).start(); 26109 } 26110 }, 26111 setProgress: function() { 26112 if (this._progress_v >= this.value) { 26113 this.circle.stop(); 26114 this.animated = true; 26115 this.$label.html(this.label_value + this.options.units); 26116 return this._progress_v; 26117 } 26118 this._progress_v += 0.01; 26119 if (!isNaN(this.label_value)) { 26120 var label_value = this._progress_v/this.value*this.label_value; 26121 var val = Math.round(label_value) + this.options.units; 26122 this.$label.html(val); 26123 } else this.$label.html(this.label_value + this.options.units); 26124 return this._progress_v; 26125 }, 26126 animate: function() { 26127 if(this.animated !== true) { 26128 this.circle.addEntry({ 26129 fillColor: this.color, 26130 progressListener: $.proxy(this.setProgress, this) 26131 }).start(10); 26132 } 26133 }, 26134 setWayPoint: function() { 26135 if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) { 26136 this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' }); 26137 } else { 26138 this.animate(); 26139 } 26140 } 26141 }; 26142 /** 26143 * jQuery plugin 26144 * @param option - object with settings 26145 * @return {*} 26146 */ 26147 $.fn.vcChat = function(option, value) { 26148 return this.each(function () { 26149 var $this = $(this), 26150 data = $this.data('vc_chart'), 26151 options = typeof option === 'object' ? option : { 26152 color: $this.data('pie-color'), 26153 units: $this.data('pie-units') 26154 }; 26155 if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options))); 26156 if (typeof option == 'string') data[option](value); 26157 }); 26158 }; 26159 /** 26160 * Allows users to rewrite function inside theme. 26161 */ 26162 if ( typeof window['vc_pieChart'] !== 'function' ) { 26163 window.vc_pieChart = function() { 26164 $('.vc_pie_chart:visible:not(.vc_ready)').vcChat(); 26165 } 26166 } 26167 $(document).ready(function(){ 26168 !window.vc_iframe && vc_pieChart(); 26169 26170 /** 26171 * Tab and collapse integration. 26172 */ 26173 $('.nav-tabs a').on('shown.bs.tab', function(e){ 26174 var $cont = $(e.target).closest('.tab-container'), 26175 $active = $('.tab-pane.active', $cont); 26176 $('.vc_pie_chart:not(.vc_ready)', $active).vcChat(); 26177 }); 26178 26179 $('.panel-collapse').on('shown.bs.collapse', function (e) { 26180 $('.vc_pie_chart:not(.vc_ready)', e.target).vcChat(); 26181 }) 26182 }); 26183 26184})(window.jQuery); 26185 26186/* Progress bar 26187 ---------------------------------------------------------- */ 26188function uncode_progress_bar() { 26189 jQuery.each(jQuery('.vc_progress_bar'), function(index, val) { 26190 if (UNCODE.isUnmodalOpen && !val.closest('#unmodal-content')) { 26191 return; 26192 } 26193 if (!UNCODE.isMobile) { 26194 new Waypoint({ 26195 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 26196 element: val, 26197 handler: function() { 26198 var element = jQuery(this.element); 26199 element.find('.vc_single_bar').each(function(index) { 26200 var $this = jQuery(this), 26201 bar = $this.find('.vc_bar'), 26202 val = bar.data('percentage-value'); 26203 setTimeout(function() { 26204 bar.css({ 26205 "width": val + '%' 26206 }); 26207 }, index * 200); 26208 }); 26209 }, 26210 offset: '80%' 26211 }); 26212 } else { 26213 var element = jQuery(val); 26214 element.find('.vc_single_bar').each(function(index) { 26215 var $this = jQuery(this), 26216 bar = $this.find('.vc_bar'), 26217 val = bar.data('percentage-value'); 26218 setTimeout(function() { 26219 bar.css({ 26220 "width": val + '%' 26221 }); 26222 }, index * 200); 26223 }); 26224 } 26225 }); 26226}; 26227uncode_progress_bar(); 26228 26229/*! 26230 * jquery.counterup.js 1.0 26231 * 26232 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal 26233 * Released under the GPL v2 License 26234 * 26235 * Date: Nov 26, 2013 26236 */ 26237(function($) { 26238 "use strict"; 26239 $.fn.counterUp = function(options) { 26240 // Defaults 26241 var settings = $.extend({ 26242 'time': 400, 26243 'delay': 10 26244 }, options); 26245 return this.each(function() { 26246 // Store the object 26247 var $this = $(this); 26248 var $settings = settings; 26249 var counterUpper = function() { 26250 var nums = []; 26251 var divisions = $settings.time / $settings.delay; 26252 var numReal = $this.attr('data-val'), 26253 num = numReal; 26254 var isComma = /[0-9]+,[0-9]+/.test(num); 26255 num = num.replace(/,/g, ''); 26256 var isInt = /^[0-9]+$/.test(num); 26257 var isFloat = /^[0-9]+\.[0-9]+$/.test(num); 26258 var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0; 26259 // Generate list of incremental numbers to display 26260 for (var i = divisions; i >= 1; i--) { 26261 // Preserve as int if input was int 26262 var newNum = parseInt(num / divisions * i); 26263 // Preserve float if input was float 26264 if (isFloat) { 26265 newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces); 26266 } 26267 // Preserve commas if input had commas 26268 if (isComma) { 26269 while (/(\d+)(\d{3})/.test(newNum.toString())) { 26270 newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2'); 26271 } 26272 } 26273 nums.unshift(newNum); 26274 } 26275 nums.push(numReal); 26276 $this.data('counterup-nums', nums); 26277 $this.text('0'); 26278 // Updates the number until we're done 26279 var f = function() { 26280 if ($this.data('counterup-nums') != null) { 26281 $this.text($this.data('counterup-nums').shift()); 26282 if ($this.data('counterup-nums').length) { 26283 setTimeout($this.data('counterup-func'), $settings.delay); 26284 } else { 26285 delete $this.data('counterup-nums'); 26286 $this.data('counterup-nums', null); 26287 $this.data('counterup-func', null); 26288 } 26289 } 26290 }; 26291 $this.data('counterup-func', f); 26292 // Start the count up 26293 setTimeout($this.data('counterup-func'), $settings.delay); 26294 }; 26295 // Perform counts when the element gets into view 26296 new Waypoint({ 26297 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 26298 element: this, 26299 handler: function() { 26300 counterUpper(); 26301 if (!UNCODE.isUnmodalOpen) { 26302 this.destroy(); 26303 } 26304 }, 26305 offset: '100%' 26306 }); 26307 }); 26308 }; 26309})(jQuery); 26310 26311/*! 26312 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/) 26313 * Copyright (c) 2016 Edson Hilios 26314 * 26315 * Permission is hereby granted, free of charge, to any person obtaining a copy of 26316 * this software and associated documentation files (the "Software"), to deal in 26317 * the Software without restriction, including without limitation the rights to 26318 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 26319 * the Software, and to permit persons to whom the Software is furnished to do so, 26320 * subject to the following conditions: 26321 * 26322 * The above copyright notice and this permission notice shall be included in all 26323 * copies or substantial portions of the Software. 26324 * 26325 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26326 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 26327 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 26328 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26329 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26330 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26331 */ 26332(function(factory) { 26333 "use strict"; 26334 if (typeof define === "function" && define.amd) { 26335 define([ "jquery" ], factory); 26336 } else { 26337 factory(jQuery); 26338 } 26339})(function($) { 26340 "use strict"; 26341 var instances = [], matchers = [], defaultOptions = { 26342 precision: 100, 26343 elapse: false, 26344 defer: false 26345 }; 26346 matchers.push(/^[0-9]*$/.source); 26347 matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 26348 matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 26349 matchers = new RegExp(matchers.join("|")); 26350 function parseDateString(dateString) { 26351 if (dateString instanceof Date) { 26352 return dateString; 26353 } 26354 if (String(dateString).match(matchers)) { 26355 if (String(dateString).match(/^[0-9]*$/)) { 26356 dateString = Number(dateString); 26357 } 26358 if (String(dateString).match(/\-/)) { 26359 dateString = String(dateString).replace(/\-/g, "/"); 26360 } 26361 return new Date(dateString); 26362 } else { 26363 throw new Error("Couldn't cast `" + dateString + "` to a date object."); 26364 } 26365 } 26366 var DIRECTIVE_KEY_MAP = { 26367 Y: "years", 26368 m: "months", 26369 n: "daysToMonth", 26370 d: "daysToWeek", 26371 w: "weeks", 26372 W: "weeksToMonth", 26373 H: "hours", 26374 M: "minutes", 26375 S: "seconds", 26376 D: "totalDays", 26377 I: "totalHours", 26378 N: "totalMinutes", 26379 T: "totalSeconds" 26380 }; 26381 function escapedRegExp(str) { 26382 var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); 26383 return new RegExp(sanitize); 26384 } 26385 function strftime(offsetObject) { 26386 return function(format) { 26387 var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi); 26388 if (directives) { 26389 for (var i = 0, len = directives.length; i < len; ++i) { 26390 var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null; 26391 directive = directive[2]; 26392 if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) { 26393 value = DIRECTIVE_KEY_MAP[directive]; 26394 value = Number(offsetObject[value]); 26395 } 26396 if (value !== null) { 26397 if (modifier === "!") { 26398 value = pluralize(plural, value); 26399 } 26400 if (modifier === "") { 26401 if (value < 10) { 26402 value = "0" + value.toString(); 26403 } 26404 } 26405 format = format.replace(regexp, value.toString()); 26406 } 26407 } 26408 } 26409 format = format.replace(/%%/, "%"); 26410 return format; 26411 }; 26412 } 26413 function pluralize(format, count) { 26414 var plural = "s", singular = ""; 26415 if (format) { 26416 format = format.rep
vendor: 8,618 bytes, lines 26416-26560
26416lace(/(:|;|\s)/gi, "").split(/\,/); 26417 if (format.length === 1) { 26418 plural = format[0]; 26419 } else { 26420 singular = format[0]; 26421 plural = format[1]; 26422 } 26423 } 26424 if (Math.abs(count) > 1) { 26425 return plural; 26426 } else { 26427 return singular; 26428 } 26429 } 26430 var Countdown = function(el, finalDate, options) { 26431 this.el = el; 26432 this.$el = $(el); 26433 this.interval = null; 26434 this.offset = {}; 26435 this.options = $.extend({}, defaultOptions); 26436 this.instanceNumber = instances.length; 26437 instances.push(this); 26438 this.$el.data("countdown-instance", this.instanceNumber); 26439 if (options) { 26440 if (typeof options === "function") { 26441 this.$el.on("update.countdown", options); 26442 this.$el.on("stoped.countdown", options); 26443 this.$el.on("finish.countdown", options); 26444 } else { 26445 this.options = $.extend({}, defaultOptions, options); 26446 } 26447 } 26448 this.setFinalDate(finalDate); 26449 if (this.options.defer === false) { 26450 this.start(); 26451 } 26452 }; 26453 $.extend(Countdown.prototype, { 26454 start: function() { 26455 if (this.interval !== null) { 26456 clearInterval(this.interval); 26457 } 26458 var self = this; 26459 this.update(); 26460 this.interval = setInterval(function() { 26461 self.update.call(self); 26462 }, this.options.precision); 26463 }, 26464 stop: function() { 26465 clearInterval(this.interval); 26466 this.interval = null; 26467 this.dispatchEvent("stoped"); 26468 }, 26469 toggle: function() { 26470 if (this.interval) { 26471 this.stop(); 26472 } else { 26473 this.start(); 26474 } 26475 }, 26476 pause: function() { 26477 this.stop(); 26478 }, 26479 resume: function() { 26480 this.start(); 26481 }, 26482 remove: function() { 26483 this.stop.call(this); 26484 instances[this.instanceNumber] = null; 26485 delete this.$el.data().countdownInstance; 26486 }, 26487 setFinalDate: function(value) { 26488 this.finalDate = parseDateString(value); 26489 }, 26490 update: function() { 26491 if (this.$el.closest("html").length === 0) { 26492 this.remove(); 26493 return; 26494 } 26495 var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft; 26496 newTotalSecsLeft = this.finalDate.getTime() - now.getTime(); 26497 newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3); 26498 newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft); 26499 if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) { 26500 return; 26501 } else { 26502 this.totalSecsLeft = newTotalSecsLeft; 26503 } 26504 this.elapsed = now >= this.finalDate; 26505 this.offset = { 26506 seconds: this.totalSecsLeft % 60, 26507 minutes: Math.floor(this.totalSecsLeft / 60) % 60, 26508 hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24, 26509 days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 26510 daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 26511 daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368), 26512 weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7), 26513 weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4, 26514 months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368), 26515 years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()), 26516 totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24), 26517 totalHours: Math.floor(this.totalSecsLeft / 60 / 60), 26518 totalMinutes: Math.floor(this.totalSecsLeft / 60), 26519 totalSeconds: this.totalSecsLeft 26520 }; 26521 if (!this.options.elapse && this.totalSecsLeft === 0) { 26522 this.stop(); 26523 this.dispatchEvent("finish"); 26524 } else { 26525 this.dispatchEvent("update"); 26526 } 26527 }, 26528 dispatchEvent: function(eventName) { 26529 var event = $.Event(eventName + ".countdown"); 26530 event.finalDate = this.finalDate; 26531 event.elapsed = this.elapsed; 26532 event.offset = $.extend({}, this.offset); 26533 event.strftime = strftime(this.offset); 26534 this.$el.trigger(event); 26535 } 26536 }); 26537 $.fn.countdown = function() { 26538 var argumentsArray = Array.prototype.slice.call(arguments, 0); 26539 return this.each(function() { 26540 var instanceNumber = $(this).data("countdown-instance"); 26541 if (instanceNumber !== undefined) { 26542 var instance = instances[instanceNumber], method = argumentsArray[0]; 26543 if (Countdown.prototype.hasOwnProperty(method)) { 26544 instance[method].apply(instance, argumentsArray.slice(1)); 26545 } else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) { 26546 instance.setFinalDate.call(instance, method); 26547 instance.start(); 26548 } else { 26549 $.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method)); 26550 } 26551 } else { 26552 new Countdown(this, argumentsArray[0], argumentsArray[1]); 26553 } 26554 }); 26555 }; 26556}); 26557 26558!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; 26559function getStyles(config){ 26560 // 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;
26560left: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+"}" 26561}; 26562 var ShareUtils; 26563 26564if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") { 26565 Object.defineProperty(HTMLElement.prototype, "classList", { 26566 get: function() { 26567 var ret, self, update; 26568 update = function(fn) { 26569 return function(value) { 26570 var classes, index; 26571 classes = self.className.split(/\s+/); 26572 index = classes.indexOf(value); 26573 fn(classes, index, value); 26574 self.className = classes.join(" "); 26575 }; 26576 }; 26577 self = this; 26578 ret = { 26579 add: update(function(classes, index, value) { 26580 ~index || classes.push(value); 26581 }), 26582 remove: update(function(classes, index) { 26583 ~index && classes.splice(index, 1); 26584 }), 26585 toggle: update(function(classes, index, value) { 26586 if (~index) { 26587 classes.splice(index, 1); 26588 } else { 26589 classes.push(value); 26590 } 26591 }), 26592 contains: function(value) { 26593 return !!~self.className.split(/\s+/).indexOf(value); 26594 }, 26595 item: function(i) { 26596 return self.className.split(/\s+/)[i] || null; 26597 } 26598 }; 26599 Object.defineProperty(ret, "length", { 26600 get: function() { 26601 return self.className.split(/\s+/).length; 26602 } 26603 }); 26604 return ret; 26605 } 26606 }); 26607} 26608 26609String.prototype.to_rfc3986 = function() { 26610 var tmp; 26611 tmp = encodeURIComponent(this); 26612 return tmp.replace(/[!'()*]/g, function(c) { 26613 return "%" + c.charCodeAt(0).toString(16); 26614 }); 26615}; 26616 26617ShareUtils = (function() { 26618 function ShareUtils() {} 26619 26620 ShareUtils.prototype.extend = function(to, from, overwrite) { 26621 var hasProp, prop; 26622 for (prop in from) { 26623 hasProp = to[prop] !== undefined; 26624 if (hasProp && typeof from[prop] === "object") { 26625 this.extend(to[prop], from[prop], overwrite); 26626 } else { 26627 if (overwrite || !hasProp) { 26628 to[prop] = from[prop]; 26629 } 26630 } 26631 } 26632 }; 26633 26634 ShareUtils.prototype.hide = function(el) { 26635 return el.style.display = "none"; 26636 }; 26637 26638 ShareUtils.prototype.show = function(el) { 26639 return el.style.display = "block"; 26640 }; 26641 26642 ShareUtils.prototype.has_class = function(el, class_name) { 26643 return el.classList.contains(class_name); 26644 }; 26645 26646 ShareUtils.prototype.add_class = function(el, class_name) { 26647 return el.classList.add(class_name); 26648 }; 26649 26650 ShareUtils.prototype.remove_class = function(el, class_name) { 26651 return el.classList.remove(class_name); 26652 }; 26653 26654 ShareUtils.prototype.is_encoded = function(str) { 26655 str = str.to_rfc3986(); 26656 return decodeURIComponent(str) !== str; 26657 }; 26658 26659 ShareUtils.prototype.encode = function(str) { 26660 if (typeof str === "undefined" || this.is_encoded(str)) { 26661 return str; 26662 } else { 26663 return str.to_rfc3986(); 26664 } 26665 }; 26666 26667 ShareUtils.prototype.popup = function(url, params) { 26668 var k, popup, qs, v; 26669 if (params == null) { 26670 params = {}; 26671 } 26672 popup = { 26673 width: 500, 26674 height: 350 26675 }; 26676 popup.top = (screen.height / 2) - (popup.height / 2); 26677 popup.left = (screen.width / 2) - (popup.width / 2); 26678 qs = ((function() { 26679 var _results; 26680 _results = []; 26681 for (k in params) { 26682 v = params[k]; 26683 _results.push("" + k + "=" + (this.encode(v))); 26684 } 26685 return _results; 26686 }).call(this)).join('&'); 26687 if (qs) { 26688 qs = "?" + qs; 26689 } 26690 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="
26690+ popup.width + ",height=" + popup.height); 26691 }; 26692 26693 return ShareUtils; 26694 26695})(); 26696var Share, 26697 __hasProp = {}.hasOwnProperty, 26698 __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; }; 26699 26700Share = (function(_super) { 26701 __extends(Share, _super); 26702 26703 function Share(element, options) { 26704 this.element = element; 26705 this.el = { 26706 head: document.getElementsByTagName('head')[0], 26707 body: document.getElementsByTagName('body')[0] 26708 }; 26709 this.config = { 26710 enabled_networks: 0, 26711 protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//', 26712 url: window.location.href.replace("&", "%26"), 26713 caption: null, 26714 title: this.default_title(), 26715 image: this.default_image(), 26716 description: this.default_description(), 26717 ui: { 26718 flyout: 'top center', 26719 button_text: 'Share', 26720 button_font: true, 26721 icon_font: true 26722 }, 26723 networks: { 26724 twitter: { 26725 enabled: true, 26726 url: null, 26727 title: null, 26728 description: null 26729 }, 26730 facebook: { 26731 enabled: true, 26732 load_sdk: true, 26733 url: null, 26734 app_id: null, 26735 title: null, 26736 caption: null, 26737 description: null, 26738 image: null 26739 }, 26740 pinterest: { 26741 enabled: true, 26742 url: null, 26743 image: null, 26744 description: null 26745 }, 26746 reddit: { 26747 enabled: true, 26748 url: null, 26749 title: null 26750 }, 26751 linkedin: { 26752 enabled: true, 26753 url: null, 26754 title: null, 26755 description: null 26756 }, 26757 xing: { 26758 enabled: true, 26759 url: null, 26760 title: null, 26761 image: null, 26762 description: null 26763 }, 26764 whatsapp: { 26765 enabled: true, 26766 description: null, 26767 url: null 26768 }, 26769 email: { 26770 enabled: true, 26771 title: null, 26772 description: null, 26773 url: null 26774 } 26775 } 26776 }; 26777 this.setup(element, options); 26778 return this; 26779 } 26780 26781 Share.prototype.setup = function(element, opts) { 26782 var index, instance, instances, _i, _len; 26783 instances = document.querySelectorAll(element); 26784 this.extend(this.config, opts, true); 26785 this.set_global_configuration(); 26786 this.normalize_network_configuration(); 26787 if (this.config.ui.icon_font) { 26788 this.inject_icons(); 26789 } 26790 if (this.config.ui.button_font) { 26791 this.inject_fonts(); 26792 } 26793 if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) { 26794 this.inject_facebook_sdk(); 26795 } 26796 for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) { 26797 instance = instances[index]; 26798 this.setup_instance(element, index); 26799 } 26800 }; 26801 26802 Share.prototype.setup_instance = function(element, index) { 26803 var button, instance, label, network, networks, _i, _len, _results, 26804 _this = this; 26805 instance = document.querySelectorAll(element)[index]; 26806 this.hide(instance); 26807 this.add_class(instance, "sharer-" + index); 26808 instance = document.querySelectorAll(element)[index]; 26809 this.inject_css(instance); 26810 this.inject_html(instance); 26811 this.show(instance); 26812 label = instance.getElementsByTagName("label")[0]; 26813 button = instance.getElementsByClassName("social")[0]; 26814 networks = instance.getElementsByTagName('li'); 26815 this.add_class(button, "networks-" + this.config.enabled_networks); 26816 label.addEventListener("click", function() { 26817 return _this.event_toggle(button); 26818 }); 26819 _this = this; 26820 _results = []; 26821 for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) { 26822 network = networks[index]; 26823 _results.push(network.addEventListener("click", function() { 26824 _this.event_network(instance, this); 26825 return _this.event_close(button); 26826 })); 26827 } 26828 return _results; 26829 }; 26830 26831 Share.prototype.event_toggle = function(button) { 26832 if (this.has_class(button, "active")) { 26833 return this.event_close(button); 26834 } else { 26835 return this.event_open(button); 26836 } 26837 }; 26838 26839 Share.prototype.event_open = function(button) { 26840 if (this.has_class(button, "load")) { 26841 this.remove_class(button, "load"); 26842 } 26843 return this.add_class(button, "active"); 26844 }; 26845 26846 Share.prototype.event_close = function(button) { 26847 return this.remove_class(button, "active"); 26848 }; 26849 26850 Share.prototype.event_network = function(instance, network) { 26851 var name; 26852 name = network.getAttribute("data-network"); 26853 this.hook("before", name, instance);
26854 this["network_" + name](); 26855 return this.hook("after", name, instance); 26856 }; 26857 26858 Share.prototype.open = function() { 26859 return this["public"]("open"); 26860 }; 26861 26862 Share.prototype.close = function() { 26863 return this["public"]("close"); 26864 }; 26865 26866 Share.prototype.toggle = function() { 26867 return this["public"]("toggle"); 26868 }; 26869 26870 Share.prototype["public"] = function(action) { 26871 var button, index, instance, _i, _len, _ref, _results; 26872 _ref = document.querySelectorAll(this.element); 26873 _results = []; 26874 for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { 26875 instance = _ref[index]; 26876 button = instance.getElementsByClassName("social")[0]; 26877 _results.push(this["event_" + action](button)); 26878 } 26879 return _results; 26880 }; 26881 26882 Share.prototype.network_facebook = function() { 26883 if (this.config.networks.facebook.load_sdk) { 26884 if (!window.FB) { 26885 return console.error("The Facebook JS SDK hasn't loaded yet."); 26886 } 26887 return FB.ui({ 26888 method: 'feed', 26889 name: this.config.networks.facebook.title, 26890 link: this.config.networks.facebook.url, 26891 picture: this.config.networks.facebook.image, 26892 caption: this.config.networks.facebook.caption, 26893 description: this.config.networks.facebook.description 26894 }); 26895 } else { 26896 return this.popup('https://www.facebook.com/sharer/sharer.php', { 26897 u: this.config.networks.facebook.url 26898 }); 26899 } 26900 }; 26901 26902 Share.prototype.network_twitter = function() { 26903 return this.popup('https://twitter.com/intent/tweet', { 26904 text: this.config.networks.twitter.title, 26905 url: this.config.networks.twitter.url 26906 }); 26907 }; 26908 26909 Share.prototype.network_pinterest = function() { 26910 return this.popup('https://www.pinterest.com/pin/create/button', { 26911 url: this.config.networks.pinterest.url, 26912 media: this.config.networks.pinterest.image, 26913 description: this.config.networks.pinterest.description 26914 }); 26915 }; 26916 26917 Share.prototype.network_linkedin = function() { 26918 return this.popup('https://www.linkedin.com/shareArticle', { 26919 url: this.config.networks.linkedin.url, 26920 title: this.config.networks.linkedin.title, 26921 summary: this.config.networks.linkedin.description 26922 }); 26923 } 26924 26925 Share.prototype.network_xing = function() { 26926 return this.popup('https://www.xing.com/spi/shares/new', { 26927 url: this.config.networks.xing.url, 26928 image: this.config.networks.xing.image, 26929 title: this.config.networks.xing.title, 26930 summary: this.config.networks.xing.description 26931 }); 26932 } 26933 26934 Share.prototype.network_email = function() { 26935 return this.popup('mailto:', { 26936 subject: this.config.networks.email.title, 26937 body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description, 26938 }); 26939 }; 26940 26941 Share.prototype.inject_icons = function() { 26942 // return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css"); 26943 }; 26944 26945 Share.prototype.inject_fonts = function() { 26946 // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text); 26947 }; 26948 26949 Share.prototype.inject_stylesheet = function(url) { 26950 var link; 26951 if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) { 26952 link = document.createElement("link"); 26953 link.setAttribute("rel", "stylesheet"); 26954 link.setAttribute("href", url); 26955 return this.el.head.appendChild(link); 26956 } 26957 }; 26958 26959 Share.prototype.inject_css = function(instance) { 26960 var css, meta, selector, style; 26961 selector = "." + (instance.getAttribute('class').split(" ").join(".")); 26962 if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) { 26963 this.config.selector = selector; 26964 css = getStyles(this.config); 26965 style = document.createElement("style"); 26966 style.type = "text/css"; 26967 if (style.styleSheet) { 26968 style.styleSheet.cssText = css; 26969 } else { 26970 style.appendChild(document.createTextNode(css)); 26971 } 26972 this.el.head.appendChild(style); 26973 delete this.config.selector; 26974 meta = document.createElement("meta"); 26975 meta.setAttribute("name", "sharer" + selector); 26976 return this.el.head.appendChild(meta); 26977 } 26978 }; 26979 26980 Share.prototype.inject_html = function(instance) { 26981 //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>"; 26982 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-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>"; 26983 }; 26984 26985 Share.prototype.inject_facebook_sdk = function() { 26986 var fb_root, script; 26987 if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) { 26988 script = document.createElement("script"); 26989 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')"; 26990 fb_root = document.createElement("div"); 26991 fb_root.id = "fb-root"; 26992 this.el.body.appendChild(fb_root); 26993 return this.el.body.appendChild(script); 26994 } 26995 }; 26996 26997 Share.prototype.hook = function(type, network, instance) { 26998 var fn, opts; 26999 fn = this.config.networks[network][type]; 27000 if (typeof fn === "function") { 27001 opts = fn.call(this.config.networks[network], instance); 27002 if (opts !== void 0) { 27003 opts = this.normalize_filter_config_updates(opts); 27004 this.extend(this.config.networks[network], opts, true); 27005 this.normalize_network_configuration(); 27006 } 27007 } 27008 }; 27009 27010 Share.prototype.default_title = function() { 27011 var content; 27012 if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) { 27013 return encodeURIComponent(content.getAttribute('content')); 27014 } else if (content = document.querySelector('title')) { 27015 return encodeURIComponent(content.innerText); 27016 } 27017 }; 27018 27019 Share.prototype.default_image = function() { 27020 var content; 27021 if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) { 27022 return content.getAttribute('content'); 27023 } 27024 }; 27025 27026 Share.prototype.default_description = function() { 27027 var content; 27028 if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) { 27029 return encodeURIComponent(content.getAttribute('content')); 27030 } else { 27031 return ''; 27032 } 27033 }; 27034 27035 Share.prototype.set_global_configuration = function() { 27036 var display, network, option, options, _ref, _results; 27037 _ref = this.config.networks; 27038 _results = []; 27039 for (network in _ref) { 27040 options = _ref[network]; 27041 for (option in options) { 27042 if (this.config.networks[network][option] == null) { 27043 this.config.networks[network][option] = this.config[option]; 27044 } 27045 } 27046 if (this.config.networks[network].enabled) { 27047 display = 'block'; 27048 this.config.enabled_networks += 1; 27049 } else { 27050 display = 'none'; 27051 } 27052 _results.push(this.config.networks[network].display = display); 27053 } 27054 return _results; 27055 }; 27056 27057 Share.prototype.normalize_network_configuration = function() { 27058 if (!this.config.networks.facebook.app_id) { 27059 this.config.networks.facebook.load_sdk = false;
27060 } 27061 if (!this.is_encoded(this.config.networks.twitter.description)) { 27062 this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description); 27063 } 27064 if (typeof this.config.networks.facebook.app_id === 'number') { 27065 return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString(); 27066 } 27067 }; 27068 27069 Share.prototype.normalize_filter_config_updates = function(opts) { 27070 if (this.config.networks.facebook.app_id !== opts.app_id) { 27071 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."); 27072 delete opts.app_id; 27073 } 27074 if (this.config.networks.facebook.load_sdk !== opts.load_sdk) { 27075 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."); 27076 delete opts.app_id; 27077 } 27078 return opts; 27079 }; 27080 27081 return Share; 27082 27083})(ShareUtils); 27084 return Share; 27085}); 27086 27087// Generated by CoffeeScript 1.9.2 27088 27089// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net 27090 27091(function() { 27092 var $, win; 27093 27094 $ = this.jQuery || window.jQuery; 27095 27096 win = $(window); 27097 27098 $.fn.stick_in_parent = function(opts) { 27099 var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class; 27100 if (opts == null) { 27101 opts = {}; 27102 } 27103 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; 27104 if (offset_top == null) { 27105 offset_top = 0; 27106 } 27107 if (parent_selector == null) { 27108 parent_selector = void 0; 27109 } 27110 if (inner_scrolling == null) { 27111 inner_scrolling = true; 27112 } 27113 if (sticky_class == null) { 27114 sticky_class = "is_stuck"; 27115 } 27116 doc = $(document); 27117 if (enable_bottoming == null) { 27118 enable_bottoming = true; 27119 } 27120 outer_width = function(el) { 27121 var _el, computed, w; 27122 if (window.getComputedStyle) { 27123 _el = el[0]; 27124 computed = window.getComputedStyle(el[0]); 27125 w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right")); 27126 if (computed.getPropertyValue("box-sizing") !== "border-box") { 27127 w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right")); 27128 } 27129 return w; 27130 } else { 27131 return el.outerWidth(true); 27132 } 27133 }; 27134 fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) { 27135 var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick; 27136 if (elm.data("sticky_kit")) { 27137 return; 27138 } 27139 elm.data("sticky_kit", true); 27140 last_scroll_height = doc.height(); 27141 parent = elm.parent(); 27142 if (parent_selector != null) { 27143 parent = parent.closest(parent_selector); 27144 } 27145 if (!parent.length) { 27146 throw "failed to find stick parent"; 27147 } 27148 fixed = false; 27149 bottomed = false; 27150 spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />"); 27151 if (spacer) { 27152 spacer.css('position', elm.css('position')); 27153 } 27154 recalc = function() { 27155 var border_top, padding_top, restore; 27156 if (detached) { 27157 return; 27158 } 27159 last_scroll_height = doc.height(); 27160 border_top = parseInt(parent.css("border-top-width"), 10); 27161 padding_top = parseInt(parent.css("padding-top"), 10); 27162 padding_bottom = parseInt(parent.css("padding-bottom"), 10); 27163 parent_top = parent.offset().top + border_top + padding_top; 27164 parent_height = parent.height(); 27165 if (fixed) { 27166 fixed = false;
vendor: 6,068 bytes, lines 27167-27361
27167 bottomed = false; 27168 if (manual_spacer == null) { 27169 elm.insertAfter(spacer); 27170 spacer.detach(); 27171 } 27172 elm.css({ 27173 position: "", 27174 top: "", 27175 width: "", 27176 bottom: "" 27177 }).removeClass(sticky_class); 27178 restore = true; 27179 } 27180 top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top; 27181 height = elm.outerHeight(true); 27182 el_float = elm.css("float"); 27183 if (spacer) { 27184 spacer.css({ 27185 width: outer_width(elm), 27186 height: height, 27187 display: elm.css("display"), 27188 "vertical-align": elm.css("vertical-align"), 27189 "float": el_float 27190 }); 27191 } 27192 if (restore) { 27193 return tick(); 27194 } 27195 }; 27196 recalc(); 27197 if (height === parent_height) { 27198 return; 27199 } 27200 last_pos = void 0; 27201 offset = offset_top; 27202 recalc_counter = recalc_every; 27203 tick = function() { 27204 var css, delta, recalced, scroll, will_bottom, win_height; 27205 if (detached) { 27206 return; 27207 } 27208 recalced = false; 27209 if (recalc_counter != null) { 27210 recalc_counter -= 1; 27211 if (recalc_counter <= 0) { 27212 recalc_counter = recalc_every; 27213 recalc(); 27214 recalced = true; 27215 } 27216 } 27217 if (!recalced && doc.height() !== last_scroll_height) { 27218 recalc(); 27219 recalced = true; 27220 } 27221 scroll = win.scrollTop(); 27222 if (last_pos != null) { 27223 delta = scroll - last_pos; 27224 } 27225 last_pos = scroll; 27226 if (fixed) { 27227 if (enable_bottoming) { 27228 will_bottom = scroll + height + offset > parent_height + parent_top; 27229 if (bottomed && !will_bottom) { 27230 bottomed = false; 27231 elm.css({ 27232 position: "fixed", 27233 bottom: "", 27234 top: offset 27235 }).trigger("sticky_kit:unbottom"); 27236 } 27237 } 27238 if (scroll < top) { 27239 fixed = false; 27240 offset = offset_top; 27241 if (manual_spacer == null) { 27242 if (el_float === "left" || el_float === "right") { 27243 elm.insertAfter(spacer); 27244 } 27245 spacer.detach(); 27246 } 27247 css = { 27248 position: "", 27249 width: "", 27250 top: "" 27251 }; 27252 elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick"); 27253 } 27254 if (inner_scrolling) { 27255 win_height = win.height(); 27256 if (height + offset_top > win_height) { 27257 if (!bottomed) { 27258 offset -= delta; 27259 offset = Math.max(win_height - height, offset); 27260 offset = Math.min(offset_top, offset); 27261 if (fixed) { 27262 elm.css({ 27263 top: offset + "px" 27264 }); 27265 } 27266 } 27267 } 27268 } 27269 } else { 27270 if (scroll > top) { 27271 fixed = true; 27272 css = { 27273 position: "fixed", 27274 top: offset 27275 }; 27276 css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px"; 27277 elm.css(css).addClass(sticky_class); 27278 if (manual_spacer == null) { 27279 elm.after(spacer); 27280 if (el_float === "left" || el_float === "right") { 27281 spacer.append(elm); 27282 } 27283 } 27284 elm.trigger("sticky_kit:stick"); 27285 } 27286 } 27287 if (fixed && enable_bottoming) { 27288 if (will_bottom == null) { 27289 will_bottom = scroll + height + offset > parent_height + parent_top; 27290 } 27291 if (!bottomed && will_bottom) { 27292 bottomed = true; 27293 if (parent.css("position") === "static") { 27294 parent.css({ 27295 position: "relative" 27296 }); 27297 } 27298 return elm.css({ 27299 position: "absolute", 27300 bottom: padding_bottom, 27301 top: "auto" 27302 }).trigger("sticky_kit:bottom"); 27303 } 27304 } 27305 }; 27306 recalc_and_tick = function() { 27307 recalc(); 27308 return tick(); 27309 }; 27310 detach = function() { 27311 detached = true; 27312 win.off("touchmove", tick); 27313 win.off("scroll", tick); 27314 win.off("resize", recalc_and_tick); 27315 $(document.body).off("sticky_kit:recalc", recalc_and_tick); 27316 elm.off("sticky_kit:detach", detach); 27317 elm.removeData("sticky_kit"); 27318 elm.css({ 27319 position: "", 27320 bottom: "", 27321 top: "", 27322 width: "" 27323 }); 27324 parent.position("position", ""); 27325 if (fixed) { 27326 if (manual_spacer == null) { 27327 if (el_float === "left" || el_float === "right") { 27328 elm.insertAfter(spacer); 27329 } 27330 spacer.remove(); 27331 } 27332 return elm.removeClass(sticky_class); 27333 } 27334 }; 27335 win.on("touchmove", tick); 27336 win.on("scroll", tick); 27337 win.on("resize", recalc_and_tick); 27338 $(document.body).on("sticky_kit:recalc", recalc_and_tick); 27339 elm.on("sticky_kit:detach", detach); 27340 return setTimeout(tick, 0); 27341 }; 27342 for (i = 0, len = this.length; i < len; i++) { 27343 elm = this[i]; 27344 fn($(elm)); 27345 } 27346 return this; 27347 }; 27348 27349}).call(this); 27350/* ========================================================================== 27351 * bootstrap-tab-history.js 27352 * Author: Michael Narayan <[email protected]> 27353 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/ 27354 * ========================================================================== 27355 * Licensed under the Apache License, Version 2.0 (the "License"); you may 27356 * not use this file except in compliance with the License. You may obtain a 27357 * copy of the License at 27358 * 27359 * http://www.apache.org/licenses/LICENSE-2.0 27360 * 27361 * Unless required by applicable law or agreed to in writing, softw
27361are 27362 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 27363 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 27364 * License for the specific language governing permissions and limitations 27365 * under the License. 27366 * ========================================================================== */ 27367 27368/* ========================================================================== */ 27369/* JSHint directives */ 27370/* */ 27371/* global BootstrapTabHistory: true */ 27372/* */ 27373/* global document */ 27374/* global jQuery */ 27375/* global history */ 27376/* global window */ 27377/* ========================================================================== */ 27378 27379/** 27380 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history) 27381 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set 27382 * the `data-tab-history` attribute to true (or a string denoting a tab grouping). 27383 * 27384 * See the README for additional information. 27385 * 27386 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes. 27387 */ 27388 27389BootstrapTabHistory = { 27390 options: { 27391 /** 27392 * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the 27393 * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true. 27394 * 27395 * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`. 27396 * 27397 * @public 27398 * @type {?number} 27399 */ 27400 defaultAnchorYOffset: 0, 27401 /** 27402 * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp. 27403 * 27404 * May be overriden on a per-element basis by the attribute `data-tab-history-changer`. 27405 * 27406 * @public 27407 * @type {string} 27408 */ 27409 defaultChanger: 'replace', 27410 /** 27411 * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise, 27412 * `null` is passed as the third parameter to these calls. 27413 * 27414 * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`. 27415 * 27416 * @public 27417 * @type {boolean} 27418 */ 27419 defaultUpdateURL: false, 27420 /** 27421 * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page 27422 * load. 27423 * 27424 * @public 27425 * @type {boolean} 27426 */ 27427 showTabsBasedOnAnchor: true 27428 } 27429}; 27430 27431(function () { 27432 'use strict'; 27433 27434 jQuery(function () { 27435 if(history && history.pushState && history.replaceState) { 27436 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27437 27438 if(bootstrapTabHistory) { 27439 showTabsBasedOnState(bootstrapTabHistory); 27440 } else { 27441 showTabsBasedOnAnchor(); 27442 } 27443 27444 backfillHistoryState(); 27445 27446 jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab); 27447 jQuery(window).on('popstate', onPopState); 27448 } else { 27449 showTabsBasedOnAnchor(); 27450 } 27451 }); 27452 27453 /** 27454 * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState. 27455 * 27456 * @type {boolean} 27457 */ 27458 var showingTabsBasedOnState = false; 27459 27460 /** 27461 * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper 27462 * `history.back` handling when `data-tab-history-update-url` is true. 27463 */ 27464 function backfillHistoryState() { 27465 var newState = null; 27466 27467 jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode 27468 var $activeTabElement = jQuery(this); 27469 var selector = getTabSelector($activeTabElement); 27470 27471 if(selector) { 27472 var tabGroup = getTabGroup($activeTabElement); 27473 27474 if(tabGroup) { 27475 newState = createNewHistoryState(newState || history.state, tabGroup, selector); 27476 } 27477 } 27478 }); 27479 27480 if(newState) { 27481 history.replaceState(newState, '', null); 27482 } 27483 } 27484 27485 /** 27486 * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to 27487 * said bootstrapTabHistory attribute. 27488 * 27489 * @param {?object} existingState 27490 * @param {!string} tabGroup 27491 * @param {!string} selector 27492 * @returns {!object} 27493 */ 27494 function createNewHistoryState(existingState, tabGroup, selector) { 27495 // Clone history.state and ensure it has a bootstrapTabHistory entry. 27496 var newState = jQuery.extend(true, {}, existingState, { 27497 bootstrapTabHistory: {} 27498 }); 27499 27500 newState.bootstrapTabHistory[tabGroup] = selector; 27501 27502 return newState; 27503 } 27504 27505 /** 27506 * @param {jQuery} $tab
27507 * @returns {?string} 27508 */ 27509 function getTabGroup($tab) { 27510 return parseTruthyAttributeValue($tab.data('tab-history')); 27511 } 27512 27513 /** 27514 * @param {jQuery} $tab 27515 * @returns {?string} 27516 */ 27517 function getTabSelector($tab) { 27518 return $tab.data('target') || $tab.attr('href'); 27519 } 27520 27521 /** 27522 * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate. 27523 * 27524 * @param {jQuery.Event} shownEvt 27525 */ 27526 function onShownTab(shownEvt) { 27527 if(!showingTabsBasedOnState) { 27528 var $activatedTab = jQuery(shownEvt.target); 27529 if ( $activatedTab.hasClass('panel-collapse') ) 27530 $activatedTab = $activatedTab.closest('.panel').find('a'); 27531 var selector = getTabSelector($activatedTab); 27532 27533 if(selector) { 27534 var tabGroup = getTabGroup($activatedTab); 27535 27536 if(tabGroup) { 27537 var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger; 27538 var newState = createNewHistoryState(history.state, tabGroup, selector); 27539 var updateURL = (function ($activatedTab) { 27540 if(selector[0] === '#') { 27541 var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url')); 27542 27543 if(elementUpdateURLOption === undefined) { 27544 return BootstrapTabHistory.options.defaultUpdateURL; 27545 } else { 27546 return elementUpdateURLOption; 27547 } 27548 } else { 27549 return false; 27550 } 27551 })($activatedTab); 27552 27553 switch(historyChanger) { 27554 case 'push': 27555 history.pushState(newState, '', updateURL ? selector : null); 27556 break; 27557 case 'replace': 27558 history.replaceState(newState, '', updateURL ? selector : null); 27559 break; 27560 default: 27561 throw new Error('Unknown tab-history-changer: ' + historyChanger); 27562 } 27563 } 27564 } 27565 } 27566 } 27567 27568 /** 27569 * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate. 27570 */ 27571 function onPopState() { 27572 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27573 27574 if(bootstrapTabHistory) { 27575 showTabsBasedOnState(bootstrapTabHistory); 27576 } 27577 } 27578 27579 /** 27580 * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned. 27581 * 27582 * Rationale: HAML data attributes which are set to `true` are rendered as a blank string. 27583 * 27584 * @param {*} value 27585 * @returns {*} 27586 */ 27587 function parseTruthyAttributeValue(value) { 27588 if(value) { 27589 return value; 27590 } else if(value === '') { 27591 return true; 27592 } else { 27593 return value; 27594 } 27595 } 27596 27597 /** 27598 * Show tabs based upon the anchor component of `window.location`. 27599 */ 27600 function showTabsBasedOnAnchor() { 27601 if(BootstrapTabHistory.options.showTabsBasedOnAnchor) { 27602 var anchor = window.location && window.location.hash; 27603 27604 if(anchor) { 27605 var $tabElement = showTabForSelector(anchor); 27606 27607 if($tabElement && window.addEventListener && window.removeEventListener) { 27608 var anchorYOffset = (function ($tabElement) { 27609 var elementSetting = $tabElement.data('tab-history-anchor-y-offset'); 27610 27611 if(elementSetting === undefined) { 27612 return BootstrapTabHistory.options.defaultAnchorYOffset; 27613 } else { 27614 return elementSetting; 27615 } 27616 })($tabElement); 27617 27618 // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get 27619 // here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the 27620 // `history.state` object should have been used (unless the browser did not support the modern History API). 27621 if(anchorYOffset || anchorYOffset === 0) { 27622 var scrollListener = function resetAnchorScroll () { 27623 window.removeEventListener('scroll', scrollListener); 27624 window.scrollTo(0, anchorYOffset); 27625 }; 27626 27627 window.addEventListener('scroll', scrollListener); 27628 } 27629 } 27630 } 27631 } 27632 } 27633 27634 /** 27635 * Show a tab which corresponds to the provided selector. 27636 * 27637 * @param {string} selector - A CSS selector. 27638 * @returns {?jQuery} - The tab which was found to show (even if said tab was already active). 27639 */ 27640 function showTabForSelector(selector) { 27641 var $tabElement = (function (selector) { 27642 var $ret = null; 27643 27644 jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () { 27645 var $potentialTab = jQuery(this); 27646 27647 if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) { 27648 $ret = $potentialTab; 27649 return false;
vendor: 43,483 bytes, lines 27650-28866
27650 } else { 27651 return null; 27652 } 27653 }); 27654 27655 return $ret; 27656 })(selector); 27657 27658 if($tabElement) { 27659 if ( !$tabElement.parent().hasClass('active') ) { 27660 $tabElement.trigger('click'); 27661 } 27662 //$tabElement.tab('show'); 27663 } 27664 27665 return $tabElement; 27666 } 27667 27668 /** 27669 * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors. 27670 * 27671 * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant. 27672 */ 27673 function showTabsBasedOnState(bootstrapTabHistory) { 27674 showingTabsBasedOnState = true; 27675 27676 try { 27677 for(var k in bootstrapTabHistory) { 27678 if(bootstrapTabHistory.hasOwnProperty(k)) { 27679 showTabForSelector(bootstrapTabHistory[k]); 27680 } 27681 } 27682 } finally { 27683 showingTabsBasedOnState = false; 27684 } 27685 } 27686})(); 27687 27688/*! 27689 * justifiedGallery - v3.8.1 27690 * http://miromannino.github.io/Justified-Gallery/ 27691 * Copyright (c) 2020 Miro Mannino 27692 * Licensed under the MIT license. 27693 */ 27694(function (factory) { 27695 if (typeof define === 'function' && define.amd) { 27696 // AMD. Register as an anonymous module. 27697 define(['jquery'], factory); 27698 } else if (typeof module === 'object' && module.exports) { 27699 // Node/CommonJS 27700 module.exports = function (root, jQuery) { 27701 if (jQuery === undefined) { 27702 // require('jQuery') returns a factory that requires window to 27703 // build a jQuery instance, we normalize how we use modules 27704 // that require this pattern but the window provided is a noop 27705 // if it's defined (how jquery works) 27706 if (typeof window !== 'undefined') { 27707 jQuery = require('jquery'); 27708 } 27709 else { 27710 jQuery = require('jquery')(root); 27711 } 27712 } 27713 factory(jQuery); 27714 return jQuery; 27715 }; 27716 } else { 27717 // Browser globals 27718 factory(jQuery); 27719 } 27720}(function ($) { 27721 27722 /** 27723 * Justified Gallery controller constructor 27724 * 27725 * @param $gallery the gallery to build 27726 * @param settings the settings (the defaults are in JustifiedGallery.defaults) 27727 * @constructor 27728 */ 27729 var JustifiedGallery = function ($gallery, settings) { 27730 27731 this.settings = settings; 27732 this.checkSettings(); 27733 27734 this.imgAnalyzerTimeout = null; 27735 this.entries = null; 27736 this.buildingRow = { 27737 entriesBuff: [], 27738 width: 0, 27739 height: 0, 27740 aspectRatio: 0 27741 }; 27742 this.lastFetchedEntry = null; 27743 this.lastAnalyzedIndex = -1; 27744 this.yield = { 27745 every: 2, // do a flush every n flushes (must be greater than 1) 27746 flushed: 0 // flushed rows without a yield 27747 }; 27748 this.border = settings.border >= 0 ? settings.border : settings.margins; 27749 this.maxRowHeight = this.retrieveMaxRowHeight(); 27750 this.suffixRanges = this.retrieveSuffixRanges(); 27751 this.offY = this.border; 27752 this.rows = 0; 27753 this.spinner = { 27754 phase: 0, 27755 timeSlot: 150, 27756 $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'), 27757 intervalId: null 27758 }; 27759 this.scrollBarOn = false; 27760 this.checkWidthIntervalId = null; 27761 this.galleryWidth = $gallery.width(); 27762 this.$gallery = $gallery; 27763 27764 }; 27765 27766 /** @returns {String} the best suffix given the width and the height */ 27767 JustifiedGallery.prototype.getSuffix = function (width, height) { 27768 var longestSide, i; 27769 longestSide = (width > height) ? width : height; 27770 for (i = 0; i < this.suffixRanges.length; i++) { 27771 if (longestSide <= this.suffixRanges[i]) { 27772 return this.settings.sizeRangeSuffixes[this.suffixRanges[i]]; 27773 } 27774 } 27775 return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]]; 27776 }; 27777 27778 /** 27779 * Remove the suffix from the string 27780 * 27781 * @returns {string} a new string without the suffix 27782 */ 27783 JustifiedGallery.prototype.removeSuffix = function (str, suffix) { 27784 return str.substring(0, str.length - suffix.length); 27785 }; 27786 27787 /** 27788 * @returns {boolean} a boolean to say if the suffix is contained in the str or not 27789 */ 27790 JustifiedGallery.prototype.endsWith = function (str, suffix) { 27791 return str.indexOf(suffix, str.length - suffix.length) !== -1; 27792 }; 27793 27794 /** 27795 * Get the used suffix of a particular url 27796 * 27797 * @param str 27798 * @returns {String} return the used suffix 27799 */ 27800 JustifiedGallery.prototype.getUsedSuffix = function (str) { 27801 for (var si in this.settings.sizeRangeSuffixes) { 27802 if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) { 27803 if (this.settings.sizeRangeSuffixes[si].length === 0) continue; 27804 if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si]; 27805 } 27806 } 27807 return ''; 27808 }; 27809 27810 /** 27811 * Given an image src, with the width and the height, returns the new image src with the 27812 * best suffix to show the best quality thumbnail. 27813 * 27814 * @returns {String} the suffix to use 27815 */ 27816 JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) { 27817 var newImageSrc; 27818 27819 if (this.settings.thumbnailPath) { 27820 newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image); 27821 } else { 27822 var matchRes = imageSrc.match(this.settings.extension); 27823 var ext = (matchRes !== null) ? matchRes[0] : ''; 27824 newImageSrc = imageSrc.replace(this.settings.extension, ''); 27825 newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc)); 27826 newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext; 27827 } 27828 27829 return newImageSrc; 27830 }; 27831 27832 /** 27833 * Shows the images that is in the given entry 27834 * 27835 * @param $entry the entry 27836 * @param callback the callback that is called when the show animation is finished 27837 */ 27838 JustifiedGallery.prototype.showImg = function ($entry, callback) { 27839 if (this.settings.cssAnimation) { 27840 $entry.addClass('jg-entry-visible'); 27841 if (callback) callback(); 27842 } else { 27843 $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27844 $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27845 } 27846 }; 27847 27848 /** 27849 * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the 27850 * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src. 27851 * 27852 * @param $image the image to analyze 27853 * @returns {String} the extracted src 27854 */ 27855 JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) { 27856 var imageSrc = $image.data('safe-src'); 27857 var imageSrcLoc = 'data-safe-src'; 27858 // Begin Uncode edit 27859 if (typeof imageSrc === 'undefined') { 27860 var imageCurrentSrc = $image[0].currentSrc; 27861 if (imageCurrentSrc) { 27862 imageSrc = imageCurrentSrc; 27863 } else { 27864 imageSrc = $image.attr('src'); 27865 } 27866 imageSrcLoc = 'src'; 27867 } 27868 // End Uncode edit 27869 $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method 27870 $image.data('jg.src', imageSrc); // this will change overtime 27871 $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method 27872 return imageSrc; 27873 }; 27874 27875 /** @returns {jQuery} the image in the given entry */ 27876 JustifiedGallery.prototype.imgFromEntry = function ($entry) { 27877 var $img = $entry.find(this.settings.imgSelector); 27878 if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode 27879 return $img.length === 0 ? null : $img; 27880 }; 27881 27882 /** @returns {jQuery} the caption in the given entry */ 27883 JustifiedGallery.prototype.captionFromEntry = function ($entry) { 27884 var $caption = $entry.find('> .jg-caption'); 27885 return $caption.length === 0 ? null : $caption; 27886 }; 27887 27888 /** 27889 * Display the entry 27890 * 27891 * @param {jQuery} $entry the entry to display 27892 * @param {int} x the x position where the entry must be positioned 27893 * @param y the y position where the entry must be positioned 27894 * @param imgWidth the image width 27895 * @param imgHeight the image height 27896 * @param rowHeight the row height of the row that owns the entry 27897 */ 27898 JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) { 27899 $entry.width(imgWidth); 27900 $entry.height(Math.floor(rowHeight));//hacked by Uncode 27901 $entry.css('top', Math.floor(y));//hacked by Uncode 27902 $entry.css('left', x); 27903 27904 var $image = this.imgFromEntry($entry); 27905 if ($image !== null) { 27906 $image.css('width', imgWidth); 27907 $image.css('height', imgHeight); 27908 $image.css('margin-left', - imgWidth / 2); 27909 $image.css('margin-top', - imgHeight / 2); 27910 27911 // Image reloading for an high quality of thumbnails 27912 var imageSrc = $image.data('jg.src'); 27913 if (imageSrc) { 27914 imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]); 27915 27916 $image.one('error', function () { 27917 this.resetImgSrc($image); //revert to the original thumbnail 27918 }); 27919 27920 var loadNewImage = function () { 27921 // if (imageSrc !== newImageSrc) { 27922 $image.attr('src', imageSrc); 27923 // } 27924 }; 27925 27926 if ($entry.data('jg.loaded') === 'skipped' && imageSrc) { 27927 this.onImageEvent(imageSrc, (function() { 27928 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27929 $entry.data('jg.loaded', true); 27930 }).bind(this)); 27931 } else { 27932 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27933 } 27934 27935 } 27936 27937 } else { 27938 this.showImg($entry); 27939 } 27940 27941 this.displayEntryCaption($entry); 27942 }; 27943 27944 /** 27945 * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt' 27946 * or the 'title' attributes. 27947 * 27948 * @param {jQuery} $entry the entry to process 27949 */ 27950 JustifiedGallery.prototype.displayEntryCaption = function ($entry) { 27951 var $image = this.imgFromEntry($entry); 27952 if ($image !== null && this.settings.captions) { 27953 var $imgCaption = this.captionFromEntry($entry); 27954 27955 // Create it if it doesn't exists 27956 if ($imgCaption === null) { 27957 var caption = $image.attr('alt'); 27958 if (!this.isValidCaption(caption)) caption = $entry.attr('title'); 27959 if (this.isValidCaption(caption)) { // Create only we found something 27960 $imgCaption = $('<div class="jg-caption">' + caption + '</div>'); 27961 $entry.append($imgCaption); 27962 $entry.data('jg.createdCaption', true); 27963 } 27964 } 27965 27966 // Create events (we check again the $imgCaption because it can be still inexistent) 27967 if ($imgCaption !== null) { 27968 if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity); 27969 this.addCaptionEventsHandlers($entry); 27970 } 27971 } else { 27972 this.removeCaptionEventsHandlers($entry); 27973 } 27974 }; 27975 27976 /** 27977 * Validates the caption 27978 * 27979 * @param caption The caption that should be validated 27980 * @return {boolean} Validation result 27981 */ 27982 JustifiedGallery.prototype.isValidCaption = function (caption) { 27983 return (typeof caption !== 'undefined' && caption.length > 0); 27984 }; 27985 27986 /** 27987 * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry. 27988 * It shows the caption using jQuery (or using CSS if it is configured so) 27989 * 27990 * @param {Event} eventObject the event object 27991 */ 27992 JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) { 27993 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 27994 if (this.settings.cssAnimation) { 27995 $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden'); 27996 } else { 27997 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 27998 this.settings.captionSettings.visibleOpacity); 27999 } 28000 }; 28001 28002 /** 28003 * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry. 28004 * It hides the caption using jQuery (or using CSS if it is configured so) 28005 * 28006 * @param {Event} eventObject the event object 28007 */ 28008 JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) { 28009 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 28010 if (this.settings.cssAnimation) { 28011 $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden'); 28012 } else { 28013 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 28014 this.settings.captionSettings.nonVisibleOpacity); 28015 } 28016 }; 28017 28018 /** 28019 * Add the handlers of the entry for the caption 28020 * 28021 * @param $entry the entry to modify 28022 */ 28023 JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) { 28024 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28025 if (typeof captionMouseEvents === 'undefined') { 28026 captionMouseEvents = { 28027 mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this), 28028 mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this) 28029 }; 28030 $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter); 28031 $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave); 28032 $entry.data('jg.captionMouseEvents', captionMouseEvents); 28033 } 28034 }; 28035 28036 /** 28037 * Remove the handlers of the entry for the caption 28038 * 28039 * @param $entry the entry to modify 28040 */ 28041 JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) { 28042 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28043 if (typeof captionMouseEvents !== 'undefined') { 28044 $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter); 28045 $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave); 28046 $entry.removeData('jg.captionMouseEvents'); 28047 } 28048 }; 28049 28050 /** 28051 * Clear the building row data to be used for a new row 28052 */ 28053 JustifiedGallery.prototype.clearBuildingRow = function () { 28054 this.buildingRow.entriesBuff = []; 28055 this.buildingRow.aspectRatio = 0; 28056 this.buildingRow.width = 0; 28057 }; 28058 28059 /** 28060 * Justify the building row, preparing it to 28061 * 28062 * @param isLastRow 28063 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28064 * @returns a boolean to know if the row has been justified or not 28065 */ 28066 JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) { 28067 var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true; 28068 var minHeight = 0; 28069 var availableWidth = this.galleryWidth - 2 * this.border - ( 28070 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28071 var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode 28072 var defaultRowHeight = this.settings.rowHeight; 28073 var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold; 28074 28075 //Skip the last row if we can't justify it and the lastRow == 'hide' 28076 if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) { 28077 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28078 $entry = this.buildingRow.entriesBuff[i]; 28079 if (this.settings.cssAnimation) 28080 $entry.removeClass('jg-entry-visible'); 28081 else { 28082 $entry.stop().fadeTo(0, 0.1); 28083 $entry.find('> img, > a > img').fadeTo(0, 0); 28084 } 28085 } 28086 return -1; 28087 } 28088 28089 // With lastRow = nojustify, justify if is justificable (the images will not become too big) 28090 if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') { 28091 justify = false; 28092 28093 if (this.rows > 0) { 28094 defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows; 28095 justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold; 28096 } 28097 } 28098 28099 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28100 $entry = this.buildingRow.entriesBuff[i]; 28101 imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28102 28103 if (justify) { 28104 newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio; 28105 newImgH = rowHeight; 28106 } else { 28107 newImgW = defaultRowHeight * imgAspectRatio; 28108 newImgH = defaultRowHeight; 28109 } 28110 28111 availableWidth -= Math.round(newImgW); 28112 $entry.data('jg.jwidth', Math.round(newImgW)); 28113 $entry.data('jg.jheight', Math.ceil(newImgH)); 28114 if (i === 0 || minHeight > newImgH) minHeight = newImgH; 28115 } 28116 28117 this.buildingRow.height = minHeight; 28118 return justify; 28119 }; 28120 28121 /** 28122 * Flush a row: justify it, modify the gallery height accordingly to the row height 28123 * 28124 * @param isLastRow 28125 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28126 */ 28127 JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) { 28128 var settings = this.settings; 28129 var $entry, buildingRowRes, offX = this.border, i; 28130 28131 buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow); 28132 if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) { 28133 this.clearBuildingRow(); 28134 return; 28135 } 28136 28137 if (this.maxRowHeight) { 28138 if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight; 28139 } 28140 28141 //Align last (unjustified) row 28142 if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) { 28143 var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins; 28144 28145 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28146 $entry = this.buildingRow.entriesBuff[i]; 28147 availableWidth -= $entry.data('jg.jwidth'); 28148 } 28149 28150 if (settings.lastRow === 'center') 28151 offX += Math.round(availableWidth / 2); 28152 else if (settings.lastRow === 'right') 28153 offX += availableWidth; 28154 } 28155 28156 var lastEntryIdx = this.buildingRow.entriesBuff.length - 1; 28157 for (i = 0; i <= lastEntryIdx; i++) { 28158 $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i]; 28159 this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height); 28160 offX += $entry.data('jg.jwidth') + settings.margins; 28161 } 28162 28163 //Gallery Height 28164 this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border; 28165 this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight()); 28166 28167 if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) { 28168 //Ready for a new row 28169 this.offY += this.buildingRow.height + settings.margins; 28170 this.rows += 1; 28171 this.clearBuildingRow(); 28172 this.settings.triggerEvent.call(this, 'jg.rowflush'); 28173 } 28174 }; 28175 28176 28177 // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221 28178 var galleryPrevStaticHeight = 0; 28179 28180 JustifiedGallery.prototype.rememberGalleryHeight = function () { 28181 galleryPrevStaticHeight = this.$gallery.height(); 28182 this.$gallery.height(galleryPrevStaticHeight); 28183 }; 28184 28185 // grow only 28186 JustifiedGallery.prototype.setGalleryTempHeight = function (height) { 28187 galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight); 28188 this.$gallery.height(galleryPrevStaticHeight); 28189 }; 28190 28191 JustifiedGallery.prototype.setGalleryFinalHeight = function (height) { 28192 galleryPrevStaticHeight = height; 28193 this.$gallery.height(height); 28194 }; 28195 28196 /** 28197 * Checks the width of the gallery container, to know if a new justification is needed 28198 */ 28199 JustifiedGallery.prototype.checkWidth = function () { 28200 this.checkWidthIntervalId = setInterval($.proxy(function () { 28201 28202 // if the gallery is not currently visible, abort. 28203 if (!this.$gallery.is(":visible")) return; 28204 28205 var galleryWidth = parseFloat(this.$gallery.width()); 28206 if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) { 28207 this.galleryWidth = galleryWidth; 28208 this.rewind(); 28209 28210 this.rememberGalleryHeight(); 28211 28212 // Restart to analyze 28213 this.startImgAnalyzer(true); 28214 } 28215 }, this), this.settings.refreshTime); 28216 }; 28217 28218 /** 28219 * @returns {boolean} a boolean saying if the spinner is active or not 28220 */ 28221 JustifiedGallery.prototype.isSpinnerActive = function () { 28222 return this.spinner.intervalId !== null; 28223 }; 28224 28225 /** 28226 * @returns {int} the spinner height 28227 */ 28228 JustifiedGallery.prototype.getSpinnerHeight = function () { 28229 return this.spinner.$el.innerHeight(); 28230 }; 28231 28232 /** 28233 * Stops the spinner animation and modify the gallery height to exclude the spinner 28234 */ 28235 JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () { 28236 clearInterval(this.spinner.intervalId); 28237 this.spinner.intervalId = null; 28238 this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight()); 28239 this.spinner.$el.detach(); 28240 }; 28241 28242 /** 28243 * Starts the spinner animation 28244 */ 28245 JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () { 28246 var spinnerContext = this.spinner; 28247 var $spinnerPoints = spinnerContext.$el.find('span'); 28248 clearInterval(spinnerContext.intervalId); 28249 this.$gallery.append(spinnerContext.$el); 28250 this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight()); 28251 spinnerContext.intervalId = setInterval(function () { 28252 if (spinnerContext.phase < $spinnerPoints.length) { 28253 $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1); 28254 } else { 28255 $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0); 28256 } 28257 spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2); 28258 }, spinnerContext.timeSlot); 28259 }; 28260 28261 /** 28262 * Rewind the image analysis to start from the first entry. 28263 */ 28264 JustifiedGallery.prototype.rewind = function () { 28265 this.lastFetchedEntry = null; 28266 this.lastAnalyzedIndex = -1; 28267 this.offY = this.border; 28268 this.rows = 0; 28269 this.clearBuildingRow(); 28270 }; 28271 28272 /** 28273 * @returns {String} `settings.selector` rejecting spinner element 28274 */ 28275 JustifiedGallery.prototype.getSelectorWithoutSpinner = function () { 28276 return this.settings.selector + ', div:not(.jg-spinner)'; 28277 }; 28278 28279 /** 28280 * @returns {Array} all entries matched by `settings.selector` 28281 */ 28282 JustifiedGallery.prototype.getAllEntries = function () { 28283 var selector = this.getSelectorWithoutSpinner(); 28284 return this.$gallery.children(selector).toArray(); 28285 }; 28286 28287 /** 28288 * Update the entries searching it from the justified gallery HTML element 28289 * 28290 * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered) 28291 * @returns {boolean} true if some entries has been founded 28292 */ 28293 JustifiedGallery.prototype.updateEntries = function (norewind) { 28294 var newEntries; 28295 28296 if (norewind && this.lastFetchedEntry != null) { 28297 var selector = this.getSelectorWithoutSpinner(); 28298 newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray(); 28299 } else { 28300 this.entries = []; 28301 newEntries = this.getAllEntries(); 28302 } 28303 28304 if (newEntries.length > 0) { 28305 28306 // Sort or randomize 28307 if ($.isFunction(this.settings.sort)) { 28308 newEntries = this.sortArray(newEntries); 28309 } else if (this.settings.randomize) { 28310 newEntries = this.shuffleArray(newEntries); 28311 } 28312 this.lastFetchedEntry = newEntries[newEntries.length - 1]; 28313 28314 // Filter 28315 if (this.settings.filter) { 28316 newEntries = this.filterArray(newEntries); 28317 } else { 28318 this.resetFilters(newEntries); 28319 } 28320 28321 } 28322 28323 this.entries = this.entries.concat(newEntries); 28324 return true; 28325 }; 28326 28327 /** 28328 * Apply the entries order to the DOM, iterating the entries and appending the images 28329 * 28330 * @param entries the entries that has been modified and that must be re-ordered in the DOM 28331 */ 28332 JustifiedGallery.prototype.insertToGallery = function (entries) { 28333 var that = this; 28334 $.each(entries, function () { 28335 $(this).appendTo(that.$gallery); 28336 }); 28337 }; 28338 28339 /** 28340 * Shuffle the array using the Fisher-Yates shuffle algorithm 28341 * 28342 * @param a the array to shuffle 28343 * @return the shuffled array 28344 */ 28345 JustifiedGallery.prototype.shuffleArray = function (a) { 28346 var i, j, temp; 28347 for (i = a.length - 1; i > 0; i--) { 28348 j = Math.floor(Math.random() * (i + 1)); 28349 temp = a[i]; 28350 a[i] = a[j]; 28351 a[j] = temp; 28352 } 28353 this.insertToGallery(a); 28354 return a; 28355 }; 28356 28357 /** 28358 * Sort the array using settings.comparator as comparator 28359 * 28360 * @param a the array to sort (it is sorted) 28361 * @return the sorted array 28362 */ 28363 JustifiedGallery.prototype.sortArray = function (a) { 28364 a.sort(this.settings.sort); 28365 this.insertToGallery(a); 28366 return a; 28367 }; 28368 28369 /** 28370 * Reset the filters removing the 'jg-filtered' class from all the entries 28371 * 28372 * @param a the array to reset 28373 */ 28374 JustifiedGallery.prototype.resetFilters = function (a) { 28375 for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered'); 28376 }; 28377 28378 /** 28379 * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering. 28380 * 28381 * @param a the array to filter 28382 * @return the filtered array 28383 */ 28384 JustifiedGallery.prototype.filterArray = function (a) { 28385 var settings = this.settings; 28386 if ($.type(settings.filter) === 'string') { 28387 // Filter only keeping the entries passed in the string 28388 return a.filter(function (el) { 28389 var $el = $(el); 28390 if ($el.is(settings.filter)) { 28391 $el.removeClass('jg-filtered'); 28392 return true; 28393 } else { 28394 $el.addClass('jg-filtered').removeClass('jg-visible'); 28395 return false; 28396 } 28397 }); 28398 } else if ($.isFunction(settings.filter)) { 28399 // Filter using the passed function 28400 var filteredArr = a.filter(settings.filter); 28401 for (var i = 0; i < a.length; i++) { 28402 if (filteredArr.indexOf(a[i]) === -1) { 28403 $(a[i]).addClass('jg-filtered').removeClass('jg-visible'); 28404 } else { 28405 $(a[i]).removeClass('jg-filtered'); 28406 } 28407 } 28408 return filteredArr; 28409 } 28410 }; 28411 28412 /** 28413 * Revert the image src to the default value. 28414 */ 28415 JustifiedGallery.prototype.resetImgSrc = function ($img) { 28416 if ($img.data('jg.originalSrcLoc') === 'src') { 28417 $img.attr('src', $img.data('jg.originalSrc')); 28418 } else { 28419 $img.attr('src', ''); 28420 } 28421 }; 28422 28423 /** 28424 * Destroy the Justified Gallery instance. 28425 * 28426 * It clears all the css properties added in the style attributes. We doesn't backup the original 28427 * values for those css attributes, because it costs (performance) and because in general one 28428 * shouldn't use the style attribute for an uniform set of images (where we suppose the use of 28429 * classes). Creating a backup is also difficult because JG could be called multiple times and 28430 * with different style attributes. 28431 */ 28432 JustifiedGallery.prototype.destroy = function () { 28433 clearInterval(this.checkWidthIntervalId); 28434 this.stopImgAnalyzerStarter(); 28435 28436 // Get fresh entries list since filtered entries are absent in `this.entries` 28437 $.each(this.getAllEntries(), $.proxy(function (_, entry) { 28438 var $entry = $(entry); 28439 28440 // Reset entry style 28441 $entry.css('width', ''); 28442 $entry.css('height', ''); 28443 $entry.css('top', ''); 28444 $entry.css('left', ''); 28445 $entry.data('jg.loaded', undefined); 28446 $entry.removeClass('jg-entry jg-filtered jg-entry-visible'); 28447 28448 // Reset image style 28449 var $img = this.imgFromEntry($entry); 28450 if ($img) { 28451 $img.css('width', ''); 28452 $img.css('height', ''); 28453 $img.css('margin-left', ''); 28454 $img.css('margin-top', ''); 28455 this.resetImgSrc($img); 28456 $img.data('jg.originalSrc', undefined); 28457 $img.data('jg.originalSrcLoc', undefined); 28458 $img.data('jg.src', undefined); 28459 } 28460 28461 // Remove caption 28462 this.removeCaptionEventsHandlers($entry); 28463 var $caption = this.captionFromEntry($entry); 28464 if ($entry.data('jg.createdCaption')) { 28465 // remove also the caption element (if created by jg) 28466 $entry.data('jg.createdCaption', undefined); 28467 if ($caption !== null) $caption.remove(); 28468 } else { 28469 if ($caption !== null) $caption.fadeTo(0, 1); 28470 } 28471 28472 }, this)); 28473 28474 this.$gallery.css('height', ''); 28475 this.$gallery.removeClass('justified-gallery'); 28476 this.$gallery.data('jg.controller', undefined); 28477 this.settings.triggerEvent.call(this, 'jg.destroy'); 28478 }; 28479 28480 /** 28481 * Analyze the images and builds the rows. It returns if it found an image that is not loaded. 28482 * 28483 * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end 28484 */ 28485 JustifiedGallery.prototype.analyzeImages = function (isForResize) { 28486 for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) { 28487 var $entry = $(this.entries[i]); 28488 if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') { 28489 var availableWidth = this.galleryWidth - 2 * this.border - ( 28490 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28491 var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28492 28493 this.buildingRow.entriesBuff.push($entry); 28494 this.buildingRow.aspectRatio += imgAspectRatio; 28495 this.buildingRow.width += imgAspectRatio * this.settings.rowHeight; 28496 this.lastAnalyzedIndex = i; 28497 28498 if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) { 28499 this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28500 28501 if (++this.yield.flushed >= this.yield.every) { 28502 this.startImgAnalyzer(isForResize); 28503 return; 28504 } 28505 } 28506 } else if ($entry.data('jg.loaded') !== 'error') { 28507 return; 28508 } 28509 } 28510 28511 // Last row flush (the row is not full) 28512 if (this.buildingRow.entriesBuff.length > 0) { 28513 this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28514 } 28515 28516 if (this.isSpinnerActive()) { 28517 this.stopLoadingSpinnerAnimation(); 28518 } 28519 28520 /* Stop, if there is, the timeout to start the analyzeImages. 28521 This is because an image can be set loaded, and the timeout can be set, 28522 but this image can be analyzed yet. 28523 */ 28524 this.stopImgAnalyzerStarter(); 28525 28526 this.setGalleryFinalHeight(this.galleryHeightToSet); 28527 28528 //On complete callback 28529 this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete'); 28530 }; 28531 28532 /** 28533 * Stops any ImgAnalyzer starter (that has an assigned timeout) 28534 */ 28535 JustifiedGallery.prototype.stopImgAnalyzerStarter = function () { 28536 this.yield.flushed = 0; 28537 if (this.imgAnalyzerTimeout !== null) { 28538 clearTimeout(this.imgAnalyzerTimeout); 28539 this.imgAnalyzerTimeout = null; 28540 } 28541 }; 28542 28543 /** 28544 * Starts the image analyzer. It is not immediately called to let the browser to update the view 28545 * 28546 * @param isForResize specifies if the image analyzer must be called for resizing or not 28547 */ 28548 JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) { 28549 var that = this; 28550 this.stopImgAnalyzerStarter(); 28551 this.imgAnalyzerTimeout = setTimeout(function () { 28552 that.analyzeImages(isForResize); 28553 }, 0.001); // we can't start it immediately due to a IE different behaviour 28554 }; 28555 28556 /** 28557 * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property, 28558 * because some browsers, with a 404 set complete = true. 28559 * 28560 * @param imageSrc the image src to load 28561 * @param onLoad callback that is called when the image has been loaded 28562 * @param onError callback that is called in case of an error 28563 */ 28564 JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) { 28565 if (!onLoad && !onError) return; 28566 28567 var memImage = new Image(); 28568 var $memImage = $(memImage); 28569 if (onLoad) { 28570 $memImage.one('load', function () { 28571 $memImage.off('load error'); 28572 onLoad(memImage); 28573 }); 28574 } 28575 if (onError) { 28576 $memImage.one('error', function () { 28577 $memImage.off('load error'); 28578 onError(memImage); 28579 }); 28580 } 28581 memImage.src = imageSrc; 28582 }; 28583 28584 /** 28585 * Init of Justified Gallery controlled 28586 * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images) 28587 */ 28588 JustifiedGallery.prototype.init = function () { 28589 var imagesToLoad = false, skippedImages = false, that = this; 28590 $.each(this.entries, function (index, entry) { 28591 var $entry = $(entry); 28592 var $image = that.imgFromEntry($entry); 28593 28594 $entry.addClass('jg-entry'); 28595 28596 if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') { 28597 28598 // Link Rel global overwrite 28599 if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel); 28600 28601 // Link Target global overwrite 28602 if (that.settings.target !== null) $entry.attr('target', that.settings.target); 28603 28604 if ($image !== null) { 28605 28606 // Image src 28607 var imageSrc = that.extractImgSrcFromImage($image); 28608 28609 /* If we have the height and the width, we don't wait that the image is loaded, 28610 but we start directly with the justification */ 28611 if (that.settings.waitThumbnailsLoad === false || !imageSrc) { 28612 var width = parseFloat($image.attr('width')); 28613 var height = parseFloat($image.attr('height')); 28614 if ($image.prop('tagName') === 'svg') { 28615 width = parseFloat($image[0].getBBox().width); 28616 height = parseFloat($image[0].getBBox().height); 28617 } 28618 if (!isNaN(width) && !isNaN(height)) { 28619 $entry.data('jg.width', width); 28620 $entry.data('jg.height', height); 28621 $entry.data('jg.loaded', 'skipped'); 28622 skippedImages = true; 28623 that.startImgAnalyzer(false); 28624 return true; // continue 28625 } 28626 } 28627 28628 $entry.data('jg.loaded', false); 28629 imagesToLoad = true; 28630 28631 // Spinner start 28632 if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation(); 28633 28634 that.onImageEvent(imageSrc, function (loadImg) { // image loaded 28635 $entry.data('jg.width', loadImg.width); 28636 $entry.data('jg.height', loadImg.height); 28637 $entry.data('jg.loaded', true); 28638 that.startImgAnalyzer(false); 28639 }, function () { // image load error 28640 $entry.data('jg.loaded', 'error'); 28641 that.startImgAnalyzer(false); 28642 }); 28643 28644 } else { 28645 $entry.data('jg.loaded', true); 28646 $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1); 28647 $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1); 28648 } 28649 28650 } 28651 28652 }); 28653 28654 if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false); 28655 this.checkWidth(); 28656 }; 28657 28658 /** 28659 * Checks that it is a valid number. If a string is passed it is converted to a number 28660 * 28661 * @param settingContainer the object that contains the setting (to allow the conversion) 28662 * @param settingName the setting name 28663 */ 28664 JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) { 28665 if ($.type(settingContainer[settingName]) === 'string') { 28666 settingContainer[settingName] = parseFloat(settingContainer[settingName]); 28667 } 28668 28669 if ($.type(settingContainer[settingName]) === 'number') { 28670 if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName; 28671 } else { 28672 throw settingName + ' must be a number'; 28673 } 28674 }; 28675 28676 /** 28677 * Checks the sizeRangeSuffixes and, if necessary, converts 28678 * its keys from string (e.g. old settings with 'lt100') to int. 28679 */ 28680 JustifiedGallery.prototype.checkSizeRangesSuffixes = function () { 28681 if ($.type(this.settings.sizeRangeSuffixes) !== 'object') { 28682 throw 'sizeRangeSuffixes must be defined and must be an object'; 28683 } 28684 28685 var suffixRanges = []; 28686 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28687 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx); 28688 } 28689 28690 var newSizeRngSuffixes = { 0: '' }; 28691 for (var i = 0; i < suffixRanges.length; i++) { 28692 if ($.type(suffixRanges[i]) === 'string') { 28693 try { 28694 var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10); 28695 newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28696 } catch (e) { 28697 throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')'; 28698 } 28699 } else { 28700 newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28701 } 28702 } 28703 28704 this.settings.sizeRangeSuffixes = newSizeRngSuffixes; 28705 }; 28706 28707 /** 28708 * check and convert the maxRowHeight setting 28709 * requires rowHeight to be already set 28710 * TODO: should be always called when only rowHeight is changed 28711 * @return number or null 28712 */ 28713 JustifiedGallery.prototype.retrieveMaxRowHeight = function () { 28714 var newMaxRowHeight = null; 28715 var rowHeight = this.settings.rowHeight; 28716 28717 if ($.type(this.settings.maxRowHeight) === 'string') { 28718 if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) { 28719 newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100; 28720 } else { 28721 newMaxRowHeight = parseFloat(this.settings.maxRowHeight); 28722 } 28723 } else if ($.type(this.settings.maxRowHeight) === 'number') { 28724 newMaxRowHeight = this.settings.maxRowHeight; 28725 } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) { 28726 return null; 28727 } else { 28728 throw 'maxRowHeight must be a number or a percentage'; 28729 } 28730 28731 // check if the converted value is not a number 28732 if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight'; 28733 28734 // check values, maxRowHeight must be >= rowHeight 28735 if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight; 28736 28737 return newMaxRowHeight; 28738 }; 28739 28740 /** 28741 * Checks the settings 28742 */ 28743 JustifiedGallery.prototype.checkSettings = function () { 28744 this.checkSizeRangesSuffixes(); 28745 28746 this.checkOrConvertNumber(this.settings, 'rowHeight'); 28747 this.checkOrConvertNumber(this.settings, 'margins'); 28748 this.checkOrConvertNumber(this.settings, 'border'); 28749 this.checkOrConvertNumber(this.settings, 'maxRowsCount'); 28750 28751 var lastRowModes = [ 28752 'justify', 28753 'nojustify', 28754 'left', 28755 'center', 28756 'right', 28757 'hide' 28758 ]; 28759 if (lastRowModes.indexOf(this.settings.lastRow) === -1) { 28760 throw 'lastRow must be one of: ' + lastRowModes.join(', '); 28761 } 28762 28763 this.checkOrConvertNumber(this.settings, 'justifyThreshold'); 28764 if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) { 28765 throw 'justifyThreshold must be in the interval [0,1]'; 28766 } 28767 if ($.type(this.settings.cssAnimation) !== 'boolean') { 28768 throw 'cssAnimation must be a boolean'; 28769 } 28770 28771 if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean'; 28772 this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration'); 28773 28774 this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity'); 28775 if (this.settings.captionSettings.visibleOpacity < 0 || 28776 this.settings.captionSettings.visibleOpacity > 1) { 28777 throw 'captionSettings.visibleOpacity must be in the interval [0, 1]'; 28778 } 28779 28780 this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity'); 28781 if (this.settings.captionSettings.nonVisibleOpacity < 0 || 28782 this.settings.captionSettings.nonVisibleOpacity > 1) { 28783 throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]'; 28784 } 28785 28786 this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration'); 28787 this.checkOrConvertNumber(this.settings, 'refreshTime'); 28788 this.checkOrConvertNumber(this.settings, 'refreshSensitivity'); 28789 if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean'; 28790 if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string'; 28791 28792 if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) { 28793 throw 'sort must be false or a comparison function'; 28794 } 28795 28796 if (this.settings.filter !== false && !$.isFunction(this.settings.filter) && 28797 $.type(this.settings.filter) !== 'string') { 28798 throw 'filter must be false, a string or a filter function'; 28799 } 28800 }; 28801 28802 /** 28803 * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned. 28804 * @returns {Array} sorted suffix ranges 28805 */ 28806 JustifiedGallery.prototype.retrieveSuffixRanges = function () { 28807 var suffixRanges = []; 28808 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28809 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10)); 28810 } 28811 suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; }); 28812 return suffixRanges; 28813 }; 28814 28815 /** 28816 * Update the existing settings only changing some of them 28817 * 28818 * @param newSettings the new settings (or a subgroup of them) 28819 */ 28820 JustifiedGallery.prototype.updateSettings = function (newSettings) { 28821 // In this case Justified Gallery has been called again changing only some options 28822 this.settings = $.extend({}, this.settings, newSettings); 28823 this.checkSettings(); 28824 28825 // As reported in the settings: negative value = same as margins, 0 = disabled 28826 this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins; 28827 28828 this.maxRowHeight = this.retrieveMaxRowHeight(); 28829 this.suffixRanges = this.retrieveSuffixRanges(); 28830 }; 28831 28832 JustifiedGallery.prototype.defaults = { 28833 sizeRangeSuffixes: {}, /* e.g. Flickr configuration 28834 { 28835 100: '_t', // used when longest is less than 100px 28836 240: '_m', // used when longest is between 101px and 240px 28837 320: '_n', // ... 28838 500: '', 28839 640: '_z', 28840 1024: '_b' // used as else case because it is the last 28841 } 28842 */ 28843 thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the 28844 path relative to a specific thumbnail size. The function should accept respectively three arguments: 28845 current path, width and height */ 28846 rowHeight: 120, // required? required to be > 0? 28847 maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels, 28848 // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height 28849 // can't exceed 3 * rowHeight) 28850 maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled) 28851 margins: 1, 28852 border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border 28853 28854 lastRow: 'nojustify', // ⦠which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide' 28855 28856 justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified 28857 * (i.e. lastRow setting is not considered) */ 28858 waitThumbnailsLoad: true, 28859 captions: true, 28860 cssAnimation: true, 28861 imagesAnimationDuration: 500, // ignored with css animations 28862 captionSettings: { // ignored with css animations 28863 animationDuration: 500, 28864 visibleOpacity: 0.7, 28865 nonVisibleOpacity: 0.0 28866 },
28867 rel: null, // rewrite the rel of each analyzed links 28868 target: null, // rewrite the target of all links 28869 extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image 28870 refreshTime: 200, // time interval (in ms) to check if the page changes its width 28871 refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery 28872 randomize: false, 28873 rtl: false, // right-to-left mode 28874 sort: false, /* 28875 - false: to do not sort 28876 - function: to sort them using the function as comparator (see Array.prototype.sort()) 28877 */ 28878 filter: false, /* 28879 - false, null or undefined: for a disabled filter 28880 - a string: an entry is kept if entry.is(filter string) returns true 28881 see jQuery's .is() function for further information 28882 - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise. 28883 It follows the specifications of the Array.prototype.filter() function of JavaScript. 28884 */ 28885 selector: 'a', // The selector that is used to know what are the entries of the gallery 28886 imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry 28887 triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger 28888 this.$gallery.trigger(event); // Consider that 'this' is this set to the JustifiedGallery object, so it can 28889 } // access to fields such as $gallery, useful to trigger events with jQuery. 28890 }; 28891 28892 28893 /** 28894 * Justified Gallery plugin for jQuery 28895 * 28896 * Events 28897 * - jg.complete : called when all the gallery has been created 28898 * - jg.resize : called when the gallery has been resized 28899 * - jg.rowflush : when a new row appears 28900 * 28901 * @param arg the action (or the settings) passed when the plugin is called 28902 * @returns {*} the object itself 28903 */ 28904 $.fn.justifiedGallery = function (arg) { 28905 return this.each(function (index, gallery) { 28906 28907 var $gallery = $(gallery); 28908 $gallery.addClass('justified-gallery'); 28909 28910 var controller = $gallery.data('jg.controller'); 28911 if (typeof controller === 'undefined') { 28912 // Create controller and assign it to the object data 28913 if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') { 28914 if (arg === 'destroy') return; // Just a call to an unexisting object 28915 throw 'The argument must be an object'; 28916 } 28917 controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg)); 28918 $gallery.data('jg.controller', controller); 28919 } else if (arg === 'norewind') { 28920 // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row 28921 // ... left to be more readable 28922 } else if (arg === 'destroy') { 28923 controller.destroy(); 28924 return; 28925 } else { 28926 // In this case Justified Gallery has been called again changing only some options 28927 controller.updateSettings(arg); 28928 controller.rewind(); 28929 } 28930 28931 // Update the entries list 28932 if (!controller.updateEntries(arg === 'norewind')) return; 28933 28934 // Init justified gallery 28935 controller.init(); 28936 28937 }); 28938 }; 28939 28940})); 28941 28942/*! 28943* Customized version of iScroll.js 0.0.1 28944* It fixes bugs affecting its integration with fullpage.js 28945*/ 28946/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */ 28947(function (window, document, Math) { 28948var rAF = window.requestAnimationFrame || 28949 window.webkitRequestAnimationFrame || 28950 window.mozRequestAnimationFrame || 28951 window.oRequestAnimationFrame || 28952 window.msRequestAnimationFrame || 28953 function (callback) { window.setTimeout(callback, 1000 / 60); }; 28954 28955var utils = (function () { 28956 var me = {}; 28957 28958 var _elementStyle = document.createElement('div').style; 28959 var _vendor = (function () { 28960 var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], 28961 transform, 28962 i = 0, 28963 l = vendors.length; 28964 28965 for ( ; i < l; i++ ) { 28966 transform = vendors[i] + 'ransform'; 28967 if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); 28968 } 28969 28970 return false;
vendor: 5,154 bytes, lines 28971-29123
28971 })(); 28972 28973 function _prefixStyle (style) { 28974 if ( _vendor === false ) return false; 28975 if ( _vendor === '' ) return style; 28976 return _vendor + style.charAt(0).toUpperCase() + style.substr(1); 28977 } 28978 28979 me.getTime = Date.now || function getTime () { return new Date().getTime(); }; 28980 28981 me.extend = function (target, obj) { 28982 for ( var i in obj ) { 28983 target[i] = obj[i]; 28984 } 28985 }; 28986 28987 me.addEvent = function (el, type, fn, capture) { 28988 el.addEventListener(type, fn, !!capture); 28989 }; 28990 28991 me.removeEvent = function (el, type, fn, capture) { 28992 el.removeEventListener(type, fn, !!capture); 28993 }; 28994 28995 me.prefixPointerEvent = function (pointerEvent) { 28996 return window.MSPointerEvent ? 28997 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8): 28998 pointerEvent; 28999 }; 29000 29001 me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { 29002 var distance = current - start, 29003 speed = Math.abs(distance) / time, 29004 destination, 29005 duration; 29006 29007 deceleration = deceleration === undefined ? 0.0006 : deceleration; 29008 29009 destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); 29010 duration = speed / deceleration; 29011 29012 if ( destination < lowerMargin ) { 29013 destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; 29014 distance = Math.abs(destination - current); 29015 duration = distance / speed; 29016 } else if ( destination > 0 ) { 29017 destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; 29018 distance = Math.abs(current) + destination; 29019 duration = distance / speed; 29020 } 29021 29022 return { 29023 destination: Math.round(destination), 29024 duration: duration 29025 }; 29026 }; 29027 29028 var _transform = _prefixStyle('transform'); 29029 29030 me.extend(me, { 29031 hasTransform: _transform !== false, 29032 hasPerspective: _prefixStyle('perspective') in _elementStyle, 29033 hasTouch: 'ontouchstart' in window, 29034 hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed 29035 hasTransition: _prefixStyle('transition') in _elementStyle 29036 }); 29037 29038 /* 29039 This should find all Android browsers lower than build 535.19 (both stock browser and webview) 29040 - galaxy S2 is ok 29041 - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1` 29042 - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29043 - galaxy S3 is badAndroid (stock brower, webview) 29044 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29045 - galaxy S4 is badAndroid (stock brower, webview) 29046 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29047 - galaxy S5 is OK 29048 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29049 - galaxy S6 is OK 29050 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29051 */ 29052 me.isBadAndroid = (function() { 29053 var appVersion = window.navigator.appVersion; 29054 // Android browser is not a chrome browser. 29055 if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) { 29056 var safariVersion = appVersion.match(/Safari\/(\d+.\d)/); 29057 if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) { 29058 return parseFloat(safariVersion[1]) < 535.19; 29059 } else { 29060 return true; 29061 } 29062 } else { 29063 return false; 29064 } 29065 })(); 29066 29067 me.extend(me.style = {}, { 29068 transform: _transform, 29069 transitionTimingFunction: _prefixStyle('transitionTimingFunction'), 29070 transitionDuration: _prefixStyle('transitionDuration'), 29071 transitionDelay: _prefixStyle('transitionDelay'), 29072 transformOrigin: _prefixStyle('transformOrigin') 29073 }); 29074 29075 me.hasClass = function (e, c) { 29076 var re = new RegExp("(^|\\s)" + c + "(\\s|$)"); 29077 return re.test(e.className); 29078 }; 29079 29080 me.addClass = function (e, c) { 29081 if ( me.hasClass(e, c) ) { 29082 return; 29083 } 29084 29085 var newclass = e.className.split(' '); 29086 newclass.push(c); 29087 e.className = newclass.join(' '); 29088 }; 29089 29090 me.removeClass = function (e, c) { 29091 if ( !me.hasClass(e, c) ) { 29092 return; 29093 } 29094 29095 var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g'); 29096 e.className = e.className.replace(re, ' '); 29097 }; 29098 29099 me.offset = function (el) { 29100 var left = -el.offsetLeft, 29101 top = -el.offsetTop; 29102 29103 // jshint -W084 29104 while (el = el.offsetParent) { 29105 left -= el.offsetLeft; 29106 top -= el.offsetTop; 29107 } 29108 // jshint +W084 29109 29110 return { 29111 left: left, 29112 top: top 29113 }; 29114 }; 29115 29116 me.preventDefaultException = function (el, exceptions) { 29117 for ( var i in exceptions ) { 29118 if ( exceptions[i].test(el[i]) ) { 29119 return true; 29120 } 29121 } 29122 29123 return false;
vendor: 5,660 bytes, lines 29124-29289
29124 }; 29125 29126 me.extend(me.eventType = {}, { 29127 touchstart: 1, 29128 touchmove: 1, 29129 touchend: 1, 29130 29131 mousedown: 2, 29132 mousemove: 2, 29133 mouseup: 2, 29134 29135 pointerdown: 3, 29136 pointermove: 3, 29137 pointerup: 3, 29138 29139 MSPointerDown: 3, 29140 MSPointerMove: 3, 29141 MSPointerUp: 3 29142 }); 29143 29144 me.extend(me.ease = {}, { 29145 quadratic: { 29146 style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', 29147 fn: function (k) { 29148 return k * ( 2 - k ); 29149 } 29150 }, 29151 circular: { 29152 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) 29153 fn: function (k) { 29154 return Math.sqrt( 1 - ( --k * k ) ); 29155 } 29156 }, 29157 back: { 29158 style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', 29159 fn: function (k) { 29160 var b = 4; 29161 return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; 29162 } 29163 }, 29164 bounce: { 29165 style: '', 29166 fn: function (k) { 29167 if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { 29168 return 7.5625 * k * k; 29169 } else if ( k < ( 2 / 2.75 ) ) { 29170 return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; 29171 } else if ( k < ( 2.5 / 2.75 ) ) { 29172 return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; 29173 } else { 29174 return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; 29175 } 29176 } 29177 }, 29178 elastic: { 29179 style: '', 29180 fn: function (k) { 29181 var f = 0.22, 29182 e = 0.4; 29183 29184 if ( k === 0 ) { return 0; } 29185 if ( k == 1 ) { return 1; } 29186 29187 return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); 29188 } 29189 } 29190 }); 29191 29192 me.tap = function (e, eventName) { 29193 var ev = document.createEvent('Event'); 29194 ev.initEvent(eventName, true, true); 29195 ev.pageX = e.pageX; 29196 ev.pageY = e.pageY; 29197 e.target.dispatchEvent(ev); 29198 }; 29199 29200 me.click = function (e) { 29201 var target = e.target, 29202 ev; 29203 29204 if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { 29205 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent 29206 // initMouseEvent is deprecated. 29207 ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event'); 29208 ev.initEvent('click', true, true); 29209 ev.view = e.view || window; 29210 ev.detail = 1; 29211 ev.screenX = target.screenX || 0; 29212 ev.screenY = target.screenY || 0; 29213 ev.clientX = target.clientX || 0; 29214 ev.clientY = target.clientY || 0; 29215 ev.ctrlKey = !!e.ctrlKey; 29216 ev.altKey = !!e.altKey; 29217 ev.shiftKey = !!e.shiftKey; 29218 ev.metaKey = !!e.metaKey; 29219 ev.button = 0; 29220 ev.relatedTarget = null; 29221 ev._constructed = true; 29222 target.dispatchEvent(ev); 29223 } 29224 }; 29225 29226 return me; 29227})(); 29228function IScroll (el, options) { 29229 this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; 29230 this.scroller = this.wrapper.children[0]; 29231 this.scrollerStyle = this.scroller.style; // cache style for better performance 29232 29233 this.options = { 29234 29235 resizeScrollbars: true, 29236 29237 mouseWheelSpeed: 20, 29238 29239 snapThreshold: 0.334, 29240 29241// INSERT POINT: OPTIONS 29242 disablePointer : !utils.hasPointer, 29243 disableTouch : utils.hasPointer || !utils.hasTouch, 29244 disableMouse : utils.hasPointer || utils.hasTouch, 29245 startX: 0, 29246 startY: 0, 29247 scrollY: true, 29248 directionLockThreshold: 5, 29249 momentum: true, 29250 29251 bounce: true, 29252 bounceTime: 600, 29253 bounceEasing: '', 29254 29255 preventDefault: true, 29256 preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ }, 29257 29258 HWCompositing: true, 29259 useTransition: true, 29260 useTransform: true, 29261 bindToWrapper: typeof window.onmousedown === "undefined" 29262 }; 29263 29264 for ( var i in options ) { 29265 this.options[i] = options[i]; 29266 } 29267 29268 // Normalize options 29269 this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : ''; 29270 29271 this.options.useTransition = utils.hasTransition && this.options.useTransition; 29272 this.options.useTransform = utils.hasTransform && this.options.useTransform; 29273 29274 this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; 29275 this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; 29276 29277 // If you want eventPassthrough I have to lock one of the axes 29278 this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; 29279 this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; 29280 29281 // With eventPassthrough we also need lockDirection mechanism 29282 this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; 29283 this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; 29284 29285 this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; 29286 29287 this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; 29288 29289 if ( this.options.tap === true ) {
vendor: 4,893 bytes, lines 29290-29461
29290 this.options.tap = 'tap'; 29291 } 29292 29293 // https://github.com/cubiq/iscroll/issues/1029 29294 if (!this.options.useTransition && !this.options.useTransform) { 29295 if(!(/relative|absolute/i).test(this.scrollerStyle.position)) { 29296 this.scrollerStyle.position = "relative"; 29297 } 29298 } 29299 29300 if ( this.options.shrinkScrollbars == 'scale' ) { 29301 this.options.useTransition = false; 29302 } 29303 29304 this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; 29305 29306// INSERT POINT: NORMALIZATION 29307 29308 // Some defaults 29309 this.x = 0; 29310 this.y = 0; 29311 this.directionX = 0; 29312 this.directionY = 0; 29313 this._events = {}; 29314 29315// INSERT POINT: DEFAULTS 29316 29317 this._init(); 29318 this.refresh(); 29319 29320 this.scrollTo(this.options.startX, this.options.startY); 29321 this.enable(); 29322} 29323 29324IScroll.prototype = { 29325 version: '5.2.0', 29326 29327 _init: function () { 29328 this._initEvents(); 29329 29330 if ( this.options.scrollbars || this.options.indicators ) { 29331 this._initIndicators(); 29332 } 29333 29334 if ( this.options.mouseWheel ) { 29335 this._initWheel(); 29336 } 29337 29338 if ( this.options.snap ) { 29339 this._initSnap(); 29340 } 29341 29342 if ( this.options.keyBindings ) { 29343 this._initKeys(); 29344 } 29345 29346// INSERT POINT: _init 29347 29348 }, 29349 29350 destroy: function () { 29351 this._initEvents(true); 29352 clearTimeout(this.resizeTimeout); 29353 this.resizeTimeout = null; 29354 this._execEvent('destroy'); 29355 }, 29356 29357 _transitionEnd: function (e) { 29358 if ( e.target != this.scroller || !this.isInTransition ) { 29359 return; 29360 } 29361 29362 this._transitionTime(); 29363 if ( !this.resetPosition(this.options.bounceTime) ) { 29364 this.isInTransition = false; 29365 this._execEvent('scrollEnd'); 29366 } 29367 }, 29368 29369 _start: function (e) { 29370 // React to left mouse button only 29371 if ( utils.eventType[e.type] != 1 ) { 29372 // for button property 29373 // http://unixpapa.com/js/mouse.html 29374 var button; 29375 if (!e.which) { 29376 /* IE case */ 29377 button = (e.button < 2) ? 0 : 29378 ((e.button == 4) ? 1 : 2); 29379 } else { 29380 /* All others */ 29381 button = e.button; 29382 } 29383 if ( button !== 0 ) { 29384 return; 29385 } 29386 } 29387 29388 if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { 29389 return; 29390 } 29391 29392 if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29393 e.preventDefault(); 29394 } 29395 29396 var point = e.touches ? e.touches[0] : e, 29397 pos; 29398 29399 this.initiated = utils.eventType[e.type]; 29400 this.moved = false; 29401 this.distX = 0; 29402 this.distY = 0; 29403 this.directionX = 0; 29404 this.directionY = 0; 29405 this.directionLocked = 0; 29406 29407 this.startTime = utils.getTime(); 29408 29409 if ( this.options.useTransition && this.isInTransition ) { 29410 this._transitionTime(); 29411 this.isInTransition = false; 29412 pos = this.getComputedPosition(); 29413 this._translate(Math.round(pos.x), Math.round(pos.y)); 29414 this._execEvent('scrollEnd'); 29415 } else if ( !this.options.useTransition && this.isAnimating ) { 29416 this.isAnimating = false; 29417 this._execEvent('scrollEnd'); 29418 } 29419 29420 this.startX = this.x; 29421 this.startY = this.y; 29422 this.absStartX = this.x; 29423 this.absStartY = this.y; 29424 this.pointX = point.pageX; 29425 this.pointY = point.pageY; 29426 29427 this._execEvent('beforeScrollStart'); 29428 }, 29429 29430 _move: function (e) { 29431 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29432 return; 29433 } 29434 29435 if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! 29436 e.preventDefault(); 29437 } 29438 29439 var point = e.touches ? e.touches[0] : e, 29440 deltaX = point.pageX - this.pointX, 29441 deltaY = point.pageY - this.pointY, 29442 timestamp = utils.getTime(), 29443 newX, newY, 29444 absDistX, absDistY; 29445 29446 this.pointX = point.pageX; 29447 this.pointY = point.pageY; 29448 29449 this.distX += deltaX; 29450 this.distY += deltaY; 29451 absDistX = Math.abs(this.distX); 29452 absDistY = Math.abs(this.distY); 29453 29454 // We need to move at least 10 pixels for the scrolling to initiate 29455 if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { 29456 return; 29457 } 29458 29459 // If you are scrolling in one direction lock the other 29460 if ( !this.directionLocked && !this.options.freeScroll ) { 29461 if ( absDistX > absDistY + this.options.directionLockThreshold ) {
vendor: 6,057 bytes, lines 29462-29648
29462 this.directionLocked = 'h'; // lock horizontally 29463 } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { 29464 this.directionLocked = 'v'; // lock vertically 29465 } else { 29466 this.directionLocked = 'n'; // no lock 29467 } 29468 } 29469 29470 if ( this.directionLocked == 'h' ) { 29471 if ( this.options.eventPassthrough == 'vertical' ) { 29472 e.preventDefault(); 29473 } else if ( this.options.eventPassthrough == 'horizontal' ) { 29474 this.initiated = false; 29475 return; 29476 } 29477 29478 deltaY = 0; 29479 } else if ( this.directionLocked == 'v' ) { 29480 if ( this.options.eventPassthrough == 'horizontal' ) { 29481 e.preventDefault(); 29482 } else if ( this.options.eventPassthrough == 'vertical' ) { 29483 this.initiated = false; 29484 return; 29485 } 29486 29487 deltaX = 0; 29488 } 29489 29490 deltaX = this.hasHorizontalScroll ? deltaX : 0; 29491 deltaY = this.hasVerticalScroll ? deltaY : 0; 29492 29493 newX = this.x + deltaX; 29494 newY = this.y + deltaY; 29495 29496 // Slow down if outside of the boundaries 29497 if ( newX > 0 || newX < this.maxScrollX ) { 29498 newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; 29499 } 29500 if ( newY > 0 || newY < this.maxScrollY ) { 29501 newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; 29502 } 29503 29504 this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; 29505 this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; 29506 29507 if ( !this.moved ) { 29508 this._execEvent('scrollStart'); 29509 } 29510 29511 this.moved = true; 29512 29513 this._translate(newX, newY); 29514 29515/* REPLACE START: _move */ 29516 29517 if ( timestamp - this.startTime > 300 ) { 29518 this.startTime = timestamp; 29519 this.startX = this.x; 29520 this.startY = this.y; 29521 } 29522 29523/* REPLACE END: _move */ 29524 29525 }, 29526 29527 _end: function (e) { 29528 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29529 return; 29530 } 29531 29532 if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29533 e.preventDefault(); 29534 } 29535 29536 var point = e.changedTouches ? e.changedTouches[0] : e, 29537 momentumX, 29538 momentumY, 29539 duration = utils.getTime() - this.startTime, 29540 newX = Math.round(this.x), 29541 newY = Math.round(this.y), 29542 distanceX = Math.abs(newX - this.startX), 29543 distanceY = Math.abs(newY - this.startY), 29544 time = 0, 29545 easing = ''; 29546 29547 this.isInTransition = 0; 29548 this.initiated = 0; 29549 this.endTime = utils.getTime(); 29550 29551 // reset if we are outside of the boundaries 29552 if ( this.resetPosition(this.options.bounceTime) ) { 29553 return; 29554 } 29555 29556 this.scrollTo(newX, newY); // ensures that the last position is rounded 29557 29558 // we scrolled less than 10 pixels 29559 if ( !this.moved ) { 29560 if ( this.options.tap ) { 29561 utils.tap(e, this.options.tap); 29562 } 29563 29564 if ( this.options.click ) { 29565 utils.click(e); 29566 } 29567 29568 this._execEvent('scrollCancel'); 29569 return; 29570 } 29571 29572 if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) { 29573 this._execEvent('flick'); 29574 return; 29575 } 29576 29577 // start momentum animation if needed 29578 if ( this.options.momentum && duration < 300 ) { 29579 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 }; 29580 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 }; 29581 newX = momentumX.destination; 29582 newY = momentumY.destination; 29583 time = Math.max(momentumX.duration, momentumY.duration); 29584 this.isInTransition = 1; 29585 } 29586 29587 29588 if ( this.options.snap ) { 29589 var snap = this._nearestSnap(newX, newY); 29590 this.currentPage = snap; 29591 time = this.options.snapSpeed || Math.max( 29592 Math.max( 29593 Math.min(Math.abs(newX - snap.x), 1000), 29594 Math.min(Math.abs(newY - snap.y), 1000) 29595 ), 300); 29596 newX = snap.x; 29597 newY = snap.y; 29598 29599 this.directionX = 0; 29600 this.directionY = 0; 29601 easing = this.options.bounceEasing; 29602 } 29603 29604// INSERT POINT: _end 29605 29606 if ( newX != this.x || newY != this.y ) { 29607 // change easing function when scroller goes out of the boundaries 29608 if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { 29609 easing = utils.ease.quadratic; 29610 } 29611 29612 this.scrollTo(newX, newY, time, easing); 29613 return; 29614 } 29615 29616 this._execEvent('scrollEnd'); 29617 }, 29618 29619 _resize: function () { 29620 var that = this; 29621 29622 clearTimeout(this.resizeTimeout); 29623 29624 this.resizeTimeout = setTimeout(function () { 29625 that.refresh(); 29626 }, this.options.resizePolling); 29627 }, 29628 29629 resetPosition: function (time) { 29630 var x = this.x, 29631 y = this.y; 29632 29633 time = time || 0; 29634 29635 if ( !this.hasHorizontalScroll || this.x > 0 ) { 29636 x = 0; 29637 } else if ( this.x < this.maxScrollX ) { 29638 x = this.maxScrollX; 29639 } 29640 29641 if ( !this.hasVerticalScroll || this.y > 0 ) { 29642 y = 0; 29643 } else if ( this.y < this.maxScrollY ) { 29644 y = this.maxScrollY; 29645 } 29646 29647 if ( x == this.x && y == this.y ) { 29648 return false;
vendor: 5,509 bytes, lines 29649-29853
29649 } 29650 29651 this.scrollTo(x, y, time, this.options.bounceEasing); 29652 29653 return true; 29654 }, 29655 29656 disable: function () { 29657 this.enabled = false; 29658 }, 29659 29660 enable: function () { 29661 this.enabled = true; 29662 }, 29663 29664 refresh: function () { 29665 var rf = this.wrapper.offsetHeight; // Force reflow 29666 29667 this.wrapperWidth = this.wrapper.clientWidth; 29668 this.wrapperHeight = this.wrapper.clientHeight; 29669 29670/* REPLACE START: refresh */ 29671 29672 this.scrollerWidth = this.scroller.offsetWidth; 29673 this.scrollerHeight = this.scroller.offsetHeight; 29674 29675 this.maxScrollX = this.wrapperWidth - this.scrollerWidth; 29676 this.maxScrollY = this.wrapperHeight - this.scrollerHeight; 29677 29678/* REPLACE END: refresh */ 29679 29680 this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; 29681 this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; 29682 29683 if ( !this.hasHorizontalScroll ) { 29684 this.maxScrollX = 0; 29685 this.scrollerWidth = this.wrapperWidth; 29686 } 29687 29688 if ( !this.hasVerticalScroll ) { 29689 this.maxScrollY = 0; 29690 this.scrollerHeight = this.wrapperHeight; 29691 } 29692 29693 this.endTime = 0; 29694 this.directionX = 0; 29695 this.directionY = 0; 29696 29697 this.wrapperOffset = utils.offset(this.wrapper); 29698 29699 this._execEvent('refresh'); 29700 29701 this.resetPosition(); 29702 29703// INSERT POINT: _refresh 29704 29705 }, 29706 29707 29708 on: function (type, fn) { 29709 if ( !this._events[type] ) { 29710 this._events[type] = []; 29711 } 29712 29713 this._events[type].push(fn); 29714 }, 29715 29716 off: function (type, fn) { 29717 if ( !this._events[type] ) { 29718 return; 29719 } 29720 29721 var index = this._events[type].indexOf(fn); 29722 29723 if ( index > -1 ) { 29724 this._events[type].splice(index, 1); 29725 } 29726 }, 29727 29728 _execEvent: function (type) { 29729 if ( !this._events[type] ) { 29730 return; 29731 } 29732 29733 var i = 0, 29734 l = this._events[type].length; 29735 29736 if ( !l ) { 29737 return; 29738 } 29739 29740 for ( ; i < l; i++ ) { 29741 this._events[type][i].apply(this, [].slice.call(arguments, 1)); 29742 } 29743 }, 29744 29745 scrollBy: function (x, y, time, easing) { 29746 x = this.x + x; 29747 y = this.y + y; 29748 time = time || 0; 29749 29750 this.scrollTo(x, y, time, easing); 29751 }, 29752 29753 scrollTo: function (x, y, time, easing) { 29754 easing = easing || utils.ease.circular; 29755 29756 this.isInTransition = this.options.useTransition && time > 0; 29757 var transitionType = this.options.useTransition && easing.style; 29758 if ( !time || transitionType ) { 29759 if(transitionType) { 29760 this._transitionTimingFunction(easing.style); 29761 this._transitionTime(time); 29762 } 29763 this._translate(x, y); 29764 } else { 29765 this._animate(x, y, time, easing.fn); 29766 } 29767 }, 29768 29769 scrollToElement: function (el, time, offsetX, offsetY, easing) { 29770 el = el.nodeType ? el : this.scroller.querySelector(el); 29771 29772 if ( !el ) { 29773 return; 29774 } 29775 29776 var pos = utils.offset(el); 29777 29778 pos.left -= this.wrapperOffset.left; 29779 pos.top -= this.wrapperOffset.top; 29780 29781 // if offsetX/Y are true we center the element to the screen 29782 if ( offsetX === true ) { 29783 offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); 29784 } 29785 if ( offsetY === true ) { 29786 offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); 29787 } 29788 29789 pos.left -= offsetX || 0; 29790 pos.top -= offsetY || 0; 29791 29792 pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; 29793 pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; 29794 29795 time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; 29796 29797 this.scrollTo(pos.left, pos.top, time, easing); 29798 }, 29799 29800 _transitionTime: function (time) { 29801 if (!this.options.useTransition) { 29802 return; 29803 } 29804 time = time || 0; 29805 var durationProp = utils.style.transitionDuration; 29806 if(!durationProp) { 29807 return; 29808 } 29809 29810 this.scrollerStyle[durationProp] = time + 'ms'; 29811 29812 if ( !time && utils.isBadAndroid ) { 29813 this.scrollerStyle[durationProp] = '0.0001ms'; 29814 // remove 0.0001ms 29815 var self = this; 29816 rAF(function() { 29817 if(self.scrollerStyle[durationProp] === '0.0001ms') { 29818 self.scrollerStyle[durationProp] = '0s'; 29819 } 29820 }); 29821 } 29822 29823 29824 if ( this.indicators ) { 29825 for ( var i = this.indicators.length; i--; ) { 29826 this.indicators[i].transitionTime(time); 29827 } 29828 } 29829 29830 29831// INSERT POINT: _transitionTime 29832 29833 }, 29834 29835 _transitionTimingFunction: function (easing) { 29836 this.scrollerStyle[utils.style.transitionTimingFunction] = easing; 29837 29838 29839 if ( this.indicators ) { 29840 for ( var i = this.indicators.length; i--; ) { 29841 this.indicators[i].transitionTimingFunction(easing); 29842 } 29843 } 29844 29845 29846// INSERT POINT: _transitionTimingFunction 29847 29848 }, 29849 29850 _translate: function (x, y) { 29851 //Uncode addition 29852 if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 ) 29853 return false;
vendor: 9,939 bytes, lines 29854-30165
29854 29855 if ( this.options.useTransform ) { 29856 29857/* REPLACE START: _translate */ 29858 29859 this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ; 29860 29861/* REPLACE END: _translate */ 29862 29863 } else { 29864 x = Math.round(x); 29865 y = Math.round(y); 29866 this.scrollerStyle.left = x + 'px'; 29867 this.scrollerStyle.top = y + 'px'; 29868 } 29869 29870 this.x = x; 29871 this.y = y; 29872 29873 29874 if ( this.indicators ) { 29875 for ( var i = this.indicators.length; i--; ) { 29876 this.indicators[i].updatePosition(); 29877 } 29878 } 29879 29880 //Uncode addition 29881 var uncodevent = new CustomEvent('fp-slide-scroll'); 29882 window.dispatchEvent(uncodevent); 29883 29884// INSERT POINT: _translate 29885 29886 }, 29887 29888 _initEvents: function (remove) { 29889 var eventType = remove ? utils.removeEvent : utils.addEvent, 29890 target = this.options.bindToWrapper ? this.wrapper : window; 29891 29892 eventType(window, 'orientationchange', this); 29893 eventType(window, 'resize', this); 29894 29895 if ( this.options.click ) { 29896 eventType(this.wrapper, 'click', this, true); 29897 } 29898 29899 if ( !this.options.disableMouse ) { 29900 eventType(this.wrapper, 'mousedown', this); 29901 eventType(target, 'mousemove', this); 29902 eventType(target, 'mousecancel', this); 29903 eventType(target, 'mouseup', this); 29904 } 29905 29906 if ( utils.hasPointer && !this.options.disablePointer ) { 29907 eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); 29908 eventType(target, utils.prefixPointerEvent('pointermove'), this); 29909 eventType(target, utils.prefixPointerEvent('pointercancel'), this); 29910 eventType(target, utils.prefixPointerEvent('pointerup'), this); 29911 } 29912 29913 if ( utils.hasTouch && !this.options.disableTouch ) { 29914 eventType(this.wrapper, 'touchstart', this); 29915 eventType(target, 'touchmove', this); 29916 eventType(target, 'touchcancel', this); 29917 eventType(target, 'touchend', this); 29918 } 29919 29920 eventType(this.scroller, 'transitionend', this); 29921 eventType(this.scroller, 'webkitTransitionEnd', this); 29922 eventType(this.scroller, 'oTransitionEnd', this); 29923 eventType(this.scroller, 'MSTransitionEnd', this); 29924 }, 29925 29926 getComputedPosition: function () { 29927 var matrix = window.getComputedStyle(this.scroller, null), 29928 x, y; 29929 29930 if ( this.options.useTransform ) { 29931 matrix = matrix[utils.style.transform].split(')')[0].split(', '); 29932 x = +(matrix[12] || matrix[4]); 29933 y = +(matrix[13] || matrix[5]); 29934 } else { 29935 x = +matrix.left.replace(/[^-\d.]/g, ''); 29936 y = +matrix.top.replace(/[^-\d.]/g, ''); 29937 } 29938 29939 return { x: x, y: y }; 29940 }, 29941 _initIndicators: function () { 29942 var interactive = this.options.interactiveScrollbars, 29943 customStyle = typeof this.options.scrollbars != 'string', 29944 indicators = [], 29945 indicator; 29946 29947 var that = this; 29948 29949 this.indicators = []; 29950 29951 if ( this.options.scrollbars ) { 29952 // Vertical scrollbar 29953 if ( this.options.scrollY ) { 29954 indicator = { 29955 el: createDefaultScrollbar('v', interactive, this.options.scrollbars), 29956 interactive: interactive, 29957 defaultScrollbars: true, 29958 customStyle: customStyle, 29959 resize: this.options.resizeScrollbars, 29960 shrink: this.options.shrinkScrollbars, 29961 fade: this.options.fadeScrollbars, 29962 listenX: false 29963 }; 29964 29965 this.wrapper.appendChild(indicator.el); 29966 indicators.push(indicator); 29967 } 29968 29969 // Horizontal scrollbar 29970 if ( this.options.scrollX ) { 29971 indicator = { 29972 el: createDefaultScrollbar('h', interactive, this.options.scrollbars), 29973 interactive: interactive, 29974 defaultScrollbars: true, 29975 customStyle: customStyle, 29976 resize: this.options.resizeScrollbars, 29977 shrink: this.options.shrinkScrollbars, 29978 fade: this.options.fadeScrollbars, 29979 listenY: false 29980 }; 29981 29982 this.wrapper.appendChild(indicator.el); 29983 indicators.push(indicator); 29984 } 29985 } 29986 29987 if ( this.options.indicators ) { 29988 // TODO: check concat compatibility 29989 indicators = indicators.concat(this.options.indicators); 29990 } 29991 29992 for ( var i = indicators.length; i--; ) { 29993 this.indicators.push( new Indicator(this, indicators[i]) ); 29994 } 29995 29996 // TODO: check if we can use array.map (wide compatibility and performance issues) 29997 function _indicatorsMap (fn) { 29998 if (that.indicators) { 29999 for ( var i = that.indicators.length; i--; ) { 30000 fn.call(that.indicators[i]); 30001 } 30002 } 30003 } 30004 30005 if ( this.options.fadeScrollbars ) { 30006 this.on('scrollEnd', function () { 30007 _indicatorsMap(function () { 30008 this.fade(); 30009 }); 30010 }); 30011 30012 this.on('scrollCancel', function () { 30013 _indicatorsMap(function () { 30014 this.fade(); 30015 }); 30016 }); 30017 30018 this.on('scrollStart', function () { 30019 _indicatorsMap(function () { 30020 this.fade(1); 30021 }); 30022 }); 30023 30024 this.on('beforeScrollStart', function () { 30025 _indicatorsMap(function () { 30026 this.fade(1, true); 30027 }); 30028 }); 30029 } 30030 30031 30032 this.on('refresh', function () { 30033 _indicatorsMap(function () { 30034 this.refresh(); 30035 }); 30036 }); 30037 30038 this.on('destroy', function () { 30039 _indicatorsMap(function () { 30040 this.destroy(); 30041 }); 30042 30043 delete this.indicators; 30044 }); 30045 }, 30046 30047 _initWheel: function () { 30048 utils.addEvent(this.wrapper, 'wheel', this); 30049 utils.addEvent(this.wrapper, 'mousewheel', this); 30050 utils.addEvent(this.wrapper, 'DOMMouseScroll', this); 30051 30052 this.on('destroy', function () { 30053 clearTimeout(this.wheelTimeout); 30054 this.wheelTimeout = null; 30055 utils.removeEvent(this.wrapper, 'wheel', this); 30056 utils.removeEvent(this.wrapper, 'mousewheel', this); 30057 utils.removeEvent(this.wrapper, 'DOMMouseScroll', this); 30058 }); 30059 }, 30060 30061 _wheel: function (e) { 30062 if ( !this.enabled ) { 30063 return; 30064 } 30065 30066 var wheelDeltaX, wheelDeltaY, 30067 newX, newY, 30068 that = this; 30069 30070 if ( this.wheelTimeout === undefined ) { 30071 that._execEvent('scrollStart'); 30072 } 30073 30074 // Execute the scrollEnd event after 400ms the wheel stopped scrolling 30075 clearTimeout(this.wheelTimeout); 30076 this.wheelTimeout = setTimeout(function () { 30077 if(!that.options.snap) { 30078 that._execEvent('scrollEnd'); 30079 } 30080 that.wheelTimeout = undefined; 30081 }, 400); 30082 30083 if ( 'deltaX' in e ) { 30084 if (e.deltaMode === 1) { 30085 wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed; 30086 wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed; 30087 } else { 30088 wheelDeltaX = -e.deltaX; 30089 wheelDeltaY = -e.deltaY; 30090 } 30091 } else if ( 'wheelDeltaX' in e ) { 30092 wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed; 30093 wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed; 30094 } else if ( 'wheelDelta' in e ) { 30095 wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed; 30096 } else if ( 'detail' in e ) { 30097 wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed; 30098 } else { 30099 return; 30100 } 30101 30102 wheelDeltaX *= this.options.invertWheelDirection; 30103 wheelDeltaY *= this.options.invertWheelDirection; 30104 30105 if ( !this.hasVerticalScroll ) { 30106 wheelDeltaX = wheelDeltaY; 30107 wheelDeltaY = 0; 30108 } 30109 30110 if ( this.options.snap ) { 30111 newX = this.currentPage.pageX; 30112 newY = this.currentPage.pageY; 30113 30114 if ( wheelDeltaX > 0 ) { 30115 newX--; 30116 } else if ( wheelDeltaX < 0 ) { 30117 newX++; 30118 } 30119 30120 if ( wheelDeltaY > 0 ) { 30121 newY--; 30122 } else if ( wheelDeltaY < 0 ) { 30123 newY++; 30124 } 30125 30126 this.goToPage(newX, newY); 30127 30128 return; 30129 } 30130 30131 newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0); 30132 newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0); 30133 30134 this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0; 30135 this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0; 30136 30137 if ( newX > 0 ) { 30138 newX = 0; 30139 } else if ( newX < this.maxScrollX ) { 30140 newX = this.maxScrollX; 30141 } 30142 30143 if ( newY > 0 ) { 30144 newY = 0; 30145 } else if ( newY < this.maxScrollY ) { 30146 newY = this.maxScrollY; 30147 } 30148 30149 this.scrollTo(newX, newY, 0); 30150 30151// INSERT POINT: _wheel 30152 }, 30153 30154 _initSnap: function () { 30155 this.currentPage = {}; 30156 30157 if ( typeof this.options.snap == 'string' ) { 30158 this.options.snap = this.scroller.querySelectorAll(this.options.snap); 30159 } 30160 30161 this.on('refresh', function () { 30162 var i = 0, l, 30163 m = 0, n, 30164 cx, cy, 30165 x = 0, y,
vendor: 7,339 bytes, lines 30166-30419
30166 stepX = this.options.snapStepX || this.wrapperWidth, 30167 stepY = this.options.snapStepY || this.wrapperHeight, 30168 el; 30169 30170 this.pages = []; 30171 30172 if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) { 30173 return; 30174 } 30175 30176 if ( this.options.snap === true ) { 30177 cx = Math.round( stepX / 2 ); 30178 cy = Math.round( stepY / 2 ); 30179 30180 while ( x > -this.scrollerWidth ) { 30181 this.pages[i] = []; 30182 l = 0; 30183 y = 0; 30184 30185 while ( y > -this.scrollerHeight ) { 30186 this.pages[i][l] = { 30187 x: Math.max(x, this.maxScrollX), 30188 y: Math.max(y, this.maxScrollY), 30189 width: stepX, 30190 height: stepY, 30191 cx: x - cx, 30192 cy: y - cy 30193 }; 30194 30195 y -= stepY; 30196 l++; 30197 } 30198 30199 x -= stepX; 30200 i++; 30201 } 30202 } else { 30203 el = this.options.snap; 30204 l = el.length; 30205 n = -1; 30206 30207 for ( ; i < l; i++ ) { 30208 if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) { 30209 m = 0; 30210 n++; 30211 } 30212 30213 if ( !this.pages[m] ) { 30214 this.pages[m] = []; 30215 } 30216 30217 x = Math.max(-el[i].offsetLeft, this.maxScrollX); 30218 y = Math.max(-el[i].offsetTop, this.maxScrollY); 30219 cx = x - Math.round(el[i].offsetWidth / 2); 30220 cy = y - Math.round(el[i].offsetHeight / 2); 30221 30222 this.pages[m][n] = { 30223 x: x, 30224 y: y, 30225 width: el[i].offsetWidth, 30226 height: el[i].offsetHeight, 30227 cx: cx, 30228 cy: cy 30229 }; 30230 30231 if ( x > this.maxScrollX ) { 30232 m++; 30233 } 30234 } 30235 } 30236 30237 this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0); 30238 30239 // Update snap threshold if needed 30240 if ( this.options.snapThreshold % 1 === 0 ) { 30241 this.snapThresholdX = this.options.snapThreshold; 30242 this.snapThresholdY = this.options.snapThreshold; 30243 } else { 30244 this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold); 30245 this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold); 30246 } 30247 }); 30248 30249 this.on('flick', function () { 30250 var time = this.options.snapSpeed || Math.max( 30251 Math.max( 30252 Math.min(Math.abs(this.x - this.startX), 1000), 30253 Math.min(Math.abs(this.y - this.startY), 1000) 30254 ), 300); 30255 30256 this.goToPage( 30257 this.currentPage.pageX + this.directionX, 30258 this.currentPage.pageY + this.directionY, 30259 time 30260 ); 30261 }); 30262 }, 30263 30264 _nearestSnap: function (x, y) { 30265 if ( !this.pages.length ) { 30266 return { x: 0, y: 0, pageX: 0, pageY: 0 }; 30267 } 30268 30269 var i = 0, 30270 l = this.pages.length, 30271 m = 0; 30272 30273 // Check if we exceeded the snap threshold 30274 if ( Math.abs(x - this.absStartX) < this.snapThresholdX && 30275 Math.abs(y - this.absStartY) < this.snapThresholdY ) { 30276 return this.currentPage; 30277 } 30278 30279 if ( x > 0 ) { 30280 x = 0; 30281 } else if ( x < this.maxScrollX ) { 30282 x = this.maxScrollX; 30283 } 30284 30285 if ( y > 0 ) { 30286 y = 0; 30287 } else if ( y < this.maxScrollY ) { 30288 y = this.maxScrollY; 30289 } 30290 30291 for ( ; i < l; i++ ) { 30292 if ( x >= this.pages[i][0].cx ) { 30293 x = this.pages[i][0].x; 30294 break; 30295 } 30296 } 30297 30298 l = this.pages[i].length; 30299 30300 for ( ; m < l; m++ ) { 30301 if ( y >= this.pages[0][m].cy ) { 30302 y = this.pages[0][m].y; 30303 break; 30304 } 30305 } 30306 30307 if ( i == this.currentPage.pageX ) { 30308 i += this.directionX; 30309 30310 if ( i < 0 ) { 30311 i = 0; 30312 } else if ( i >= this.pages.length ) { 30313 i = this.pages.length - 1; 30314 } 30315 30316 x = this.pages[i][0].x; 30317 } 30318 30319 if ( m == this.currentPage.pageY ) { 30320 m += this.directionY; 30321 30322 if ( m < 0 ) { 30323 m = 0; 30324 } else if ( m >= this.pages[0].length ) { 30325 m = this.pages[0].length - 1; 30326 } 30327 30328 y = this.pages[0][m].y; 30329 } 30330 30331 return { 30332 x: x, 30333 y: y, 30334 pageX: i, 30335 pageY: m 30336 }; 30337 }, 30338 30339 goToPage: function (x, y, time, easing) { 30340 easing = easing || this.options.bounceEasing; 30341 30342 if ( x >= this.pages.length ) { 30343 x = this.pages.length - 1; 30344 } else if ( x < 0 ) { 30345 x = 0; 30346 } 30347 30348 if ( y >= this.pages[x].length ) { 30349 y = this.pages[x].length - 1; 30350 } else if ( y < 0 ) { 30351 y = 0; 30352 } 30353 30354 var posX = this.pages[x][y].x, 30355 posY = this.pages[x][y].y; 30356 30357 time = time === undefined ? this.options.snapSpeed || Math.max( 30358 Math.max( 30359 Math.min(Math.abs(posX - this.x), 1000), 30360 Math.min(Math.abs(posY - this.y), 1000) 30361 ), 300) : time; 30362 30363 this.currentPage = { 30364 x: posX, 30365 y: posY, 30366 pageX: x, 30367 pageY: y 30368 }; 30369 30370 this.scrollTo(posX, posY, time, easing); 30371 }, 30372 30373 next: function (time, easing) { 30374 var x = this.currentPage.pageX, 30375 y = this.currentPage.pageY; 30376 30377 x++; 30378 30379 if ( x >= this.pages.length && this.hasVerticalScroll ) { 30380 x = 0; 30381 y++; 30382 } 30383 30384 this.goToPage(x, y, time, easing); 30385 }, 30386 30387 prev: function (time, easing) { 30388 var x = this.currentPage.pageX, 30389 y = this.currentPage.pageY; 30390 30391 x--; 30392 30393 if ( x < 0 && this.hasVerticalScroll ) { 30394 x = 0; 30395 y--; 30396 } 30397 30398 this.goToPage(x, y, time, easing); 30399 }, 30400 30401 _initKeys: function (e) { 30402 // default key bindings 30403 var keys = { 30404 pageUp: 33, 30405 pageDown: 34, 30406 end: 35, 30407 home: 36, 30408 left: 37, 30409 up: 38, 30410 right: 39, 30411 down: 40 30412 }; 30413 var i; 30414 30415 // if you give me characters I give you keycode 30416 if ( typeof this.options.keyBindings == 'object' ) { 30417 for ( i in this.options.keyBindings ) { 30418 if ( typeof this.options.keyBindings[i] == 'string' ) { 30419 this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
vendor: 11,097 bytes, lines 30419-30772
30419deAt(0); 30420 } 30421 } 30422 } else { 30423 this.options.keyBindings = {}; 30424 } 30425 30426 for ( i in keys ) { 30427 this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i]; 30428 } 30429 30430 utils.addEvent(window, 'keydown', this); 30431 30432 this.on('destroy', function () { 30433 utils.removeEvent(window, 'keydown', this); 30434 }); 30435 }, 30436 30437 _key: function (e) { 30438 if ( !this.enabled ) { 30439 return; 30440 } 30441 30442 var snap = this.options.snap, // we are using this alot, better to cache it 30443 newX = snap ? this.currentPage.pageX : this.x, 30444 newY = snap ? this.currentPage.pageY : this.y, 30445 now = utils.getTime(), 30446 prevTime = this.keyTime || 0, 30447 acceleration = 0.250, 30448 pos; 30449 30450 if ( this.options.useTransition && this.isInTransition ) { 30451 pos = this.getComputedPosition(); 30452 30453 this._translate(Math.round(pos.x), Math.round(pos.y)); 30454 this.isInTransition = false; 30455 } 30456 30457 this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0; 30458 30459 switch ( e.keyCode ) { 30460 case this.options.keyBindings.pageUp: 30461 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30462 newX += snap ? 1 : this.wrapperWidth; 30463 } else { 30464 newY += snap ? 1 : this.wrapperHeight; 30465 } 30466 break; 30467 case this.options.keyBindings.pageDown: 30468 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30469 newX -= snap ? 1 : this.wrapperWidth; 30470 } else { 30471 newY -= snap ? 1 : this.wrapperHeight; 30472 } 30473 break; 30474 case this.options.keyBindings.end: 30475 newX = snap ? this.pages.length-1 : this.maxScrollX; 30476 newY = snap ? this.pages[0].length-1 : this.maxScrollY; 30477 break; 30478 case this.options.keyBindings.home: 30479 newX = 0; 30480 newY = 0; 30481 break; 30482 case this.options.keyBindings.left: 30483 newX += snap ? -1 : 5 + this.keyAcceleration>>0; 30484 break; 30485 case this.options.keyBindings.up: 30486 newY += snap ? 1 : 5 + this.keyAcceleration>>0; 30487 break; 30488 case this.options.keyBindings.right: 30489 newX -= snap ? -1 : 5 + this.keyAcceleration>>0; 30490 break; 30491 case this.options.keyBindings.down: 30492 newY -= snap ? 1 : 5 + this.keyAcceleration>>0; 30493 break; 30494 default: 30495 return; 30496 } 30497 30498 if ( snap ) { 30499 this.goToPage(newX, newY); 30500 return; 30501 } 30502 30503 if ( newX > 0 ) { 30504 newX = 0; 30505 this.keyAcceleration = 0; 30506 } else if ( newX < this.maxScrollX ) { 30507 newX = this.maxScrollX; 30508 this.keyAcceleration = 0; 30509 } 30510 30511 if ( newY > 0 ) { 30512 newY = 0; 30513 this.keyAcceleration = 0; 30514 } else if ( newY < this.maxScrollY ) { 30515 newY = this.maxScrollY; 30516 this.keyAcceleration = 0; 30517 } 30518 30519 this.scrollTo(newX, newY, 0); 30520 30521 this.keyTime = now; 30522 }, 30523 30524 _animate: function (destX, destY, duration, easingFn) { 30525 var that = this, 30526 startX = this.x, 30527 startY = this.y, 30528 startTime = utils.getTime(), 30529 destTime = startTime + duration; 30530 30531 function step () { 30532 var now = utils.getTime(), 30533 newX, newY, 30534 easing; 30535 30536 if ( now >= destTime ) { 30537 that.isAnimating = false; 30538 that._translate(destX, destY); 30539 30540 if ( !that.resetPosition(that.options.bounceTime) ) { 30541 that._execEvent('scrollEnd'); 30542 } 30543 30544 return; 30545 } 30546 30547 now = ( now - startTime ) / duration; 30548 easing = easingFn(now); 30549 newX = ( destX - startX ) * easing + startX; 30550 newY = ( destY - startY ) * easing + startY; 30551 that._translate(newX, newY); 30552 30553 if ( that.isAnimating ) { 30554 rAF(step); 30555 } 30556 } 30557 30558 this.isAnimating = true; 30559 step(); 30560 }, 30561 handleEvent: function (e) { 30562 switch ( e.type ) { 30563 case 'touchstart': 30564 case 'pointerdown': 30565 case 'MSPointerDown': 30566 case 'mousedown': 30567 this._start(e); 30568 break; 30569 case 'touchmove': 30570 case 'pointermove': 30571 case 'MSPointerMove': 30572 case 'mousemove': 30573 this._move(e); 30574 break; 30575 case 'touchend': 30576 case 'pointerup': 30577 case 'MSPointerUp': 30578 case 'mouseup': 30579 case 'touchcancel': 30580 case 'pointercancel': 30581 case 'MSPointerCancel': 30582 case 'mousecancel': 30583 this._end(e); 30584 break; 30585 case 'orientationchange': 30586 case 'resize': 30587 this._resize(); 30588 break; 30589 case 'transitionend': 30590 case 'webkitTransitionEnd': 30591 case 'oTransitionEnd': 30592 case 'MSTransitionEnd': 30593 this._transitionEnd(e); 30594 break; 30595 case 'wheel': 30596 case 'DOMMouseScroll': 30597 case 'mousewheel': 30598 this._wheel(e); 30599 break; 30600 case 'keydown': 30601 this._key(e); 30602 break; 30603 case 'click': 30604 if ( this.enabled && !e._constructed ) { 30605 e.preventDefault(); 30606 e.stopPropagation(); 30607 } 30608 break; 30609 } 30610 } 30611}; 30612function createDefaultScrollbar (direction, interactive, type) { 30613 var scrollbar = document.createElement('div'), 30614 indicator = document.createElement('div'); 30615 30616 if ( type === true ) { 30617 scrollbar.style.cssText = 'position:absolute;z-index:9999'; 30618 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'; 30619 } 30620 30621 indicator.className = 'iScrollIndicator'; 30622 30623 if ( direction == 'h' ) { 30624 if ( type === true ) { 30625 scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0'; 30626 indicator.style.height = '100%'; 30627 } 30628 scrollbar.className = 'iScrollHorizontalScrollbar'; 30629 } else { 30630 if ( type === true ) { 30631 scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px'; 30632 indicator.style.width = '100%'; 30633 } 30634 scrollbar.className = 'iScrollVerticalScrollbar'; 30635 } 30636 30637 scrollbar.style.cssText += ';overflow:hidden'; 30638 30639 if ( !interactive ) { 30640 scrollbar.style.pointerEvents = 'none'; 30641 } 30642 30643 scrollbar.appendChild(indicator); 30644 30645 return scrollbar; 30646} 30647 30648function Indicator (scroller, options) { 30649 this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; 30650 this.wrapperStyle = this.wrapper.style; 30651 this.indicator = this.wrapper.children[0]; 30652 this.indicatorStyle = this.indicator.style; 30653 this.scroller = scroller; 30654 30655 this.options = { 30656 listenX: true, 30657 listenY: true, 30658 interactive: false, 30659 resize: true, 30660 defaultScrollbars: false, 30661 shrink: false, 30662 fade: false, 30663 speedRatioX: 0, 30664 speedRatioY: 0 30665 }; 30666 30667 for ( var i in options ) { 30668 this.options[i] = options[i]; 30669 } 30670 30671 this.sizeRatioX = 1; 30672 this.sizeRatioY = 1; 30673 this.maxPosX = 0; 30674 this.maxPosY = 0; 30675 30676 if ( this.options.interactive ) { 30677 if ( !this.options.disableTouch ) { 30678 utils.addEvent(this.indicator, 'touchstart', this); 30679 utils.addEvent(window, 'touchend', this); 30680 } 30681 if ( !this.options.disablePointer ) { 30682 utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30683 utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this); 30684 } 30685 if ( !this.options.disableMouse ) { 30686 utils.addEvent(this.indicator, 'mousedown', this); 30687 utils.addEvent(window, 'mouseup', this); 30688 } 30689 } 30690 30691 if ( this.options.fade ) { 30692 this.wrapperStyle[utils.style.transform] = this.scroller.translateZ; 30693 var durationProp = utils.style.transitionDuration; 30694 if(!durationProp) { 30695 return; 30696 } 30697 this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms'; 30698 // remove 0.0001ms 30699 var self = this; 30700 if(utils.isBadAndroid) { 30701 rAF(function() { 30702 if(self.wrapperStyle[durationProp] === '0.0001ms') { 30703 self.wrapperStyle[durationProp] = '0s'; 30704 } 30705 }); 30706 } 30707 this.wrapperStyle.opacity = '0'; 30708 } 30709} 30710 30711Indicator.prototype = { 30712 handleEvent: function (e) { 30713 switch ( e.type ) { 30714 case 'touchstart': 30715 case 'pointerdown': 30716 case 'MSPointerDown': 30717 case 'mousedown': 30718 this._start(e); 30719 break; 30720 case 'touchmove': 30721 case 'pointermove': 30722 case 'MSPointerMove': 30723 case 'mousemove': 30724 this._move(e); 30725 break; 30726 case 'touchend': 30727 case 'pointerup': 30728 case 'MSPointerUp': 30729 case 'mouseup': 30730 case 'touchcancel': 30731 case 'pointercancel': 30732 case 'MSPointerCancel': 30733 case 'mousecancel': 30734 this._end(e); 30735 break; 30736 } 30737 }, 30738 30739 destroy: function () { 30740 if ( this.options.fadeScrollbars ) { 30741 clearTimeout(this.fadeTimeout); 30742 this.fadeTimeout = null; 30743 } 30744 if ( this.options.interactive ) { 30745 utils.removeEvent(this.indicator, 'touchstart', this); 30746 utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30747 utils.removeEvent(this.indicator, 'mousedown', this); 30748 30749 utils.removeEvent(window, 'touchmove', this); 30750 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30751 utils.removeEvent(window, 'mousemove', this); 30752 30753 utils.removeEvent(window, 'touchend', this); 30754 utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this); 30755 utils.removeEvent(window, 'mouseup', this); 30756 } 30757 30758 if ( this.options.defaultScrollbars ) { 30759 this.wrapper.parentNode.removeChild(this.wrapper); 30760 } 30761 }, 30762 30763 _start: function (e) { 30764 var point = e.touches ? e.touches[0] : e; 30765 30766 e.preventDefault(); 30767 e.stopPropagation(); 30768 30769 this.transitionTime(); 30770 30771 this.initiated = true; 30772 this.moved = false;
vendor: 9,615 bytes, lines 30773-31031
30773 this.lastPointX = point.pageX; 30774 this.lastPointY = point.pageY; 30775 30776 this.startTime = utils.getTime(); 30777 30778 if ( !this.options.disableTouch ) { 30779 utils.addEvent(window, 'touchmove', this); 30780 } 30781 if ( !this.options.disablePointer ) { 30782 utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this); 30783 } 30784 if ( !this.options.disableMouse ) { 30785 utils.addEvent(window, 'mousemove', this); 30786 } 30787 30788 this.scroller._execEvent('beforeScrollStart'); 30789 }, 30790 30791 _move: function (e) { 30792 var point = e.touches ? e.touches[0] : e, 30793 deltaX, deltaY, 30794 newX, newY, 30795 timestamp = utils.getTime(); 30796 30797 if ( !this.moved ) { 30798 this.scroller._execEvent('scrollStart'); 30799 } 30800 30801 this.moved = true; 30802 30803 deltaX = point.pageX - this.lastPointX; 30804 this.lastPointX = point.pageX; 30805 30806 deltaY = point.pageY - this.lastPointY; 30807 this.lastPointY = point.pageY; 30808 30809 newX = this.x + deltaX; 30810 newY = this.y + deltaY; 30811 30812 this._pos(newX, newY); 30813 30814// INSERT POINT: indicator._move 30815 30816 e.preventDefault(); 30817 e.stopPropagation(); 30818 }, 30819 30820 _end: function (e) { 30821 if ( !this.initiated ) { 30822 return; 30823 } 30824 30825 this.initiated = false; 30826 30827 e.preventDefault(); 30828 e.stopPropagation(); 30829 30830 utils.removeEvent(window, 'touchmove', this); 30831 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30832 utils.removeEvent(window, 'mousemove', this); 30833 30834 if ( this.scroller.options.snap ) { 30835 var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); 30836 30837 var time = this.options.snapSpeed || Math.max( 30838 Math.max( 30839 Math.min(Math.abs(this.scroller.x - snap.x), 1000), 30840 Math.min(Math.abs(this.scroller.y - snap.y), 1000) 30841 ), 300); 30842 30843 if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) { 30844 this.scroller.directionX = 0; 30845 this.scroller.directionY = 0; 30846 this.scroller.currentPage = snap; 30847 this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing); 30848 } 30849 } 30850 30851 if ( this.moved ) { 30852 this.scroller._execEvent('scrollEnd'); 30853 } 30854 }, 30855 30856 transitionTime: function (time) { 30857 time = time || 0; 30858 var durationProp = utils.style.transitionDuration; 30859 if(!durationProp) { 30860 return; 30861 } 30862 30863 this.indicatorStyle[durationProp] = time + 'ms'; 30864 30865 if ( !time && utils.isBadAndroid ) { 30866 this.indicatorStyle[durationProp] = '0.0001ms'; 30867 // remove 0.0001ms 30868 var self = this; 30869 rAF(function() { 30870 if(self.indicatorStyle[durationProp] === '0.0001ms') { 30871 self.indicatorStyle[durationProp] = '0s'; 30872 } 30873 }); 30874 } 30875 }, 30876 30877 transitionTimingFunction: function (easing) { 30878 this.indicatorStyle[utils.style.transitionTimingFunction] = easing; 30879 }, 30880 30881 refresh: function () { 30882 this.transitionTime(); 30883 30884 if ( this.options.listenX && !this.options.listenY ) { 30885 this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; 30886 } else if ( this.options.listenY && !this.options.listenX ) { 30887 this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; 30888 } else { 30889 this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; 30890 } 30891 30892 if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) { 30893 utils.addClass(this.wrapper, 'iScrollBothScrollbars'); 30894 utils.removeClass(this.wrapper, 'iScrollLoneScrollbar'); 30895 30896 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30897 if ( this.options.listenX ) { 30898 this.wrapper.style.right = '8px'; 30899 } else { 30900 this.wrapper.style.bottom = '8px'; 30901 } 30902 } 30903 } else { 30904 utils.removeClass(this.wrapper, 'iScrollBothScrollbars'); 30905 utils.addClass(this.wrapper, 'iScrollLoneScrollbar'); 30906 30907 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30908 if ( this.options.listenX ) { 30909 this.wrapper.style.right = '2px'; 30910 } else { 30911 this.wrapper.style.bottom = '2px'; 30912 } 30913 } 30914 } 30915 30916 var r = this.wrapper.offsetHeight; // force refresh 30917 30918 if ( this.options.listenX ) { 30919 this.wrapperWidth = this.wrapper.clientWidth; 30920 if ( this.options.resize ) { 30921 this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); 30922 this.indicatorStyle.width = this.indicatorWidth + 'px'; 30923 } else { 30924 this.indicatorWidth = this.indicator.clientWidth; 30925 } 30926 30927 this.maxPosX = this.wrapperWidth - this.indicatorWidth; 30928 30929 if ( this.options.shrink == 'clip' ) { 30930 this.minBoundaryX = -this.indicatorWidth + 8; 30931 this.maxBoundaryX = this.wrapperWidth - 8; 30932 } else { 30933 this.minBoundaryX = 0; 30934 this.maxBoundaryX = this.maxPosX; 30935 } 30936 30937 this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); 30938 } 30939 30940 if ( this.options.listenY ) { 30941 this.wrapperHeight = this.wrapper.clientHeight; 30942 if ( this.options.resize ) { 30943 this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); 30944 this.indicatorStyle.height = this.indicatorHeight + 'px'; 30945 } else { 30946 this.indicatorHeight = this.indicator.clientHeight; 30947 } 30948 30949 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 30950 30951 if ( this.options.shrink == 'clip' ) { 30952 this.minBoundaryY = -this.indicatorHeight + 8; 30953 this.maxBoundaryY = this.wrapperHeight - 8; 30954 } else { 30955 this.minBoundaryY = 0; 30956 this.maxBoundaryY = this.maxPosY; 30957 } 30958 30959 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 30960 this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); 30961 } 30962 30963 this.updatePosition(); 30964 }, 30965 30966 updatePosition: function () { 30967 var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, 30968 y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; 30969 30970 if ( !this.options.ignoreBoundaries ) { 30971 if ( x < this.minBoundaryX ) { 30972 if ( this.options.shrink == 'scale' ) { 30973 this.width = Math.max(this.indicatorWidth + x, 8); 30974 this.indicatorStyle.width = this.width + 'px'; 30975 } 30976 x = this.minBoundaryX; 30977 } else if ( x > this.maxBoundaryX ) { 30978 if ( this.options.shrink == 'scale' ) { 30979 this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); 30980 this.indicatorStyle.width = this.width + 'px'; 30981 x = this.maxPosX + this.indicatorWidth - this.width; 30982 } else { 30983 x = this.maxBoundaryX; 30984 } 30985 } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) { 30986 this.width = this.indicatorWidth; 30987 this.indicatorStyle.width = this.width + 'px'; 30988 } 30989 30990 if ( y < this.minBoundaryY ) { 30991 if ( this.options.shrink == 'scale' ) { 30992 this.height = Math.max(this.indicatorHeight + y * 3, 8); 30993 this.indicatorStyle.height = this.height + 'px'; 30994 } 30995 y = this.minBoundaryY; 30996 } else if ( y > this.maxBoundaryY ) { 30997 if ( this.options.shrink == 'scale' ) { 30998 this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); 30999 this.indicatorStyle.height = this.height + 'px'; 31000 y = this.maxPosY + this.indicatorHeight - this.height; 31001 } else { 31002 y = this.maxBoundaryY; 31003 } 31004 } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) { 31005 this.height = this.indicatorHeight; 31006 this.indicatorStyle.height = this.height + 'px'; 31007 } 31008 } 31009 31010 this.x = x; 31011 this.y = y; 31012 31013 if ( this.scroller.options.useTransform ) { 31014 this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ; 31015 } else { 31016 this.indicatorStyle.left = x + 'px'; 31017 this.indicatorStyle.top = y + 'px'; 31018 } 31019 }, 31020 31021 _pos: function (x, y) { 31022 if ( x < 0 ) { 31023 x = 0; 31024 } else if ( x > this.maxPosX ) { 31025 x = this.maxPosX; 31026 } 31027 31028 if ( y < 0 ) { 31029 y = 0; 31030 } else if ( y > this.maxPosY ) { 31031 y = this.maxPosY;
31032 } 31033 31034 x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x; 31035 y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y; 31036 31037 this.scroller.scrollTo(x, y); 31038 }, 31039 31040 fade: function (val, hold) { 31041 if ( hold && !this.visible ) { 31042 return; 31043 } 31044 31045 clearTimeout(this.fadeTimeout); 31046 this.fadeTimeout = null; 31047 31048 var time = val ? 250 : 500, 31049 delay = val ? 0 : 300; 31050 31051 val = val ? '1' : '0'; 31052 31053 this.wrapperStyle[utils.style.transitionDuration] = time + 'ms'; 31054 31055 this.fadeTimeout = setTimeout((function (val) { 31056 this.wrapperStyle.opacity = val; 31057 this.visible = +val; 31058 }).bind(this, val), delay); 31059 } 31060}; 31061 31062IScroll.utils = utils; 31063 31064if ( typeof module != 'undefined' && module.exports ) { 31065 module.exports = IScroll; 31066} else if ( typeof define == 'function' && define.amd ) { 31067 define( function () { return IScroll; } ); 31068} else { 31069 window.IScroll = IScroll; 31070} 31071 31072})(window, document, Math); 31073/*! 31074 * fullPage 2.9.4 31075 * https://github.com/alvarotrigo/fullPage.js 31076 * @license MIT licensed 31077 * 31078 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo 31079 */ 31080(function(global, factory) { 31081 'use strict'; 31082 if (typeof define === 'function' && define.amd) { 31083 define(['jquery'], function($) { 31084 return factory($, global, global.document, global.Math); 31085 }); 31086 } else if (typeof exports === "object" && exports) { 31087 module.exports = factory(require('jquery'), global, global.document, global.Math); 31088 } else { 31089 factory(jQuery, global, global.document, global.Math); 31090 } 31091})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { 31092 'use strict'; 31093 31094 // keeping central set of classnames and selectors 31095 var WRAPPER = 'fullpage-wrapper'; 31096 var WRAPPER_SEL = '.' + WRAPPER; 31097 31098 // slimscroll 31099 var SCROLLABLE = 'fp-scrollable'; 31100 var SCROLLABLE_SEL = '.' + SCROLLABLE; 31101 31102 // util 31103 var RESPONSIVE = 'fp-responsive'; 31104 var NO_TRANSITION = 'fp-notransition'; 31105 var DESTROYED = 'fp-destroyed'; 31106 var ENABLED = 'fp-enabled'; 31107 var VIEWING_PREFIX = 'fp-viewing'; 31108 var ACTIVE = 'active'; 31109 var ACTIVE_SEL = '.' + ACTIVE; 31110 var COMPLETELY = 'fp-completely'; 31111 var COMPLETELY_SEL = '.' + COMPLETELY; 31112 31113 // section 31114 var SECTION_DEFAULT_SEL = '.section'; 31115 var SECTION = 'fp-section'; 31116 var SECTION_SEL = '.' + SECTION; 31117 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 31118 var SECTION_FIRST_SEL = SECTION_SEL + ':first'; 31119 var SECTION_LAST_SEL = SECTION_SEL + ':last'; 31120 var TABLE_CELL = 'fp-tableCell'; 31121 var TABLE_CELL_SEL = '.' + TABLE_CELL; 31122 var AUTO_HEIGHT = 'fp-auto-height'; 31123 var AUTO_HEIGHT_SEL = '.fp-auto-height'; 31124 var NORMAL_SCROLL = 'fp-normal-scroll'; 31125 var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; 31126 31127 // section nav 31128 var SECTION_NAV = 'fp-nav'; 31129 var SECTION_NAV_SEL = '#' + SECTION_NAV; 31130 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 31131 var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; 31132 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; 31133 31134 // slide 31135 var SLIDE_DEFAULT_SEL = '.slide'; 31136 var SLIDE = 'fp-slide'; 31137 var SLIDE_SEL = '.' + SLIDE; 31138 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 31139 var SLIDES_WRAPPER = 'fp-slides'; 31140 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 31141 var SLIDES_CONTAINER = 'fp-slidesContainer'; 31142 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 31143 var TABLE = 'fp-table'; 31144 31145 // slide nav 31146 var SLIDES_NAV = 'fp-slidesNav'; 31147 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 31148 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 31149 var SLIDES_ARROW = 'fp-controlArrow'; 31150 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 31151 var SLIDES_PREV = 'fp-prev'; 31152 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 31153 var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; 31154 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 31155 var SLIDES_NEXT = 'fp-next';
31156 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 31157 var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; 31158 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 31159 31160 var $window = $(window); 31161 var $document = $(document); 31162 31163 // Default options for iScroll.js used when using scrollOverflow 31164 var iscrollOptions = { 31165 scrollbars: true, 31166 mouseWheel: true, 31167 hideScrollbars: false, 31168 fadeScrollbars: false, 31169 disableMouse: true, 31170 interactiveScrollbars: true, 31171 bounce: false, 31172 }; 31173 31174 $.fn.fullpage = function(options) { 31175 //only once my friend! 31176 if($('html').hasClass(ENABLED)){ displayWarnings(); return; } 31177 31178 // common jQuery objects 31179 var $htmlBody = $('html, body'); 31180 var $body = $('body'); 31181 31182 var FP = $.fn.fullpage; 31183 31184 // Creating some defaults, extending them with any options that were provided 31185 options = $.extend({ 31186 //navigation 31187 menu: false, 31188 anchors:[], 31189 lockAnchors: false, 31190 navigation: false, 31191 navigationPosition: 'right', 31192 navigationTooltips: [], 31193 showActiveTooltip: false, 31194 slidesNavigation: false, 31195 slidesNavPosition: 'bottom', 31196 scrollBar: false, 31197 hybrid: false, 31198 31199 //scrolling 31200 css3: true, 31201 scrollingSpeed: 700, 31202 autoScrolling: true, 31203 fitToSection: true, 31204 fitToSectionDelay: 1000, 31205 easing: 'easeInOutCubic', 31206 easingcss3: 'ease', 31207 loopBottom: false, 31208 loopTop: false, 31209 loopHorizontal: true, 31210 continuousVertical: false, 31211 continuousHorizontal: false, 31212 scrollHorizontally: false, 31213 interlockedSlides: false, 31214 dragAndMove: false, 31215 offsetSections: false, 31216 resetSliders: false, 31217 fadingEffect: false, 31218 normalScrollElements: null, 31219 scrollOverflow: false, 31220 scrollOverflowReset: false, 31221 scrollOverflowHandler: iscrollHandler, 31222 scrollOverflowOptions: null, 31223 touchSensitivity: 5, 31224 normalScrollElementTouchThreshold: 5, 31225 bigSectionsDestination: null, 31226 31227 //Accessibility 31228 keyboardScrolling: true, 31229 animateAnchor: true, 31230 recordHistory: true, 31231 31232 //design 31233 controlArrows: true, 31234 controlArrowColor: '#fff', 31235 verticalCentered: true, 31236 sectionsColor : [], 31237 paddingTop: 0, 31238 paddingBottom: 0, 31239 fixedElements: null, 31240 responsive: 0, //backwards compabitility with responsiveWiddth 31241 responsiveWidth: 0, 31242 responsiveHeight: 0, 31243 responsiveSlides: false, 31244 parallax: false, 31245 parallaxOptions: { 31246 type: 'reveal', 31247 percentage: 62, 31248 property: 'translate' 31249 }, 31250 31251 //Custom selectors 31252 sectionSelector: SECTION_DEFAULT_SEL, 31253 slideSelector: SLIDE_DEFAULT_SEL, 31254 31255 //events 31256 afterLoad: null, 31257 onLeave: null, 31258 afterRender: null, 31259 afterResize: null, 31260 afterReBuild: null, 31261 afterSlideLoad: null, 31262 onSlideLeave: null, 31263 afterResponsive: null, 31264 31265 lazyLoading: true 31266 }, options); 31267 31268 //flag to avoid very fast sliding for landscape sliders 31269 var slideMoving = false; 31270 31271 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 31272 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 31273 var container = $(this); 31274 var windowsHeight = $window.height(); 31275 var isResizing = false; 31276 var isWindowFocused = true; 31277 var lastScrolledDestiny; 31278 var lastScrolledSlide; 31279 var canScroll = true; 31280 var scrollings = []; 31281 var controlPressed; 31282 var startingSection; 31283 var isScrollAllowed = {}; 31284 isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; 31285 isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); 31286 var MSPointer = getMSPointer(); 31287 var events = { 31288 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer.move, 31289 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer.down 31290 }; 31291 31292 //cheks for passive event support 31293 //added by Uncode from new fullPage updates 31294 var g_supportsPassive = false;
31295 try { 31296 var opts = Object.defineProperty({}, 'passive', { 31297 get: function() { 31298 g_supportsPassive = true; 31299 } 31300 }); 31301 window.addEventListener("testPassive", null, opts); 31302 window.removeEventListener("testPassive", null, opts); 31303 } catch (e) {} 31304 31305 //timeouts 31306 var resizeId; 31307 var afterSectionLoadsId; 31308 var afterSlideLoadsId; 31309 var scrollId; 31310 var scrollId2; 31311 var keydownId; 31312 var originals = $.extend(true, {}, options); //deep copy 31313 31314 //Uncode addition 31315 var $masthead = $('#masthead'); 31316 var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false; 31317 var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight; 31318 var bodyBorder = UNCODE.bodyBorder; 31319 var adminBarHeight = UNCODE.adminBarHeight; 31320 31321 displayWarnings(); 31322 31323 //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783 31324 iscrollOptions.click = isTouch; // see #2035 31325 31326 //extending iScroll options with the user custom ones 31327 iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions); 31328 31329 //easeInOutCubic animation included in the plugin 31330 $.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;}}); 31331 31332 /** 31333 * Sets the autoScroll option. 31334 * It changes the scroll bar visibility and the history of the site as a result. 31335 */ 31336 function setAutoScrolling(value, type){ 31337 //removing the transformation 31338 if(!value){ 31339 silentScroll(0); 31340 } 31341 31342 setVariableState('autoScrolling', value, type); 31343 31344 var element = $(SECTION_ACTIVE_SEL); 31345 31346 if(options.autoScrolling && !options.scrollBar){ 31347 $htmlBody.css({ 31348 'overflow' : 'hidden !important', 31349 'height' : '100%' 31350 }); 31351 31352 //Uncode addition 31353 //setRecordHistory(originals.recordHistory, 'internal'); 31354 31355 //for IE touch devices 31356 container.css({ 31357 '-ms-touch-action': 'none', 31358 'touch-action': 'none' 31359 }); 31360 31361 if(element.length){ 31362 //moving the container up 31363 silentScroll(element.position().top); 31364 } 31365 31366 }else{ 31367 $htmlBody.css({ 31368 'overflow' : 'visible !important', 31369 'height' : 'initial' 31370 }); 31371 31372 //Uncode addition 31373 //setRecordHistory(false, 'internal'); 31374 31375 //for IE touch devices 31376 container.css({ 31377 '-ms-touch-action': '', 31378 'touch-action': '' 31379 }); 31380 31381 //scrolling the page to the section with no animation 31382 if (element.length) { 31383 $htmlBody.scrollTop(element.position().top); 31384 } 31385 } 31386 } 31387 31388 /** 31389 * Defines wheter to record the history for each hash change in the URL. 31390 */ 31391 function setRecordHistory(value, type){ 31392 setVariableState('recordHistory', value, type); 31393 } 31394 31395 /** 31396 * Defines the scrolling speed 31397 */ 31398 function setScrollingSpeed(value, type){ 31399 setVariableState('scrollingSpeed', value, type); 31400 } 31401 31402 /** 31403 * Sets fitToSection 31404 */ 31405 function setFitToSection(value, type){ 31406 setVariableState('fitToSection', value, type); 31407 } 31408 31409 /** 31410 * Sets lockAnchors 31411 */ 31412 function setLockAnchors(value){ 31413 options.lockAnchors = value; 31414 } 31415 31416 /** 31417 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. 31418 */ 31419 function setMouseWheelScrolling(value){ 31420 if(value){ 31421 addMouseWheelHandler(); 31422 addMiddleWheelHandler(); 31423 }else{ 31424 removeMouseWheelHandler(); 31425 removeMiddleWheelHandler(); 31426 } 31427 } 31428 31429 /** 31430 * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 31431 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 31432 * 31433 * @param directions string containing the direction or directions separated by comma. 31434 */ 31435 function setAllowScrolling(value, directions){ 31436 if(typeof directions !== 'undefined'){ 31437 directions = directions.replace(/ /g,'').split(','); 31438 31439 $.each(directions, function (index, direction){ 31440 setIsScrollAllowed(value, direction, 'm'); 31441 }); 31442 } 31443 else if(value){ 31444 setMouseWheelScrolling(true); 31445 addTouchHandler(); 31446 }else{ 31447 setMouseWheelScrolling(false); 31448 removeTouchHandler(); 31449 } 31450 } 31451 31452 /** 31453 * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys 31454 */ 31455 function setKeyboardScrolling(value, directions){ 31456 if(typeof directions !== 'undefined'){ 31457 directions = directions.replace(/ /g,'').split(','); 31458 31459 $.each(directions, function (index, direction){ 31460 setIsScrollAllowed(value, direction, 'k'); 31461 }); 31462 }else{ 31463 options.keyboardScrolling = value; 31464 } 31465 } 31466 31467 /** 31468 * Moves the page up one section. 31469 */ 31470 function moveSectionUp(){ 31471 var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); 31472 31473 //looping to the bottom if there's no more sections above 31474 if (!prev.length && (options.loopTop || options.continuousVertical)) {
31475 prev = $(SECTION_SEL).last(); 31476 } 31477 31478 if (prev.length) { 31479 scrollPage(prev, null, true); 31480 } 31481 } 31482 31483 /** 31484 * Moves the page down one section. 31485 */ 31486 function moveSectionDown(){ 31487 var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); 31488 31489 //looping to the top if there's no more sections below 31490 if(!next.length && 31491 (options.loopBottom || options.continuousVertical)){ 31492 next = $(SECTION_SEL).first(); 31493 } 31494 31495 if(next.length){ 31496 scrollPage(next, null, false); 31497 } 31498 } 31499 31500 /** 31501 * Moves the page to the given section and slide with no animation. 31502 * Anchors or index positions can be used as params. 31503 */ 31504 function silentMoveTo(sectionAnchor, slideAnchor){ 31505 setScrollingSpeed (0, 'internal'); 31506 moveTo(sectionAnchor, slideAnchor); 31507 setScrollingSpeed (originals.scrollingSpeed, 'internal'); 31508 } 31509 31510 /** 31511 * Moves the page to the given section and slide. 31512 * Anchors or index positions can be used as params. 31513 */ 31514 function moveTo(sectionAnchor, slideAnchor){ 31515 var destiny = getSectionByAnchor(sectionAnchor); 31516 31517 if (typeof slideAnchor !== 'undefined'){ 31518 scrollPageAndSlide(sectionAnchor, slideAnchor); 31519 }else if(destiny.length > 0){ 31520 scrollPage(destiny); 31521 } 31522 } 31523 31524 /** 31525 * Slides right the slider of the active section. 31526 * Optional `section` param. 31527 */ 31528 function moveSlideRight(section){ 31529 moveSlide('right', section); 31530 } 31531 31532 /** 31533 * Slides left the slider of the active section. 31534 * Optional `section` param. 31535 */ 31536 function moveSlideLeft(section){ 31537 moveSlide('left', section); 31538 } 31539 31540 /** 31541 * When resizing is finished, we adjust the slides sizes and positions 31542 */ 31543 function reBuild(resizing){ 31544 if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed 31545 31546 isResizing = true; 31547 31548 windowsHeight = $window.height(); //updating global var 31549 31550 $(SECTION_SEL).each(function(){ 31551 var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); 31552 var slides = $(this).find(SLIDE_SEL); 31553 31554 //adjusting the height of the table-cell for IE and Firefox 31555 if(options.verticalCentered){ 31556 $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); 31557 } 31558 31559 $(this).css('height', windowsHeight + 'px'); 31560 31561 //resizing the scrolling divs 31562 if(options.scrollOverflow){ 31563 if(slides.length){ 31564 slides.each(function(){ 31565 createScrollBar($(this)); 31566 }); 31567 }else{ 31568 createScrollBar($(this)); 31569 } 31570 } 31571 31572 //adjusting the position fo the FULL WIDTH slides... 31573 if (slides.length > 1) { 31574 landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); 31575 } 31576 }); 31577 31578 var activeSection = $(SECTION_ACTIVE_SEL); 31579 var sectionIndex = activeSection.index(SECTION_SEL); 31580 31581 //isn't it the first section? 31582 if(sectionIndex){ 31583 //adjusting the position for the current section 31584 silentMoveTo(sectionIndex + 1); 31585 } 31586 31587 isResizing = false; 31588 // Uncode change 31589 // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); 31590 $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight()); 31591 $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); 31592 } 31593 31594 /** 31595 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 31596 * are smaller than the set limit values. 31597 */ 31598 function setResponsive(active){ 31599 var isResponsive = $body.hasClass(RESPONSIVE); 31600 31601 if(active){ 31602 if(!isResponsive){ 31603 setAutoScrolling(false, 'internal'); 31604 setFitToSection(false, 'internal'); 31605 $(SECTION_NAV_SEL).hide(); 31606 $body.addClass(RESPONSIVE); 31607 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31608 } 31609 } 31610 else if(isResponsive){ 31611 setAutoScrolling(originals.autoScrolling, 'internal'); 31612 setFitToSection(originals.autoScrolling, 'internal'); 31613 $(SECTION_NAV_SEL).show(); 31614 $body.removeClass(RESPONSIVE); 31615 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31616 } 31617 } 31618 31619 if($(this).length){ 31620 //public functions 31621 FP.setAutoScrolling = setAutoScrolling; 31622 FP.setRecordHistory = setRecordHistory; 31623 FP.setScrollingSpeed = setScrollingSpeed; 31624 FP.setFitToSection = setFitToSection; 31625 FP.setLockAnchors = setLockAnchors; 31626 FP.setMouseWheelScrolling = setMouseWheelScrolling; 31627 FP.setAllowScrolling = setAllowScrolling; 31628 FP.setKeyboardScrolling = setKeyboardScrolling; 31629 FP.moveSectionUp = moveSectionUp; 31630 FP.moveSectionDown = moveSectionDown; 31631 FP.silentMoveTo = silentMoveTo; 31632 FP.moveTo = moveTo; 31633 FP.moveSlideRight = moveSlideRight; 31634 FP.moveSlideLeft = moveSlideLeft; 31635 FP.fitToSection = fitToSection; 31636 FP.reBuild = reBuild; 31637 FP.setResponsive = setResponsive; 31638 FP.destroy = destroy; 31639 31640 init(); 31641 31642 bindEvents(); 31643 } 31644
31645 function init(){ 31646 //if css3 is not supported, it will use jQuery animations 31647 if(options.css3){ 31648 options.css3 = support3d(); 31649 } 31650 31651 options.scrollBar = options.scrollBar || options.hybrid; 31652 31653 setOptionsFromDOM(); 31654 prepareDom(); 31655 setAllowScrolling(true); 31656 setAutoScrolling(options.autoScrolling, 'internal'); 31657 responsive(); 31658 31659 //setting the class for the body element 31660 setBodyClass(); 31661 31662 //Uncode addition 31663 // if(document.readyState === 'complete'){ 31664 // scrollToAnchor(); 31665 // } 31666 // $window.on('load', scrollToAnchor); 31667 } 31668 31669 function bindEvents(){ 31670 $window 31671 //when scrolling... 31672 //.on('scroll', scrollHandler) 31673 31674 //detecting any change on the URL to scroll to the given anchor link 31675 //(a way to detect back history button as we play with the hashes on the URL) 31676 .on('hashchange', hashChangeHandler) 31677 31678 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 31679 .blur(blurHandler) 31680 31681 //when resizing the site, we adjust the heights of the sections, slimScroll... 31682 .resize(resizeHandler); 31683 31684 $document 31685 //Sliding with arrow keys, both, vertical and horizontal 31686 .keydown(keydownHandler) 31687 31688 //to prevent scrolling while zooming 31689 .keyup(keyUpHandler) 31690 31691 //Scrolls to the section when clicking the navigation bullet 31692 .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) 31693 31694 //Scrolls the slider to the given slide destination for the given section 31695 .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) 31696 31697 .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); 31698 31699 //Scrolling horizontally when clicking on the slider controls. 31700 $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); 31701 31702 /** 31703 * Applying normalScroll elements. 31704 * Ignoring the scrolls over the specified selectors. 31705 */ 31706 if(options.normalScrollElements){ 31707 $document.on('mouseenter', options.normalScrollElements, function () { 31708 setMouseWheelScrolling(false); 31709 }); 31710 31711 $document.on('mouseleave', options.normalScrollElements, function(){ 31712 setMouseWheelScrolling(true); 31713 }); 31714 } 31715 } 31716 31717 /** 31718 * Setting options from DOM elements if they are not provided. 31719 */ 31720 function setOptionsFromDOM(){ 31721 var sections = container.find(options.sectionSelector); 31722 31723 //no anchors option? Checking for them in the DOM attributes 31724 if(!options.anchors.length){ 31725 options.anchors = sections.filter('[data-anchor]').map(function(){ 31726 return $(this).data('anchor').toString(); 31727 }).get(); 31728 } 31729 31730 //no tooltips option? Checking for them in the DOM attributes 31731 if(!options.navigationTooltips.length){ 31732 options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ 31733 return $(this).data('tooltip').toString(); 31734 }).get(); 31735 } 31736 } 31737 31738 /** 31739 * Works over the DOM structure to set it up for the current fullpage options. 31740 */ 31741 function prepareDom(){ 31742 container.css({ 31743 'height': '100%', 31744 'position': 'relative' 31745 }); 31746 31747 //adding a class to recognize the container internally in the code 31748 container.addClass(WRAPPER); 31749 $('html').addClass(ENABLED); 31750 31751 windowsHeight = $window.height(); 31752 31753 container.removeClass(DESTROYED); //in case it was destroyed before initializing it again 31754 31755 addInternalSelectors(); 31756 31757 //styling the sections / slides / menu 31758 $(SECTION_SEL).each(function(index){ 31759 var section = $(this); 31760 var slides = section.find(SLIDE_SEL); 31761 var numSlides = slides.length; 31762 31763 styleSection(section, index); 31764 styleMenu(section, index); 31765 31766 // if there's any slide 31767 if (numSlides > 0) { 31768 styleSlides(section, slides, numSlides); 31769 }else{ 31770 if(options.verticalCentered){ 31771 addTableClass(section); 31772 } 31773 } 31774 }); 31775 31776 //fixed elements need to be moved out of the plugin container due to problems with CSS3. 31777 if(options.fixedElements && options.css3){ 31778 $(options.fixedElements).appendTo($body); 31779 } 31780 31781 //vertical centered of the navigation + active bullet 31782 if(options.navigation){ 31783 addVerticalNavigation(); 31784 } 31785 31786 enableYoutubeAPI(); 31787 31788 if(options.scrollOverflow){ 31789 if(document.readyState === 'complete'){ 31790 createScrollBarHandler(); 31791 } 31792 //after DOM and images are loaded 31793 $window.on('load', createScrollBarHandler); 31794 }else{ 31795 afterRenderActions(); 31796 } 31797 } 31798 31799 /** 31800 * Styles the horizontal slides for a section. 31801 */ 31802 function styleSlides(section, slides, numSlides){ 31803 var sliderWidth = numSlides * 100; 31804 var slideWidth = 100 / numSlides; 31805 31806 slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />'); 31807 slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />'); 31808 31809 section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); 31810 31811 if(numSlides > 1){ 31812 if(options.controlArrows){ 31813 createSlideArrows(section); 31814 } 31815 31816 if(options.slidesNavigation){ 31817 addSlidesNavigation(section, numSlides); 31818 } 31819 } 31820 31821 slides.each(function(index) { 31822 $(this).css('width', slideWidth + '%'); 31823 31824 if(options.verticalCentered){ 31825 addTableClass($(this)); 31826 } 31827 }); 31828 31829 var startingSlide = section.find(SLIDE_ACTIVE_SEL); 31830 31831 //if the slide won't be an starting point, the default will be the first one 31832 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
31832ide by default. 31833 if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ 31834 silentLandscapeScroll(startingSlide, 'internal'); 31835 }else{ 31836 slides.eq(0).addClass(ACTIVE); 31837 } 31838 } 31839 31840 /** 31841 * Styling vertical sections 31842 */ 31843 function styleSection(section, index){ 31844 //if no active section is defined, the 1st one will be the default one 31845 if(!index && $(SECTION_ACTIVE_SEL).length === 0) { 31846 section.addClass(ACTIVE); 31847 } 31848 startingSection = $(SECTION_ACTIVE_SEL); 31849 31850 section.css('height', windowsHeight + 'px'); 31851 31852 if(options.paddingTop){ 31853 section.css('padding-top', options.paddingTop); 31854 } 31855 31856 if(options.paddingBottom){ 31857 section.css('padding-bottom', options.paddingBottom); 31858 } 31859 31860 if (typeof options.sectionsColor[index] !== 'undefined') { 31861 section.css('background-color', options.sectionsColor[index]); 31862 } 31863 31864 if (typeof options.anchors[index] !== 'undefined') { 31865 section.attr('data-anchor', options.anchors[index]); 31866 } 31867 } 31868 31869 /** 31870 * Sets the data-anchor attributes to the menu elements and activates the current one. 31871 */ 31872 function styleMenu(section, index){ 31873 if (typeof options.anchors[index] !== 'undefined') { 31874 //activating the menu / nav element on load 31875 if(section.hasClass(ACTIVE)){ 31876 activateMenuAndNav(options.anchors[index], index); 31877 } 31878 } 31879 31880 //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 31881 if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ 31882 $(options.menu).appendTo($body); 31883 } 31884 } 31885 31886 /** 31887 * Adds internal classes to be able to provide customizable selectors 31888 * keeping the link with the style sheet. 31889 */ 31890 function addInternalSelectors(){ 31891 container.find(options.sectionSelector).addClass(SECTION); 31892 container.find(options.slideSelector).addClass(SLIDE); 31893 } 31894 31895 /** 31896 * Creates the control arrows for the given section 31897 */ 31898 function createSlideArrows(section){ 31899 section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>'); 31900 31901 if(options.controlArrowColor!='#fff'){ 31902 section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); 31903 section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); 31904 } 31905 31906 if(!options.loopHorizontal){ 31907 section.find(SLIDES_ARROW_PREV_SEL).hide(); 31908 } 31909 } 31910 31911 /** 31912 * Creates a vertical navigation bar. 31913 */ 31914 function addVerticalNavigation(){ 31915 $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>'); 31916 var nav = $(SECTION_NAV_SEL); 31917 31918 nav.addClass(function() { 31919 return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; 31920 }); 31921 31922 for (var i = 0; i < $(SECTION_SEL).length; i++) { 31923 var link = ''; 31924 if (options.anchors.length) { 31925 link = options.anchors[i]; 31926 } 31927 31928 var li = '<li><a href="#' + link + '"><span></span></a>'; 31929 31930 // Only add tooltip if needed (defined by user) 31931 var tooltip = options.navigationTooltips[i]; 31932 31933 if (typeof tooltip !== 'undefined' && tooltip !== '') { 31934 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>'; 31935 } 31936 31937 li += '</li>'; 31938 31939 nav.find('ul').append(li); 31940 } 31941 31942 //centering it vertically 31943 $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px'); 31944 31945 //activating the current active section 31946 $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); 31947 } 31948 31949 /** 31950 * Creates the slim scroll scrollbar for the sections and slides inside them. 31951 */ 31952 function createScrollBarHandler(){ 31953 $(SECTION_SEL).each(function(){ 31954 var slides = $(this).find(SLIDE_SEL); 31955 31956 if(slides.length){ 31957 slides.each(function(){ 31958 createScrollBar($(this)); 31959 }); 31960 }else{ 31961 createScrollBar($(this)); 31962 } 31963 31964 }); 31965 afterRenderActions(); 31966 } 31967 31968 /*
31969 * Enables the Youtube videos API so we can control their flow if necessary. 31970 */ 31971 function enableYoutubeAPI(){ 31972 container.find('iframe[src*="youtube.com/embed/"]').each(function(){ 31973 addURLParam($(this), 'enablejsapi=1'); 31974 }); 31975 } 31976 31977 /** 31978 * Adds a new parameter and its value to the `src` of a given element 31979 */ 31980 function addURLParam(element, newParam){ 31981 var originalSrc = element.attr('src'); 31982 element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam); 31983 } 31984 31985 /* 31986 * Returns the prefix sign to use for a new parameter in an existen URL. 31987 * 31988 * @return {String} ? | & 31989 */ 31990 function getUrlParamSign(url){ 31991 return ( !/\?/.test( url ) ) ? '?' : '&'; 31992 } 31993 31994 /** 31995 * Actions and callbacks to fire afterRender 31996 */ 31997 function afterRenderActions(){ 31998 var section = $(SECTION_ACTIVE_SEL); 31999 32000 section.addClass(COMPLETELY); 32001 32002 if(options.scrollOverflowHandler.afterRender){ 32003 options.scrollOverflowHandler.afterRender(section); 32004 } 32005 lazyLoad(section); 32006 playMedia(section); 32007 options.scrollOverflowHandler.afterLoad(); 32008 32009 if(isDestinyTheStartingSection()){ 32010 $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); 32011 } 32012 32013 // Uncode change 32014 // $.isFunction( options.afterRender ) && options.afterRender.call(container); 32015 $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight()); 32016 } 32017 32018 /** 32019 * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization) 32020 */ 32021 function isDestinyTheStartingSection(){ 32022 var anchors = window.location.hash.replace('#', '').split('/'); 32023 var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0])); 32024 32025 return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index(); 32026 } 32027 32028 32029 var isScrolling = false; 32030 var lastScroll = 0; 32031 32032 //when scrolling... 32033 function scrollHandler(){ 32034 var currentSection; 32035 32036 if(!options.autoScrolling || options.scrollBar){ 32037 var currentScroll = $window.scrollTop(); 32038 var scrollDirection = getScrollDirection(currentScroll); 32039 var visibleSectionIndex = 0; 32040 var screen_mid = currentScroll + ($window.height() / 2.0); 32041 var isAtBottom = $body.height() - $window.height() === currentScroll; 32042 var sections = document.querySelectorAll(SECTION_SEL); 32043 32044 //when using `auto-height` for a small last section it won't be centered in the viewport 32045 if(isAtBottom){ 32046 visibleSectionIndex = sections.length - 1; 32047 } 32048 //is at top? when using `auto-height` for a small first section it won't be centered in the viewport 32049 else if(!currentScroll){ 32050 visibleSectionIndex = 0; 32051 } 32052 32053 //taking the section which is showing more content in the viewport 32054 else{ 32055 for (var i = 0; i < sections.length; ++i) { 32056 var section = sections[i]; 32057 32058 // Pick the the last section which passes the middle line of the screen. 32059 if (section.offsetTop <= screen_mid) 32060 { 32061 visibleSectionIndex = i; 32062 } 32063 } 32064 } 32065 32066 if(isCompletelyInViewPort(scrollDirection)){ 32067 if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ 32068 $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32069 } 32070 } 32071 32072 //geting the last one, the current one on the screen 32073 currentSection = $(sections).eq(visibleSectionIndex); 32074 32075 //setting the visible section as active when manually scrolling 32076 //executing only once the first time we reach the section 32077 if(!currentSection.hasClass(ACTIVE)){ 32078 isScrolling = true; 32079 var leavingSection = $(SECTION_ACTIVE_SEL); 32080 var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; 32081 var yMovement = getYmovement(currentSection); 32082 var anchorLink = currentSection.data('anchor'); 32083 var sectionIndex = currentSection.index(SECTION_SEL) + 1; 32084 var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); 32085 var slideIndex; 32086 var slideAnchorLink; 32087 32088 if(activeSlide.length){ 32089 slideAnchorLink = activeSlide.data('anchor'); 32090 slideIndex = activeSlide.index(); 32091 } 32092 32093 if(canScroll){ 32094 currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32095 32096 $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); 32097 $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); 32098 32099 stopMedia(leavingSection); 32100 lazyLoad(currentSection); 32101 playMedia(currentSection); 32102 32103 activateMenuAndNav(anchorLink, sectionIndex - 1); 32104 32105 if(options.anchors.length){ 32106 //needed to enter in hashChange event when using the menu with anchor links 32107 lastScrolledDestiny = anchorLink; 32108 } 32109 setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); 32110 } 32111 32112 //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 32113 clearTimeout(scrollId); 32114 scrollId = setTimeout(function(){ 32115 isScrolling = false;
32116 }, 100); 32117 } 32118 32119 if(options.fitToSection){ 32120 //for the auto adjust of the viewport to fit a whole section 32121 clearTimeout(scrollId2); 32122 32123 scrollId2 = setTimeout(function(){ 32124 //checking it again in case it changed during the delay 32125 if(options.fitToSection){ 32126 fitToSection(); 32127 } 32128 }, options.fitToSectionDelay); 32129 } 32130 } 32131 } 32132 32133 /** 32134 * Fits the site to the nearest active section 32135 */ 32136 function fitToSection(){ 32137 //checking fitToSection again in case it was set to false before the timeout delay 32138 if(canScroll){ 32139 //allows to scroll to an active section and 32140 //if the section is already active, we prevent firing callbacks 32141 isResizing = true; 32142 32143 scrollPage($(SECTION_ACTIVE_SEL)); 32144 isResizing = false; 32145 } 32146 } 32147 32148 /** 32149 * Determines whether the active section has seen in its whole or not. 32150 */ 32151 function isCompletelyInViewPort(movement){ 32152 var top = $(SECTION_ACTIVE_SEL).position().top; 32153 var bottom = top + $window.height(); 32154 32155 if(movement == 'up'){ 32156 return bottom >= ($window.scrollTop() + $window.height()); 32157 } 32158 return top <= $window.scrollTop(); 32159 } 32160 32161 /** 32162 * Gets the directon of the the scrolling fired by the scroll event. 32163 */ 32164 function getScrollDirection(currentScroll){ 32165 var direction = currentScroll > lastScroll ? 'down' : 'up'; 32166 32167 lastScroll = currentScroll; 32168 32169 //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination 32170 previousDestTop = currentScroll; 32171 32172 return direction; 32173 } 32174 32175 /** 32176 * Determines the way of scrolling up or down: 32177 * by 'automatically' scrolling a section or by using the default and normal scrolling. 32178 */ 32179 function scrolling(type, scrollable){ 32180 if (!isScrollAllowed.m[type]){ 32181 return; 32182 } 32183 var check = (type === 'down') ? 'bottom' : 'top'; 32184 var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp; 32185 32186 if(scrollable.length > 0 ){ 32187 //is the scrollbar at the start/end of the scroll? 32188 if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ 32189 scrollSection(); 32190 }else{ 32191 return true; 32192 } 32193 }else{ 32194 // moved up/down 32195 scrollSection(); 32196 } 32197 } 32198 32199 /* 32200 * Preventing bouncing in iOS #2285 32201 */ 32202 function preventBouncing(event){ 32203 var e = event.originalEvent; 32204 if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){ 32205 //preventing the easing on iOS devices 32206 event.preventDefault(); 32207 } 32208 } 32209 32210 var touchStartY = 0; 32211 var touchStartX = 0; 32212 var touchEndY = 0; 32213 var touchEndX = 0; 32214 32215 /* Detecting touch events 32216 32217 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 32218 * This way, the touchstart and the touch moves shows an small difference between them which is the 32219 * used one to determine the direction. 32220 */ 32221 function touchMoveHandler(event){ 32222 var e = event.originalEvent; 32223 var activeSection = $(e.target).closest(SECTION_SEL); 32224 32225 // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain 32226 if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) { 32227 32228 if(options.autoScrolling){ 32229 //preventing the easing on iOS devices 32230 event.preventDefault(); 32231 } 32232 32233 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32234 var touchEvents = getEventsPage(e); 32235 32236 touchEndY = touchEvents.y; 32237 touchEndX = touchEvents.x; 32238 32239 //if movement in the X axys is greater than in the Y and the currect section has slides... 32240 if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { 32241 32242 //is the movement greater than the minimum resistance to scroll? 32243 if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { 32244 if (touchStartX > touchEndX) { 32245 if(isScrollAllowed.m.right){ 32246 moveSlideRight(activeSection); //next 32247 } 32248 } else { 32249 if(isScrollAllowed.m.left){ 32250 moveSlideLeft(activeSection); //prev 32251 } 32252 } 32253 } 32254 } 32255 32256 //vertical scrolling (only when autoScrolling is enabled) 32257 else if(options.autoScrolling && canScroll){ 32258 32259 //is the movement greater than the minimum resistance to scroll? 32260 if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { 32261 if (touchStartY > touchEndY) { 32262 scrolling('down', scrollable); 32263 } else if (touchEndY > touchStartY) { 32264 scrolling('up', scrollable); 32265 } 32266 } 32267 } 32268 } 32269 } 32270 32271 /** 32272 * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements 32273 * Currently works well for iOS - Android might need some testing 32274 * @param {Element} el target element / jquery selector (in subsequent nodes) 32275 * @param {int} hop current hop compared to options.normalScrollElementTouchThreshold 32276 * @return {boolean} true if there is a match to options.normalScrollElements 32277 */ 32278 function checkParentForNormalScrollElement (el, hop) { 32279 hop = hop || 0; 32280 var parent = $(el).parent(); 32281 32282 if (hop < options.normalScrollElementTouchThreshold && 32283 parent.is(options.normalScrollElements) ) { 32284 return true; 32285 } else if (hop == options.normalScrollElementTouchThreshold) { 32286 return false;
32287 } else { 32288 return checkParentForNormalScrollElement(parent, ++hop); 32289 } 32290 } 32291 32292 /** 32293 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 32294 * this way we make sure that is really a touch event what IE is detecting. 32295 */ 32296 function isReallyTouch(e){ 32297 //if is not IE || IE is detecting `touch` or `pen` 32298 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 32299 } 32300 32301 /** 32302 * Handler for the touch start event. 32303 */ 32304 function touchStartHandler(event){ 32305 var e = event.originalEvent; 32306 32307 //stopping the auto scroll to adjust to a section 32308 if(options.fitToSection){ 32309 $htmlBody.stop(); 32310 } 32311 32312 if(isReallyTouch(e)){ 32313 var touchEvents = getEventsPage(e); 32314 touchStartY = touchEvents.y; 32315 touchStartX = touchEvents.x; 32316 } 32317 } 32318 32319 /** 32320 * Gets the average of the last `number` elements of the given array. 32321 */ 32322 function getAverage(elements, number){ 32323 var sum = 0; 32324 32325 //taking `number` elements from the end to make the average, if there are not enought, 1 32326 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 32327 32328 for(var i = 0; i < lastElements.length; i++){ 32329 sum = sum + lastElements[i]; 32330 } 32331 32332 return Math.ceil(sum/number); 32333 } 32334 32335 /** 32336 * Detecting mousewheel scrolling 32337 * 32338 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 32339 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 32340 */ 32341 var prevTime = new Date().getTime(); 32342 32343 function MouseWheelHandler(e) { 32344 var curTime = new Date().getTime(); 32345 var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); 32346 32347 //autoscrolling and not zooming? 32348 if(options.autoScrolling && !controlPressed && !isNormalScroll){ 32349 // cross-browser wheel delta 32350 e = e || window.event; 32351 var value = e.wheelDelta || -e.deltaY || -e.detail; 32352 var delta = Math.max(-1, Math.min(1, value)); 32353 32354 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 32355 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 32356 32357 //Limiting the array to 150 (lets not waste memory!) 32358 if(scrollings.length > 149){ 32359 scrollings.shift(); 32360 } 32361 32362 //keeping record of the previous scrollings 32363 scrollings.push(Math.abs(value)); 32364 32365 //preventing to scroll the site on mouse wheel when scrollbar is present 32366 if(options.scrollBar){ 32367 e.preventDefault ? e.preventDefault() : e.returnValue = false; 32368 } 32369 32370 var activeSection = $(SECTION_ACTIVE_SEL); 32371 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32372 32373 //time difference between the last scroll and the current one 32374 var timeDiff = curTime-prevTime; 32375 prevTime = curTime; 32376 32377 //haven't they scrolled in a while? 32378 //(enough to be consider a different scrolling action to scroll another section) 32379 if(timeDiff > 200){ 32380 //emptying the array, we dont care about old scrollings for our averages 32381 scrollings = []; 32382 } 32383 32384 if(canScroll){ 32385 var averageEnd = getAverage(scrollings, 10); 32386 var averageMiddle = getAverage(scrollings, 70); 32387 var isAccelerating = averageEnd >= averageMiddle; 32388 32389 //to avoid double swipes... 32390 if(isAccelerating && isScrollingVertically){ 32391 //scrolling down? 32392 if (delta < 0) { 32393 scrolling('down', scrollable); 32394 32395 //scrolling up? 32396 }else { 32397 scrolling('up', scrollable); 32398 } 32399 } 32400 } 32401 32402 return false;
32403 } 32404 32405 if(options.fitToSection){ 32406 //stopping the auto scroll to adjust to a section 32407 $htmlBody.stop(); 32408 } 32409 } 32410 32411 /** 32412 * Slides a slider to the given direction. 32413 * Optional `section` param. 32414 */ 32415 function moveSlide(direction, section){ 32416 var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; 32417 var slides = activeSection.find(SLIDES_WRAPPER_SEL); 32418 var numSlides = slides.find(SLIDE_SEL).length; 32419 32420 // more than one slide needed and nothing should be sliding 32421 if (!slides.length || slideMoving || numSlides < 2) { 32422 return; 32423 } 32424 32425 var currentSlide = slides.find(SLIDE_ACTIVE_SEL); 32426 var destiny = null; 32427 32428 if(direction === 'left'){ 32429 destiny = currentSlide.prev(SLIDE_SEL); 32430 }else{ 32431 destiny = currentSlide.next(SLIDE_SEL); 32432 } 32433 32434 //isn't there a next slide in the secuence? 32435 if(!destiny.length){ 32436 //respect loopHorizontal settin 32437 if (!options.loopHorizontal) return; 32438 32439 if(direction === 'left'){ 32440 destiny = currentSlide.siblings(':last'); 32441 }else{ 32442 destiny = currentSlide.siblings(':first'); 32443 } 32444 } 32445 32446 slideMoving = true; 32447 32448 landscapeScroll(slides, destiny, direction); 32449 } 32450 32451 /** 32452 * Maintains the active slides in the viewport 32453 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 32454 */ 32455 function keepSlidesPosition(){ 32456 $(SLIDE_ACTIVE_SEL).each(function(){ 32457 silentLandscapeScroll($(this), 'internal'); 32458 }); 32459 } 32460 32461 var previousDestTop = 0; 32462 /** 32463 * Returns the destination Y position based on the scrolling direction and 32464 * the height of the section. 32465 */ 32466 function getDestinationPosition(element){ 32467 var elemPosition = element.position(); 32468 32469 //top of the desination will be at the top of the viewport 32470 var position = elemPosition.top; 32471 var isScrollingDown = elemPosition.top > previousDestTop; 32472 var sectionBottom = position - windowsHeight + element.outerHeight(); 32473 var bigSectionsDestination = options.bigSectionsDestination; 32474 32475 //Uncode addition 32476 var containerH = container.outerHeight(); 32477 var containerPosition = container.offset(); 32478 32479 //########### Commented by Uncode - START ########### 32480 //is the destination element bigger than the viewport? 32481 // if(element.outerHeight() > windowsHeight){ 32482 // //scrolling up? 32483 // if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){ 32484 // position = sectionBottom; 32485 // } 32486 // } 32487 32488 // //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 32489 // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ 32490 // //The bottom of the destination will be at the bottom of the viewport 32491 // position = sectionBottom; 32492 // } 32493 //########### Commented by Uncode - END ########### 32494 32495 //Uncode addition 32496 if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') ) 32497 position += 18; 32498 if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) { 32499 position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight; 32500 } 32501 32502 /* 32503 Keeping record of the last scrolled position to determine the scrolling direction. 32504 No conventional methods can be used as the scroll bar might not be present 32505 AND the section might not be active if it is auto-height and didnt reach the middle 32506 of the viewport. 32507 */ 32508 previousDestTop = position; 32509 return position; 32510 } 32511 32512 /** 32513 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 32514 */ 32515 function scrollPage(element, callback, isMovementUp){ 32516 if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function 32517 32518 var dtop = getDestinationPosition(element); 32519 var slideAnchorLink; 32520 var slideIndex; 32521 32522 //local variables 32523 var v = { 32524 element: element, 32525 callback: callback, 32526 isMovementUp: isMovementUp, 32527 dtop: dtop, 32528 yMovement: getYmovement(element), 32529 anchorLink: element.data('anchor'), 32530 sectionIndex: element.index(SECTION_SEL), 32531 activeSlide: element.find(SLIDE_ACTIVE_SEL), 32532 activeSection: $(SECTION_ACTIVE_SEL), 32533 leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, 32534 32535 //caching the value of isResizing at the momment the function is called 32536 //because it will be checked later inside a setTimeout and the value might change 32537 localIsResizing: isResizing 32538 }; 32539 32540 //quiting when destination scroll is the same as the current one 32541 if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } 32542 32543 if(v.activeSlide.length){ 32544 slideAnchorLink = v.activeSlide.data('anchor'); 32545 slideIndex = v.activeSlide.index(); 32546 } 32547 32548 // If continuousVertical && we need to wrap around 32549 if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && 32550 ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or 32551 (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down 32552 32553 v = createInfiniteSections(v); 32554 } 32555 32556 //callback (onLeave) if the site is not just resizing and readjusting the slides 32557 if($.isFunction(options.onLeave) && !v.localIsResizing){ 32558 if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ 32559 return; 32560 } 32561 } 32562 32563 //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one) 32564 if(!v.localIsResizing){ 32565 stopMedia(v.activeSection); 32566 } 32567 32568 options.scrollOverflowHandler.beforeLeave(); 32569 element.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32570 lazyLoad(element); 32571 options.scrollOverflowHandler.onLeave(); 32572 32573 32574 //preventing from activating the MouseWheelHandler event 32575 //more than once if the page is scrolling 32576 canScroll = false;
32577 32578 setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); 32579 32580 performMovement(v); 32581 32582 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 32583 lastScrolledDestiny = v.anchorLink; 32584 32585 //avoid firing it twice (as it does also on scroll) 32586 activateMenuAndNav(v.anchorLink, v.sectionIndex); 32587 } 32588 32589 /** 32590 * Performs the vertical movement (by CSS3 or by jQuery) 32591 */ 32592 function performMovement(v){ 32593 // using CSS3 translate functionality 32594 if (options.css3 && options.autoScrolling && !options.scrollBar) { 32595 32596 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 32597 // that's why we round it to 0. 32598 var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; 32599 transformContainer(translate3d, true); 32600 32601 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 32602 //scrollingSpeed to change in case of using silentMoveTo(); 32603 if(options.scrollingSpeed){ 32604 clearTimeout(afterSectionLoadsId); 32605 afterSectionLoadsId = setTimeout(function () { 32606 afterSectionLoads(v); 32607 }, options.scrollingSpeed); 32608 }else{ 32609 afterSectionLoads(v); 32610 } 32611 } 32612 32613 // using jQuery animate 32614 else{ 32615 var scrollSettings = getScrollSettings(v); 32616 32617 $(scrollSettings.element).animate( 32618 scrollSettings.options, 32619 options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating `html, body` 32620 if(options.scrollBar){ 32621 32622 /* Hack! 32623 The timeout prevents setting the most dominant section in the viewport as "active" when the user 32624 scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. 32625 32626 When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. 32627 */ 32628 setTimeout(function(){ 32629 afterSectionLoads(v); 32630 },30); 32631 }else{ 32632 afterSectionLoads(v); 32633 } 32634 }); 32635 } 32636 } 32637 32638 /** 32639 * Gets the scrolling settings depending on the plugin autoScrolling option 32640 */ 32641 function getScrollSettings(v){ 32642 var scroll = {}; 32643 32644 if(options.autoScrolling && !options.scrollBar){ 32645 scroll.options = { 'top': -v.dtop}; 32646 scroll.element = WRAPPER_SEL; 32647 }else{ 32648 scroll.options = { 'scrollTop': v.dtop}; 32649 scroll.element = 'html, body'; 32650 } 32651 32652 return scroll; 32653 } 32654 32655 /** 32656 * Adds sections before or after the current one to create the infinite effect. 32657 */ 32658 function createInfiniteSections(v){ 32659 // Scrolling down 32660 if (!v.isMovementUp) { 32661 // Move all previous sections to after the active section 32662 $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); 32663 } 32664 else { // Scrolling up 32665 // Move all next sections to before the active section 32666 $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); 32667 } 32668 32669 // Maintain the displayed position (now that we changed the element order) 32670 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32671 32672 // Maintain the active slides visible in the viewport 32673 keepSlidesPosition(); 32674 32675 // save for later the elements that still need to be reordered 32676 v.wrapAroundElements = v.activeSection; 32677 32678 // Recalculate animation variables 32679 v.dtop = v.element.position().top; 32680 v.yMovement = getYmovement(v.element); 32681 32682 return v; 32683 } 32684 32685 /** 32686 * Fix section order after continuousVertical changes have been animated 32687 */ 32688 function continuousVerticalFixSectionOrder (v) {
32689 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 32690 // finish moving the elements around so the direct navigation will function more simply 32691 if (!v.wrapAroundElements || !v.wrapAroundElements.length) { 32692 return; 32693 } 32694 32695 if (v.isMovementUp) { 32696 $(SECTION_FIRST_SEL).before(v.wrapAroundElements); 32697 } 32698 else { 32699 $(SECTION_LAST_SEL).after(v.wrapAroundElements); 32700 } 32701 32702 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32703 32704 // Maintain the active slides visible in the viewport 32705 keepSlidesPosition(); 32706 } 32707 32708 32709 /** 32710 * Actions to do once the section is loaded. 32711 */ 32712 function afterSectionLoads (v){ 32713 continuousVerticalFixSectionOrder(v); 32714 32715 //callback (afterLoad) if the site is not just resizing and readjusting the slides 32716 $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); 32717 options.scrollOverflowHandler.afterLoad(); 32718 32719 if(!v.localIsResizing){ 32720 playMedia(v.element); 32721 } 32722 32723 v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32724 32725 canScroll = true; 32726 32727 $.isFunction(v.callback) && v.callback.call(this); 32728 } 32729 32730 /** 32731 * Sets the value for the given attribute from the `data-` attribute with the same suffix 32732 * ie: data-srcset ==> srcset | data-src ==> src 32733 */ 32734 function setSrc(element, attribute){ 32735 element 32736 .attr(attribute, element.data(attribute)) 32737 .removeAttr('data-' + attribute); 32738 } 32739 32740 /** 32741 * Lazy loads image, video and audio elements. 32742 */ 32743 function lazyLoad(destiny){ 32744 if (!options.lazyLoading){ 32745 return; 32746 } 32747 32748 var panel = getSlideOrSection(destiny); 32749 var element; 32750 32751 panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 32752 element = $(this); 32753 32754 $.each(['src', 'srcset'], function(index, type){ 32755 var attribute = element.attr('data-' + type); 32756 if(typeof attribute !== 'undefined' && attribute){ 32757 setSrc(element, type); 32758 } 32759 }); 32760 32761 if(element.is('source')){ 32762 element.closest('video').get(0).load(); 32763 } 32764 }); 32765 } 32766 32767 /** 32768 * Plays video and audio elements. 32769 */ 32770 function playMedia(destiny){ 32771 var panel = getSlideOrSection(destiny); 32772 32773 //playing HTML5 media elements 32774 panel.find('video, audio').each(function(){ 32775 var element = $(this).get(0); 32776 32777 if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) { 32778 element.play(); 32779 } 32780 }); 32781 32782 //youtube videos 32783 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32784 var element = $(this).get(0); 32785 32786 if ( element.hasAttribute('data-autoplay') ){ 32787 playYoutube(element); 32788 } 32789 32790 //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. 32791 element.onload = function() { 32792 if ( element.hasAttribute('data-autoplay') ){ 32793 playYoutube(element); 32794 } 32795 }; 32796 }); 32797 } 32798 32799 /** 32800 * Plays a youtube video 32801 */ 32802 function playYoutube(element){ 32803 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 32804 } 32805 32806 /** 32807 * Stops video and audio elements. 32808 */ 32809 function stopMedia(destiny){ 32810 var panel = getSlideOrSection(destiny); 32811 32812 //stopping HTML5 media elements 32813 panel.find('video, audio').each(function(){ 32814 var element = $(this).get(0); 32815 32816 if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { 32817 element.pause(); 32818 } 32819 }); 32820 32821 //youtube videos 32822 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32823 var element = $(this).get(0); 32824 32825 if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ 32826 $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); 32827 } 32828 }); 32829 } 32830 32831 /** 32832 * Gets the active slide (or section) for the given section 32833 */ 32834 function getSlideOrSection(destiny){ 32835 var slide = destiny.find(SLIDE_ACTIVE_SEL); 32836 if( slide.length ) { 32837 destiny = $(slide); 32838 } 32839 32840 return destiny; 32841 } 32842 32843 /**
32844 * Scrolls to the anchor in the URL when loading the site 32845 */ 32846 function scrollToAnchor(){ 32847 //getting the anchor link in the URL and deleting the `#` 32848 var value = window.location.hash.replace('#', '').split('/'); 32849 var sectionAnchor = decodeURIComponent(value[0]); 32850 var slideAnchor = decodeURIComponent(value[1]); 32851 32852 if(sectionAnchor){ //if theres any # 32853 if(options.animateAnchor){ 32854 scrollPageAndSlide(sectionAnchor, slideAnchor); 32855 }else{ 32856 silentMoveTo(sectionAnchor, slideAnchor); 32857 } 32858 } 32859 } 32860 32861 /** 32862 * Detecting any change on the URL to scroll to the given anchor link 32863 * (a way to detect back history button as we play with the hashes on the URL) 32864 */ 32865 function hashChangeHandler(){ 32866 if(!isScrolling && !options.lockAnchors){ 32867 var value = window.location.hash.replace('#', '').split('/'); 32868 var sectionAnchor = decodeURIComponent(value[0]); 32869 var slideAnchor = decodeURIComponent(value[1]); 32870 32871 //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 32872 var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); 32873 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving); 32874 32875 32876 if(sectionAnchor.length){ 32877 /*in order to call scrollpage() only once for each destination at a time 32878 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 32879 event is fired on every scroll too.*/ 32880 if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor )) { 32881 scrollPageAndSlide(sectionAnchor, slideAnchor); 32882 } 32883 } 32884 } 32885 } 32886 32887 //Sliding with arrow keys, both, vertical and horizontal 32888 function keydownHandler(e) { 32889 32890 clearTimeout(keydownId); 32891 32892 var activeElement = $(':focus'); 32893 32894 if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 32895 activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && 32896 options.keyboardScrolling && options.autoScrolling){ 32897 var keyCode = e.which; 32898 32899 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 32900 var keyControls = [40, 38, 32, 33, 34]; 32901 if($.inArray(keyCode, keyControls) > -1){ 32902 e.preventDefault(); 32903 } 32904 32905 controlPressed = e.ctrlKey; 32906 32907 keydownId = setTimeout(function(){ 32908 onkeydown(e); 32909 },150); 32910 } 32911 } 32912 32913 function tooltipTextHandler(){ 32914 $(this).prev().trigger('click'); 32915 } 32916 32917 //to prevent scrolling while zooming 32918 function keyUpHandler(e){ 32919 if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox 32920 controlPressed = e.ctrlKey; 32921 } 32922 } 32923 32924 //binding the mousemove when the mouse's middle button is released 32925 function mouseDownHandler(e){ 32926 //middle button 32927 if (e.which == 2){ 32928 oldPageY = e.pageY; 32929 container.on('mousemove', mouseMoveHandler); 32930 } 32931 } 32932 32933 //unbinding the mousemove when the mouse's middle button is released 32934 function mouseUpHandler(e){ 32935 //middle button 32936 if (e.which == 2){ 32937 container.off('mousemove'); 32938 } 32939 } 32940 32941 //Scrolling horizontally when clicking on the slider controls. 32942 function slideArrowHandler(){ 32943 var section = $(this).closest(SECTION_SEL); 32944 32945 if ($(this).hasClass(SLIDES_PREV)) { 32946 if(isScrollAllowed.m.left){ 32947 moveSlideLeft(section); 32948 } 32949 } else { 32950 if(isScrollAllowed.m.right){ 32951 moveSlideRight(section); 32952 } 32953 } 32954 } 32955 32956 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 32957 function blurHandler(){ 32958 isWindowFocused = false;
32959 controlPressed = false; 32960 } 32961 32962 //Scrolls to the section when clicking the navigation bullet 32963 function sectionBulletHandler(e){ 32964 e.preventDefault(); 32965 var index = $(this).parent().index(); 32966 scrollPage($(SECTION_SEL).eq(index)); 32967 } 32968 32969 //Scrolls the slider to the given slide destination for the given section 32970 function slideBulletHandler(e){ 32971 e.preventDefault(); 32972 var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); 32973 var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); 32974 32975 landscapeScroll(slides, destiny); 32976 } 32977 32978 /** 32979 * Keydown event 32980 */ 32981 function onkeydown(e){ 32982 var shiftPressed = e.shiftKey; 32983 32984 //do nothing if we can not scroll or we are not using horizotnal key arrows. 32985 if(!canScroll && [37,39].indexOf(e.which) < 0){ 32986 return; 32987 } 32988 32989 switch (e.which) { 32990 //up 32991 case 38: 32992 case 33: 32993 if(isScrollAllowed.k.up){ 32994 moveSectionUp(); 32995 } 32996 break; 32997 32998 //down 32999 case 32: //spacebar 33000 if(shiftPressed && isScrollAllowed.k.up){ 33001 moveSectionUp(); 33002 break; 33003 } 33004 /* falls through */ 33005 case 40: 33006 case 34: 33007 if(isScrollAllowed.k.down){ 33008 moveSectionDown(); 33009 } 33010 break; 33011 33012 //Home 33013 case 36: 33014 if(isScrollAllowed.k.up){ 33015 moveTo(1); 33016 } 33017 break; 33018 33019 //End 33020 case 35: 33021 if(isScrollAllowed.k.down){ 33022 moveTo( $(SECTION_SEL).length ); 33023 } 33024 break; 33025 33026 //left 33027 case 37: 33028 if(isScrollAllowed.k.left){ 33029 moveSlideLeft(); 33030 } 33031 break; 33032 33033 //right 33034 case 39: 33035 if(isScrollAllowed.k.right){ 33036 moveSlideRight(); 33037 } 33038 break; 33039 33040 default: 33041 return; // exit this handler for other keys 33042 } 33043 } 33044 33045 /** 33046 * Detecting the direction of the mouse movement. 33047 * Used only for the middle button of the mouse. 33048 */ 33049 var oldPageY = 0; 33050 function mouseMoveHandler(e){ 33051 if(canScroll){ 33052 // moving up 33053 if (e.pageY < oldPageY && isScrollAllowed.m.up){ 33054 moveSectionUp(); 33055 } 33056 33057 // moving down 33058 else if(e.pageY > oldPageY && isScrollAllowed.m.down){ 33059 moveSectionDown(); 33060 } 33061 } 33062 oldPageY = e.pageY; 33063 } 33064 33065 /** 33066 * Scrolls horizontal sliders. 33067 */ 33068 function landscapeScroll(slides, destiny, direction){ 33069 var section = slides.closest(SECTION_SEL); 33070 var v = { 33071 slides: slides, 33072 destiny: destiny, 33073 direction: direction, 33074 destinyPos: destiny.position(), 33075 slideIndex: destiny.index(), 33076 section: section, 33077 sectionIndex: section.index(SECTION_SEL), 33078 anchorLink: section.data('anchor'), 33079 slidesNav: section.find(SLIDES_NAV_SEL), 33080 slideAnchor: getAnchor(destiny), 33081 prevSlide: section.find(SLIDE_ACTIVE_SEL), 33082 prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(), 33083 33084 //caching the value of isResizing at the momment the function is called 33085 //because it will be checked later inside a setTimeout and the value might change 33086 localIsResizing: isResizing 33087 }; 33088 v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); 33089 v.direction = v.direction ? v.direction : v.xMovement; 33090 33091 //important!! Only do it when not resizing 33092 if(!v.localIsResizing){ 33093 //preventing from scrolling to the next/prev section when using scrollHorizontally 33094 canScroll = false;
33095 } 33096 33097 if(options.onSlideLeave){ 33098 33099 //if the site is not just resizing and readjusting the slides 33100 if(!v.localIsResizing && v.xMovement!=='none'){ 33101 if($.isFunction( options.onSlideLeave )){ 33102 if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){ 33103 slideMoving = false; 33104 return; 33105 } 33106 } 33107 } 33108 } 33109 33110 destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); 33111 33112 if(!v.localIsResizing){ 33113 stopMedia(v.prevSlide); 33114 lazyLoad(destiny); 33115 } 33116 33117 if(!options.loopHorizontal && options.controlArrows){ 33118 //hidding it for the fist slide, showing for the rest 33119 section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0); 33120 33121 //hidding it for the last slide, showing for the rest 33122 section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); 33123 } 33124 33125 //only changing the URL if the slides are in the current section (not for resize re-adjusting) 33126 if(section.hasClass(ACTIVE) && !v.localIsResizing){ 33127 setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex); 33128 } 33129 33130 performHorizontalMove(slides, v, true); 33131 } 33132 33133 33134 function afterSlideLoads(v){ 33135 activeSlidesNavigation(v.slidesNav, v.slideIndex); 33136 33137 //if the site is not just resizing and readjusting the slides 33138 if(!v.localIsResizing){ 33139 $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex); 33140 33141 //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally 33142 //and to prevent double scroll right after a windows resize 33143 canScroll = true; 33144 33145 playMedia(v.destiny); 33146 } 33147 33148 //letting them slide again 33149 slideMoving = false; 33150 } 33151 33152 /** 33153 * Performs the horizontal movement. (CSS3 or jQuery) 33154 * 33155 * @param fireCallback {Bool} - determines whether or not to fire the callback 33156 */ 33157 function performHorizontalMove(slides, v, fireCallback){ 33158 var destinyPos = v.destinyPos; 33159 33160 if(options.css3){ 33161 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 33162 33163 addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v); 33164 33165 afterSlideLoadsId = setTimeout(function(){ 33166 fireCallback && afterSlideLoads(v); 33167 }, options.scrollingSpeed, options.easing); 33168 }else{ 33169 slides.animate({ 33170 scrollLeft : Math.round(destinyPos.left) 33171 }, options.scrollingSpeed, options.easing, function() { 33172 33173 fireCallback && afterSlideLoads(v); 33174 }); 33175 } 33176 } 33177 33178 /** 33179 * Sets the state for the horizontal bullet navigations. 33180 */ 33181 function activeSlidesNavigation(slidesNav, slideIndex){ 33182 slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); 33183 slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); 33184 } 33185 33186 var previousHeight = windowsHeight; 33187 33188 //when resizing the site, we adjust the heights of the sections, slimScroll... 33189 function resizeHandler(){ 33190 //checking if it needs to get responsive 33191 responsive(); 33192 33193 // rebuild immediately on touch devices 33194 if (isTouchDevice) { 33195 var activeElement = $(document.activeElement); 33196 33197 //if the keyboard is NOT visible 33198 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 33199 var currentHeight = $window.height(); 33200 33201 //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) 33202 if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 33203 reBuild(true); 33204 previousHeight = currentHeight; 33205 } 33206 } 33207 }else{ 33208 //in order to call the functions only when the resize is finished 33209 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 33210 clearTimeout(resizeId); 33211 33212 resizeId = setTimeout(function(){ 33213 reBuild(true); 33214 }, 350); 33215 } 33216 } 33217 33218 /** 33219 * Checks if the site needs to get responsive and disables autoScrolling if so. 33220 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 33221 */ 33222 function responsive(){ 33223 var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity 33224 var heightLimit = options.responsiveHeight; 33225 33226 //only calculating what we need. Remember its called on the resize event. 33227 var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; 33228 var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; 33229 33230 if(widthLimit && heightLimit){ 33231 setResponsive(isBreakingPointWidth || isBreakingPointHeight); 33232 } 33233 else if(widthLimit){ 33234 setResponsive(isBreakingPointWidth); 33235 } 33236 else if(heightLimit){ 33237 setResponsive(isBreakingPointHeight); 33238 } 33239 } 33240 33241 /** 33242 * Adds transition animations for the given element 33243 */ 33244 function addAnimation(container, element){ 33245 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 33246 33247 container.removeClass(NO_TRANSITION); 33248 return container.css({
33249 '-webkit-transition': transition, 33250 'transition': transition 33251 }); 33252 } 33253 33254 /** 33255 * Remove transition animations for the given element 33256 */ 33257 function removeAnimation(element){ 33258 return element.addClass(NO_TRANSITION); 33259 } 33260 33261 /** 33262 * Activating the vertical navigation bullets according to the given slide name. 33263 */ 33264 function activateNavDots(name, sectionIndex){ 33265 if(options.navigation){ 33266 $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); 33267 if(name){ 33268 $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); 33269 }else{ 33270 $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); 33271 } 33272 } 33273 } 33274 33275 /** 33276 * Activating the website main menu elements according to the given slide name. 33277 */ 33278 function activateMenuElement(name){ 33279 if(options.menu){ 33280 $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); 33281 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); 33282 } 33283 } 33284 33285 /** 33286 * Sets to active the current menu and vertical nav items. 33287 */ 33288 function activateMenuAndNav(anchor, index){ 33289 activateMenuElement(anchor); 33290 activateNavDots(anchor, index); 33291 } 33292 33293 /** 33294 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 33295 * from the current section. 33296 */ 33297 function getYmovement(destiny){ 33298 var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); 33299 var toIndex = destiny.index(SECTION_SEL); 33300 if( fromIndex == toIndex){ 33301 return 'none'; 33302 } 33303 if(fromIndex > toIndex){ 33304 return 'up'; 33305 } 33306 return 'down'; 33307 } 33308 33309 /** 33310 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 33311 * from the current slide. 33312 */ 33313 function getXmovement(fromIndex, toIndex){ 33314 if( fromIndex == toIndex){ 33315 return 'none'; 33316 } 33317 if(fromIndex > toIndex){ 33318 return 'left'; 33319 } 33320 return 'right'; 33321 } 33322 33323 /** 33324 * Checks if the element needs scrollbar and if the user wants to apply it. 33325 * If so it creates it. 33326 * 33327 * @param {Object} element jQuery object of the section or slide 33328 */ 33329 function createScrollBar(element){ 33330 //User doesn't want scrollbar here? Sayonara baby! 33331 if(element.hasClass('fp-noscroll')) return; 33332 33333 //needed to make `scrollHeight` work under Opera 12 33334 element.css('overflow', 'hidden'); 33335 33336 var scrollOverflowHandler = options.scrollOverflowHandler; 33337 var wrap = scrollOverflowHandler.wrapContent(); 33338 //in case element is a slide 33339 var section = element.closest(SECTION_SEL); 33340 var scrollable = scrollOverflowHandler.scrollable(element); 33341 var contentHeight; 33342 33343 //if there was scroll, the contentHeight will be the one in the scrollable section 33344 if(scrollable.length){ 33345 contentHeight = scrollOverflowHandler.scrollHeight(element); 33346 }else{ 33347 contentHeight = element.get(0).scrollHeight; 33348 if(options.verticalCentered){ 33349 contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight; 33350 } 33351 } 33352 33353 var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top')); 33354 33355 //needs scroll? 33356 if ( contentHeight > scrollHeight) { 33357 //did we already have an scrollbar ? Updating it 33358 if(scrollable.length){ 33359 scrollOverflowHandler.update(element, scrollHeight); 33360 } 33361 //creating the scrolling 33362 else{ 33363 if(options.verticalCentered){ 33364 element.find(TABLE_CELL_SEL).wrapInner(wrap); 33365 }else{ 33366 element.wrapInner(wrap); 33367 } 33368 scrollOverflowHandler.create(element, scrollHeight); 33369 } 33370 } 33371 //removing the scrolling when it is not necessary anymore 33372 else{ 33373 scrollOverflowHandler.remove(element); 33374 } 33375 33376 //undo 33377 element.css('overflow', ''); 33378 } 33379 33380 function addTableClass(element){ 33381 //In case we are styling for the 2nd time as in with reponsiveSlides 33382 if(!element.hasClass(TABLE)){ 33383 element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 33384 } 33385 } 33386 33387 function getTableHeight(element){ 33388 var sectionHeight = windowsHeight; 33389 33390 if(options.paddingTop || options.paddingBottom){ 33391 var section = element; 33392 if(!section.hasClass(SECTION)){ 33393 section = element.closest(SECTION_SEL); 33394 } 33395 33396 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 33397 sectionHeight = (windowsHeight - paddings); 33398 } 33399 33400 return sectionHeight; 33401 } 33402 33403 /** 33404 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 33405 */ 33406 function transformContainer(translate3d, animated){ 33407 if(animated){ 33408 addAnimation(container); 33409 }else{ 33410 removeAnimation(container); 33411 } 33412 33413 container.css(getTransforms(translate3d)); 33414 33415 //syncronously removing the class after the animation has been applied. 33416 setTimeout(function(){ 33417 container.removeClass(NO_TRANSITION); 33418 },10); 33419 } 33420 33421 /** 33422 * Gets a section by its anchor / index 33423 */ 33424 function getSectionByAnchor(sectionAnchor){ 33425 if(!sectionAnchor) return []; 33426 33427 var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); 33428 if(!section.length){ 33429 section = $(SECTION_SEL).eq( sectionAnchor -1); 33430 } 33431 33432 return section; 33433 } 33434 33435 /** 33436 * Gets a slide inside a given section by its anchor / index 33437 */ 33438 function getSlideByAnchor(slideAnchor, section){ 33439 var slides = section.find(SLIDES_WRAPPER_SEL); 33440 var slide = slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]'); 33441
33442 if(!slide.length){ 33443 slide = slides.find(SLIDE_SEL).eq(slideAnchor); 33444 } 33445 33446 return slide; 33447 } 33448 33449 /** 33450 * Scrolls to the given section and slide anchors 33451 */ 33452 function scrollPageAndSlide(destiny, slide){ 33453 var section = getSectionByAnchor(destiny); 33454 33455 //do nothing if there's no section with the given anchor name 33456 if(!section.length) return; 33457 33458 //default slide 33459 if (typeof slide === 'undefined') { 33460 slide = 0; 33461 } 33462 33463 //we need to scroll to the section and then to the slide 33464 if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ 33465 scrollPage(section, function(){ 33466 scrollSlider(section, slide); 33467 }); 33468 } 33469 //if we were already in the section 33470 else{ 33471 scrollSlider(section, slide); 33472 } 33473 } 33474 33475 /** 33476 * Scrolls the slider to the given slide destination for the given section 33477 */ 33478 function scrollSlider(section, slideAnchor){ 33479 if(typeof slideAnchor !== 'undefined'){ 33480 var slides = section.find(SLIDES_WRAPPER_SEL); 33481 var destiny = getSlideByAnchor(slideAnchor, section); 33482 33483 if(destiny.length){ 33484 landscapeScroll(slides, destiny); 33485 } 33486 } 33487 } 33488 33489 /** 33490 * Creates a landscape navigation bar with dots for horizontal sliders. 33491 */ 33492 function addSlidesNavigation(section, numSlides){ 33493 section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>'); 33494 var nav = section.find(SLIDES_NAV_SEL); 33495 33496 //top or bottom 33497 nav.addClass(options.slidesNavPosition); 33498 33499 for(var i=0; i< numSlides; i++){ 33500 nav.find('ul').append('<li><a href="#"><span></span></a></li>'); 33501 } 33502 33503 //centering it 33504 nav.css('margin-left', '-' + (nav.width()/2) + 'px'); 33505 33506 nav.find('li').first().find('a').addClass(ACTIVE); 33507 } 33508 33509 33510 /** 33511 * Sets the state of the website depending on the active section/slide. 33512 * It changes the URL hash when needed and updates the body class. 33513 */ 33514 function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ 33515 var sectionHash = ''; 33516 33517 if(options.anchors.length && !options.lockAnchors){ 33518 33519 //isn't it the first slide? 33520 if(slideIndex){ 33521 if(typeof anchorLink !== 'undefined'){ 33522 sectionHash = anchorLink; 33523 } 33524 33525 //slide without anchor link? We take the index instead. 33526 if(typeof slideAnchor === 'undefined'){ 33527 slideAnchor = slideIndex; 33528 } 33529 33530 lastScrolledSlide = slideAnchor; 33531 setUrlHash(sectionHash + '/' + slideAnchor); 33532 33533 //first slide won't have slide anchor, just the section one 33534 }else if(typeof slideIndex !== 'undefined'){ 33535 lastScrolledSlide = slideAnchor; 33536 setUrlHash(anchorLink); 33537 } 33538 33539 //section without slides 33540 else{ 33541 setUrlHash(anchorLink); 33542 } 33543 } 33544 33545 setBodyClass(); 33546 } 33547 33548 /** 33549 * Sets the URL hash. 33550 */ 33551 function setUrlHash(url){ 33552 //Uncode addition 33553 if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer ) 33554 return false; 33555 33556 if(options.recordHistory){ 33557 location.hash = url; 33558 }else{ 33559 //Uncode addition 33560 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 33561 // if(isTouchDevice || isTouch){ 33562 // window.history.replaceState(undefined, undefined, '#' + url); 33563 // }else{ 33564 // var baseUrl = window.location.href.split('#')[0]; 33565 // window.location.replace( baseUrl + '#' + url ); 33566 // } 33567 return false;
33568 } 33569 } 33570 33571 /** 33572 * Gets the anchor for the given slide / section. Its index will be used if there's none. 33573 */ 33574 function getAnchor(element){ 33575 var anchor = element.data('anchor'); 33576 var index = element.index(); 33577 33578 //Slide without anchor link? We take the index instead. 33579 if(typeof anchor === 'undefined'){ 33580 anchor = index; 33581 } 33582 33583 return anchor; 33584 } 33585 33586 /** 33587 * Sets a class for the body of the page depending on the active section / slide 33588 */ 33589 function setBodyClass(){ 33590 var section = $(SECTION_ACTIVE_SEL); 33591 var slide = section.find(SLIDE_ACTIVE_SEL); 33592 33593 var sectionAnchor = getAnchor(section); 33594 var slideAnchor = getAnchor(slide); 33595 33596 var text = String(sectionAnchor); 33597 33598 if(slide.length){ 33599 text = text + '-' + slideAnchor; 33600 } 33601 33602 //changing slash for dash to make it a valid CSS style 33603 text = text.replace('/', '-').replace('#',''); 33604 33605 //removing previous anchor classes 33606 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 33607 $body[0].className = $body[0].className.replace(classRe, ''); 33608 33609 //adding the current anchor 33610 $body.addClass(VIEWING_PREFIX + '-' + text); 33611 } 33612 33613 /** 33614 * Checks for translate3d support 33615 * @return boolean 33616 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 33617 */ 33618 function support3d() { 33619 var el = document.createElement('p'), 33620 has3d, 33621 transforms = { 33622 'webkitTransform':'-webkit-transform', 33623 'OTransform':'-o-transform', 33624 'msTransform':'-ms-transform', 33625 'MozTransform':'-moz-transform', 33626 'transform':'transform' 33627 }; 33628 33629 // Add it to the body to get the computed style. 33630 document.body.insertBefore(el, null); 33631 33632 for (var t in transforms) { 33633 if (el.style[t] !== undefined) { 33634 el.style[t] = 'translate3d(1px,1px,1px)'; 33635 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 33636 } 33637 } 33638 33639 document.body.removeChild(el); 33640 33641 return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); 33642 } 33643 33644 /** 33645 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 33646 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 33647 */ 33648 function removeMouseWheelHandler(){ 33649 if (document.addEventListener) { 33650 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 33651 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 33652 document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 33653 } else { 33654 document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 33655 } 33656 } 33657 33658 /** 33659 * Adds the auto scrolling action for the mouse wheel and trackpad. 33660 * After this function is called, the mousewheel and trackpad movements will scroll through sections 33661 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 33662 */ 33663 function addMouseWheelHandler(){ 33664 var prefix = ''; 33665 var _addEventListener; 33666 33667 if (window.addEventListener){ 33668 _addEventListener = "addEventListener"; 33669 }else{ 33670 _addEventListener = "attachEvent"; 33671 prefix = 'on'; 33672 } 33673 33674 // detect available wheel event 33675 var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 33676 document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 33677 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 33678 var passiveEvent = g_supportsPassive ? {passive: false }
33678: false; 33679 33680 33681 if(support == 'DOMMouseScroll'){ 33682 document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent); 33683 } 33684 33685 //handle MozMousePixelScroll in older Firefox 33686 else{ 33687 document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent); 33688 } 33689 } 33690 33691 /** 33692 * Binding the mousemove when the mouse's middle button is pressed 33693 */ 33694 function addMiddleWheelHandler(){ 33695 container 33696 .on('mousedown', mouseDownHandler) 33697 .on('mouseup', mouseUpHandler); 33698 } 33699 33700 /** 33701 * Unbinding the mousemove when the mouse's middle button is released 33702 */ 33703 function removeMiddleWheelHandler(){ 33704 container 33705 .off('mousedown', mouseDownHandler) 33706 .off('mouseup', mouseUpHandler); 33707 } 33708 33709 /** 33710 * Adds the possibility to auto scroll through sections on touch devices. 33711 */ 33712 function addTouchHandler(){ 33713 if(isTouchDevice || isTouch){ 33714 if(options.autoScrolling){ 33715 $body.off(events.touchmove).on(events.touchmove, preventBouncing); 33716 } 33717 33718 $(WRAPPER_SEL) 33719 .off(events.touchstart).on(events.touchstart, touchStartHandler) 33720 .off(events.touchmove).on(events.touchmove, touchMoveHandler); 33721 } 33722 } 33723 33724 /** 33725 * Removes the auto scrolling for touch devices. 33726 */ 33727 function removeTouchHandler(){ 33728 if(isTouchDevice || isTouch){ 33729 $(WRAPPER_SEL) 33730 .off(events.touchstart) 33731 .off(events.touchmove); 33732 } 33733 } 33734 33735 /* 33736 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11) 33737 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 33738 */ 33739 function getMSPointer(){ 33740 var pointer; 33741 33742 //IE >= 11 & rest of browsers 33743 if(window.PointerEvent){ 33744 pointer = { down: 'pointerdown', move: 'pointermove'}; 33745 } 33746 33747 //IE < 11 33748 else{ 33749 pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; 33750 } 33751 33752 return pointer; 33753 } 33754 33755 /** 33756 * Gets the pageX and pageY properties depending on the browser. 33757 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 33758 */ 33759 function getEventsPage(e){ 33760 var events = []; 33761 33762 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 33763 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 33764 33765 //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 33766 if(isTouch && isReallyTouch(e) && options.scrollBar){ 33767 events.y = e.touches[0].pageY; 33768 events.x = e.touches[0].pageX; 33769 } 33770 33771 return events; 33772 } 33773 33774 /** 33775 * Slides silently (with no animation) the active slider to the given slide. 33776 * @param noCallback {bool} true or defined -> no callbacks 33777 */ 33778 function silentLandscapeScroll(activeSlide, noCallbacks){ 33779 setScrollingSpeed (0, 'internal'); 33780 33781 if(typeof noCallbacks !== 'undefined'){ 33782 //preventing firing callbacks afterSlideLoad etc. 33783 isResizing = true; 33784 } 33785 33786 landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); 33787 33788 if(typeof noCallbacks !== 'undefined'){ 33789 isResizing = false; 33790 } 33791 33792 setScrollingSpeed(originals.scrollingSpeed, 'internal'); 33793 } 33794 33795 /** 33796 * Scrolls silently (with no animation) the page to the given Y position. 33797 */ 33798 function silentScroll(top){ 33799 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 33800 // that's why we round it to 0. 33801 var roundedTop = Math.round(top); 33802 33803 if (options.css3 && options.autoScrolling && !options.scrollBar){ 33804 var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; 33805 transformContainer(translate3d, false); 33806 } 33807 else if(options.autoScrolling && !options.scrollBar){ 33808 container.css('top', -roundedTop); 33809 } 33810 else{ 33811 $htmlBody.scrollTop(roundedTop); 33812 } 33813 } 33814 33815 /** 33816 * Returns the cross-browser transform string. 33817 */ 33818 function getTransforms(translate3d){ 33819 return {
33820 '-webkit-transform': translate3d, 33821 '-moz-transform': translate3d, 33822 '-ms-transform':translate3d, 33823 'transform': translate3d 33824 }; 33825 } 33826 33827 /** 33828 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 33829 * @type m (mouse) or k (keyboard) 33830 */ 33831 function setIsScrollAllowed(value, direction, type){ 33832 switch (direction){ 33833 case 'up': isScrollAllowed[type].up = value; break; 33834 case 'down': isScrollAllowed[type].down = value; break; 33835 case 'left': isScrollAllowed[type].left = value; break; 33836 case 'right': isScrollAllowed[type].right = value; break; 33837 case 'all': 33838 if(type == 'm'){ 33839 setAllowScrolling(value); 33840 }else{ 33841 setKeyboardScrolling(value); 33842 } 33843 } 33844 } 33845 33846 /* 33847 * Destroys fullpage.js plugin events and optinally its html markup and styles 33848 */ 33849 function destroy(all){ 33850 setAutoScrolling(false, 'internal'); 33851 setAllowScrolling(false); 33852 setKeyboardScrolling(false); 33853 container.addClass(DESTROYED); 33854 33855 clearTimeout(afterSlideLoadsId); 33856 clearTimeout(afterSectionLoadsId); 33857 clearTimeout(resizeId); 33858 clearTimeout(scrollId); 33859 clearTimeout(scrollId2); 33860 33861 $window 33862 .off('scroll', scrollHandler) 33863 .off('hashchange', hashChangeHandler) 33864 .off('resize', resizeHandler); 33865 33866 $document 33867 .off('click touchstart', SECTION_NAV_SEL + ' a') 33868 .off('mouseenter', SECTION_NAV_SEL + ' li') 33869 .off('mouseleave', SECTION_NAV_SEL + ' li') 33870 .off('click touchstart', SLIDES_NAV_LINK_SEL) 33871 .off('mouseover', options.normalScrollElements) 33872 .off('mouseout', options.normalScrollElements); 33873 33874 $(SECTION_SEL) 33875 .off('click touchstart', SLIDES_ARROW_SEL); 33876 33877 clearTimeout(afterSlideLoadsId); 33878 clearTimeout(afterSectionLoadsId); 33879 33880 //lets make a mess! 33881 if(all){ 33882 destroyStructure(); 33883 } 33884 } 33885 33886 /* 33887 * Removes inline styles added by fullpage.js 33888 */ 33889 function destroyStructure(){ 33890 //reseting the `top` or `translate` properties to 0 33891 silentScroll(0); 33892 33893 //loading all the lazy load content 33894 container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 33895 setSrc($(this), 'src'); 33896 }); 33897 33898 container.find('img[data-srcset]').each(function(){ 33899 setSrc($(this), 'srcset'); 33900 }); 33901 33902 $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); 33903 33904 //removing inline styles 33905 $(SECTION_SEL).css( { 33906 'height': '', 33907 'background-color' : '', 33908 'padding': '' 33909 }); 33910 33911 $(SLIDE_SEL).css( { 33912 'width': '' 33913 }); 33914 33915 container.css({ 33916 'height': '', 33917 'position': '', 33918 '-ms-touch-action': '', 33919 'touch-action': '' 33920 }); 33921 33922 $htmlBody.css({ 33923 'overflow': '', 33924 'height': '' 33925 }); 33926 33927 // remove .fp-enabled class 33928 $('html').removeClass(ENABLED); 33929 33930 // remove .fp-responsive class 33931 $body.removeClass(RESPONSIVE); 33932 33933 // remove all of the .fp-viewing- classes 33934 $.each($body.get(0).className.split(/\s+/), function (index, className) { 33935 if (className.indexOf(VIEWING_PREFIX) === 0) { 33936 $body.removeClass(className); 33937 } 33938 }); 33939 33940 //removing added classes 33941 $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ 33942 options.scrollOverflowHandler.remove($(this)); 33943 $(this).removeClass(TABLE + ' ' + ACTIVE); 33944 }); 33945 33946 removeAnimation(container); 33947 33948 //Unwrapping content 33949 container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ 33950 //unwrap not being use in case there's no child element inside and its just text 33951 $(this).replaceWith(this.childNodes); 33952 }); 33953 33954 //removing the applied transition from the fullpage wrapper 33955 container.css({
33956 '-webkit-transition': 'none', 33957 'transition': 'none' 33958 }); 33959 33960 //scrolling the page to the top with no animation 33961 $htmlBody.scrollTop(0); 33962 33963 //removing selectors 33964 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 33965 $.each(usedSelectors, function(index, value){ 33966 $('.' + value).removeClass(value); 33967 }); 33968 } 33969 33970 /* 33971 * Sets the state for a variable with multiple states (original, and temporal) 33972 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 33973 * This function is used to keep track of both states, the original and the temporal one. 33974 * If type is not 'internal', then we assume the user is globally changing the variable. 33975 */ 33976 function setVariableState(variable, value, type){ 33977 options[variable] = value; 33978 if(type !== 'internal'){ 33979 originals[variable] = value; 33980 } 33981 } 33982 33983 /** 33984 * Displays warnings 33985 */ 33986 function displayWarnings(){ 33987 var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax']; 33988 //UNCODE.addition 33989 // if($('html').hasClass(ENABLED)){ 33990 // showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 33991 // return; 33992 // } 33993 33994 // Disable mutually exclusive settings 33995 //UNCODE.addition 33996 // if (options.continuousVertical && 33997 // (options.loopTop || options.loopBottom)) { 33998 // options.continuousVertical = false;
33999 // showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34000 // } 34001 34002 // if(options.scrollBar && options.scrollOverflow){ 34003 // showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); 34004 // } 34005 34006 // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){ 34007 // options.continuousVertical = false; 34008 // showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34009 // } 34010 34011 //using extensions? Wrong file! 34012 $.each(extensions, function(index, extension){ 34013 //is the option set to true? 34014 if(options[extension]){ 34015 showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension); 34016 } 34017 }); 34018 34019 //anchors can not have the same value as any element ID or NAME 34020 $.each(options.anchors, function(index, name){ 34021 34022 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 34023 var nameAttr = $document.find('[name]').filter(function() { 34024 return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); 34025 }); 34026 34027 var idAttr = $document.find('[id]').filter(function() { 34028 return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); 34029 }); 34030 34031 if(idAttr.length || nameAttr.length ){ 34032 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); 34033 idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); 34034 nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); 34035 } 34036 }); 34037 } 34038 34039 /** 34040 * Shows a message in the console of the given type. 34041 */ 34042 function showError(type, text){ 34043 console && console[type] && console[type]('fullPage: ' + text); 34044 } 34045 34046 }; //end of $.fn.fullpage 34047 34048 if(typeof IScroll !== 'undefined'){ 34049 /* 34050 * Turns iScroll `mousewheel` option off dynamically 34051 * https://github.com/cubiq/iscroll/issues/1036 34052 */ 34053 IScroll.prototype.wheelOn = function () { 34054 this.wrapper.addEventListener('wheel', this); 34055 this.wrapper.addEventListener('mousewheel', this); 34056 this.wrapper.addEventListener('DOMMouseScroll', this); 34057 }; 34058 34059 /* 34060 * Turns iScroll `mousewheel` option on dynamically 34061 * https://github.com/cubiq/iscroll/issues/1036 34062 */ 34063 IScroll.prototype.wheelOff = function () { 34064 this.wrapper.removeEventListener('wheel', this); 34065 this.wrapper.removeEventListener('mousewheel', this); 34066 this.wrapper.removeEventListener('DOMMouseScroll', this); 34067 }; 34068 } 34069 34070 /** 34071 * An object to handle overflow scrolling. 34072 * This uses jquery.slimScroll to accomplish overflow scrolling. 34073 * It is possible to pass in an alternate scrollOverflowHandler 34074 * to the fullpage.js option that implements the same functions 34075 * as this handler. 34076 * 34077 * @type {Object} 34078 */ 34079 var iscrollHandler = { 34080 refreshId: null, 34081 iScrollInstances: [], 34082 34083 // Enables or disables the mouse wheel for the active section or all slides in it 34084 toggleWheel: function(value){ 34085 var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL); 34086 scrollable.each(function(){ 34087 var iScrollInstance = $(this).data('iscrollInstance'); 34088 if(typeof iScrollInstance !== 'undefined' && iScrollInstance){ 34089 if(value){ 34090 iScrollInstance.wheelOn(); 34091 } 34092 else{ 34093 iScrollInstance.wheelOff(); 34094 } 34095 } 34096 }); 34097 }, 34098 34099 /** 34100 * Turns off iScroll for the destination section. 34101 * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
34102 * scroll the destination section/slide before the sections animations ends. 34103 */ 34104 onLeave: function(){ 34105 iscrollHandler.toggleWheel(false); 34106 }, 34107 34108 // Turns off iScroll for the leaving section 34109 beforeLeave: function(){ 34110 iscrollHandler.onLeave() 34111 }, 34112 34113 // Turns on iScroll on section load 34114 afterLoad: function(){ 34115 iscrollHandler.toggleWheel(true); 34116 }, 34117 34118 /** 34119 * Called when overflow scrolling is needed for a section. 34120 * 34121 * @param {Object} element jQuery object containing current section 34122 * @param {Number} scrollHeight Current window height in pixels 34123 */ 34124 create: function(element, scrollHeight) { 34125 var scrollable = element.find(SCROLLABLE_SEL); 34126 34127 scrollable.height(scrollHeight); 34128 scrollable.each(function() { 34129 var $this = $(this); 34130 var iScrollInstance = $this.data('iscrollInstance'); 34131 if (iScrollInstance) { 34132 $.each(iscrollHandler.iScrollInstances, function(){ 34133 $(this).destroy(); 34134 }); 34135 } 34136 34137 iScrollInstance = new IScroll($this.get(0), iscrollOptions); 34138 iscrollHandler.iScrollInstances.push(iScrollInstance); 34139 34140 //off by default until the section gets active 34141 iScrollInstance.wheelOff(); 34142 34143 $this.data('iscrollInstance', iScrollInstance); 34144 }); 34145 }, 34146 34147 /** 34148 * Return a boolean depending on whether the scrollable element is a 34149 * the end or at the start of the scrolling depending on the given type. 34150 * 34151 * @param {String} type Either 'top' or 'bottom' 34152 * @param {Object} scrollable jQuery object for the scrollable element 34153 * @return {Boolean} 34154 */ 34155 isScrolled: function(type, scrollable) { 34156 var scroller = scrollable.data('iscrollInstance'); 34157 34158 //no scroller? 34159 if (!scroller) { 34160 return true; 34161 } 34162 34163 //Uncode addition 34164 var uncode_body_borders = parseFloat($('.body-borders').attr('data-border')) || 0; 34165 //End Uncode addition 34166 34167 if (type === 'top') { 34168 return scroller.y >= 0 && !scrollable.scrollTop(); 34169 } else if (type === 'bottom') { 34170 //Uncode change 34171 // return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34172 return (0 - scroller.y) + scrollable.scrollTop() + 1 + ( uncode_body_borders * 2 ) + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34173 //End Uncode change 34174 } 34175 }, 34176 34177 /** 34178 * Returns the scrollable element for the given section. 34179 * If there are landscape slides, will only return a scrollable element 34180 * if it is in the active slide. 34181 * 34182 * @param {Object} activeSection jQuery object containing current section 34183 * @return {Boolean} 34184 */ 34185 scrollable: function(activeSection){ 34186 // if there are landscape slides, we check if the scrolling bar is in the current one or not 34187 if (activeSection.find(SLIDES_WRAPPER_SEL).length) { 34188 return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL); 34189 } 34190 return activeSection.find(SCROLLABLE_SEL); 34191 }, 34192 34193 /** 34194 * Returns the scroll height of the wrapped content. 34195 * If this is larger than the window height minus section padding, 34196 * overflow scrolling is needed. 34197 * 34198 * @param {Object} element jQuery object containing current section 34199 * @return {Number} 34200 */ 34201 scrollHeight: function(element) { 34202 return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight; 34203 }, 34204 34205 /** 34206 * Called when overflow scrolling is no longer needed for a section. 34207 * 34208 * @param {Object}
34208 element jQuery object containing current section 34209 */ 34210 remove: function(element) { 34211 var scrollable = element.find(SCROLLABLE_SEL); 34212 if (scrollable.length) { 34213 var iScrollInstance = scrollable.data('iscrollInstance'); 34214 iScrollInstance.destroy(); 34215 34216 scrollable.data('iscrollInstance', null); 34217 } 34218 element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap(); 34219 }, 34220 34221 /** 34222 * Called when overflow scrolling has already been setup but the 34223 * window height has potentially changed. 34224 * 34225 * @param {Object} element jQuery object containing current section 34226 * @param {Number} scrollHeight Current window height in pixels 34227 */ 34228 update: function(element, scrollHeight) { 34229 //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a 34230 //short period of time. 34231 //it also comes on handy because iScroll requires the use of timeout when using `refresh`. 34232 clearTimeout(iscrollHandler.refreshId); 34233 iscrollHandler.refreshId = setTimeout(function(){ 34234 $.each(iscrollHandler.iScrollInstances, function(){ 34235 $(this).get(0).refresh(); 34236 }); 34237 }, 150); 34238 34239 //updating the wrappers height 34240 element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px'); 34241 }, 34242 34243 /** 34244 * Called to get any additional elements needed to wrap the section 34245 * content in order to facilitate overflow scrolling. 34246 * 34247 * @return {String|Object} Can be a string containing HTML, 34248 * a DOM element, or jQuery object. 34249 */ 34250 wrapContent: function() { 34251 return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>'; 34252 } 34253 }; 34254}); 34255 34256(function (global, factory) { 34257 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 34258 typeof define === 'function' && define.amd ? define(['exports'], factory) : 34259 (global = global || self, factory(global.window = global.window || {})); 34260}(this, (function (exports) { 'use strict'; 34261 34262 /*! 34263 * ScrollTrigger 3.8.0 34264 * https://greensock.com 34265 * 34266 * @license Copyright 2008-2021, GreenSock. All rights reserved. 34267 * Subject to the terms at https://greensock.com/standard-license or for 34268 * Club GreenSock members, the agreement issued with that membership. 34269 * @author: Jack Doyle, [email protected] 34270 */ 34271 var gsap, 34272 _coreInitted, 34273 _win, 34274 _doc, 34275 _docEl, 34276 _body, 34277 _root, 34278 _resizeDelay, 34279 _raf, 34280 _request, 34281 _toArray, 34282 _clamp, 34283 _time2, 34284 _syncInterval, 34285 _refreshing, 34286 _pointerIsDown, 34287 _transformProp, 34288 _i, 34289 _prevWidth, 34290 _prevHeight, 34291 _autoRefresh, 34292 _sort, 34293 _suppressOverwrites, 34294 _ignoreResize, 34295 _limitCallbacks, 34296 _startup = 1, 34297 _proxies = [], 34298 _scrollers = [], 34299 _getTime = Date.now, 34300 _time1 = _getTime(), 34301 _lastScrollTime = 0, 34302 _enabled = 1, 34303 _passThrough = function _passThrough(v) { 34304 return v; 34305 }, 34306 _getTarget = function _getTarget(t) { 34307 return _toArray(t)[0] || (_isString(t) ? console.warn("Element not found:", t) : null); 34308 }, 34309 _round = function _round(value) { 34310 return Math.round(value * 100000) / 100000 || 0; 34311 }, 34312 _windowExists = function _windowExists() { 34313 return typeof window !== "undefined"; 34314 }, 34315 _getGSAP = function _getGSAP() { 34316 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 34317 }, 34318 _isViewport = function _isViewport(e) { 34319 return !!~_root.indexOf(e); 34320 }, 34321 _getProxyProp = function _getProxyProp(element, property) { 34322 return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; 34323 }, 34324 _getScrollFunc = function _getScrollFunc(element, _ref) { 34325 var s = _ref.s, 34326 sc = _ref.sc; 34327 34328 var i = _scrollers.indexOf(element), 34329 offset = sc === _vertical.sc ? 1 : 2; 34330 34331 !~i && (i = _scrollers.push(element) - 1); 34332 return _scrollers[i + offset] || (_scrollers[i + offset] = _getProxyProp(element, s) || (_isViewport(element) ? sc : function (value) { 34333 return arguments.length ? element[s] = value : element[s]; 34334 })); 34335 }, 34336 _getBoundsFunc = function _getBoundsFunc(element) { 34337 return _getProxyProp(element, "getBoundingClientRect") || (_isViewport(element) ? function () { 34338 _winOffsets.width = _win.innerWidth; 34339 _winOffsets.height = _win.innerHeight; 34340 return _winOffsets; 34341 } : function () { 34342 return _getBounds(element); 34343 }); 34344 }, 34345 _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref2) { 34346 var d = _ref2.d, 34347 d2 = _ref2.d2, 34348 a = _ref2.a; 34349 return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () { 34350 return a()[d]; 34351 } : function () { 34352 return (isViewport ? _win["inner" + d2] : scroller["client" + d2]) || 0; 34353 }; 34354 }, 34355 _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) { 34356 return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () { 34357 return _winOffsets; 34358 }; 34359 }, 34360 _maxScroll = function _maxScroll(element, _ref3) { 34361 var s = _ref3.s, 34362 d2 = _ref3.d2, 34363 d = _ref3.d, 34364 a = _ref3.a; 34365 return (s = "scroll" + d2) && (a = _getProxyProp(element, s)) ? a() - _getBoundsFunc(element)()[d] : _isViewport(element) ? (_body[s] || _docEl[s]) - (_win["inner" + d2] || _docEl["client" + d2] || _body["client" + d2]) : element[s] - element["offset" + d2]; 34366 }, 34367 _iterateAutoRefresh = function _iterateAutoRefresh(func, events) { 34368 for (var i = 0; i < _autoRefresh.length; i += 3) {
vendor: 5,689 bytes, lines 34369-34573
34369 (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]); 34370 } 34371 }, 34372 _isString = function _isString(value) { 34373 return typeof value === "string"; 34374 }, 34375 _isFunction = function _isFunction(value) { 34376 return typeof value === "function"; 34377 }, 34378 _isNumber = function _isNumber(value) { 34379 return typeof value === "number"; 34380 }, 34381 _isObject = function _isObject(value) { 34382 return typeof value === "object"; 34383 }, 34384 _callIfFunc = function _callIfFunc(value) { 34385 return _isFunction(value) && value(); 34386 }, 34387 _combineFunc = function _combineFunc(f1, f2) { 34388 return function () { 34389 var result1 = _callIfFunc(f1), 34390 result2 = _callIfFunc(f2); 34391 34392 return function () { 34393 _callIfFunc(result1); 34394 34395 _callIfFunc(result2); 34396 }; 34397 }; 34398 }, 34399 _endAnimation = function _endAnimation(animation, reversed, pause) { 34400 return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause(); 34401 }, 34402 _callback = function _callback(self, func) { 34403 var result = func(self); 34404 result && result.totalTime && (self.callbackAnimation = result); 34405 }, 34406 _abs = Math.abs, 34407 _scrollLeft = "scrollLeft", 34408 _scrollTop = "scrollTop", 34409 _left = "left", 34410 _top = "top", 34411 _right = "right", 34412 _bottom = "bottom", 34413 _width = "width", 34414 _height = "height", 34415 _Right = "Right", 34416 _Left = "Left", 34417 _Top = "Top", 34418 _Bottom = "Bottom", 34419 _padding = "padding", 34420 _margin = "margin", 34421 _Width = "Width", 34422 _Height = "Height", 34423 _px = "px", 34424 _horizontal = { 34425 s: _scrollLeft, 34426 p: _left, 34427 p2: _Left, 34428 os: _right, 34429 os2: _Right, 34430 d: _width, 34431 d2: _Width, 34432 a: "x", 34433 sc: function sc(value) { 34434 return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; 34435 } 34436 }, 34437 _vertical = { 34438 s: _scrollTop, 34439 p: _top, 34440 p2: _Top, 34441 os: _bottom, 34442 os2: _Bottom, 34443 d: _height, 34444 d2: _Height, 34445 a: "y", 34446 op: _horizontal, 34447 sc: function sc(value) { 34448 return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; 34449 } 34450 }, 34451 _getComputedStyle = function _getComputedStyle(element) { 34452 return _win.getComputedStyle(element); 34453 }, 34454 _makePositionable = function _makePositionable(element) { 34455 var position = _getComputedStyle(element).position; 34456 34457 element.style.position = position === "absolute" || position === "fixed" ? position : "relative"; 34458 }, 34459 _setDefaults = function _setDefaults(obj, defaults) { 34460 for (var p in defaults) { 34461 p in obj || (obj[p] = defaults[p]); 34462 } 34463 34464 return obj; 34465 }, 34466 _getBounds = function _getBounds(element, withoutTransforms) { 34467 var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap.to(element, { 34468 x: 0, 34469 y: 0, 34470 xPercent: 0, 34471 yPercent: 0, 34472 rotation: 0, 34473 rotationX: 0, 34474 rotationY: 0, 34475 scale: 1, 34476 skewX: 0, 34477 skewY: 0 34478 }).progress(1), 34479 bounds = element.getBoundingClientRect(); 34480 tween && tween.progress(0).kill(); 34481 return bounds; 34482 }, 34483 _getSize = function _getSize(element, _ref4) { 34484 var d2 = _ref4.d2; 34485 return element["offset" + d2] || element["client" + d2] || 0; 34486 }, 34487 _getLabelRatioArray = function _getLabelRatioArray(timeline) { 34488 var a = [], 34489 labels = timeline.labels, 34490 duration = timeline.duration(), 34491 p; 34492 34493 for (p in labels) { 34494 a.push(labels[p] / duration); 34495 } 34496 34497 return a; 34498 }, 34499 _getClosestLabel = function _getClosestLabel(animation) { 34500 return function (value) { 34501 return gsap.utils.snap(_getLabelRatioArray(animation), value); 34502 }; 34503 }, 34504 _snapDirectional = function _snapDirectional(snapIncrementOrArray) { 34505 var snap = gsap.utils.snap(snapIncrementOrArray), 34506 a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) { 34507 return a - b; 34508 }); 34509 return a ? function (value, direction) { 34510 var i; 34511 34512 if (!direction) { 34513 return snap(value); 34514 } 34515 34516 if (direction > 0) { 34517 value -= 1e-4; 34518 34519 for (i = 0; i < a.length; i++) { 34520 if (a[i] >= value) { 34521 return a[i]; 34522 } 34523 } 34524 34525 return a[i - 1]; 34526 } else { 34527 i = a.length; 34528 value += 1e-4; 34529 34530 while (i--) { 34531 if (a[i] <= value) { 34532 return a[i]; 34533 } 34534 } 34535 } 34536 34537 return a[0]; 34538 } : function (value, direction) { 34539 var snapped = snap(value); 34540 return !direction || Math.abs(snapped - value) < 0.001 || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray); 34541 }; 34542 }, 34543 _getLabelAtDirection = function _getLabelAtDirection(timeline) { 34544 return function (value, st) { 34545 return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction); 34546 }; 34547 }, 34548 _multiListener = function _multiListener(func, element, types, callback) { 34549 return types.split(",").forEach(function (type) { 34550 return func(element, type, callback); 34551 }); 34552 }, 34553 _addListener = function _addListener(element, type, func) { 34554 return element.addEventListener(type, func, { 34555 passive: true 34556 }); 34557 }, 34558 _removeListener = function _removeListener(element, type, func) { 34559 return element.removeEventListener(type, func); 34560 }, 34561 _markerDefaults = { 34562 startColor: "green", 34563 endColor: "red", 34564 indent: 0, 34565 fontSize: "16px", 34566 fontWeight: "normal" 34567 }, 34568 _defaults = { 34569 toggleActions: "play", 34570 anticipatePin: 0 34571 }, 34572 _keywords = { 34573 top: 0,
34574 left: 0, 34575 center: 0.5, 34576 bottom: 1, 34577 right: 1 34578 }, 34579 _offsetToPx = function _offsetToPx(value, size) { 34580 if (_isString(value)) { 34581 var eqIndex = value.indexOf("="), 34582 relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0; 34583 34584 if (~eqIndex) { 34585 value.indexOf("%") > eqIndex && (relative *= size / 100); 34586 value = value.substr(0, eqIndex - 1); 34587 } 34588 34589 value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0); 34590 } 34591 34592 return value; 34593 }, 34594 _createMarker = function _createMarker(type, name, container, direction, _ref5, offset, matchWidthEl, containerAnimation) { 34595 var startColor = _ref5.startColor, 34596 endColor = _ref5.endColor, 34597 fontSize = _ref5.fontSize, 34598 indent = _ref5.indent, 34599 fontWeight = _ref5.fontWeight; 34600 34601 var e = _doc.createElement("div"), 34602 useFixedPosition = _isViewport(container) || _getProxyProp(container, "pinType") === "fixed", 34603 isScroller = type.indexOf("scroller") !== -1, 34604 parent = useFixedPosition ? _body : container, 34605 isStart = type.indexOf("start") !== -1, 34606 color = isStart ? startColor : endColor, 34607 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;"; 34608 34609 css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;"); 34610 (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;"); 34611 matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;"); 34612 e._isStart = isStart; 34613 e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : "")); 34614 e.style.cssText = css; 34615 e.innerText = name || name === 0 ? type + "-" + name : type; 34616 parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e); 34617 e._offset = e["offset" + direction.op.d2]; 34618 34619 _positionMarker(e, 0, direction, isStart); 34620 34621 return e; 34622 }, 34623 _positionMarker = function _positionMarker(marker, start, direction, flipped) { 34624 var vars = { 34625 display: "block" 34626 }, 34627 side = direction[flipped ? "os2" : "p2"], 34628 oppositeSide = direction[flipped ? "p2" : "os2"]; 34629 marker._isFlipped = flipped; 34630 vars[direction.a + "Percent"] = flipped ? -100 : 0; 34631 vars[direction.a] = flipped ? "1px" : 0; 34632 vars["border" + side + _Width] = 1; 34633 vars["border" + oppositeSide + _Width] = 0; 34634 vars[direction.p] = start + "px"; 34635 gsap.set(marker, vars); 34636 }, 34637 _triggers = [], 34638 _ids = {}, 34639 _sync = function _sync() { 34640 return _getTime() - _lastScrollTime > 20 && _updateAll(); 34641 }, 34642 _onScroll = function _onScroll() { 34643 var time = _getTime(); 34644 34645 if (_lastScrollTime !== time) { 34646 _updateAll(); 34647 34648 _lastScrollTime || _dispatch("scrollStart"); 34649 _lastScrollTime = time; 34650 } else if (!_request) { 34651 _request = _raf(_updateAll); 34652 } 34653 }, 34654 _onResize = function _onResize() { 34655 return !_refreshing && !_ignoreResize && !_doc.fullscreenElement && _resizeDelay.restart(true); 34656 }, 34657 _listeners = {}, 34658 _emptyArray = [], 34659 _media = [], 34660 _creatingMedia, 34661 _lastMediaTick, 34662 _onMediaChange = function _onMediaChange(e) { 34663 var tick = gsap.ticker.frame, 34664 matches = [], 34665 i = 0, 34666 index; 34667 34668 if (_lastMediaTick !== tick || _startup) { 34669 _revertAll(); 34670 34671 for (; i < _media.length; i += 4) { 34672 index = _win.matchMedia(_media[i]).matches; 34673 34674 if (index !== _media[i + 3]) { 34675 _media[i + 3] = index; 34676 index ? matches.push(i) : _revertAll(1, _media[i]) || _isFunction(_media[i + 2]) && _media[i + 2](); 34677 } 34678 } 34679 34680 _revertRecorded(); 34681 34682 for (i = 0; i < matches.length; i++) { 34683 index = matches[i]; 34684 _creatingMedia = _media[index]; 34685 _media[index + 2] = _media[index + 1](e); 34686 } 34687 34688 _creatingMedia = 0; 34689 _coreInitted && _refreshAll(0, 1); 34690 _lastMediaTick = tick; 34691 34692 _dispatch("matchMedia"); 34693 } 34694 }, 34695 _softRefresh = function _softRefresh() { 34696 return _removeListener(ScrollTrigger, "scrollEnd", _softRefresh) || _refreshAll(true); 34697 }, 34698 _dispatch = function _dispatch(type) { 34699 return _listeners[type] && _listeners[type].map(function (f) { 34700 return f(); 34701 }) || _emptyArray; 34702 }, 34703 _savedStyles = [], 34704 _revertRecorded = function _revertRecorded(media) { 34705 for (var i = 0; i < _savedStyles.length; i += 5) { 34706 if (!media || _savedStyles[i + 4] === media) { 34707 _savedStyles[i].style.cssText = _savedStyles[i + 1]; 34708 _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || ""); 34709 _savedStyles[i + 3].uncache = 1; 34710 } 34711 } 34712 }, 34713 _revertAll = function _revertAll(kill, media) { 34714 var trigger; 34715 34716 for (_i = 0; _i < _triggers.length; _i++) { 34717 trigger = _triggers[_i]; 34718 34719 if (!media || trigger.media === media) { 34720 if (kill) { 34721 trigger.kill(1); 34722 } else { 34723 trigger.revert(); 34724 } 34725 } 34726 } 34727 34728 media && _revertRecorded(media); 34729 media || _dispatch("revert"); 34730 }, 34731 _clearScrollMemory = function _clearScrollMemory() {
vendor: 10,266 bytes, lines 34732-35066
34732 return _scrollers.forEach(function (obj) { 34733 return typeof obj === "function" && (obj.rec = 0); 34734 }); 34735 }, 34736 _refreshingAll, 34737 _refreshAll = function _refreshAll(force, skipRevert) { 34738 if (_lastScrollTime && !force) { 34739 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 34740 34741 return; 34742 } 34743 34744 _refreshingAll = true; 34745 34746 var refreshInits = _dispatch("refreshInit"); 34747 34748 _sort && ScrollTrigger.sort(); 34749 skipRevert || _revertAll(); 34750 34751 _triggers.forEach(function (t) { 34752 return t.refresh(); 34753 }); 34754 34755 refreshInits.forEach(function (result) { 34756 return result && result.render && result.render(-1); 34757 }); 34758 34759 _clearScrollMemory(); 34760 34761 _resizeDelay.pause(); 34762 34763 _refreshingAll = false; 34764 34765 _dispatch("refresh"); 34766 }, 34767 _lastScroll = 0, 34768 _direction = 1, 34769 _updateAll = function _updateAll() { 34770 if (!_refreshingAll) { 34771 var l = _triggers.length, 34772 time = _getTime(), 34773 recordVelocity = time - _time1 >= 50, 34774 scroll = l && _triggers[0].scroll(); 34775 34776 _direction = _lastScroll > scroll ? -1 : 1; 34777 _lastScroll = scroll; 34778 34779 if (recordVelocity) { 34780 if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) { 34781 _lastScrollTime = 0; 34782 34783 _dispatch("scrollEnd"); 34784 } 34785 34786 _time2 = _time1; 34787 _time1 = time; 34788 } 34789 34790 if (_direction < 0) { 34791 _i = l; 34792 34793 while (_i-- > 0) { 34794 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34795 } 34796 34797 _direction = 1; 34798 } else { 34799 for (_i = 0; _i < l; _i++) { 34800 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34801 } 34802 } 34803 34804 _request = 0; 34805 } 34806 }, 34807 _propNamesToCopy = [_left, _top, _bottom, _right, _margin + _Bottom, _margin + _Right, _margin + _Top, _margin + _Left, "display", "flexShrink", "float", "zIndex", "grid-column-start", "grid-column-end", "grid-row-start", "grid-row-end", "grid-area", "justify-self", "align-self", "place-self"], 34808 _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]), 34809 _swapPinOut = function _swapPinOut(pin, spacer, state) { 34810 _setState(state); 34811 34812 var cache = pin._gsap; 34813 34814 if (cache.spacerIsNative) { 34815 _setState(cache.spacerState); 34816 } else if (pin.parentNode === spacer) { 34817 var parent = spacer.parentNode; 34818 34819 if (parent) { 34820 parent.insertBefore(pin, spacer); 34821 parent.removeChild(spacer); 34822 } 34823 } 34824 }, 34825 _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) { 34826 if (pin.parentNode !== spacer) { 34827 var i = _propNamesToCopy.length, 34828 spacerStyle = spacer.style, 34829 pinStyle = pin.style, 34830 p; 34831 34832 while (i--) { 34833 p = _propNamesToCopy[i]; 34834 spacerStyle[p] = cs[p]; 34835 } 34836 34837 spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative"; 34838 cs.display === "inline" && (spacerStyle.display = "inline-block"); 34839 pinStyle[_bottom] = pinStyle[_right] = "auto"; 34840 spacerStyle.overflow = "visible"; 34841 spacerStyle.boxSizing = "border-box"; 34842 spacerStyle[_width] = _getSize(pin, _horizontal) + _px; 34843 spacerStyle[_height] = _getSize(pin, _vertical) + _px; 34844 spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0"; 34845 34846 _setState(spacerState); 34847 34848 pinStyle[_width] = pinStyle["max" + _Width] = cs[_width]; 34849 pinStyle[_height] = pinStyle["max" + _Height] = cs[_height]; 34850 pinStyle[_padding] = cs[_padding]; 34851 pin.parentNode.insertBefore(spacer, pin); 34852 spacer.appendChild(pin); 34853 } 34854 }, 34855 _capsExp = /([A-Z])/g, 34856 _setState = function _setState(state) { 34857 if (state) { 34858 var style = state.t.style, 34859 l = state.length, 34860 i = 0, 34861 p, 34862 value; 34863 (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; 34864 34865 for (; i < l; i += 2) { 34866 value = state[i + 1]; 34867 p = state[i]; 34868 34869 if (value) { 34870 style[p] = value; 34871 } else if (style[p]) { 34872 style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 34873 } 34874 } 34875 } 34876 }, 34877 _getState = function _getState(element) { 34878 var l = _stateProps.length, 34879 style = element.style, 34880 state = [], 34881 i = 0; 34882 34883 for (; i < l; i++) { 34884 state.push(_stateProps[i], style[_stateProps[i]]); 34885 } 34886 34887 state.t = element; 34888 return state; 34889 }, 34890 _copyState = function _copyState(state, override, omitOffsets) { 34891 var result = [], 34892 l = state.length, 34893 i = omitOffsets ? 8 : 0, 34894 p; 34895 34896 for (; i < l; i += 2) { 34897 p = state[i]; 34898 result.push(p, p in override ? override[p] : state[i + 1]); 34899 } 34900 34901 result.t = state.t; 34902 return result; 34903 }, 34904 _winOffsets = { 34905 left: 0, 34906 top: 0 34907 }, 34908 _parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation) { 34909 _isFunction(value) && (value = value(self)); 34910 34911 if (_isString(value) && value.substr(0, 3) === "max") { 34912 value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0); 34913 } 34914 34915 var time = containerAnimation ? containerAnimation.time() : 0, 34916 p1, 34917 p2, 34918 element; 34919 containerAnimation && containerAnimation.seek(0); 34920 34921 if (!_isNumber(value)) { 34922 _isFunction(trigger) && (trigger = trigger(self)); 34923 var offsets = value.split(" "), 34924 bounds, 34925 localOffset, 34926 globalOffset, 34927 display; 34928 element = _getTarget(trigger) || _body; 34929 bounds = _getBounds(element) || {}; 34930 34931 if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") { 34932 display = element.style.display; 34933 element.style.display = "block"; 34934 bounds = _getBounds(element); 34935 display ? element.style.display = display : element.style.removeProperty("display"); 34936 } 34937 34938 localOffset = _offsetToPx(offsets[0], bounds[direction.d]); 34939 globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize); 34940 value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset; 34941 markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20); 34942 scrollerSize -= scrollerSize - globalOffset; 34943 } else if (markerScroller) { 34944 _positionMarker(markerScroller, scrollerSize, direction, true); 34945 } 34946 34947 if (marker) { 34948 var position = value + scrollerSize, 34949 isStart = marker._isStart; 34950 p1 = "scroll" + direction.d2; 34951 34952 _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[p1], _docEl[p1]) : marker.parentNode[p1]) <= position + 1); 34953 34954 if (useFixedPosition) { 34955 scrollerBounds = _getBounds(markerScroller); 34956 useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px); 34957 } 34958 } 34959 34960 if (containerAnimation && element) { 34961 p1 = _getBounds(element); 34962 containerAnimation.seek(scrollerMax); 34963 p2 = _getBounds(element); 34964 containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p]; 34965 value = value / containerAnimation._caScrollDist * scrollerMax; 34966 } 34967 34968 containerAnimation && containerAnimation.seek(time); 34969 return containerAnimation ? value : Math.round(value); 34970 }, 34971 _prefixExp = /(?:webkit|moz|length|cssText|inset)/i, 34972 _reparent = function _reparent(element, parent, top, left) { 34973 if (element.parentNode !== parent) { 34974 var style = element.style, 34975 p, 34976 cs; 34977 34978 if (parent === _body) { 34979 element._stOrig = style.cssText; 34980 cs = _getComputedStyle(element); 34981 34982 for (p in cs) { 34983 if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") { 34984 style[p] = cs[p]; 34985 } 34986 } 34987 34988 style.top = top; 34989 style.left = left; 34990 } else { 34991 style.cssText = element._stOrig; 34992 } 34993 34994 gsap.core.getCache(element).uncache = 1; 34995 parent.appendChild(element); 34996 } 34997 }, 34998 _getTweenCreator = function _getTweenCreator(scroller, direction) { 34999 var getScroll = _getScrollFunc(scroller, direction), 35000 prop = "_scroll" + direction.p2, 35001 lastScroll1, 35002 lastScroll2, 35003 getTween = function getTween(scrollTo, vars, initialValue, change1, change2) { 35004 var tween = getTween.tween, 35005 onComplete = vars.onComplete, 35006 modifiers = {}; 35007 tween && tween.kill(); 35008 lastScroll1 = Math.round(initialValue); 35009 vars[prop] = scrollTo; 35010 vars.modifiers = modifiers; 35011 35012 modifiers[prop] = function (value) { 35013 value = _round(getScroll()); 35014 35015 if (value !== lastScroll1 && value !== lastScroll2 && Math.abs(value - lastScroll1) > 2) { 35016 tween.kill(); 35017 getTween.tween = 0; 35018 } else { 35019 value = initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio; 35020 } 35021 35022 lastScroll2 = lastScroll1; 35023 return lastScroll1 = _round(value); 35024 }; 35025 35026 vars.onComplete = function () { 35027 getTween.tween = 0; 35028 onComplete && onComplete.call(tween); 35029 }; 35030 35031 tween = getTween.tween = gsap.to(scroller, vars); 35032 return tween; 35033 }; 35034 35035 scroller[prop] = getScroll; 35036 scroller.addEventListener("wheel", function () { 35037 return getTween.tween && getTween.tween.kill() && (getTween.tween = 0); 35038 }, { 35039 passive: true 35040 }); 35041 return getTween; 35042 }; 35043 35044 _horizontal.op = _vertical; 35045 var ScrollTrigger = function () { 35046 function ScrollTrigger(vars, animation) { 35047 _coreInitted || ScrollTrigger.register(gsap) || console.warn("Please gsap.registerPlugin(ScrollTrigger)"); 35048 this.init(vars, animation); 35049 } 35050 35051 var _proto = ScrollTrigger.prototype; 35052 35053 _proto.init = function init(vars, animation) { 35054 this.progress = this.start = 0; 35055 this.vars && this.kill(1); 35056 35057 if (!_enabled) { 35058 this.update = this.refresh = this.kill = _passThrough; 35059 return; 35060 } 35061 35062 vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? { 35063 trigger: vars 35064 } : vars, _defaults); 35065 35066 var _vars = vars,
35067 onUpdate = _vars.onUpdate, 35068 toggleClass = _vars.toggleClass, 35069 id = _vars.id, 35070 onToggle = _vars.onToggle, 35071 onRefresh = _vars.onRefresh, 35072 scrub = _vars.scrub, 35073 trigger = _vars.trigger, 35074 pin = _vars.pin, 35075 pinSpacing = _vars.pinSpacing, 35076 invalidateOnRefresh = _vars.invalidateOnRefresh, 35077 anticipatePin = _vars.anticipatePin, 35078 onScrubComplete = _vars.onScrubComplete, 35079 onSnapComplete = _vars.onSnapComplete, 35080 once = _vars.once, 35081 snap = _vars.snap, 35082 pinReparent = _vars.pinReparent, 35083 pinSpacer = _vars.pinSpacer, 35084 containerAnimation = _vars.containerAnimation, 35085 fastScrollEnd = _vars.fastScrollEnd, 35086 preventOverlaps = _vars.preventOverlaps, 35087 direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical, 35088 isToggle = !scrub && scrub !== 0, 35089 scroller = _getTarget(vars.scroller || _win), 35090 scrollerCache = gsap.core.getCache(scroller), 35091 isViewport = _isViewport(scroller), 35092 useFixedPosition = ("pinType" in vars ? vars.pinType : _getProxyProp(scroller, "pinType") || isViewport && "fixed") === "fixed", 35093 callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack], 35094 toggleActions = isToggle && vars.toggleActions.split(" "), 35095 markers = "markers" in vars ? vars.markers : _defaults.markers, 35096 borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 35097 self = this, 35098 onRefreshInit = vars.onRefreshInit && function () { 35099 return vars.onRefreshInit(self); 35100 }, 35101 getScrollerSize = _getSizeFunc(scroller, isViewport, direction), 35102 getScrollerOffsets = _getOffsetsFunc(scroller, isViewport), 35103 lastSnap = 0, 35104 scrollFunc = _getScrollFunc(scroller, direction), 35105 tweenTo, 35106 pinCache, 35107 snapFunc, 35108 scroll1, 35109 scroll2, 35110 start, 35111 end, 35112 markerStart, 35113 markerEnd, 35114 markerStartTrigger, 35115 markerEndTrigger, 35116 markerVars, 35117 change, 35118 pinOriginalState, 35119 pinActiveState, 35120 pinState, 35121 spacer, 35122 offset, 35123 pinGetter, 35124 pinSetter, 35125 pinStart, 35126 pinChange, 35127 spacingStart, 35128 spacerState, 35129 markerStartSetter, 35130 markerEndSetter, 35131 cs, 35132 snap1, 35133 snap2, 35134 scrubTween, 35135 scrubSmooth, 35136 snapDurClamp, 35137 snapDelayedCall, 35138 prevProgress, 35139 prevScroll, 35140 prevAnimProgress, 35141 caMarkerSetter; 35142 35143 self.media = _creatingMedia; 35144 anticipatePin *= 45; 35145 self.scroller = scroller; 35146 self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc; 35147 scroll1 = scrollFunc(); 35148 self.vars = vars; 35149 animation = animation || vars.animation; 35150 "refreshPriority" in vars && (_sort = 1); 35151 scrollerCache.tweenScroll = scrollerCache.tweenScroll || { 35152 top: _getTweenCreator(scroller, _vertical), 35153 left: _getTweenCreator(scroller, _horizontal) 35154 }; 35155 self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p]; 35156 35157 if (animation) { 35158 animation.vars.lazy = false; 35159 animation._initted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.render(0, true, true); 35160 self.animation = animation.pause(); 35161 animation.scrollTrigger = self; 35162 scrubSmooth = _isNumber(scrub) && scrub; 35163 scrubSmooth && (scrubTween = gsap.to(animation, { 35164 ease: "power3", 35165 duration: scrubSmooth, 35166 onComplete: function onComplete() { 35167 return onScrubComplete && onScrubComplete(self); 35168 } 35169 })); 35170 snap1 = 0; 35171 id || (id = animation.vars.id); 35172 } 35173 35174 _triggers.push(self); 35175 35176 if (snap) { 35177 if (!_isObject(snap) || snap.push) { 35178 snap = { 35179 snapTo: snap 35180 }; 35181 } 35182 35183 "scrollBehavior" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, { 35184 scrollBehavior: "auto" 35185 }); 35186 snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) { 35187 return _snapDirectional(snap.snapTo)(value, st.direction); 35188 } : gsap.utils.snap(snap.snapTo); 35189 snapDurClamp = snap.duration || { 35190 min: 0.1, 35191 max: 2 35192 }; 35193 snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp); 35194 snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () { 35195 if (Math.abs(self.getVelocity()) < 10 && !_pointerIsDown && lastSnap !== scrollFunc()) { 35196 var totalProgress = animation && !isToggle ? animation.totalProgress() : self.progress, 35197 velocity = (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0, 35198 change1 = gsap.utils.clamp(-self.progress, 1 - self.progress, _abs(velocity / 2) * velocity / 0.185), 35199 naturalEnd = self.progress + (snap.inertia === false ? 0 : change1), 35200 endValue = _clamp(0, 1, snapFunc(naturalEnd, self)), 35201 scroll = scrollFunc(), 35202 endScroll = Math.round(start + endValue * change), 35203 _snap = snap, 35204 onStart = _snap.onStart, 35205 _onInterrupt = _snap.onInterrupt, 35206 _onComplete = _snap.onComplete, 35207 tween = tweenTo.tween; 35208 35209 if (scroll <= end && scroll >= start && endScroll !== scroll) { 35210 if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) { 35211 return; 35212 } 35213 35214 if (snap.inertia === false) { 35215 change1 = endValue - self.progress; 35216 } 35217 35218 tweenTo(endScroll, { 35219 duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)), 35220 ease: snap.ease || "power3", 35221 data: _abs(endScroll - scroll), 35222 onInterrupt: function onInterrupt() { 35223 return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self); 35224 }, 35225 onComplete: function onComplete() { 35226 lastSnap = scrollFunc(); 35227 snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress; 35228 onSnapComplete && onSnapComplete(self); 35229 _onComplete && _onComplete(self); 35230 } 35231 }, scroll, change1 * change, endScroll - scroll - change1 * change); 35232 onStart && onStart(self, tweenTo.tween); 35233 } 35234 } else if (self.isActive) { 35235 snapDelayedCall.restart(true); 35236 } 35237 }).pause(); 35238 } 35239 35240 id && (_ids[id] = self); 35241 trigger = self.trigger = _getTarget(trigger || pin); 35242 pin = pin === true ? trigger : _getTarget(pin); 35243 _isString(toggleClass) && (toggleClass = { 35244 targets: trigger, 35245 className: toggleClass 35246 }); 35247 35248 if (pin) { 35249 pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding); 35250 self.pin = pin; 35251 vars.force3D !== false && gsap.set(pin, {
35252 force3D: true 35253 }); 35254 pinCache = gsap.core.getCache(pin); 35255 35256 if (!pinCache.spacer) { 35257 if (pinSpacer) { 35258 pinSpacer = _getTarget(pinSpacer); 35259 pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); 35260 pinCache.spacerIsNative = !!pinSpacer; 35261 pinSpacer && (pinCache.spacerState = _getState(pinSpacer)); 35262 } 35263 35264 pinCache.spacer = spacer = pinSpacer || _doc.createElement("div"); 35265 spacer.classList.add("pin-spacer"); 35266 id && spacer.classList.add("pin-spacer-" + id); 35267 pinCache.pinState = pinOriginalState = _getState(pin); 35268 } else { 35269 pinOriginalState = pinCache.pinState; 35270 } 35271 35272 self.spacer = spacer = pinCache.spacer; 35273 cs = _getComputedStyle(pin); 35274 spacingStart = cs[pinSpacing + direction.os2]; 35275 pinGetter = gsap.getProperty(pin); 35276 pinSetter = gsap.quickSetter(pin, direction.a, _px); 35277 35278 _swapPinIn(pin, spacer, cs); 35279 35280 pinState = _getState(pin); 35281 } 35282 35283 if (markers) { 35284 markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults; 35285 markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0); 35286 markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger); 35287 offset = markerStartTrigger["offset" + direction.op.d2]; 35288 markerStart = _createMarker("start", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35289 markerEnd = _createMarker("end", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35290 containerAnimation && (caMarkerSetter = gsap.quickSetter([markerStart, markerEnd], direction.a, _px)); 35291 35292 if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, "fixedMarkers") === true)) { 35293 _makePositionable(isViewport ? _body : scroller); 35294 35295 gsap.set([markerStartTrigger, markerEndTrigger], { 35296 force3D: true 35297 }); 35298 markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px); 35299 markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px); 35300 } 35301 } 35302 35303 if (containerAnimation) { 35304 var oldOnUpdate = containerAnimation.vars.onUpdate, 35305 oldParams = containerAnimation.vars.onUpdateParams; 35306 containerAnimation.eventCallback("onUpdate", function () { 35307 self.update(0, 0, 1); 35308 oldOnUpdate && oldOnUpdate.apply(oldParams || []); 35309 }); 35310 } 35311 35312 self.previous = function () { 35313 return _triggers[_triggers.indexOf(self) - 1]; 35314 }; 35315 35316 self.next = function () { 35317 return _triggers[_triggers.indexOf(self) + 1]; 35318 }; 35319 35320 self.revert = function (revert) { 35321 var r = revert !== false || !self.enabled, 35322 prevRefreshing = _refreshing; 35323 35324 if (r !== self.isReverted) { 35325 if (r) { 35326 self.scroll.rec || (self.scroll.rec = scrollFunc()); 35327 prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0); 35328 prevProgress = self.progress; 35329 prevAnimProgress = animation && animation.progress(); 35330 } 35331 35332 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35333 return m.style.display = r ? "none" : "block"; 35334 }); 35335 r && (_refreshing = 1); 35336 self.update(r); 35337 _refreshing = prevRefreshing; 35338 pin && (r ? _swapPinOut(pin, spacer, pinOriginalState) : (!pinReparent || !self.isActive) && _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState)); 35339 self.isReverted = r; 35340 } 35341 }; 35342 35343 self.refresh = function (soft, force) { 35344 if ((_refreshing || !self.enabled) && !force) { 35345 return; 35346 } 35347 35348 if (pin && soft && _lastScrollTime) { 35349 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 35350 35351 return; 35352 } 35353 35354 _refreshing = 1; 35355 scrubTween && scrubTween.pause(); 35356 invalidateOnRefresh && animation && animation.progress(0).invalidate(); 35357 self.isReverted || self.revert(); 35358 35359 var size = getScrollerSize(), 35360 scrollerBounds = getScrollerOffsets(),
35361 max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction), 35362 offset = 0, 35363 otherPinOffset = 0, 35364 parsedEnd = vars.end, 35365 parsedEndTrigger = vars.endTrigger || trigger, 35366 parsedStart = vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"), 35367 pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer), 35368 triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0, 35369 i = triggerIndex, 35370 cs, 35371 bounds, 35372 scroll, 35373 isVertical, 35374 override, 35375 curTrigger, 35376 curPin, 35377 oppositeScroll, 35378 initted, 35379 revertedPins; 35380 35381 while (i--) { 35382 curTrigger = _triggers[i]; 35383 curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = 1); 35384 curPin = curTrigger.pin; 35385 35386 if (curPin && (curPin === trigger || curPin === pin) && !curTrigger.isReverted) { 35387 revertedPins || (revertedPins = []); 35388 revertedPins.unshift(curTrigger); 35389 curTrigger.revert(); 35390 } 35391 } 35392 35393 _isFunction(parsedStart) && (parsedStart = parsedStart(self)); 35394 start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation) || (pin ? -0.001 : 0); 35395 _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self)); 35396 35397 if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) { 35398 if (~parsedEnd.indexOf(" ")) { 35399 parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd; 35400 } else { 35401 offset = _offsetToPx(parsedEnd.substr(2), size); 35402 parsedEnd = _isString(parsedStart) ? parsedStart : start + offset; 35403 parsedEndTrigger = trigger; 35404 } 35405 } 35406 35407 end = Math.max(start, _parsePosition(parsedEnd || (parsedEndTrigger ? "100% 0" : max), parsedEndTrigger, size, direction, scrollFunc() + offset, markerEnd, markerEndTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation)) || -0.001; 35408 change = end - start || (start -= 0.01) && 0.001; 35409 offset = 0; 35410 i = triggerIndex; 35411 35412 while (i--) { 35413 curTrigger = _triggers[i]; 35414 curPin = curTrigger.pin; 35415 35416 if (curPin && curTrigger.start - curTrigger._pinPush < start && !containerAnimation) { 35417 cs = curTrigger.end - curTrigger.start; 35418 (curPin === trigger || curPin === pinnedContainer) && !_isNumber(parsedStart) && (offset += cs); 35419 curPin === pin && (otherPinOffset += cs); 35420 } 35421 } 35422 35423 start += offset; 35424 end += offset; 35425 self._pinPush = otherPinOffset; 35426 35427 if (markerStart && offset) { 35428 cs = {}; 35429 cs[direction.a] = "+=" + offset; 35430 pinnedContainer && (cs[direction.p] = "-=" + scrollFunc()); 35431 gsap.set([markerStart, markerEnd], cs); 35432 } 35433 35434 if (pin) { 35435 cs = _getComputedStyle(pin); 35436 isVertical = direction === _vertical; 35437 scroll = scrollFunc(); 35438 pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset; 35439 !max && end > 1 && ((isViewport ? _body : scroller).style["overflow-" + direction.a] = "scroll"); 35440 35441 _swapPinIn(pin, spacer, cs); 35442 35443 pinState = _getState(pin); 35444 bounds = _getBounds(pin, true); 35445 oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)(); 35446 35447 if (pinSpacing) { 35448 spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px]; 35449 spacerState.t = spacer; 35450 i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0; 35451 i && spacerState.push(direction.d, i + _px); 35452 35453 _setState(spacerState); 35454 35455 useFixedPosition && scrollFunc(prevScroll); 35456 } 35457 35458 if (useFixedPosition) { 35459 override = { 35460 top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px, 35461 left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px, 35462 boxSizing: "border-box", 35463 position: "fixed" 35464 }; 35465 override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px; 35466 override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px; 35467 override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0"; 35468 override[_padding] = cs[_padding]; 35469 override[_padding + _Top] = cs[_padding + _Top]; 35470 override[_padding + _Right] = cs[_padding + _Right]; 35471 override[_padding + _Bottom] = cs[_padding + _Bottom]; 35472 override[_padding + _Left] = cs[_padding + _Left]; 35473 pinActiveState = _copyState(pinOriginalState, override, pinReparent); 35474 } 35475 35476 if (animation) { 35477 initted = animation._initted; 35478 35479 _suppressOverwrites(1); 35480 35481 animation.render(animation.duration(), true, true); 35482 pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset; 35483 change !== pinChange && pinActiveState.splice(pinActiveState.length - 2, 2); 35484 animation.render(0, true, true); 35485 initted || animation.invalidate(); 35486 35487 _suppressOverwrites(0); 35488 } else { 35489 pinChange = change; 35490 } 35491 } else if (trigger && scrollFunc() && !containerAnimation) { 35492 bounds = trigger.parentNode; 35493 35494 while (bounds && bounds !== _body) { 35495 if (bounds._pinOffset) { 35496 start -= bounds._pinOffset; 35497 end -= bounds._pinOffset; 35498 } 35499 35500 bounds = bounds.parentNode; 35501 } 35502 } 35503 35504 revertedPins && revertedPins.forEach(function (t) { 35505 return t.revert(false); 35506 }); 35507 self.start = start; 35508 self.end = end; 35509 scroll1 = scroll2 = scrollFunc(); 35510 35511 if (!containerAnimation) { 35512 scroll1 < prevScroll && scrollFunc(prevScroll); 35513 self.scroll.rec = 0; 35514 } 35515 35516 self.revert(false); 35517 _refreshing = 0; 35518 animation && isToggle && animation._initted && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress, true).render(animation.time(), true, true); 35519 35520 if (prevProgress !== self.progress) { 35521 animation && !isToggle && animation.totalProgress(prevProgress, true); 35522 self.progress = prevProgress; 35523 self.update(0, 0, 1); 35524 } 35525 35526 pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange)); 35527 onRefresh && onRefresh(self); 35528 }; 35529 35530 self.getVelocity = function () { 35531 return (scrollFunc() - scroll2) / (_getTime() - _time2) * 1000 || 0; 35532 }; 35533 35534 self.endAnimation = function () {
vendor: 8,601 bytes, lines 35535-35773
35535 _endAnimation(self.callbackAnimation); 35536 35537 if (animation) { 35538 scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1); 35539 } 35540 }; 35541 35542 self.getTrailing = function (name) { 35543 var i = _triggers.indexOf(self), 35544 a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1); 35545 35546 return _isString(name) ? a.filter(function (t) { 35547 return t.vars.preventOverlaps === name; 35548 }) : a; 35549 }; 35550 35551 self.update = function (reset, recordVelocity, forceFake) { 35552 if (containerAnimation && !forceFake && !reset) { 35553 return; 35554 } 35555 35556 var scroll = self.scroll(), 35557 p = reset ? 0 : (scroll - start) / change, 35558 clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0, 35559 prevProgress = self.progress, 35560 isActive, 35561 wasActive, 35562 toggleState, 35563 action, 35564 stateChanged, 35565 toggled, 35566 isAtMax, 35567 isTakingAction; 35568 35569 if (recordVelocity) { 35570 scroll2 = scroll1; 35571 scroll1 = containerAnimation ? scrollFunc() : scroll; 35572 35573 if (snap) { 35574 snap2 = snap1; 35575 snap1 = animation && !isToggle ? animation.totalProgress() : clipped; 35576 } 35577 } 35578 35579 anticipatePin && !clipped && pin && !_refreshing && !_startup && _lastScrollTime && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin && (clipped = 0.0001); 35580 35581 if (clipped !== prevProgress && self.enabled) { 35582 isActive = self.isActive = !!clipped && clipped < 1; 35583 wasActive = !!prevProgress && prevProgress < 1; 35584 toggled = isActive !== wasActive; 35585 stateChanged = toggled || !!clipped !== !!prevProgress; 35586 self.direction = clipped > prevProgress ? 1 : -1; 35587 self.progress = clipped; 35588 35589 if (stateChanged && !_refreshing) { 35590 toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; 35591 35592 if (isToggle) { 35593 action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState]; 35594 isTakingAction = animation && (action === "complete" || action === "reset" || action in animation); 35595 } 35596 } 35597 35598 preventOverlaps && toggled && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) { 35599 return t.endAnimation(); 35600 })); 35601 35602 if (!isToggle) { 35603 if (scrubTween && !_refreshing && !_startup) { 35604 scrubTween.vars.totalProgress = clipped; 35605 scrubTween.invalidate().restart(); 35606 } else if (animation) { 35607 animation.totalProgress(clipped, !!_refreshing); 35608 } 35609 } 35610 35611 if (pin) { 35612 reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart); 35613 35614 if (!useFixedPosition) { 35615 pinSetter(pinStart + pinChange * clipped); 35616 } else if (stateChanged) { 35617 isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); 35618 35619 if (pinReparent) { 35620 if (!reset && (isActive || isAtMax)) { 35621 var bounds = _getBounds(pin, true), 35622 _offset = scroll - start; 35623 35624 _reparent(pin, _body, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px); 35625 } else { 35626 _reparent(pin, spacer); 35627 } 35628 } 35629 35630 _setState(isActive || isAtMax ? pinActiveState : pinState); 35631 35632 pinChange !== change && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0)); 35633 } 35634 } 35635 35636 snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true); 35637 toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) { 35638 return el.classList[isActive || once ? "add" : "remove"](toggleClass.className); 35639 }); 35640 onUpdate && !isToggle && !reset && onUpdate(self); 35641 35642 if (stateChanged && !_refreshing) { 35643 if (isToggle) { 35644 if (isTakingAction) { 35645 if (action === "complete") { 35646 animation.pause().totalProgress(1); 35647 } else if (action === "reset") { 35648 animation.restart(true).pause(); 35649 } else if (action === "restart") { 35650 animation.restart(true); 35651 } else { 35652 animation[action](); 35653 } 35654 } 35655 35656 onUpdate && onUpdate(self); 35657 } 35658 35659 if (toggled || !_limitCallbacks) { 35660 onToggle && toggled && _callback(self, onToggle); 35661 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35662 once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); 35663 35664 if (!toggled) { 35665 toggleState = clipped === 1 ? 1 : 3; 35666 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35667 } 35668 } 35669 35670 if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) { 35671 _endAnimation(self.callbackAnimation); 35672 35673 scrubTween ? scrubTween.progress(1) : _endAnimation(animation, !clipped, 1); 35674 } 35675 } else if (isToggle && onUpdate && !_refreshing) { 35676 onUpdate(self); 35677 } 35678 } 35679 35680 if (markerEndSetter) { 35681 var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll; 35682 markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0)); 35683 markerEndSetter(n); 35684 } 35685 35686 caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0)); 35687 }; 35688 35689 self.enable = function (reset, refresh) { 35690 if (!self.enabled) { 35691 self.enabled = true; 35692 35693 _addListener(scroller, "resize", _onResize); 35694 35695 _addListener(scroller, "scroll", _onScroll); 35696 35697 onRefreshInit && _addListener(ScrollTrigger, "refreshInit", onRefreshInit); 35698 35699 if (reset !== false) { 35700 self.progress = prevProgress = 0; 35701 scroll1 = scroll2 = lastSnap = scrollFunc(); 35702 } 35703 35704 refresh !== false && self.refresh(); 35705 } 35706 }; 35707 35708 self.getTween = function (snap) { 35709 return snap && tweenTo ? tweenTo.tween : scrubTween; 35710 }; 35711 35712 self.disable = function (reset, allowAnimation) { 35713 if (self.enabled) { 35714 reset !== false && self.revert(); 35715 self.enabled = self.isActive = false; 35716 allowAnimation || scrubTween && scrubTween.pause(); 35717 prevScroll = 0; 35718 pinCache && (pinCache.uncache = 1); 35719 onRefreshInit && _removeListener(ScrollTrigger, "refreshInit", onRefreshInit); 35720 35721 if (snapDelayedCall) { 35722 snapDelayedCall.pause(); 35723 tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0); 35724 } 35725 35726 if (!isViewport) { 35727 var i = _triggers.length; 35728 35729 while (i--) { 35730 if (_triggers[i].scroller === scroller && _triggers[i] !== self) { 35731 return; 35732 } 35733 } 35734 35735 _removeListener(scroller, "resize", _onResize); 35736 35737 _removeListener(scroller, "scroll", _onScroll); 35738 } 35739 } 35740 }; 35741 35742 self.kill = function (revert, allowAnimation) { 35743 self.disable(revert, allowAnimation); 35744 scrubTween && scrubTween.kill(); 35745 id && delete _ids[id]; 35746 35747 var i = _triggers.indexOf(self); 35748 35749 _triggers.splice(i, 1); 35750 35751 i === _i && _direction > 0 && _i--; 35752 i = 0; 35753 35754 _triggers.forEach(function (t) { 35755 return t.scroller === self.scroller && (i = 1); 35756 }); 35757 35758 i || (self.scroll.rec = 0); 35759 35760 if (animation) { 35761 animation.scrollTrigger = null; 35762 revert && animation.render(-1); 35763 allowAnimation || animation.kill(); 35764 } 35765 35766 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35767 return m.parentNode && m.parentNode.removeChild(m); 35768 }); 35769 35770 if (pin) { 35771 pinCache && (pinCache.uncache = 1); 35772 i = 0; 35773
35774 _triggers.forEach(function (t) { 35775 return t.pin === pin && i++; 35776 }); 35777 35778 i || (pinCache.spacer = 0); 35779 } 35780 }; 35781 35782 self.enable(false, false); 35783 !animation || !animation.add || change ? self.refresh() : gsap.delayedCall(0.01, function () { 35784 return start || end || self.refresh(); 35785 }) && (change = 0.01) && (start = end = 0); 35786 }; 35787 35788 ScrollTrigger.register = function register(core) { 35789 if (!_coreInitted) { 35790 gsap = core || _getGSAP(); 35791 35792 if (_windowExists() && window.document) { 35793 _win = window; 35794 _doc = document; 35795 _docEl = _doc.documentElement; 35796 _body = _doc.body; 35797 } 35798 35799 if (gsap) { 35800 _toArray = gsap.utils.toArray; 35801 _clamp = gsap.utils.clamp; 35802 _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough; 35803 gsap.core.globals("ScrollTrigger", ScrollTrigger); 35804 35805 if (_body) { 35806 _raf = _win.requestAnimationFrame || function (f) { 35807 return setTimeout(f, 16); 35808 }; 35809 35810 _addListener(_win, "wheel", _onScroll); 35811 35812 _root = [_win, _doc, _docEl, _body]; 35813 35814 _addListener(_doc, "scroll", _onScroll); 35815 35816 var bodyStyle = _body.style, 35817 border = bodyStyle.borderTopStyle, 35818 bounds; 35819 bodyStyle.borderTopStyle = "solid"; 35820 bounds = _getBounds(_body); 35821 _vertical.m = Math.round(bounds.top + _vertical.sc()) || 0; 35822 _horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0; 35823 border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style"); 35824 _syncInterval = setInterval(_sync, 200); 35825 gsap.delayedCall(0.5, function () { 35826 return _startup = 0; 35827 }); 35828 35829 _addListener(_doc, "touchcancel", _passThrough); 35830 35831 _addListener(_body, "touchstart", _passThrough); 35832 35833 _multiListener(_addListener, _doc, "pointerdown,touchstart,mousedown", function () { 35834 return _pointerIsDown = 1; 35835 }); 35836 35837 _multiListener(_addListener, _doc, "pointerup,touchend,mouseup", function () { 35838 return _pointerIsDown = 0; 35839 }); 35840 35841 _transformProp = gsap.utils.checkPrefix("transform"); 35842 35843 _stateProps.push(_transformProp); 35844 35845 _coreInitted = _getTime(); 35846 _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause(); 35847 _autoRefresh = [_doc, "visibilitychange", function () { 35848 var w = _win.innerWidth, 35849 h = _win.innerHeight; 35850 35851 if (_doc.hidden) { 35852 _prevWidth = w; 35853 _prevHeight = h; 35854 } else if (_prevWidth !== w || _prevHeight !== h) { 35855 _onResize(); 35856 } 35857 }, _doc, "DOMContentLoaded", _refreshAll, _win, "load", function () { 35858 return _lastScrollTime || _refreshAll(); 35859 }, _win, "resize", _onResize]; 35860 35861 _iterateAutoRefresh(_addListener); 35862 } 35863 } 35864 } 35865 35866 return _coreInitted; 35867 }; 35868 35869 ScrollTrigger.defaults = function defaults(config) { 35870 for (var p in config) { 35871 _defaults[p] = config[p]; 35872 } 35873 }; 35874 35875 ScrollTrigger.kill = function kill() { 35876 _enabled = 0; 35877 35878 _triggers.slice(0).forEach(function (trigger) { 35879 return trigger.kill(1); 35880 }); 35881 }; 35882 35883 ScrollTrigger.config = function config(vars) { 35884 "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks); 35885 var ms = vars.syncInterval; 35886 ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms); 35887 35888 if ("autoRefreshEvents" in vars) { 35889 _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || "none"); 35890 _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1; 35891 } 35892 }; 35893 35894 ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) { 35895 var t = _getTarget(target), 35896 i = _scrollers.indexOf(t), 35897 isViewport = _isViewport(t); 35898 35899 if (~i) { 35900 _scrollers.splice(i, isViewport ? 6 : 2); 35901 } 35902 35903 isViewport ? _proxies.unshift(_win, vars, _body, vars, _docEl, vars) : _proxies.unshift(t, vars); 35904 }; 35905 35906 ScrollTrigger.matchMedia = function matchMedia(vars) { 35907 var mq, p, i, func, result; 35908 35909 for (p in vars) { 35910 i = _media.indexOf(p); 35911 func = vars[p]; 35912 _creatingMedia = p; 35913 35914 if (p === "all") { 35915 func(); 35916 } else { 35917 mq = _win.matchMedia(p); 35918 35919 if (mq) { 35920 mq.matches && (result = func()); 35921 35922 if (~i) { 35923 _media[i + 1] = _combineFunc(_media[i + 1], func); 35924 _media[i + 2] = _combineFunc(_media[i + 2], result); 35925 } else { 35926 i = _media.length; 35927 35928 _media.push(p, func, result); 35929 35930 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 35931 } 35932 35933 _media[i + 3] = mq.matches; 35934 } 35935 } 35936 35937 _creatingMedia = 0; 35938 } 35939 35940 return _media; 35941 }; 35942 35943 ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) { 35944 query || (_media.length = 0); 35945 query = _media.indexOf(query); 35946 query >= 0 && _media.splice(query, 4); 35947 }; 35948 35949 ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) { 35950 var bounds = (_isString(element) ? _getTarget(element) : element).getBoundingClientRect(), 35951 offset = bounds[horizontal ? _width : _height] * ratio || 0; 35952 return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win.innerHeight; 35953 }; 35954 35955 ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) { 35956 _isString(element) && (element = _getTarget(element)); 35957 var bounds = element.getBoundingClientRect(), 35958 size = bounds[horizontal ? _width : _height], 35959 offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0; 35960 return horizontal ? (bounds.left + offset) / _win.innerWidth : (bounds.top + offset) / _win.innerHeight; 35961 }; 35962 35963 return ScrollTrigger; 35964 }(); 35965 ScrollTrigger.version = "3.8.0"; 35966 35967 ScrollTrigger.saveStyles = function (targets) {
35968 return targets ? _toArray(targets).forEach(function (target) { 35969 if (target && target.style) { 35970 var i = _savedStyles.indexOf(target); 35971 35972 i >= 0 && _savedStyles.splice(i, 5); 35973 35974 _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap.core.getCache(target), _creatingMedia); 35975 } 35976 }) : _savedStyles; 35977 }; 35978 35979 ScrollTrigger.revert = function (soft, media) { 35980 return _revertAll(!soft, media); 35981 }; 35982 35983 ScrollTrigger.create = function (vars, animation) { 35984 return new ScrollTrigger(vars, animation); 35985 }; 35986 35987 ScrollTrigger.refresh = function (safe) { 35988 return safe ? _onResize() : (_coreInitted || ScrollTrigger.register()) && _refreshAll(true); 35989 }; 35990 35991 ScrollTrigger.update = _updateAll; 35992 ScrollTrigger.clearScrollMemory = _clearScrollMemory; 35993 35994 ScrollTrigger.maxScroll = function (element, horizontal) { 35995 return _maxScroll(element, horizontal ? _horizontal : _vertical); 35996 }; 35997 35998 ScrollTrigger.getScrollFunc = function (element, horizontal) { 35999 return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical); 36000 }; 36001 36002 ScrollTrigger.getById = function (id) { 36003 return _ids[id]; 36004 }; 36005 36006 ScrollTrigger.getAll = function () { 36007 return _triggers.slice(0); 36008 }; 36009 36010 ScrollTrigger.isScrolling = function () { 36011 return !!_lastScrollTime; 36012 }; 36013 36014 ScrollTrigger.snapDirectional = _snapDirectional; 36015 36016 ScrollTrigger.addEventListener = function (type, callback) { 36017 var a = _listeners[type] || (_listeners[type] = []); 36018 ~a.indexOf(callback) || a.push(callback); 36019 }; 36020 36021 ScrollTrigger.removeEventListener = function (type, callback) { 36022 var a = _listeners[type], 36023 i = a && a.indexOf(callback); 36024 i >= 0 && a.splice(i, 1); 36025 }; 36026 36027 ScrollTrigger.batch = function (targets, vars) { 36028 var result = [], 36029 varsCopy = {}, 36030 interval = vars.interval || 0.016, 36031 batchMax = vars.batchMax || 1e9, 36032 proxyCallback = function proxyCallback(type, callback) { 36033 var elements = [], 36034 triggers = [], 36035 delay = gsap.delayedCall(interval, function () { 36036 callback(elements, triggers); 36037 elements = []; 36038 triggers = []; 36039 }).pause(); 36040 return function (self) { 36041 elements.length || delay.restart(true); 36042 elements.push(self.trigger); 36043 triggers.push(self); 36044 batchMax <= elements.length && delay.progress(1); 36045 }; 36046 }, 36047 p; 36048 36049 for (p in vars) { 36050 varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p]; 36051 } 36052 36053 if (_isFunction(batchMax)) { 36054 batchMax = batchMax(); 36055 36056 _addListener(ScrollTrigger, "refresh", function () { 36057 return batchMax = vars.batchMax(); 36058 }); 36059 } 36060 36061 _toArray(targets).forEach(function (target) { 36062 var config = {}; 36063 36064 for (p in varsCopy) { 36065 config[p] = varsCopy[p]; 36066 } 36067 36068 config.trigger = target; 36069 result.push(ScrollTrigger.create(config)); 36070 }); 36071 36072 return result; 36073 }; 36074 36075 ScrollTrigger.sort = function (func) { 36076 return _triggers.sort(func || function (a, b) { 36077 return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6); 36078 }); 36079 }; 36080 36081 _getGSAP() && gsap.registerPlugin(ScrollTrigger); 36082 36083 exports.ScrollTrigger = ScrollTrigger; 36084 exports.default = ScrollTrigger; 36085 36086 Object.defineProperty(exports, '__esModule', { value: true }); 36087 36088}))); 36089 36090/* ======================================================================== 36091 * Bootstrap: collapse.js v3.1.1 36092 * http://getbootstrap.com/javascript/#collapse 36093 * ======================================================================== 36094 * Copyright 2011-2014 Twitter, Inc. 36095 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36096 * ======================================================================== */ 36097 36098 36099+function ($) { 36100 'use strict'; 36101 36102 // COLLAPSE PUBLIC CLASS DEFINITION 36103 // ================================ 36104 36105 var Collapse = function (element, options) { 36106 this.$element = $(element) 36107 this.options = $.extend({}, Collapse.DEFAULTS, options) 36108 this.transitioning = null 36109 36110 if (this.options.parent) this.$parent = $(this.options.parent) 36111 if (this.options.toggle) this.toggle() 36112 } 36113 36114 Collapse.DEFAULTS = { 36115 toggle: true 36116 } 36117 36118 Collapse.prototype.dimension = function () { 36119 var hasWidth = this.$element.hasClass('width') 36120 return hasWidth ? 'width' : 'height' 36121 } 36122 36123 Collapse.prototype.show = function () { 36124 if (this.transitioning || this.$element.hasClass('in')) return 36125 36126 var startEvent = $.Event('show.bs.collapse') 36127 this.$element.trigger(startEvent) 36128 if (startEvent.isDefaultPrevented()) return 36129 36130 var actives = this.$parent && this.$parent.find('> .panel > .in') 36131 36132 if (actives && actives.length) { 36133 var hasData = actives.data('bs.collapse') 36134 if (hasData && hasData.transitioning) return 36135 //START UNCODE EDIT 36136 var parentNoToggle = this.$parent.data('no-toggle') 36137 if (!parentNoToggle) { 36138 actives.collapse('hide') 36139 } 36140 //END UNCODE EDIT 36141 hasData || actives.data('bs.collapse', null) 36142 } 36143 36144 var dimension = this.dimension() 36145 36146 this.$element 36147 .removeClass('collapse') 36148 .addClass('collapsing')[dimension](0) 36149 36150 this.transitioning = 1 36151 36152 var complete = function (e) { 36153 if (e && e.target != this.$element[0]) return 36154 this.$element 36155 .removeClass('collapsing') 36156 .addClass('collapse in')[dimension]('auto') 36157 this.transitioning = 0 36158 this.$element.trigger('shown.bs.collapse') 36159 } 36160 36161 if (!$.support.transition) return complete.call(this) 36162 36163 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 36164 36165 this.$element 36166 .one($.support.transition.end, $.proxy(complete, this)) 36167 .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) 36168 } 36169 36170 Collapse.prototype.hide = function () { 36171 if (this.transitioning || !this.$element.hasClass('in')) return 36172 36173 var startEvent = $.Event('hide.bs.collapse') 36174 this.$element.trigger(startEvent) 36175 if (startEvent.isDefaultPrevented()) return 36176 36177 var dimension = this.dimension() 36178 36179 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 36180 36181 this.$element 36182 .addClass('collapsing') 36183 .removeClass('collapse') 36184 .removeClass('in') 36185 36186 this.transitioning = 1 36187 36188 var complete = function (e) { 36189 if (e && e.target != this.$element[0]) return 36190 this.transitioning = 0 36191 this.$element 36192 .trigger('hidden.bs.collapse') 36193 .removeClass('collapsing') 36194 .addClass('collapse') 36195 } 36196 36197 if (!$.support.transition) return complete.call(this) 36198 36199 this.$element 36200 [dimension](0) 36201 .one($.support.transition.end, $.proxy(complete, this)) 36202 .emulateTransitionEnd(350) 36203 } 36204 36205 Collapse.prototype.toggle = function () { 36206 this[this.$element.hasClass('in') ? 'hide' : 'show']() 36207 } 36208 36209 36210 // COLLAPSE PLUGIN DEFINITION 36211 // ========================== 36212 36213 var old = $.fn.collapse 36214 36215 $.fn.collapse = function (option) { 36216 return this.each(function () { 36217 var $this = $(this) 36218 var data = $this.data('bs.collapse') 36219 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 36220 36221 if (!data && options.toggle && option == 'show') option = !option 36222 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 36223 if (typeof option == 'string') data[option]() 36224 }) 36225 } 36226 36227 $.fn.collapse.Constructor = Collapse 36228 36229 36230 // COLLAPSE NO CONFLICT 36231 // ==================== 36232 36233 $.fn.collapse.noConflict = function () { 36234 $.fn.collapse = old 36235 return this 36236 } 36237 36238 36239 // COLLAPSE DATA-API 36240 // ================= 36241 36242 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 36243 var $this = $(this), href 36244 var target = $this.attr('data-target') 36245 || e.preventDefault() 36246 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 36247 //Edited by Uncode to replace ID in panel [START] 36248 var _target = href.replace(/^#/, ""); 36249 if ( $('[data-id="' + _target + '"]').length ) { 36250 var $target = $('[data-id="' + _target + '"]') 36251 } else { 36252 var $target = $(target) 36253 } 36254 //Edited by Uncode to replace ID in panel [END] 36255 var data = $target.data('bs.collapse') 36256 var option = data ? 'toggle' : $this.data() 36257 var parent = $this.attr('data-parent') 36258 var $parent = parent && $(parent) 36259 36260 if (!data || !data.transitioning) { 36261 if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') 36262 $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 36263 } 36264 36265 $target.collapse(option) 36266 }) 36267 36268}(jQuery); 36269 36270/* ======================================================================== 36271 * Bootstrap: tab.js v3.1.1 36272 * http://getbootstrap.com/javascript/#tabs 36273 * ======================================================================== 36274 * Copyright 2011-2014 Twitter, Inc. 36275 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36276 * ======================================================================== */ 36277 36278 36279+function ($) { 36280 'use strict'; 36281 36282 // TAB CLASS DEFINITION 36283 // ==================== 36284 36285 var Tab = function (element) { 36286 this.element = $(element) 36287 } 36288 36289 Tab.prototype.show = function () { 36290 var $this = this.element 36291 var $ul = $this.closest('ul:not(.dropdown-menu)') 36292 var selector = $this.data('target') 36293 36294 if (!selector) { 36295 selector = $this.attr('href') 36296 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 36297 } 36298 36299 if ($this.parent('li').hasClass('active')) return 36300 36301 var previous = $ul.find('.active:last a')[0] 36302 var e = $.Event('show.bs.tab', { 36303 relatedTarget: previous 36304 }) 36305 36306 $this.trigger(e) 36307 36308 if (e.isDefaultPrevented()) return 36309 36310 //Edited by Uncode to replace ID in panel [START] 36311 var _target = selector.replace(/^#/, ""); 36312 if ( $('[data-id="' + _target + '"]').length ) 36313 var $target = $('[data-id="' + _target + '"]') 36314 else 36315 var $target = $(selector) 36316 //Edited by Uncode to replace ID in panel [END] 36317 36318 this.activate($this.parent('li'), $ul) 36319 this.activate($target, $target.parent(), function () { 36320 $this.trigger({ 36321 type: 'shown.bs.tab', 36322 relatedTarget: previous 36323 }) 36324 }) 36325 } 36326 36327 Tab.prototype.activate = function (element, container, callback) { 36328 var $active = container.find('> .active').add(container.find('> .active > .active')) 36329 var transition = callback 36330 && $.support.transition 36331 && $active.hasClass('fade') 36332 36333 function next() { 36334 $active 36335 .removeClass('active') 36336 .find('> .dropdown-menu > .active') 36337 .removeClass('active') 36338 36339 $active 36340 .find('.tab-excerpt').slideUp(); 36341 36342 element.addClass('active') 36343 $('.tab-excerpt', element).slideDown(); 36344 36345 //if (transition) { 36346 element[0].offsetWidth // reflow for transition 36347 element.add($active).addClass('in') 36348 /*} else { 36349 element.removeClass('fade') 36350 }*/ 36351 36352 if (element.parent('.dropdown-menu')) { 36353 element.closest('li.dropdown').addClass('active') 36354 } 36355 36356 callback && callback() 36357 } 36358 36359 transition ? 36360 $active 36361 .one($.support.transition.end, next) 36362 .emulateTransitionEnd(150) : 36363 next() 36364 36365 $active.removeClass('in') 36366 } 36367 36368 36369 // TAB PLUGIN DEFINITION 36370 // ===================== 36371 36372 var old = $.fn.tab 36373 36374 $.fn.tab = function ( option ) { 36375 return this.each(function () { 36376 var $this = $(this) 36377 var data = $this.data('bs.tab') 36378 36379 if (!data) $this.data('bs.tab', (data = new Tab(this))) 36380 if (typeof option == 'string') data[option]() 36381 }) 36382 } 36383 36384 $.fn.tab.Constructor = Tab 36385 36386 36387 // TAB NO CONFLICT 36388 // =============== 36389 36390 $.fn.tab.noConflict = function () { 36391 $.fn.tab = old 36392 return this 36393 } 36394 36395 36396 // TAB DATA-API 36397 // ============ 36398 36399 $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 36400 e.preventDefault() 36401 $(this).tab('show') 36402 }) 36403 36404}(jQuery); 36405 36406/* ======================================================================== 36407 * Bootstrap: tooltip.js v3.1.1 36408 * http://getbootstrap.com/javascript/#tooltip 36409 * Inspired by the original jQuery.tipsy by Jason Frame 36410 * ======================================================================== 36411 * Copyright 2011-2014 Twitter, Inc. 36412 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36413 * ======================================================================== */ 36414 36415 36416+function ($) { 36417 'use strict'; 36418 36419 // TOOLTIP PUBLIC CLASS DEFINITION 36420 // =============================== 36421 36422 var Tooltip = function (element, options) { 36423 this.type = 36424 this.options = 36425 this.enabled = 36426 this.timeout = 36427 this.hoverState = 36428 this.$element = null 36429 36430 this.init('tooltip', element, options) 36431 } 36432 36433 Tooltip.DEFAULTS = { 36434 animation: true, 36435 placement: 'top', 36436 selector: false, 36437 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 36438 trigger: 'hover focus', 36439 title: '', 36440 delay: 0, 36441 html: false, 36442 container: false, 36443 viewport: { 36444 selector: 'body', 36445 padding: 0 36446 } 36447 } 36448 36449 Tooltip.prototype.init = function (type, element, options) { 36450 this.enabled = true 36451 this.type = type 36452 this.$element = $(element) 36453 this.options = this.getOptions(options) 36454 this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) 36455 36456 var triggers = this.options.trigger.split(' ') 36457 36458 for (var i = triggers.length; i--;) { 36459 var trigger = triggers[i] 36460 36461 if (trigger == 'click') { 36462 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 36463 } else if (trigger != 'manual') { 36464 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 36465 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 36466 36467 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 36468 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 36469 } 36470 } 36471 36472 this.options.selector ? 36473 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 36474 this.fixTitle() 36475 } 36476 36477 Tooltip.prototype.getDefaults = function () { 36478 return Tooltip.DEFAULTS 36479 } 36480 36481 Tooltip.prototype.getOptions = function (options) { 36482 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 36483 36484 if (options.delay && typeof options.delay == 'number') { 36485 options.delay = { 36486 show: options.delay, 36487 hide: options.delay 36488 } 36489 } 36490 36491 return options 36492 } 36493 36494 Tooltip.prototype.getDelegateOptions = function () { 36495 var options = {} 36496 var defaults = this.getDefaults() 36497 36498 this._options && $.each(this._options, function (key, value) { 36499 if (defaults[key] != value) options[key] = value 36500 }) 36501 36502 return options 36503 } 36504 36505 Tooltip.prototype.enter = function (obj) { 36506 var self = obj instanceof this.constructor ? 36507 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36508 36509 clearTimeout(self.timeout) 36510 36511 self.hoverState = 'in' 36512 36513 if (!self.options.delay || !self.options.delay.show) return self.show() 36514 36515 self.timeout = setTimeout(function () { 36516 if (self.hoverState == 'in') self.show() 36517 }, self.options.delay.show) 36518 } 36519 36520 Tooltip.prototype.leave = function (obj) { 36521 var self = obj instanceof this.constructor ? 36522 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36523 36524 clearTimeout(self.timeout) 36525 36526 self.hoverState = 'out' 36527 36528 if (!self.options.delay || !self.options.delay.hide) return self.hide() 36529 36530 self.timeout = setTimeout(function () { 36531 if (self.hoverState == 'out') self.hide() 36532 }, self.options.delay.hide) 36533 } 36534 36535 Tooltip.prototype.show = function () { 36536 var e = $.Event('show.bs.' + this.type) 36537 36538 if (this.hasContent() && this.enabled) { 36539 this.$element.trigger(e) 36540 36541 if (e.isDefaultPrevented()) return 36542 var that = this; 36543 36544 var $tip = this.tip() 36545 36546 this.setContent() 36547 36548 if (this.options.animation) $tip.addClass('fade') 36549 36550 var placement = typeof this.options.placement == 'function' ? 36551 this.options.placement.call(this, $tip[0], this.$element[0]) : 36552 this.options.placement 36553 36554 var autoToken = /\s?auto?\s?/i 36555 var autoPlace = autoToken.test(placement) 36556 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 36557 36558 $tip 36559 .detach() 36560 .cs
36560s({ top: 0, left: 0, display: 'block' }) 36561 .addClass(placement) 36562 36563 this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) 36564 36565 var pos = this.getPosition() 36566 var actualWidth = $tip[0].offsetWidth 36567 var actualHeight = $tip[0].offsetHeight 36568 36569 if (autoPlace) { 36570 var orgPlacement = placement 36571 var $parent = this.$element.parent() 36572 var parentDim = this.getPosition($parent) 36573 36574 placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : 36575 placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : 36576 placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : 36577 placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : 36578 placement 36579 36580 $tip 36581 .removeClass(orgPlacement) 36582 .addClass(placement) 36583 } 36584 36585 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 36586 36587 this.applyPlacement(calculatedOffset, placement) 36588 this.hoverState = null 36589 36590 var complete = function() { 36591 that.$element.trigger('shown.bs.' + that.type) 36592 } 36593 36594 $.support.transition && this.$tip.hasClass('fade') ? 36595 $tip 36596 .one($.support.transition.end, complete) 36597 .emulateTransitionEnd(150) : 36598 complete() 36599 } 36600 } 36601 36602 Tooltip.prototype.applyPlacement = function (offset, placement) { 36603 var $tip = this.tip() 36604 var width = $tip[0].offsetWidth 36605 var height = $tip[0].offsetHeight 36606 36607 // manually read margins because getBoundingClientRect includes difference 36608 var marginTop = parseInt($tip.css('margin-top'), 10) 36609 var marginLeft = parseInt($tip.css('margin-left'), 10) 36610 36611 // we must check for NaN for ie 8/9 36612 if (isNaN(marginTop)) marginTop = 0 36613 if (isNaN(marginLeft)) marginLeft = 0 36614 36615 offset.top = offset.top + marginTop 36616 offset.left = offset.left + marginLeft 36617 36618 // $.fn.offset doesn't round pixel values 36619 // so we use setOffset directly with our own function B-0 36620 $.offset.setOffset($tip[0], $.extend({ 36621 using: function (props) { 36622 $tip.css({ 36623 top: Math.round(props.top), 36624 left: Math.round(props.left) 36625 }) 36626 } 36627 }, offset), 0) 36628 36629 $tip.addClass('in') 36630 36631 // check to see if placing tip in new offset caused the tip to resize itself 36632 var actualWidth = $tip[0].offsetWidth 36633 var actualHeight = $tip[0].offsetHeight 36634 36635 if (placement == 'top' && actualHeight != height) { 36636 offset.top = offset.top + height - actualHeight 36637 } 36638 36639 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 36640 36641 if (delta.left) offset.left += delta.left 36642 else offset.top += delta.top 36643 36644 var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 36645 var arrowPosition = delta.left ? 'left' : 'top' 36646 var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' 36647 36648 $tip.offset(offset) 36649 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) 36650 } 36651 36652 Tooltip.prototype.replaceArrow = function (delta, dimension, position) { 36653 this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '') 36654 } 36655 36656 Tooltip.prototype.setContent = function () { 36657 var $tip = this.tip() 36658 var title = this.getTitle() 36659 36660 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 36661 $tip.removeClass('fade in top bottom left right') 36662 } 36663 36664 Tooltip.prototype.hide = function () { 36665 var that = this 36666 var $tip = this.tip() 36667 var e = $.Event('hide.bs.' + this.type) 36668 36669 function complete() { 36670 if (that.hoverState != 'in') $tip.detach() 36671 that.$element.trigger('hidden.bs.' + that.type) 36672 } 36673 36674 this.$element.trigger(e) 36675 36676 if (e.isDefaultPrevented()) return 36677 36678 $tip.removeClass('in') 36679 36680 $.support.transition && this.$tip.hasClass('fade') ? 36681 $tip 36682 .one($.support.transition.end, complete) 36683 .emulateTransitionEnd(150) : 36684 complete() 36685 36686 this.hoverState = null 36687 36688 return this 36689 } 36690 36691 Tooltip.prototype.fixTitle = function () { 36692 var $e = this.$element 36693 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { 36694 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 36695 } 36696 } 36697 36698 Tooltip.prototype.hasContent = function () { 36699 return this.getTitle() 36700 } 36701 36702 Tooltip.prototype.getPosition = function ($element) { 36703 $element = $element || this.$element 36704 var el = $element[0] 36705 var isBody = el.tagName == 'BODY' 36706 return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, { 36707 scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), 36708 width: isBody ? $(window).width() : $element.outerWidth(), 36709 height: isBody ? $(window).height() : $element.outerHeight() 36710 }, isBody ? {top: 0, left: 0} : $element.offset()) 36711 } 36712 36713 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 36714 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36715 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36716 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 36717 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 36718 36719 } 36720 36721 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 36722 var delta = { top: 0, left: 0 } 36723 if (!this.$viewport) return delta 36724 36725 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 36726 var viewportDimensions = this.getPosition(this.$viewport) 36727 36728 if (/right|left/.test(placement)) { 36729 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 36730 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 36731 if (topEdgeOffset < viewportDimensions.top) { // top overflow 36732 delta.top = viewportDimensions.top - topEdgeOffset 36733 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 36734 delta.top = viewportDimensions.top + viewportDimensions.height - bottom
36734EdgeOffset 36735 } 36736 } else { 36737 var leftEdgeOffset = pos.left - viewportPadding 36738 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 36739 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 36740 delta.left = viewportDimensions.left - leftEdgeOffset 36741 } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow 36742 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 36743 } 36744 } 36745 36746 return delta 36747 } 36748 36749 Tooltip.prototype.getTitle = function () { 36750 var title 36751 var $e = this.$element 36752 var o = this.options 36753 36754 title = $e.attr('data-original-title') 36755 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 36756 36757 return title 36758 } 36759 36760 Tooltip.prototype.tip = function () { 36761 return this.$tip = this.$tip || $(this.options.template) 36762 } 36763 36764 Tooltip.prototype.arrow = function () { 36765 return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow') 36766 } 36767 36768 Tooltip.prototype.validate = function () { 36769 if (!this.$element[0].parentNode) { 36770 this.hide() 36771 this.$element = null 36772 this.options = null 36773 } 36774 } 36775 36776 Tooltip.prototype.enable = function () { 36777 this.enabled = true 36778 } 36779 36780 Tooltip.prototype.disable = function () { 36781 this.enabled = false 36782 } 36783 36784 Tooltip.prototype.toggleEnabled = function () { 36785 this.enabled = !this.enabled 36786 } 36787 36788 Tooltip.prototype.toggle = function (e) { 36789 var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this 36790 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 36791 } 36792 36793 Tooltip.prototype.destroy = function () { 36794 clearTimeout(this.timeout) 36795 this.hide().$element.off('.' + this.type).removeData('bs.' + this.type) 36796 } 36797 36798 36799 // TOOLTIP PLUGIN DEFINITION 36800 // ========================= 36801 36802 var old = $.fn.tooltip 36803 36804 $.fn.tooltip = function (option) { 36805 return this.each(function () { 36806 var $this = $(this) 36807 var data = $this.data('bs.tooltip') 36808 var options = typeof option == 'object' && option 36809 36810 if (!data && option == 'destroy') return 36811 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 36812 if (typeof option == 'string') data[option]() 36813 }) 36814 } 36815 36816 $.fn.tooltip.Constructor = Tooltip 36817 36818 36819 // TOOLTIP NO CONFLICT 36820 // =================== 36821 36822 $.fn.tooltip.noConflict = function () { 36823 $.fn.tooltip = old 36824 return this 36825 } 36826 36827}(jQuery); 36828 36829/* ======================================================================== 36830 * Bootstrap: transition.js v3.1.1 36831 * http://getbootstrap.com/javascript/#transitions 36832 * ======================================================================== 36833 * Copyright 2011-2014 Twitter, Inc. 36834 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36835 * ======================================================================== */ 36836 36837 36838+function ($) { 36839 'use strict'; 36840 36841 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 36842 // ============================================================ 36843 36844 function transitionEnd() { 36845 var el = document.createElement('bootstrap') 36846 36847 var transEndEventNames = { 36848 WebkitTransition : 'webkitTransitionEnd', 36849 MozTransition : 'transitionend', 36850 OTransition : 'oTransitionEnd otransitionend', 36851 transition : 'transitionend' 36852 } 36853 36854 for (var name in transEndEventNames) { 36855 if (el.style[name] !== undefined) { 36856 return { end: transEndEventNames[name] } 36857 } 36858 } 36859 36860 return false // explicit for ie8 ( ._.) 36861 } 36862 36863 // http://blog.alexmaccaw.com/css-transitions 36864 $.fn.emulateTransitionEnd = function (duration) { 36865 var called = false, $el = this 36866 $(this).one($.support.transition.end, function () { called = true }) 36867 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 36868 setTimeout(callback, duration) 36869 return this 36870 } 36871 36872 $(function () { 36873 $.support.transition = transitionEnd() 36874 }) 36875 36876}(jQuery); 36877 36878 36879// ------------------------------------------ 36880// Rellax.js 36881// Buttery smooth parallax library 36882// Copyright (c) 2016 Moe Amaya (@moeamaya) 36883// MIT license 36884// 36885// Thanks to Paraxify.js and Jaime Cabllero 36886// for parallax concepts 36887// ------------------------------------------ 36888 36889(function (root, factory) { 36890 if (typeof define === 'function' && define.amd) { 36891 // AMD. Register as an anonymous module. 36892 define([], factory); 36893 } else if (typeof module === 'object' && module.exports) { 36894 // Node. Does not work with strict CommonJS, but 36895 // only CommonJS-like environments that support module.exports, 36896 // like Node. 36897 module.exports = factory(); 36898 } else { 36899 // Browser globals (root is window) 36900 root.Rellax = factory(); 36901 } 36902}(typeof window !== "undefined" ? window : global, function () { 36903 var Rellax = function(el, options){ 36904 "use strict"; 36905 36906 var self = Object.create(Rellax.prototype); 36907 36908 var posY = 0; 36909 var screenY = 0; 36910 var posX = 0; 36911 var screenX = 0; 36912 var blocks = []; 36913 var pause = true; 36914 36915 // check what requestAnimationFrame to use, and if 36916 // it's not supported, use the onscroll event 36917 var loop = window.requestAnimationFrame || 36918 window.webkitRequestAnimationFrame || 36919 window.mozRequestAnimationFrame || 36920 window.msRequestAnimationFrame || 36921 window.oRequestAnimationFrame || 36922 function(callback){ return setTimeout(callback, 1000 / 60); }; 36923 36924 // store the id for later use 36925 var loopId = null; 36926 36927 // Test via a getter in the options object to see if the passive property is accessed 36928 var supportsPassive = false;
vendor: 10,724 bytes, lines 36929-37230
36929 try { 36930 var opts = Object.defineProperty({}, 'passive', { 36931 get: function() { 36932 supportsPassive = true; 36933 } 36934 }); 36935 window.addEventListener("testPassive", null, opts); 36936 window.removeEventListener("testPassive", null, opts); 36937 } catch (e) {} 36938 36939 // check what cancelAnimation method to use 36940 var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout; 36941 36942 // check which transform property to use 36943 var transformProp = window.transformProp || (function(){ 36944 var testEl = document.createElement('div'); 36945 if (testEl.style.transform === null) { 36946 var vendors = ['Webkit', 'Moz', 'ms']; 36947 for (var vendor in vendors) { 36948 if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) { 36949 return vendors[vendor] + 'Transform'; 36950 } 36951 } 36952 } 36953 return 'transform'; 36954 })(); 36955 36956 // Default Settings 36957 self.options = { 36958 speed: -2, 36959 verticalSpeed: null, 36960 horizontalSpeed: null, 36961 breakpoints: [576, 768, 1201], 36962 center: false, 36963 wrapper: null, 36964 relativeToWrapper: false, 36965 round: true, 36966 vertical: true, 36967 horizontal: false, 36968 verticalScrollAxis: "y", 36969 horizontalScrollAxis: "x", 36970 callback: function() {}, 36971 }; 36972 36973 // User defined options (might have more in the future) 36974 if (options){ 36975 Object.keys(options).forEach(function(key){ 36976 self.options[key] = options[key]; 36977 }); 36978 } 36979 36980 function validateCustomBreakpoints () { 36981 if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) { 36982 var isAscending = true; 36983 var isNumerical = true; 36984 var lastVal; 36985 self.options.breakpoints.forEach(function (i) { 36986 if (typeof i !== 'number') isNumerical = false; 36987 if (lastVal !== null) { 36988 if (i < lastVal) isAscending = false; 36989 } 36990 lastVal = i; 36991 }); 36992 if (isAscending && isNumerical) return; 36993 } 36994 // revert defaults if set incorrectly 36995 self.options.breakpoints = [576, 768, 1201]; 36996 console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted"); 36997 } 36998 36999 if (options && options.breakpoints) { 37000 validateCustomBreakpoints(); 37001 } 37002 37003 // By default, rellax class 37004 if (!el) { 37005 el = '.rellax'; 37006 } 37007 37008 // check if el is a className or a node 37009 var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el]; 37010 37011 // Now query selector 37012 if (elements.length > 0) { 37013 self.elems = elements; 37014 } 37015 37016 // The elements don't exist 37017 else { 37018 console.warn("Rellax: The elements you're trying to select don't exist."); 37019 return; 37020 } 37021 37022 // Has a wrapper and it exists 37023 if (self.options.wrapper) { 37024 if (!self.options.wrapper.nodeType) { 37025 var wrapper = document.querySelector(self.options.wrapper); 37026 37027 if (wrapper) { 37028 self.options.wrapper = wrapper; 37029 } else { 37030 console.warn("Rellax: The wrapper you're trying to use doesn't exist."); 37031 return; 37032 } 37033 } 37034 } 37035 37036 // set a placeholder for the current breakpoint 37037 var currentBreakpoint; 37038 37039 // helper to determine current breakpoint 37040 var getCurrentBreakpoint = function (w) { 37041 var bp = self.options.breakpoints; 37042 if (w < bp[0]) return 'xs'; 37043 if (w >= bp[0] && w < bp[1]) return 'sm'; 37044 if (w >= bp[1] && w < bp[2]) return 'md'; 37045 return 'lg'; 37046 }; 37047 37048 // Get and cache initial position of all elements 37049 var cacheBlocks = function() { 37050 for (var i = 0; i < self.elems.length; i++){ 37051 var block = createBlock(self.elems[i]); 37052 blocks.push(block); 37053 } 37054 }; 37055 37056 37057 // Let's kick this script off 37058 // Build array for cached element values 37059 var init = function() { 37060 for (var i = 0; i < blocks.length; i++){ 37061 self.elems[i].style.cssText = blocks[i].style; 37062 } 37063 37064 blocks = []; 37065 37066 screenY = window.innerHeight; 37067 screenX = window.innerWidth; 37068 currentBreakpoint = getCurrentBreakpoint(screenX); 37069 37070 setPosition(); 37071 37072 cacheBlocks(); 37073 37074 animate(); 37075 37076 // If paused, unpause and set listener for window resizing events 37077 if (pause) { 37078 window.addEventListener('resize', init); 37079 pause = false; 37080 // Start the loop 37081 update(); 37082 } 37083 }; 37084 37085 // We want to cache the parallax blocks' 37086 // values: base, top, height, speed 37087 // el: is dom object, return: el cache values 37088 var createBlock = function(el) { 37089 var dataPercentage = el.getAttribute( 'data-rellax-percentage' ); 37090 var dataSpeed = el.getAttribute( 'data-rellax-speed' ); 37091 var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' ); 37092 var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' ); 37093 var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' ); 37094 var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' ); 37095 var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed'); 37096 var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed'); 37097 var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis'); 37098 var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis'); 37099 var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0; 37100 var dataMin = el.getAttribute( 'data-rellax-min' ); 37101 var dataMax = el.getAttribute( 'data-rellax-max' ); 37102 var dataMinX = el.getAttribute('data-rellax-min-x'); 37103 var dataMaxX = el.getAttribute('data-rellax-max-x'); 37104 var dataMinY = el.getAttribute('data-rellax-min-y'); 37105 var dataMaxY = el.getAttribute('data-rellax-max-y'); 37106 var mapBreakpoints; 37107 var breakpoints = true; 37108 37109 if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) { 37110 breakpoints = false; 37111 } else { 37112 mapBreakpoints = { 37113 'xs': dataXsSpeed, 37114 'sm': dataMobileSpeed, 37115 'md': dataTabletSpeed, 37116 'lg': dataDesktopSpeed 37117 }; 37118 } 37119 37120 // initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser) 37121 // ensures elements are positioned based on HTML layout. 37122 // 37123 // If the element has the percentage attribute, the posY and posX needs to be 37124 // the current scroll position's value, so that the elements are still positioned based on HTML layout 37125 var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37126 // If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll. 37127 if (self.options.relativeToWrapper) { 37128 var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37129 wrapperPosY = scrollPosY - self.options.wrapper.offsetTop; 37130 } 37131 var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0; 37132 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; 37133 37134 var blockTop = posY + el.getBoundingClientRect().top; 37135 var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight; 37136 37137 var blockLeft = posX + el.getBoundingClientRect().left; 37138 var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth; 37139 37140 // apparently parallax equation everyone uses 37141 var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY); 37142 var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX); 37143 if(self.options.center){ percentageX = 0.5; percentageY = 0.5; } 37144 37145 // Optional individual block speed as data attr, otherwise global speed 37146 var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed); 37147 var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed; 37148 var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed; 37149 37150 // Optional individual block movement axis direction as data attr, otherwise global movement direction 37151 var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis; 37152 var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis; 37153 37154 var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed); 37155 37156 // ~~Store non-translate3d transforms~~ 37157 // Store inline styles and extract transforms 37158 var style = el.style.cssText; 37159 var transform = ''; 37160 37161 // Check if there's an inline styled transform 37162 var searchResult = /transform\s*:/i.exec(style); 37163 if (searchResult) { 37164 // Get the index of the transform 37165 var index = searchResult.index; 37166 37167 // Trim the style to the transform point and get the following semi-colon index 37168 var trimmedStyle = style.slice(index); 37169 var delimiter = trimmedStyle.indexOf(';'); 37170 37171 // Remove "transform" string and save the attribute 37172 if (delimiter) { 37173 transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,''); 37174 } else { 37175 transform = " " + trimmedStyle.slice(11).replace(/\s/g,''); 37176 } 37177 } 37178 37179 return { 37180 baseX: bases.x, 37181 baseY: bases.y, 37182 top: blockTop, 37183 left: blockLeft, 37184 height: blockHeight, 37185 width: blockWidth, 37186 speed: speed, 37187 verticalSpeed: verticalSpeed, 37188 horizontalSpeed: horizontalSpeed, 37189 verticalScrollAxis: verticalScrollAxis, 37190 horizontalScrollAxis: horizontalScrollAxis, 37191 style: style, 37192 transform: transform, 37193 zindex: dataZindex, 37194 min: dataMin, 37195 max: dataMax, 37196 minX: dataMinX, 37197 maxX: dataMaxX, 37198 minY: dataMinY, 37199 maxY: dataMaxY 37200 }; 37201 }; 37202 37203 // set scroll position (posY, posX) 37204 // side effect method is not ideal, but okay for now 37205 // returns true if the scroll changed, false if nothing happened 37206 var setPosition = function() { 37207 var oldY = posY; 37208 var oldX = posX; 37209 37210 posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37211 posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset; 37212 // If option relativeToWrapper is true, use relative wrapper value instead. 37213 if (self.options.relativeToWrapper) { 37214 var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37215 posY = scrollPosY - self.options.wrapper.offsetTop; 37216 } 37217 37218 37219 if (oldY != posY && self.options.vertical) { 37220 // scroll changed, return true 37221 return true; 37222 } 37223 37224 if (oldX != posX && self.options.horizontal) { 37225 // scroll changed, return true 37226 return true; 37227 } 37228 37229 // scroll did not change 37230 return false;
37231 }; 37232 37233 // Ahh a pure function, gets new transform value 37234 // based on scrollPosition and speed 37235 // Allow for decimal pixel values 37236 var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) { 37237 var result = {}; 37238 var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX))); 37239 var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY))); 37240 37241 result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100; 37242 result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100; 37243 37244 return result; 37245 }; 37246 37247 // Remove event listeners and loop again 37248 var deferredUpdate = function() { 37249 window.removeEventListener('resize', deferredUpdate); 37250 window.removeEventListener('orientationchange', deferredUpdate); 37251 (self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate); 37252 (self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate); 37253 37254 // loop again 37255 loopId = loop(update); 37256 }; 37257 37258 // Loop 37259 var update = function() { 37260 if (setPosition() && pause === false) { 37261 animate(); 37262 37263 // loop again 37264 loopId = loop(update); 37265 } else { 37266 loopId = null; 37267 37268 // Don't animate until we get a position updating event 37269 window.addEventListener('resize', deferredUpdate); 37270 window.addEventListener('orientationchange', deferredUpdate); 37271 (self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false); 37272 (self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false); 37273 } 37274 }; 37275 37276 // Transform3d on parallax element 37277 var animate = function() { 37278 var positions; 37279 for (var i = 0; i < self.elems.length; i++){ 37280 // Determine relevant movement directions 37281 var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase(); 37282 var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase(); 37283 var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0; 37284 var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0; 37285 var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0; 37286 var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0; 37287 37288 var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY)); 37289 var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX)); 37290 37291 // Subtracting initialize value, so element stays in same spot as HTML 37292 positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed); 37293 var positionY = positions.y - blocks[i].baseY; 37294 var positionX = positions.x - blocks[i].baseX; 37295 37296 // The next two "if" blocks go like this: 37297 // Check if a limit is defined (first "min", then "max"); 37298 // Check if we need to change the Y or the X 37299 // (Currently working only if just one of the axes is enabled) 37300 // Then, check if the new position is inside the allowed limit 37301 // If so, use new position. If not, set position to limit. 37302 37303 // Check if a min limit is defined 37304 if (blocks[i].min !== null) { 37305 if (self.options.vertical && !self.options.horizontal) { 37306 positionY = positionY <= blocks[i].min ? blocks[i].min : positionY; 37307 } 37308 if (self.options.horizontal && !self.options.vertical) { 37309 positionX = positionX <= blocks[i].min ? blocks[i].min : positionX; 37310 } 37311 } 37312 37313 // Check if directional min limits are defined 37314 if (blocks[i].minY != null) { 37315 positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY; 37316 } 37317 if (blocks[i].minX != null) { 37318 positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX; 37319 } 37320 37321 // Check if a max limit is defined 37322 if (blocks[i].max !== null) { 37323 if (self.options.vertical && !self.options.horizontal) { 37324 positionY = positionY >= blocks[i].max ? blocks[i].max : positionY; 37325 } 37326 if (self.options.horizontal && !self.options.vertical) { 37327 positionX = positionX >= blocks[i].max ? blocks[i].max : positionX; 37328 } 37329 } 37330 37331 // Check if directional max limits are defined 37332 if (blocks[i].maxY != null) { 37333 positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY; 37334 } 37335 if (blocks[i].maxX != null) { 37336 positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX; 37337 } 37338 37339 var zindex = blocks[i].zindex; 37340 37341 // Move that element 37342 // (Set the new translation and append initial inline transforms.) 37343 var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform; 37344 self.elems[i].style[transformProp] = translate; 37345 } 37346 self.options.callback(positions); 37347 }; 37348 37349 self.destroy = function() { 37350 for (var i = 0; i < self.elems.length; i++){ 37351 self.elems[i].style.cssText = blocks[i].style; 37352 } 37353 37354 // Remove resize event listener if not pause, and pause 37355 if (!pause) { 37356 window.removeEventListener('resize', init); 37357 pause = true; 37358 } 37359 37360 // Clear the animation loop to prevent possible memory leak 37361 clearLoop(loopId); 37362 loopId = null; 37363 }; 37364 37365 // Init 37366 init(); 37367 37368 // Allow to recalculate the initial values whenever we want 37369 self.refresh = init; 37370 37371 return self; 37372 }; 37373 return Rellax; 37374})); 37375 37376/* 37377 * OKVideo by OKFocus v2.3.2 37378 * http://okfoc.us 37379 * 37380 * Copyright 2014, OKFocus 37381 * Licensed under the MIT license. 37382 * 37383 */ 37384var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array(); 37385// youtube player ready 37386function onYouTubeIframeAPIReady() { 37387 YTplayers = new Array(); 37388 jQuery('.uncode-video-container.video').each(function() { 37389 var playerY; 37390 if (jQuery(this).attr('data-provider') == 'youtube') { 37391 var id = jQuery(this).attr('data-id'), 37392 start = jQuery(this).attr('data-start'), 37393 end = jQuery(this).attr('data-end'); 37394 start = typeof start && start !== null ? start : 0; 37395 end = typeof end && end !== null ? end : 0; 37396 options = jQuery(window).data('okoptions-' + id); 37397 if ( typeof options === 'undefined' ) { 37398 return true; 37399 } 37400 options.time = jQuery(this).attr('data-t'); 37401 playerY = new YT.Player('okplayer-' + id, { 37402 videoId: options.video ? options.video.id : null, 37403 playerVars: { 37404 'autohide': 1, 37405 'autoplay': jQuery(this).hasClass('is-no-control') ? options.autoplay : 0, //options.autoplay, 37406 'disablekb': 1, 37407 'cc_load_policy': options.captions, 37408 'controls': 0, 37409 'enablejsapi': 1, 37410 'fs': 0, 37411 'modestbranding': 1, 37412 'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname), 37413 'iv_load_policy': options.annotations, 37414 'loop': options.loop, 37415 'showinfo': 0, 37416 'rel': 0, 37417 'wmode': 'opaque', 37418 'hd': options.hd, 37419 'mute': 1, 37420 'start': start, 37421 'end': end 37422 }, 37423 events: { 37424 'onReady': OKEvents.yt.ready, 37425 'onStateChange': OKEvents.yt.onStateChange, 37426 'onError': OKEvents.yt.error 37427 } 37428 }); 37429 YTplayers[id] = playerY; 37430 playerY.videoId = id; 37431 } 37432 37433 }); 37434} 37435// vimeo player ready 37436function vimeoPlayerReady(id) { 37437 options = jQuery(window).data('okoptions-' + id); 37438 if ( typeof options === 'undefined' ) { 37439 return true; 37440 }
37441 var jIframe = options.jobject, 37442 iframe = jIframe[0]; 37443 37444 jIframe.attr('src', jIframe.data('src')); 37445 var playerV = new Vimeo.Player(iframe); 37446 // hide player until Vimeo hides controls... 37447 playerV.on('loaded', function(e) { 37448 OKEvents.v.onReady(iframe); 37449 var carouselContainer = jQuery(iframe).closest('.owl-carousel'); 37450 if (carouselContainer.length) { 37451 UNCODE.owlPlayVideo(carouselContainer); 37452 } 37453 // "Do not try to add listeners or call functions before receiving this event." 37454 if (OKEvents.utils.isMobile()) { 37455 // mobile devices cannot listen for play event 37456 OKEvents.v.onPlay(playerV); 37457 } else { 37458 playerV.on('play', function(){ 37459 OKEvents.v.onPlay(playerV); 37460 jQuery(window).trigger('okevents.v.play', [playerV]); 37461 }); 37462 playerV.on('pause', function(){ 37463 OKEvents.v.onPause; 37464 jQuery(window).trigger('okevents.v.pause', [playerV]); 37465 }); 37466 playerV.on('ended', function(){ 37467 OKEvents.v.onFinish 37468 jQuery(window).trigger('okevents.v.ended', [playerV]); 37469 }); 37470 } 37471 if (options.time != null) { 37472 var optsTimeStr = (options.time).replace('t=', ''), 37473 timeV = ''; 37474 37475 if ( /[a-zA-Z]/g.test(optsTimeStr) ) { 37476 var timeArr = optsTimeStr.split(/([^\d.-])/); 37477 for ( var i = 0; i < timeArr.length; i++ ) { 37478 if ( timeArr[i] === 'h' ) { 37479 timeV += parseFloat(timeArr[i-1]) * 3600; 37480 } else if ( timeArr[i] === 'm' ) { 37481 timeV += parseFloat(timeArr[i-1]) * 60; 37482 } else if ( timeArr[i] === 's' ) { 37483 timeV += parseFloat(timeArr[i-1]); 37484 } 37485 } 37486 } else { 37487 timeV = optsTimeStr; 37488 } 37489 37490 playerV.setCurrentTime(timeV); 37491 } 37492 37493 playerV.setVolume(0); 37494 playerV.play(); 37495 jQuery(iframe).css({ 37496 visibility: 'visible', 37497 opacity: 1 37498 }); 37499 jQuery(iframe).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37500 jQuery(iframe).closest('#page-header').addClass('video-started'); 37501 jQuery(iframe).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37502 37503 jQuery(window).trigger('okevents.v.loaded', [playerV]); 37504 }); 37505} 37506OKEvents = { 37507 yt: { 37508 ready: function(event) { 37509 var id = event.target.videoId, 37510 $video = jQuery('#okplayer-' + id), 37511 options = jQuery(window).data('okoptions-' + id); 37512 if ( typeof options === 'undefined' ) { 37513 return true; 37514 } 37515 youtubePlayers[id] = event.target; 37516 event.target.setVolume(options.volume); 37517 if (options.autoplay === 1) { 37518 if (options.playlist.list) { 37519 player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality); 37520 } else { 37521 var inCarousel = $video.closest('.owl-item'); 37522 if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) { 37523 if (options.time != null) { 37524 event.target.seekTo(parseInt(options.time)); 37525 } 37526 event.target.playVideo(); 37527 } else { 37528 event.target.pauseVideo(); 37529 } 37530 } 37531 } 37532 OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target); 37533 37534 $video.closest('[data-provider]').on('uncode-resume', function(){ 37535 if (options.time != null) { 37536 event.target.seekTo(parseInt(options.time)).playVideo(); 37537 } else { 37538 event.target.seekTo(0).playVideo(); 37539 } 37540 }); 37541 37542 $video.closest('[data-provider]').on('uncode-pause', function(){ 37543 if (options.time != null) { 37544 event.target.seekTo(parseInt(options.time)).pauseVideo(); 37545 } else { 37546 event.target.seekTo(0).pauseVideo(); 37547 } 37548 }); 37549 jQuery(window).trigger('okevents.y.loaded', [event]); 37550 }, 37551 onStateChange: function(event) { 37552 var id = event.target.videoId, 37553 $video = jQuery('#okplayer-' + id), 37554 options = jQuery(window).data('okoptions-' + id); 37555 if ( typeof options === 'undefined' ) { 37556 return true; 37557 } 37558 youtubePlayers[id] = event.target; 37559 event.target.setVolume(options.volume); 37560 var $fluid = $video.closest('.fluid-object'), 37561 $tmb = $video.closest('.tmb'), 37562 setTime; 37563 switch (event.data) { 37564 case -1: 37565 OKEvents.utils.isFunction(options.unstarted) && options.unstarted(); 37566 break; 37567 case 0: 37568 OKEvents.utils.isFunction(options.onFinished) && options.onFinished(); 37569 options.loop && event.target.playVideo(); 37570 break; 37571 case 1: 37572 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37573 setTimeout(function() { 37574 UNCODE.initVideoComponent(document.body, '.uncode-video-container.video:not(.drop-move), .uncode-video-container.self-video:not(.drop-move)'); 37575 jQuery('#okplayer-' + id).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37576 jQuery('#okplayer-' + id).closest('#page-header').addClass('video-started'); 37577 jQuery('#okplayer-' + id).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37578 }, 300); 37579 break; 37580 case 2: 37581 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37582 break; 37583 case 3: 37584 OKEvents.utils.isFunction(options.buffering) && options.buffering(); 37585 break; 37586 case 5: 37587 OKEvents.utils.isFunction(options.cued) && options.cued(); 37588 break; 37589 default:
37590 throw "OKVideo: received invalid data from YT player."; 37591 } 37592 37593 jQuery(window).trigger('okevents.y.change', [event]); 37594 }, 37595 error: function(event) { 37596 throw event; 37597 } 37598 }, 37599 v: { 37600 onReady: function(target) { 37601 if ( typeof options === 'undefined' ) { 37602 return true; 37603 } 37604 OKEvents.utils.isFunction(options.onReady) && options.onReady(target); 37605 }, 37606 onPlay: function(player) { 37607 if ( typeof options === 'undefined' ) { 37608 return true; 37609 } 37610 if (!OKEvents.utils.isMobile()) player.setVolume(options.volume); 37611 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37612 jQuery(player.element).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37613 jQuery(player.element).closest('#page-header').addClass('video-started'); 37614 jQuery(player.element).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37615 }, 37616 onPause: function() { 37617 if ( typeof options === 'undefined' ) { 37618 return true; 37619 } 37620 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37621 }, 37622 onFinish: function() { 37623 if ( typeof options === 'undefined' ) { 37624 return true; 37625 } 37626 OKEvents.utils.isFunction(options.onFinish) && options.onFinish(); 37627 } 37628 }, 37629 utils: { 37630 isFunction: function(func) { 37631 if (typeof func === 'function') { 37632 return true; 37633 } else { 37634 return false; 37635 } 37636 }, 37637 isMobile: function() { 37638 if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) { 37639 return true; 37640 } else { 37641 return false; 37642 } 37643 } 37644 } 37645}; 37646 37647/** 37648 * vivus - JavaScript library to make drawing animation on SVG 37649 * @version v0.4.4 37650 * @link https://github.com/maxwellito/vivus 37651 * @license MIT 37652 */ 37653 37654'use strict'; 37655 37656(function () { 37657 37658 'use strict'; 37659 37660/** 37661 * Pathformer 37662 * Beta version 37663 * 37664 * Take any SVG version 1.1 and transform 37665 * child elements to 'path' elements 37666 * 37667 * This code is purely forked from 37668 * https://github.com/Waest/SVGPathConverter 37669 */ 37670 37671/** 37672 * Class constructor 37673 * 37674 * @param {DOM|String} element Dom element of the SVG or id of it 37675 */ 37676function Pathformer(element) { 37677 // Test params 37678 if (typeof element === 'undefined') { 37679 throw new Error('Pathformer [constructor]: "element" parameter is required'); 37680 } 37681 37682 // Set the element 37683 if (element.constructor === String) { 37684 element = document.getElementById(element); 37685 if (!element) { 37686 throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID'); 37687 } 37688 } 37689 if (element instanceof window.SVGElement || 37690 element instanceof window.SVGGElement || 37691 /^svg$/i.test(element.nodeName)) { 37692 this.el = element; 37693 } else { 37694 throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'); 37695 } 37696 37697 // Start 37698 this.scan(element); 37699} 37700 37701/** 37702 * List of tags which can be transformed 37703 * to path elements 37704 * 37705 * @type {Array} 37706 */ 37707Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect']; 37708 37709/** 37710 * List of attribute names which contain 37711 * data. This array list them to check if 37712 * they contain bad values, like percentage. 37713 * 37714 * @type {Array} 37715 */ 37716Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
vendor: 24,640 bytes, lines 37716-38514
37716y1', 'y2']; 37717 37718/** 37719 * Finds the elements compatible for transform 37720 * and apply the liked method 37721 * 37722 * @param {object} options Object from the constructor 37723 */ 37724Pathformer.prototype.scan = function (svg) { 37725 var fn, element, pathData, pathDom, 37726 elements = svg.querySelectorAll(this.TYPES.join(',')); 37727 37728 for (var i = 0; i < elements.length; i++) { 37729 element = elements[i]; 37730 fn = this[element.tagName.toLowerCase() + 'ToPath']; 37731 pathData = fn(this.parseAttr(element.attributes)); 37732 pathDom = this.pathMaker(element, pathData); 37733 element.parentNode.replaceChild(pathDom, element); 37734 } 37735}; 37736 37737 37738/** 37739 * Read `line` element to extract and transform 37740 * data, to make it ready for a `path` object. 37741 * 37742 * @param {DOMelement} element Line element to transform 37743 * @return {object} Data for a `path` element 37744 */ 37745Pathformer.prototype.lineToPath = function (element) { 37746 var newElement = {}, 37747 x1 = element.x1 || 0, 37748 y1 = element.y1 || 0, 37749 x2 = element.x2 || 0, 37750 y2 = element.y2 || 0; 37751 37752 newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2; 37753 return newElement; 37754}; 37755 37756/** 37757 * Read `rect` element to extract and transform 37758 * data, to make it ready for a `path` object. 37759 * The radius-border is not taken in charge yet. 37760 * (your help is more than welcomed) 37761 * 37762 * @param {DOMelement} element Rect element to transform 37763 * @return {object} Data for a `path` element 37764 */ 37765Pathformer.prototype.rectToPath = function (element) { 37766 var newElement = {}, 37767 x = parseFloat(element.x) || 0, 37768 y = parseFloat(element.y) || 0, 37769 width = parseFloat(element.width) || 0, 37770 height = parseFloat(element.height) || 0; 37771 37772 if (element.rx || element.ry) { 37773 var rx = parseInt(element.rx, 10) || -1, 37774 ry = parseInt(element.ry, 10) || -1; 37775 rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2); 37776 ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2); 37777 37778 newElement.d = 'M ' + (x + rx) + ',' + y + ' ' + 37779 'L ' + (x + width - rx) + ',' + y + ' ' + 37780 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' + 37781 'L ' + (x + width) + ',' + (y + height - ry) + ' ' + 37782 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' + 37783 'L ' + (x + rx) + ',' + (y + height) + ' ' + 37784 'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' + 37785 'L ' + x + ',' + (y + ry) + ' ' + 37786 'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y; 37787 } 37788 else { 37789 newElement.d = 'M' + x + ' ' + y + ' ' + 37790 'L' + (x + width) + ' ' + y + ' ' + 37791 'L' + (x + width) + ' ' + (y + height) + ' ' + 37792 'L' + x + ' ' + (y + height) + ' Z'; 37793 } 37794 return newElement; 37795}; 37796 37797/** 37798 * Read `polyline` element to extract and transform 37799 * data, to make it ready for a `path` object. 37800 * 37801 * @param {DOMelement} element Polyline element to transform 37802 * @return {object} Data for a `path` element 37803 */ 37804Pathformer.prototype.polylineToPath = function (element) { 37805 var newElement = {}, 37806 points = element.points.trim().split(' '), 37807 i, path; 37808 37809 // Reformatting if points are defined without commas 37810 if (element.points.indexOf(',') === -1) { 37811 var formattedPoints = []; 37812 for (i = 0; i < points.length; i+=2) { 37813 formattedPoints.push(points[i] + ',' + points[i+1]); 37814 } 37815 points = formattedPoints; 37816 } 37817 37818 // Generate the path.d value 37819 path = 'M' + points[0]; 37820 for(i = 1; i < points.length; i++) { 37821 if (points[i].indexOf(',') !== -1) { 37822 path += 'L' + points[i]; 37823 } 37824 } 37825 newElement.d = path; 37826 return newElement; 37827}; 37828 37829/** 37830 * Read `polygon` element to extract and transform 37831 * data, to make it ready for a `path` object. 37832 * This method rely on polylineToPath, because the 37833 * logic is similar. The path created is just closed, 37834 * so it needs an 'Z' at the end. 37835 * 37836 * @param {DOMelement} element Polygon element to transform 37837 * @return {object} Data for a `path` element 37838 */ 37839Pathformer.prototype.polygonToPath = function (element) { 37840 var newElement = Pathformer.prototype.polylineToPath(element); 37841 37842 newElement.d += 'Z'; 37843 return newElement; 37844}; 37845 37846/** 37847 * Read `ellipse` element to extract and transform 37848 * data, to make it ready for a `path` object. 37849 * 37850 * @param {DOMelement} element ellipse element to transform 37851 * @return {object} Data for a `path` element 37852 */ 37853Pathformer.prototype.ellipseToPath = function (element) { 37854 var newElement = {}, 37855 rx = parseFloat(element.rx) || 0, 37856 ry = parseFloat(element.ry) || 0, 37857 cx = parseFloat(element.cx) || 0, 37858 cy = parseFloat(element.cy) || 0, 37859 startX = cx - rx, 37860 startY = cy, 37861 endX = parseFloat(cx) + parseFloat(rx), 37862 endY = cy; 37863 37864 newElement.d = 'M' + startX + ',' + startY + 37865 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY + 37866 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY; 37867 return newElement; 37868}; 37869 37870/** 37871 * Read `circle` element to extract and transform 37872 * data, to make it ready for a `path` object. 37873 * 37874 * @param {DOMelement} element Circle element to transform 37875 * @return {object} Data for a `path` element 37876 */ 37877Pathformer.prototype.circleToPath = function (element) { 37878 var newElement = {}, 37879 r = parseFloat(element.r) || 0, 37880 cx = parseFloat(element.cx) || 0, 37881 cy = parseFloat(element.cy) || 0, 37882 startX = cx - r, 37883 startY = cy, 37884 endX = parseFloat(cx) + parseFloat(r), 37885 endY = cy; 37886 37887 newElement.d = 'M' + startX + ',' + startY + 37888 'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY + 37889 'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY; 37890 return newElement; 37891}; 37892 37893/** 37894 * Create `path` elements form original element 37895 * and prepared objects 37896 * 37897 * @param {DOMelement} element Original element to transform 37898 * @param {object} pathData Path data (from `toPath` methods) 37899 * @return {DOMelement} Path element 37900 */ 37901Pathformer.prototype.pathMaker = function (element, pathData) { 37902 var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path'); 37903 for(i = 0; i < element.attributes.length; i++) { 37904 attr = element.attributes[i]; 37905 if (this.ATTR_WATCH.indexOf(attr.name) === -1) { 37906 pathTag.setAttribute(attr.name, attr.value); 37907 } 37908 } 37909 for(i in pathData) { 37910 pathTag.setAttribute(i, pathData[i]); 37911 } 37912 return pathTag; 37913}; 37914 37915/** 37916 * Parse attributes of a DOM element to 37917 * get an object of attribute => value 37918 * 37919 * @param {NamedNodeMap} attributes Attributes object from DOM element to parse 37920 * @return {object} Object of attributes 37921 */ 37922Pathformer.prototype.parseAttr = function (element) { 37923 var attr, output = {}; 37924 for (var i = 0; i < element.length; i++) { 37925 attr = element[i]; 37926 // Check if no data attribute contains '%', or the transformation is impossible 37927 if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) { 37928 throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.'); 37929 } 37930 output[attr.name] = attr.value; 37931 } 37932 return output; 37933}; 37934 37935 'use strict'; 37936 37937var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt; 37938 37939/** 37940 * Vivus 37941 * Beta version 37942 * 37943 * Take any SVG and make the animation 37944 * to give give the impression of live drawing 37945 * 37946 * This in more than just inspired from codrops 37947 * At that point, it's a pure fork. 37948 */ 37949 37950/** 37951 * Class constructor 37952 * option structure 37953 * type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed) 37954 * duration: <int> (in frames) 37955 * start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport) 37956 * delay: <int> (delay between the drawing of first and last path) 37957 * dashGap <integer> whitespace extra margin between dashes 37958 * pathTimingFunction <function> timing animation function for each path element of the SVG 37959 * animTimingFunction <function> timing animation function for the complete SVG 37960 * forceRender <boolean> force the browser to re-render all updated path items 37961 * selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original 37962 * 37963 * The attribute 'type' is by default on 'delayed'. 37964 * - 'delayed' 37965 * all paths are draw at the same time but with a 37966 * little delay between them before start 37967 * - 'sync' 37968 * all path are start and finish at the same time 37969 * - 'oneByOne' 37970 * only one path is draw at the time 37971 * the end of the first one will trigger the draw 37972 * of the next one 37973 * 37974 * All these values can be overwritten individually 37975 * for each path item in the SVG 37976 * The value of frames will always take the advantage of 37977 * the duration value. 37978 * If you fail somewhere, an error will be thrown. 37979 * Good luck. 37980 * 37981 * @constructor 37982 * @this {Vivus} 37983 * @param {DOM|String} element Dom element of the SVG or id of it 37984 * @param {Object} options Options about the animation 37985 * @param {Function} callback Callback for the end of the animation 37986 */ 37987function Vivus (element, options, callback) { 37988 37989 setupEnv(); 37990 37991 // Setup 37992 this.isReady = false; 37993 this.setElement(element, options); 37994 this.setOptions(options); 37995 this.setCallback(callback); 37996 37997 if (this.isReady) { 37998 this.init(); 37999 } 38000} 38001 38002/** 38003 * Timing functions 38004 ************************************** 38005 * 38006 * Default functions to help developers. 38007 * It always take a number as parameter (between 0 to 1) then 38008 * return a number (between 0 and 1) 38009 */ 38010Vivus.LINEAR = function (x) {return x;}; 38011Vivus.EASE = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;}; 38012Vivus.EASE_OUT = function (x) {return 1 - Math.pow(1-x, 3);}; 38013Vivus.EASE_IN = function (x) {return Math.pow(x, 3);}; 38014Vivus.EASE_OUT_BOUNCE = function (x) { 38015 var base = -Math.cos(x * (0.5 * Math.PI)) + 1, 38016 rate = Math.pow(base,1.5), 38017 rateR = Math.pow(1 - x, 2), 38018 progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1; 38019 return (1- rateR) + (progress * rateR); 38020}; 38021 38022 38023/** 38024 * Setters 38025 ************************************** 38026 */ 38027 38028/** 38029 * Check and set the element in the instance 38030 * The method will not return anything, but will throw an 38031 * error if the parameter is invalid 38032 * 38033 * @param {DOM|String} element SVG Dom element or id of it 38034 */ 38035Vivus.prototype.setElement = function (element, options) { 38036 var onLoad, self; 38037 38038 // Basic check 38039 if (typeof element === 'undefined') { 38040 throw new Error('Vivus [constructor]: "element" parameter is required'); 38041 } 38042 38043 // Set the element 38044 if (element.constructor === String) { 38045 element = document.getElementById(element); 38046 if (!element) { 38047 throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID'); 38048 } 38049 } 38050 this.parentEl = element; 38051 38052 // Load the SVG with XMLHttpRequest and extract the SVG 38053 if (options && options.file) { 38054 var self = this; 38055 onLoad = function (e) { 38056 var domSandbox = document.createElement('div'); 38057 domSandbox.innerHTML = this.responseText; 38058 38059 var svgTag = domSandbox.querySelector('svg'); 38060 if (!svgTag) { 38061 throw new Error('Vivus [load]: Cannot find the SVG in the loaded file : ' + options.file); 38062 } 38063 38064 self.el = svgTag 38065 self.el.setAttribute('width', '100%'); 38066 self.el.setAttribute('height', '100%'); 38067 self.parentEl.appendChild(self.el) 38068 self.isReady = true; 38069 self.init(); 38070 self = null; 38071 } 38072 38073 var oReq = new window.XMLHttpRequest(); 38074 oReq.addEventListener('load', onLoad); 38075 oReq.open('GET', options.file); 38076 oReq.send(); 38077 return; 38078 } 38079 38080 switch (element.constructor) { 38081 case window.SVGSVGElement: 38082 case window.SVGElement: 38083 case window.SVGGElement: 38084 this.el = element; 38085 this.isReady = true; 38086 break; 38087 38088 case window.HTMLObjectElement: 38089 self = this; 38090 onLoad = function (e) { 38091 if (self.isReady) { 38092 return; 38093 } 38094 self.el = element.contentDocument && element.contentDocument.querySelector('svg'); 38095 if (!self.el && e) { 38096 throw new Error('Vivus [constructor]: object loaded does not contain any SVG'); 38097 } 38098 else if (self.el) { 38099 if (element.getAttribute('built-by-vivus')) { 38100 self.parentEl.insertBefore(self.el, element); 38101 self.parentEl.removeChild(element); 38102 self.el.setAttribute('width', '100%'); 38103 self.el.setAttribute('height', '100%'); 38104 } 38105 self.isReady = true; 38106 self.init(); 38107 self = null; 38108 } 38109 }; 38110 38111 if (!onLoad()) { 38112 element.addEventListener('load', onLoad); 38113 } 38114 break; 38115 38116 default: 38117 throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'); 38118 } 38119}; 38120 38121/** 38122 * Set up user option to the instance 38123 * The method will not return anything, but will throw an 38124 * error if the parameter is invalid 38125 * 38126 * @param {object} options Object from the constructor 38127 */ 38128Vivus.prototype.setOptions = function (options) { 38129 var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync']; 38130 var allowedStarts = ['inViewport', 'manual', 'autostart']; 38131 38132 // Basic check 38133 if (options !== undefined && options.constructor !== Object) { 38134 throw new Error('Vivus [constructor]: "options" parameter must be an object'); 38135 } 38136 else { 38137 options = options || {}; 38138 } 38139 38140 // Set the animation type 38141 if (options.type && allowedTypes.indexOf(options.type) === -1) { 38142 throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`'); 38143 } 38144 else { 38145 this.type = options.type || allowedTypes[0]; 38146 } 38147 38148 // Set the start type 38149 if (options.start && allowedStarts.indexOf(options.start) === -1) { 38150 throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option'); 38151 } 38152 else { 38153 this.start = options.start || allowedStarts[0]; 38154 } 38155 38156 this.isIE = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 ); 38157 this.duration = parsePositiveInt(options.duration, 120); 38158 this.delay = parsePositiveInt(options.delay, null); 38159 //Uncode addition 38160 this.delayStart = parsePositiveInt(options.delayStart, null); 38161 //#END 38162 this.dashGap = parsePositiveInt(options.dashGap, 1); 38163 this.forceRender = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE; 38164 this.reverseStack = !!options.reverseStack; 38165 this.selfDestroy = !!options.selfDestroy; 38166 this.onReady = options.onReady; 38167 this.map = []; 38168 this.frameLength = this.currentFrame = this.delayUnit = this.speed = this.handle = null; 38169 38170 this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false; 38171 38172 this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR; 38173 this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR; 38174 38175 if (this.delay >= this.duration) { 38176 throw new Error('Vivus [constructor]: delay must be shorter than duration'); 38177 } 38178}; 38179 38180/** 38181 * Set up callback to the instance 38182 * The method will not return enything, but will throw an 38183 * error if the parameter is invalid 38184 * 38185 * @param {Function} callback Callback for the animation end 38186 */ 38187Vivus.prototype.setCallback = function (callback) { 38188 // Basic check 38189 if (!!callback && callback.constructor !== Function) { 38190 throw new Error('Vivus [constructor]: "callback" parameter must be a function'); 38191 } 38192 this.callback = callback || function () {}; 38193}; 38194 38195 38196/** 38197 * Core 38198 ************************************** 38199 */ 38200 38201/** 38202 * Map the svg, path by path. 38203 * The method return nothing, it just fill the 38204 * `map` array. Each item in this array represent 38205 * a path element from the SVG, with informations for 38206 * the animation. 38207 * 38208 * ``` 38209 * [ 38210 * { 38211 * el: <DOMobj> the path element 38212 * length: <number> length of the path line 38213 * startAt: <number> time start of the path animation (in frames) 38214 * duration: <number> path animation duration (in frames) 38215 * }, 38216 * ... 38217 * ] 38218 * ``` 38219 * 38220 */ 38221Vivus.prototype.mapping = function () { 38222 var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint; 38223 timePoint = totalLength = lengthMeter = 0; 38224 paths = this.el.querySelectorAll('path'); 38225 38226 for (i = 0; i < paths.length; i++) { 38227 path = paths[i]; 38228 if (this.isInvisible(path)) { 38229 continue; 38230 } 38231 pathObj = { 38232 el: path, 38233 length: Math.ceil(path.getTotalLength()) 38234 }; 38235 // Test if the path length is correct 38236 if (isNaN(pathObj.length)) { 38237 if (window.console && console.warn) { 38238 console.warn('Vivus [mapping]: cannot retrieve a path element length', path); 38239 } 38240 continue; 38241 } 38242 this.map.push(pathObj); 38243 path.style.strokeDasharray = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2); 38244 path.style.strokeDashoffset = pathObj.length + this.dashGap; 38245 pathObj.length += this.dashGap; 38246 totalLength += pathObj.length; 38247 38248 this.renderPath(i); 38249 } 38250 38251 totalLength = totalLength === 0 ? 1 : totalLength; 38252 this.delay = this.delay === null ? this.duration / 3 : this.delay; 38253 this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1); 38254 38255 // Reverse stack if asked 38256 if (this.reverseStack) { 38257 this.map.reverse(); 38258 } 38259 38260 for (i = 0; i < this.map.length; i++) { 38261 pathObj = this.map[i]; 38262 38263 switch (this.type) { 38264 case 'delayed': 38265 pathObj.startAt = this.delayUnit * i; 38266 pathObj.duration = this.duration - this.delay; 38267 break; 38268 38269 case 'oneByOne': 38270 pathObj.startAt = lengthMeter / totalLength * this.duration; 38271 pathObj.duration = pathObj.length / totalLength * this.duration; 38272 break; 38273 38274 case 'sync': 38275 case 'async': 38276 case 'nsync': 38277 pathObj.startAt = 0; 38278 pathObj.duration = this.duration; 38279 break; 38280 38281 case 'scenario-sync': 38282 path = pathObj.el; 38283 pAttrs = this.parseAttr(path); 38284 pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0); 38285 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38286 timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration; 38287 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38288 break; 38289 38290 case 'scenario': 38291 path = pathObj.el; 38292 pAttrs = this.parseAttr(path); 38293 pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0; 38294 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38295 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38296 break; 38297 } 38298 lengthMeter += pathObj.length; 38299 this.frameLength = this.frameLength || this.duration; 38300 } 38301}; 38302 38303/** 38304 * Interval method to draw the SVG from current 38305 * position of the animation. It update the value of 38306 * `currentFrame` and re-trace the SVG. 38307 * 38308 * It use this.handle to store the requestAnimationFrame 38309 * and clear it one the animation is stopped. So this 38310 * attribute can be used to know if the animation is 38311 * playing. 38312 * 38313 * Once the animation at the end, this method will 38314 * trigger the Vivus callback. 38315 * 38316 */ 38317Vivus.prototype.drawer = function () { 38318 var self = this; 38319 this.currentFrame += this.speed; 38320 38321 if (this.currentFrame <= 0) { 38322 this.stop(); 38323 this.reset(); 38324 } else if (this.currentFrame >= this.frameLength) { 38325 this.stop(); 38326 this.currentFrame = this.frameLength; 38327 this.trace(); 38328 if (this.selfDestroy) { 38329 this.destroy(); 38330 } 38331 } else { 38332 this.trace(); 38333 this.handle = requestAnimFrame(function () { 38334 self.drawer(); 38335 }); 38336 return; 38337 } 38338 38339 this.callback(this); 38340 if (this.instanceCallback) { 38341 this.instanceCallback(this); 38342 this.instanceCallback = null; 38343 } 38344}; 38345 38346/** 38347 * Draw the SVG at the current instant from the 38348 * `currentFrame` value. Here is where most of the magic is. 38349 * The trick is to use the `strokeDashoffset` style property. 38350 * 38351 * For optimisation reasons, a new property called `progress` 38352 * is added in each item of `map`. This one contain the current 38353 * progress of the path element. Only if the new value is different 38354 * the new value will be applied to the DOM element. This 38355 * method save a lot of resources to re-render the SVG. And could 38356 * be improved if the animation couldn't be played forward. 38357 * 38358 */ 38359Vivus.prototype.trace = function () { 38360 var i, progress, path, currentFrame; 38361 currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength; 38362 for (i = 0; i < this.map.length; i++) { 38363 path = this.map[i]; 38364 progress = (currentFrame - path.startAt) / path.duration; 38365 progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress))); 38366 if (path.progress !== progress) { 38367 path.progress = progress; 38368 path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress)); 38369 this.renderPath(i); 38370 } 38371 } 38372}; 38373 38374/** 38375 * Method forcing the browser to re-render a path element 38376 * from it's index in the map. Depending on the `forceRender` 38377 * value. 38378 * The trick is to replace the path element by it's clone. 38379 * This practice is not recommended because it's asking more 38380 * ressources, too much DOM manupulation.. 38381 * but it's the only way to let the magic happen on IE. 38382 * By default, this fallback is only applied on IE. 38383 * 38384 * @param {Number} index Path index 38385 */ 38386Vivus.prototype.renderPath = function (index) { 38387 if (this.forceRender && this.map && this.map[index]) { 38388 var pathObj = this.map[index], 38389 newPath = pathObj.el.cloneNode(true); 38390 pathObj.el.parentNode.replaceChild(newPath, pathObj.el); 38391 pathObj.el = newPath; 38392 } 38393}; 38394 38395/** 38396 * When the SVG object is loaded and ready, 38397 * this method will continue the initialisation. 38398 * 38399 * This this mainly due to the case of passing an 38400 * object tag in the constructor. It will wait 38401 * the end of the loading to initialise. 38402 * 38403 */ 38404Vivus.prototype.init = function () { 38405 // Set object variables 38406 this.frameLength = 0; 38407 this.currentFrame = 0; 38408 this.map = []; 38409 38410 // Start 38411 new Pathformer(this.el); 38412 this.mapping(); 38413 this.starter(); 38414 38415 if (this.onReady) { 38416 this.onReady(this); 38417 } 38418}; 38419 38420/** 38421 * Trigger to start of the animation. 38422 * Depending on the `start` value, a different script 38423 * will be applied. 38424 * 38425 * If the `start` value is not valid, an error will be thrown. 38426 * Even if technically, this is impossible. 38427 * 38428 */ 38429Vivus.prototype.starter = function () { 38430 switch (this.start) { 38431 case 'manual': 38432 return; 38433 38434 case 'autostart': 38435 this.play(); 38436 break; 38437 38438 case 'inViewport': 38439 var self = this, 38440 listener = function () { 38441 if (self.isInViewport(self.parentEl, 1)) { 38442 self.play(); 38443 window.removeEventListener('scroll', listener); 38444 //Uncode addition 38445 window.removeEventListener('fp-slide-changed', listener); 38446 window.removeEventListener('fp-slide-scroll', listener); 38447 //#END 38448 } 38449 }; 38450 window.addEventListener('scroll', listener); 38451 //Uncode addition 38452 window.addEventListener('fp-slide-changed', listener); 38453 window.addEventListener('fp-slide-scroll', listener); 38454 //#END 38455 listener(); 38456 break; 38457 } 38458}; 38459 38460 38461/** 38462 * Controls 38463 ************************************** 38464 */ 38465 38466/** 38467 * Get the current status of the animation between 38468 * three different states: 'start', 'progress', 'end'. 38469 * @return {string} Instance status 38470 */ 38471Vivus.prototype.getStatus = function () { 38472 return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress'; 38473}; 38474 38475/** 38476 * Reset the instance to the initial state : undraw 38477 * Be careful, it just reset the animation, if you're 38478 * playing the animation, this won't stop it. But just 38479 * make it start from start. 38480 * 38481 */ 38482Vivus.prototype.reset = function () { 38483 return this.setFrameProgress(0); 38484}; 38485 38486/** 38487 * Set the instance to the final state : drawn 38488 * Be careful, it just set the animation, if you're 38489 * playing the animation on rewind, this won't stop it. 38490 * But just make it start from the end. 38491 * 38492 */ 38493Vivus.prototype.finish = function () { 38494 return this.setFrameProgress(1); 38495}; 38496 38497/** 38498 * Set the level of progress of the drawing. 38499 * 38500 * @param {number} progress Level of progress to set 38501 */ 38502Vivus.prototype.setFrameProgress = function (progress) { 38503 progress = Math.min(1, Math.max(0, progress)); 38504 this.currentFrame = Math.round(this.frameLength * progress); 38505 this.trace(); 38506 return this; 38507}; 38508 38509/** 38510 * Play the animation at the desired speed. 38511 * Speed must be a valid number (no zero). 38512 * By default, the speed value is 1. 38513 * But a negative value is accepted to go forward. 38514 *
38515 * And works with float too. 38516 * But don't forget we are in JavaScript, se be nice 38517 * with him and give him a 1/2^x value. 38518 * 38519 * @param {number} speed Animation speed [optional] 38520 */ 38521Vivus.prototype.play = function (speed, callback) { 38522 this.instanceCallback = null; 38523 38524 if (speed && typeof speed === 'function') { 38525 this.instanceCallback = speed; // first parameter is actually the callback function 38526 speed = null; 38527 } 38528 else if (speed && typeof speed !== 'number') { 38529 throw new Error('Vivus [play]: invalid speed'); 38530 } 38531 // if the first parameter wasn't the callback, check if the seconds was 38532 if (callback && typeof(callback) === 'function' && !this.instanceCallback) { 38533 this.instanceCallback = callback; 38534 } 38535 38536 38537 this.speed = speed || 1; 38538 //Uncode addition 38539 if (!this.handle) { 38540 var $this = this, 38541 delay = (this.delayStart != null) ? this.delayStart : 0; 38542 setTimeout(function() { 38543 $this.drawer(); 38544 }, delay); 38545 } 38546 //#END 38547 return this; 38548}; 38549 38550/** 38551 * Stop the current animation, if on progress. 38552 * Should not trigger any error. 38553 * 38554 */ 38555Vivus.prototype.stop = function () { 38556 if (this.handle) { 38557 cancelAnimFrame(this.handle); 38558 this.handle = null; 38559 } 38560 return this; 38561}; 38562 38563/** 38564 * Destroy the instance. 38565 * Remove all bad styling attributes on all 38566 * path tags 38567 * 38568 */ 38569Vivus.prototype.destroy = function () { 38570 this.stop(); 38571 var i, path; 38572 for (i = 0; i < this.map.length; i++) { 38573 path = this.map[i]; 38574 path.el.style.strokeDashoffset = null; 38575 path.el.style.strokeDasharray = null; 38576 this.renderPath(i); 38577 } 38578}; 38579 38580 38581/** 38582 * Utils methods 38583 * include methods from Codrops 38584 ************************************** 38585 */ 38586 38587/** 38588 * Method to best guess if a path should added into 38589 * the animation or not. 38590 * 38591 * 1. Use the `data-vivus-ignore` attribute if set 38592 * 2. Check if the instance must ignore invisible paths 38593 * 3. Check if the path is visible 38594 * 38595 * For now the visibility checking is unstable. 38596 * It will be used for a beta phase. 38597 * 38598 * Other improvments are planned. Like detecting 38599 * is the path got a stroke or a valid opacity. 38600 */ 38601Vivus.prototype.isInvisible = function (el) { 38602 var rect, 38603 ignoreAttr = el.getAttribute('data-ignore'); 38604 38605 if (ignoreAttr !== null) { 38606 return ignoreAttr !== 'false'; 38607 } 38608 38609 if (this.ignoreInvisible) { 38610 rect = el.getBoundingClientRect(); 38611 return !rect.width && !rect.height; 38612 } 38613 else { 38614 return false; 38615 } 38616}; 38617 38618/** 38619 * Parse attributes of a DOM element to 38620 * get an object of {attributeName => attributeValue} 38621 * 38622 * @param {object} element DOM element to parse 38623 * @return {object} Object of attributes 38624 */ 38625Vivus.prototype.parseAttr = function (element) { 38626 var attr, output = {}; 38627 if (element && element.attributes) { 38628 for (var i = 0; i < element.attributes.length; i++) { 38629 attr = element.attributes[i]; 38630 output[attr.name] = attr.value; 38631 } 38632 } 38633 return output; 38634}; 38635 38636/** 38637 * Reply if an element is in the page viewport 38638 * 38639 * @param {object} el Element to observe 38640 * @param {number} h Percentage of height 38641 * @return {boolean} 38642 */ 38643Vivus.prototype.isInViewport = function (el, h) { 38644 var scrolled = this.scrollY(), 38645 viewed = scrolled + this.getViewportH(), 38646 elBCR = el.getBoundingClientRect(), 38647 elHeight = elBCR.height, 38648 elTop = scrolled + elBCR.top, 38649 elBottom = elTop + elHeight; 38650 38651 // if 0, the element is considered in the viewport as soon as it enters. 38652 // if 1, the element is considered in the viewport only when it's fully inside 38653 // value in percentage (1 >= h >= 0) 38654 h = h || 0; 38655 38656 return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled; 38657}; 38658 38659 38660/** 38661 * Get the viewport height in pixels 38662 * 38663 * @return {integer} Viewport height 38664 */ 38665Vivus.prototype.getViewportH = function () { 38666 var client = this.docElem.clientHeight, 38667 inner = window.innerHeight; 38668 38669 if (client < inner) { 38670 return inner; 38671 } 38672 else { 38673 return client; 38674 } 38675}; 38676 38677/** 38678 * Get the page Y offset 38679 * 38680 * @return {integer} Page Y offset 38681 */ 38682Vivus.prototype.scrollY = function () { 38683 return window.pageYOffset || this.docElem.scrollTop; 38684}; 38685 38686setupEnv = function () { 38687 38688 if (Vivus.prototype.docElem) { 38689 return; 38690 } 38691 38692 /** 38693 * Alias for document element 38694 * 38695 * @type {DOMelement} 38696 */ 38697 Vivus.prototype.docElem = window.document.documentElement; 38698 38699 /** 38700 * Alias for `requestAnimationFrame` or 38701 * `setTimeout` function for deprecated browsers. 38702 * 38703 */ 38704 requestAnimFrame = (function () { 38705 return ( 38706 window.requestAnimationFrame || 38707 window.webkitRequestAnimationFrame || 38708 window.mozRequestAnimationFrame || 38709 window.oRequestAnimationFrame || 38710 window.msRequestAnimationFrame || 38711 function(/* function */ callback){ 38712 return window.setTimeout(callback, 1000 / 60); 38713 } 38714 ); 38715 })(); 38716 38717 /** 38718 * Alias for `cancelAnimationFrame` or 38719 * `cancelTimeout` function for deprecated browsers. 38720 * 38721 */ 38722 cancelAnimFrame = (function () { 38723 return ( 38724 window.cancelAnimationFrame || 38725 window.webkitCancelAnimationFrame || 38726 window.mozCancelAnimationFrame || 38727 window.oCancelAnimationFrame || 38728 window.msCancelAnimationFrame || 38729 function(id){ 38730 return window.clearTimeout(id); 38731 } 38732 ); 38733 })(); 38734}; 38735 38736/** 38737 * Parse string to integer. 38738 * If the number is not positive or null 38739 * the method will return the default value 38740 * or 0 if undefined 38741 * 38742 * @param {string} value String to parse 38743 * @param {*}
38743 defaultValue Value to return if the result parsed is invalid 38744 * @return {number} 38745 * 38746 */ 38747parsePositiveInt = function (value, defaultValue) { 38748 var output = parseInt(value, 10); 38749 return (output >= 0) ? output : defaultValue; 38750}; 38751 38752 38753 if (typeof define === 'function' && define.amd) { 38754 // AMD. Register as an anonymous module. 38755 define([], function() { 38756 return Vivus; 38757 }); 38758 } else if (typeof exports === 'object') { 38759 // Node. Does not work with strict CommonJS, but 38760 // only CommonJS-like environments that support module.exports, 38761 // like Node. 38762 module.exports = Vivus; 38763 } else { 38764 // Browser globals 38765 window.Vivus = Vivus; 38766 } 38767 38768}());
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.