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 title: 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_whatsapp = function() { 26935 return this.popup('https://api.whatsapp.com/send', { 26936 text: this.config.networks.whatsapp.title + '%20' + this.config.networks.whatsapp.url, 26937 }); 26938 } 26939 26940 Share.prototype.network_email = function() { 26941 return this.popup('mailto:', { 26942 subject: this.config.networks.email.title, 26943 body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description, 26944 }); 26945 }; 26946 26947 Share.prototype.inject_icons = function() { 26948 // return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css"); 26949 }; 26950 26951 Share.prototype.inject_fonts = function() { 26952 // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text); 26953 }; 26954 26955 Share.prototype.inject_stylesheet = function(url) { 26956 var link; 26957 if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) { 26958 link = document.createElement("link"); 26959 link.setAttribute("rel", "stylesheet"); 26960 link.setAttribute("href", url); 26961 return this.el.head.appendChild(link); 26962 } 26963 }; 26964 26965 Share.prototype.inject_css = function(instance) { 26966 var css, meta, selector, style; 26967 selector = "." + (instance.getAttribute('class').split(" ").join(".")); 26968 if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) { 26969 this.config.selector = selector; 26970 css = getStyles(this.config); 26971 style = document.createElement("style"); 26972 style.type = "text/css"; 26973 if (style.styleSheet) { 26974 style.styleSheet.cssText = css; 26975 } else { 26976 style.appendChild(document.createTextNode(css)); 26977 } 26978 this.el.head.appendChild(style); 26979 delete this.config.selector; 26980 meta = document.createElement("meta"); 26981 meta.setAttribute("name", "sharer" + selector); 26982 return this.el.head.appendChild(meta); 26983 } 26984 }; 26985 26986 Share.prototype.inject_html = function(instance) { 26987 //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>"; 26988 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-whatsapp' data-network='whatsapp' 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>"; 26989 }; 26990 26991 Share.prototype.inject_facebook_sdk = function() { 26992 var fb_root, script; 26993 if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) { 26994 script = document.createElement("script"); 26995 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')"; 26996 fb_root = document.createElement("div"); 26997 fb_root.id = "fb-root"; 26998 this.el.body.appendChild(fb_root); 26999 return this.el.body.appendChild(script); 27000 } 27001 }; 27002 27003 Share.prototype.hook = function(type, network, instance) { 27004 var fn, opts; 27005 fn = this.config.networks[network][type]; 27006 if (typeof fn === "function") { 27007 opts = fn.call(this.config.networks[network], instance); 27008 if (opts !== void 0) { 27009 opts = this.normalize_filter_config_updates(opts); 27010 this.extend(this.config.networks[network], opts, true); 27011 this.normalize_network_configuration(); 27012 } 27013 } 27014 }; 27015 27016 Share.prototype.default_title = function() { 27017 var content; 27018 if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) { 27019 return encodeURIComponent(content.getAttribute('content')); 27020 } else if (content = document.querySelector('title')) { 27021 return encodeURIComponent(content.innerText); 27022 } 27023 }; 27024 27025 Share.prototype.default_image = function() { 27026 var content; 27027 if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) { 27028 return content.getAttribute('content'); 27029 } 27030 }; 27031 27032 Share.prototype.default_description = function() { 27033 var content; 27034 if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) { 27035 return encodeURIComponent(content.getAttribute('content')); 27036 } else { 27037 return ''; 27038 } 27039 }; 27040 27041 Share.prototype.set_global_configuration = function() { 27042 var display, network, option, options, _ref, _results; 27043 _ref = this.config.networks; 27044 _results = []; 27045 for (network in _ref) { 27046 options = _ref[network]; 27047 for (option in options) { 27048 if (this.config.networks[network][option] == null) { 27049 this.config.networks[network][option] = this.config[option]; 27050 } 27051 } 27052 if (this.config.networks[network].enabled) { 27053 display = 'block'; 27054 this.config.enabled_networks += 1; 27055 } else { 27056 display = 'none'; 27057 } 27058 _results.push(this.config.networks[network].display = display); 27059 } 27060 return _results; 27061 }; 27062 27063 Share.prototype.normalize_network_configuration = function() { 27064 if (!this.config.networks.facebook.app_id) { 27065 this.config.networks.facebook.load_sdk = false;
27066 } 27067 if (!this.is_encoded(this.config.networks.twitter.description)) { 27068 this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description); 27069 } 27070 if (typeof this.config.networks.facebook.app_id === 'number') { 27071 return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString(); 27072 } 27073 }; 27074 27075 Share.prototype.normalize_filter_config_updates = function(opts) { 27076 if (this.config.networks.facebook.app_id !== opts.app_id) { 27077 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."); 27078 delete opts.app_id; 27079 } 27080 if (this.config.networks.facebook.load_sdk !== opts.load_sdk) { 27081 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."); 27082 delete opts.app_id; 27083 } 27084 return opts; 27085 }; 27086 27087 return Share; 27088 27089})(ShareUtils); 27090 return Share; 27091}); 27092 27093// Generated by CoffeeScript 1.9.2 27094 27095// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net 27096 27097(function() { 27098 var $, win; 27099 27100 $ = this.jQuery || window.jQuery; 27101 27102 win = $(window); 27103 27104 $.fn.stick_in_parent = function(opts) { 27105 var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class; 27106 if (opts == null) { 27107 opts = {}; 27108 } 27109 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; 27110 if (offset_top == null) { 27111 offset_top = 0; 27112 } 27113 if (parent_selector == null) { 27114 parent_selector = void 0; 27115 } 27116 if (inner_scrolling == null) { 27117 inner_scrolling = true; 27118 } 27119 if (sticky_class == null) { 27120 sticky_class = "is_stuck"; 27121 } 27122 doc = $(document); 27123 if (enable_bottoming == null) { 27124 enable_bottoming = true; 27125 } 27126 outer_width = function(el) { 27127 var _el, computed, w; 27128 if (window.getComputedStyle) { 27129 _el = el[0]; 27130 computed = window.getComputedStyle(el[0]); 27131 w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right")); 27132 if (computed.getPropertyValue("box-sizing") !== "border-box") { 27133 w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right")); 27134 } 27135 return w; 27136 } else { 27137 return el.outerWidth(true); 27138 } 27139 }; 27140 fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) { 27141 var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick; 27142 if (elm.data("sticky_kit")) { 27143 return; 27144 } 27145 elm.data("sticky_kit", true); 27146 last_scroll_height = doc.height(); 27147 parent = elm.parent(); 27148 if (parent_selector != null) { 27149 parent = parent.closest(parent_selector); 27150 } 27151 if (!parent.length) { 27152 throw "failed to find stick parent"; 27153 } 27154 fixed = false; 27155 bottomed = false; 27156 spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />"); 27157 if (spacer) { 27158 spacer.css('position', elm.css('position')); 27159 } 27160 recalc = function() { 27161 var border_top, padding_top, restore; 27162 if (detached) { 27163 return; 27164 } 27165 last_scroll_height = doc.height(); 27166 border_top = parseInt(parent.css("border-top-width"), 10); 27167 padding_top = parseInt(parent.css("padding-top"), 10); 27168 padding_bottom = parseInt(parent.css("padding-bottom"), 10); 27169 parent_top = parent.offset().top + border_top + padding_top; 27170 parent_height = parent.height(); 27171 if (fixed) { 27172 fixed = false;
vendor: 6,068 bytes, lines 27173-27367
27173 bottomed = false; 27174 if (manual_spacer == null) { 27175 elm.insertAfter(spacer); 27176 spacer.detach(); 27177 } 27178 elm.css({ 27179 position: "", 27180 top: "", 27181 width: "", 27182 bottom: "" 27183 }).removeClass(sticky_class); 27184 restore = true; 27185 } 27186 top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top; 27187 height = elm.outerHeight(true); 27188 el_float = elm.css("float"); 27189 if (spacer) { 27190 spacer.css({ 27191 width: outer_width(elm), 27192 height: height, 27193 display: elm.css("display"), 27194 "vertical-align": elm.css("vertical-align"), 27195 "float": el_float 27196 }); 27197 } 27198 if (restore) { 27199 return tick(); 27200 } 27201 }; 27202 recalc(); 27203 if (height === parent_height) { 27204 return; 27205 } 27206 last_pos = void 0; 27207 offset = offset_top; 27208 recalc_counter = recalc_every; 27209 tick = function() { 27210 var css, delta, recalced, scroll, will_bottom, win_height; 27211 if (detached) { 27212 return; 27213 } 27214 recalced = false; 27215 if (recalc_counter != null) { 27216 recalc_counter -= 1; 27217 if (recalc_counter <= 0) { 27218 recalc_counter = recalc_every; 27219 recalc(); 27220 recalced = true; 27221 } 27222 } 27223 if (!recalced && doc.height() !== last_scroll_height) { 27224 recalc(); 27225 recalced = true; 27226 } 27227 scroll = win.scrollTop(); 27228 if (last_pos != null) { 27229 delta = scroll - last_pos; 27230 } 27231 last_pos = scroll; 27232 if (fixed) { 27233 if (enable_bottoming) { 27234 will_bottom = scroll + height + offset > parent_height + parent_top; 27235 if (bottomed && !will_bottom) { 27236 bottomed = false; 27237 elm.css({ 27238 position: "fixed", 27239 bottom: "", 27240 top: offset 27241 }).trigger("sticky_kit:unbottom"); 27242 } 27243 } 27244 if (scroll < top) { 27245 fixed = false; 27246 offset = offset_top; 27247 if (manual_spacer == null) { 27248 if (el_float === "left" || el_float === "right") { 27249 elm.insertAfter(spacer); 27250 } 27251 spacer.detach(); 27252 } 27253 css = { 27254 position: "", 27255 width: "", 27256 top: "" 27257 }; 27258 elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick"); 27259 } 27260 if (inner_scrolling) { 27261 win_height = win.height(); 27262 if (height + offset_top > win_height) { 27263 if (!bottomed) { 27264 offset -= delta; 27265 offset = Math.max(win_height - height, offset); 27266 offset = Math.min(offset_top, offset); 27267 if (fixed) { 27268 elm.css({ 27269 top: offset + "px" 27270 }); 27271 } 27272 } 27273 } 27274 } 27275 } else { 27276 if (scroll > top) { 27277 fixed = true; 27278 css = { 27279 position: "fixed", 27280 top: offset 27281 }; 27282 css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px"; 27283 elm.css(css).addClass(sticky_class); 27284 if (manual_spacer == null) { 27285 elm.after(spacer); 27286 if (el_float === "left" || el_float === "right") { 27287 spacer.append(elm); 27288 } 27289 } 27290 elm.trigger("sticky_kit:stick"); 27291 } 27292 } 27293 if (fixed && enable_bottoming) { 27294 if (will_bottom == null) { 27295 will_bottom = scroll + height + offset > parent_height + parent_top; 27296 } 27297 if (!bottomed && will_bottom) { 27298 bottomed = true; 27299 if (parent.css("position") === "static") { 27300 parent.css({ 27301 position: "relative" 27302 }); 27303 } 27304 return elm.css({ 27305 position: "absolute", 27306 bottom: padding_bottom, 27307 top: "auto" 27308 }).trigger("sticky_kit:bottom"); 27309 } 27310 } 27311 }; 27312 recalc_and_tick = function() { 27313 recalc(); 27314 return tick(); 27315 }; 27316 detach = function() { 27317 detached = true; 27318 win.off("touchmove", tick); 27319 win.off("scroll", tick); 27320 win.off("resize", recalc_and_tick); 27321 $(document.body).off("sticky_kit:recalc", recalc_and_tick); 27322 elm.off("sticky_kit:detach", detach); 27323 elm.removeData("sticky_kit"); 27324 elm.css({ 27325 position: "", 27326 bottom: "", 27327 top: "", 27328 width: "" 27329 }); 27330 parent.position("position", ""); 27331 if (fixed) { 27332 if (manual_spacer == null) { 27333 if (el_float === "left" || el_float === "right") { 27334 elm.insertAfter(spacer); 27335 } 27336 spacer.remove(); 27337 } 27338 return elm.removeClass(sticky_class); 27339 } 27340 }; 27341 win.on("touchmove", tick); 27342 win.on("scroll", tick); 27343 win.on("resize", recalc_and_tick); 27344 $(document.body).on("sticky_kit:recalc", recalc_and_tick); 27345 elm.on("sticky_kit:detach", detach); 27346 return setTimeout(tick, 0); 27347 }; 27348 for (i = 0, len = this.length; i < len; i++) { 27349 elm = this[i]; 27350 fn($(elm)); 27351 } 27352 return this; 27353 }; 27354 27355}).call(this); 27356/* ========================================================================== 27357 * bootstrap-tab-history.js 27358 * Author: Michael Narayan <[email protected]> 27359 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/ 27360 * ========================================================================== 27361 * Licensed under the Apache License, Version 2.0 (the "License"); you may 27362 * not use this file except in compliance with the License. You may obtain a 27363 * copy of the License at 27364 * 27365 * http://www.apache.org/licenses/LICENSE-2.0 27366 * 27367 * Unless required by applicable law or agreed to in writing, softw
27367are 27368 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 27369 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 27370 * License for the specific language governing permissions and limitations 27371 * under the License. 27372 * ========================================================================== */ 27373 27374/* ========================================================================== */ 27375/* JSHint directives */ 27376/* */ 27377/* global BootstrapTabHistory: true */ 27378/* */ 27379/* global document */ 27380/* global jQuery */ 27381/* global history */ 27382/* global window */ 27383/* ========================================================================== */ 27384 27385/** 27386 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history) 27387 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set 27388 * the `data-tab-history` attribute to true (or a string denoting a tab grouping). 27389 * 27390 * See the README for additional information. 27391 * 27392 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes. 27393 */ 27394 27395BootstrapTabHistory = { 27396 options: { 27397 /** 27398 * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the 27399 * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true. 27400 * 27401 * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`. 27402 * 27403 * @public 27404 * @type {?number} 27405 */ 27406 defaultAnchorYOffset: 0, 27407 /** 27408 * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp. 27409 * 27410 * May be overriden on a per-element basis by the attribute `data-tab-history-changer`. 27411 * 27412 * @public 27413 * @type {string} 27414 */ 27415 defaultChanger: 'replace', 27416 /** 27417 * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise, 27418 * `null` is passed as the third parameter to these calls. 27419 * 27420 * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`. 27421 * 27422 * @public 27423 * @type {boolean} 27424 */ 27425 defaultUpdateURL: false, 27426 /** 27427 * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page 27428 * load. 27429 * 27430 * @public 27431 * @type {boolean} 27432 */ 27433 showTabsBasedOnAnchor: true 27434 } 27435}; 27436 27437(function () { 27438 'use strict'; 27439 27440 jQuery(function () { 27441 if(history && history.pushState && history.replaceState) { 27442 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27443 27444 if(bootstrapTabHistory) { 27445 showTabsBasedOnState(bootstrapTabHistory); 27446 } else { 27447 showTabsBasedOnAnchor(); 27448 } 27449 27450 backfillHistoryState(); 27451 27452 jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab); 27453 jQuery(window).on('popstate', onPopState); 27454 } else { 27455 showTabsBasedOnAnchor(); 27456 } 27457 }); 27458 27459 /** 27460 * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState. 27461 * 27462 * @type {boolean} 27463 */ 27464 var showingTabsBasedOnState = false; 27465 27466 /** 27467 * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper 27468 * `history.back` handling when `data-tab-history-update-url` is true. 27469 */ 27470 function backfillHistoryState() { 27471 var newState = null; 27472 27473 jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode 27474 var $activeTabElement = jQuery(this); 27475 var selector = getTabSelector($activeTabElement); 27476 27477 if(selector) { 27478 var tabGroup = getTabGroup($activeTabElement); 27479 27480 if(tabGroup) { 27481 newState = createNewHistoryState(newState || history.state, tabGroup, selector); 27482 } 27483 } 27484 }); 27485 27486 if(newState) { 27487 history.replaceState(newState, '', null); 27488 } 27489 } 27490 27491 /** 27492 * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to 27493 * said bootstrapTabHistory attribute. 27494 * 27495 * @param {?object} existingState 27496 * @param {!string} tabGroup 27497 * @param {!string} selector 27498 * @returns {!object} 27499 */ 27500 function createNewHistoryState(existingState, tabGroup, selector) { 27501 // Clone history.state and ensure it has a bootstrapTabHistory entry. 27502 var newState = jQuery.extend(true, {}, existingState, { 27503 bootstrapTabHistory: {} 27504 }); 27505 27506 newState.bootstrapTabHistory[tabGroup] = selector; 27507 27508 return newState; 27509 } 27510 27511 /** 27512 * @param {jQuery} $tab
27513 * @returns {?string} 27514 */ 27515 function getTabGroup($tab) { 27516 return parseTruthyAttributeValue($tab.data('tab-history')); 27517 } 27518 27519 /** 27520 * @param {jQuery} $tab 27521 * @returns {?string} 27522 */ 27523 function getTabSelector($tab) { 27524 return $tab.data('target') || $tab.attr('href'); 27525 } 27526 27527 /** 27528 * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate. 27529 * 27530 * @param {jQuery.Event} shownEvt 27531 */ 27532 function onShownTab(shownEvt) { 27533 if(!showingTabsBasedOnState) { 27534 var $activatedTab = jQuery(shownEvt.target); 27535 if ( $activatedTab.hasClass('panel-collapse') ) 27536 $activatedTab = $activatedTab.closest('.panel').find('a'); 27537 var selector = getTabSelector($activatedTab); 27538 27539 if(selector) { 27540 var tabGroup = getTabGroup($activatedTab); 27541 27542 if(tabGroup) { 27543 var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger; 27544 var newState = createNewHistoryState(history.state, tabGroup, selector); 27545 var updateURL = (function ($activatedTab) { 27546 if(selector[0] === '#') { 27547 var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url')); 27548 27549 if(elementUpdateURLOption === undefined) { 27550 return BootstrapTabHistory.options.defaultUpdateURL; 27551 } else { 27552 return elementUpdateURLOption; 27553 } 27554 } else { 27555 return false; 27556 } 27557 })($activatedTab); 27558 27559 switch(historyChanger) { 27560 case 'push': 27561 history.pushState(newState, '', updateURL ? selector : null); 27562 break; 27563 case 'replace': 27564 history.replaceState(newState, '', updateURL ? selector : null); 27565 break; 27566 default: 27567 throw new Error('Unknown tab-history-changer: ' + historyChanger); 27568 } 27569 } 27570 } 27571 } 27572 } 27573 27574 /** 27575 * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate. 27576 */ 27577 function onPopState() { 27578 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27579 27580 if(bootstrapTabHistory) { 27581 showTabsBasedOnState(bootstrapTabHistory); 27582 } 27583 } 27584 27585 /** 27586 * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned. 27587 * 27588 * Rationale: HAML data attributes which are set to `true` are rendered as a blank string. 27589 * 27590 * @param {*} value 27591 * @returns {*} 27592 */ 27593 function parseTruthyAttributeValue(value) { 27594 if(value) { 27595 return value; 27596 } else if(value === '') { 27597 return true; 27598 } else { 27599 return value; 27600 } 27601 } 27602 27603 /** 27604 * Show tabs based upon the anchor component of `window.location`. 27605 */ 27606 function showTabsBasedOnAnchor() { 27607 if(BootstrapTabHistory.options.showTabsBasedOnAnchor) { 27608 var anchor = window.location && window.location.hash; 27609 27610 if(anchor) { 27611 var $tabElement = showTabForSelector(anchor); 27612 27613 if($tabElement && window.addEventListener && window.removeEventListener) { 27614 var anchorYOffset = (function ($tabElement) { 27615 var elementSetting = $tabElement.data('tab-history-anchor-y-offset'); 27616 27617 if(elementSetting === undefined) { 27618 return BootstrapTabHistory.options.defaultAnchorYOffset; 27619 } else { 27620 return elementSetting; 27621 } 27622 })($tabElement); 27623 27624 // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get 27625 // here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the 27626 // `history.state` object should have been used (unless the browser did not support the modern History API). 27627 if(anchorYOffset || anchorYOffset === 0) { 27628 var scrollListener = function resetAnchorScroll () { 27629 window.removeEventListener('scroll', scrollListener); 27630 window.scrollTo(0, anchorYOffset); 27631 }; 27632 27633 window.addEventListener('scroll', scrollListener); 27634 } 27635 } 27636 } 27637 } 27638 } 27639 27640 /** 27641 * Show a tab which corresponds to the provided selector. 27642 * 27643 * @param {string} selector - A CSS selector. 27644 * @returns {?jQuery} - The tab which was found to show (even if said tab was already active). 27645 */ 27646 function showTabForSelector(selector) { 27647 var $tabElement = (function (selector) { 27648 var $ret = null; 27649 27650 jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () { 27651 var $potentialTab = jQuery(this); 27652 27653 if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) { 27654 $ret = $potentialTab; 27655 return false;
vendor: 43,483 bytes, lines 27656-28872
27656 } else { 27657 return null; 27658 } 27659 }); 27660 27661 return $ret; 27662 })(selector); 27663 27664 if($tabElement) { 27665 if ( !$tabElement.parent().hasClass('active') ) { 27666 $tabElement.trigger('click'); 27667 } 27668 //$tabElement.tab('show'); 27669 } 27670 27671 return $tabElement; 27672 } 27673 27674 /** 27675 * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors. 27676 * 27677 * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant. 27678 */ 27679 function showTabsBasedOnState(bootstrapTabHistory) { 27680 showingTabsBasedOnState = true; 27681 27682 try { 27683 for(var k in bootstrapTabHistory) { 27684 if(bootstrapTabHistory.hasOwnProperty(k)) { 27685 showTabForSelector(bootstrapTabHistory[k]); 27686 } 27687 } 27688 } finally { 27689 showingTabsBasedOnState = false; 27690 } 27691 } 27692})(); 27693 27694/*! 27695 * justifiedGallery - v3.8.1 27696 * http://miromannino.github.io/Justified-Gallery/ 27697 * Copyright (c) 2020 Miro Mannino 27698 * Licensed under the MIT license. 27699 */ 27700(function (factory) { 27701 if (typeof define === 'function' && define.amd) { 27702 // AMD. Register as an anonymous module. 27703 define(['jquery'], factory); 27704 } else if (typeof module === 'object' && module.exports) { 27705 // Node/CommonJS 27706 module.exports = function (root, jQuery) { 27707 if (jQuery === undefined) { 27708 // require('jQuery') returns a factory that requires window to 27709 // build a jQuery instance, we normalize how we use modules 27710 // that require this pattern but the window provided is a noop 27711 // if it's defined (how jquery works) 27712 if (typeof window !== 'undefined') { 27713 jQuery = require('jquery'); 27714 } 27715 else { 27716 jQuery = require('jquery')(root); 27717 } 27718 } 27719 factory(jQuery); 27720 return jQuery; 27721 }; 27722 } else { 27723 // Browser globals 27724 factory(jQuery); 27725 } 27726}(function ($) { 27727 27728 /** 27729 * Justified Gallery controller constructor 27730 * 27731 * @param $gallery the gallery to build 27732 * @param settings the settings (the defaults are in JustifiedGallery.defaults) 27733 * @constructor 27734 */ 27735 var JustifiedGallery = function ($gallery, settings) { 27736 27737 this.settings = settings; 27738 this.checkSettings(); 27739 27740 this.imgAnalyzerTimeout = null; 27741 this.entries = null; 27742 this.buildingRow = { 27743 entriesBuff: [], 27744 width: 0, 27745 height: 0, 27746 aspectRatio: 0 27747 }; 27748 this.lastFetchedEntry = null; 27749 this.lastAnalyzedIndex = -1; 27750 this.yield = { 27751 every: 2, // do a flush every n flushes (must be greater than 1) 27752 flushed: 0 // flushed rows without a yield 27753 }; 27754 this.border = settings.border >= 0 ? settings.border : settings.margins; 27755 this.maxRowHeight = this.retrieveMaxRowHeight(); 27756 this.suffixRanges = this.retrieveSuffixRanges(); 27757 this.offY = this.border; 27758 this.rows = 0; 27759 this.spinner = { 27760 phase: 0, 27761 timeSlot: 150, 27762 $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'), 27763 intervalId: null 27764 }; 27765 this.scrollBarOn = false; 27766 this.checkWidthIntervalId = null; 27767 this.galleryWidth = $gallery.width(); 27768 this.$gallery = $gallery; 27769 27770 }; 27771 27772 /** @returns {String} the best suffix given the width and the height */ 27773 JustifiedGallery.prototype.getSuffix = function (width, height) { 27774 var longestSide, i; 27775 longestSide = (width > height) ? width : height; 27776 for (i = 0; i < this.suffixRanges.length; i++) { 27777 if (longestSide <= this.suffixRanges[i]) { 27778 return this.settings.sizeRangeSuffixes[this.suffixRanges[i]]; 27779 } 27780 } 27781 return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]]; 27782 }; 27783 27784 /** 27785 * Remove the suffix from the string 27786 * 27787 * @returns {string} a new string without the suffix 27788 */ 27789 JustifiedGallery.prototype.removeSuffix = function (str, suffix) { 27790 return str.substring(0, str.length - suffix.length); 27791 }; 27792 27793 /** 27794 * @returns {boolean} a boolean to say if the suffix is contained in the str or not 27795 */ 27796 JustifiedGallery.prototype.endsWith = function (str, suffix) { 27797 return str.indexOf(suffix, str.length - suffix.length) !== -1; 27798 }; 27799 27800 /** 27801 * Get the used suffix of a particular url 27802 * 27803 * @param str 27804 * @returns {String} return the used suffix 27805 */ 27806 JustifiedGallery.prototype.getUsedSuffix = function (str) { 27807 for (var si in this.settings.sizeRangeSuffixes) { 27808 if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) { 27809 if (this.settings.sizeRangeSuffixes[si].length === 0) continue; 27810 if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si]; 27811 } 27812 } 27813 return ''; 27814 }; 27815 27816 /** 27817 * Given an image src, with the width and the height, returns the new image src with the 27818 * best suffix to show the best quality thumbnail. 27819 * 27820 * @returns {String} the suffix to use 27821 */ 27822 JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) { 27823 var newImageSrc; 27824 27825 if (this.settings.thumbnailPath) { 27826 newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image); 27827 } else { 27828 var matchRes = imageSrc.match(this.settings.extension); 27829 var ext = (matchRes !== null) ? matchRes[0] : ''; 27830 newImageSrc = imageSrc.replace(this.settings.extension, ''); 27831 newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc)); 27832 newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext; 27833 } 27834 27835 return newImageSrc; 27836 }; 27837 27838 /** 27839 * Shows the images that is in the given entry 27840 * 27841 * @param $entry the entry 27842 * @param callback the callback that is called when the show animation is finished 27843 */ 27844 JustifiedGallery.prototype.showImg = function ($entry, callback) { 27845 if (this.settings.cssAnimation) { 27846 $entry.addClass('jg-entry-visible'); 27847 if (callback) callback(); 27848 } else { 27849 $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27850 $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27851 } 27852 }; 27853 27854 /** 27855 * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the 27856 * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src. 27857 * 27858 * @param $image the image to analyze 27859 * @returns {String} the extracted src 27860 */ 27861 JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) { 27862 var imageSrc = $image.data('safe-src'); 27863 var imageSrcLoc = 'data-safe-src'; 27864 // Begin Uncode edit 27865 if (typeof imageSrc === 'undefined') { 27866 var imageCurrentSrc = $image[0].currentSrc; 27867 if (imageCurrentSrc) { 27868 imageSrc = imageCurrentSrc; 27869 } else { 27870 imageSrc = $image.attr('src'); 27871 } 27872 imageSrcLoc = 'src'; 27873 } 27874 // End Uncode edit 27875 $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method 27876 $image.data('jg.src', imageSrc); // this will change overtime 27877 $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method 27878 return imageSrc; 27879 }; 27880 27881 /** @returns {jQuery} the image in the given entry */ 27882 JustifiedGallery.prototype.imgFromEntry = function ($entry) { 27883 var $img = $entry.find(this.settings.imgSelector); 27884 if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode 27885 return $img.length === 0 ? null : $img; 27886 }; 27887 27888 /** @returns {jQuery} the caption in the given entry */ 27889 JustifiedGallery.prototype.captionFromEntry = function ($entry) { 27890 var $caption = $entry.find('> .jg-caption'); 27891 return $caption.length === 0 ? null : $caption; 27892 }; 27893 27894 /** 27895 * Display the entry 27896 * 27897 * @param {jQuery} $entry the entry to display 27898 * @param {int} x the x position where the entry must be positioned 27899 * @param y the y position where the entry must be positioned 27900 * @param imgWidth the image width 27901 * @param imgHeight the image height 27902 * @param rowHeight the row height of the row that owns the entry 27903 */ 27904 JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) { 27905 $entry.width(imgWidth); 27906 $entry.height(Math.floor(rowHeight));//hacked by Uncode 27907 $entry.css('top', Math.floor(y));//hacked by Uncode 27908 $entry.css('left', x); 27909 27910 var $image = this.imgFromEntry($entry); 27911 if ($image !== null) { 27912 $image.css('width', imgWidth); 27913 $image.css('height', imgHeight); 27914 $image.css('margin-left', - imgWidth / 2); 27915 $image.css('margin-top', - imgHeight / 2); 27916 27917 // Image reloading for an high quality of thumbnails 27918 var imageSrc = $image.data('jg.src'); 27919 if (imageSrc) { 27920 imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]); 27921 27922 $image.one('error', function () { 27923 this.resetImgSrc($image); //revert to the original thumbnail 27924 }); 27925 27926 var loadNewImage = function () { 27927 // if (imageSrc !== newImageSrc) { 27928 $image.attr('src', imageSrc); 27929 // } 27930 }; 27931 27932 if ($entry.data('jg.loaded') === 'skipped' && imageSrc) { 27933 this.onImageEvent(imageSrc, (function() { 27934 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27935 $entry.data('jg.loaded', true); 27936 }).bind(this)); 27937 } else { 27938 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27939 } 27940 27941 } 27942 27943 } else { 27944 this.showImg($entry); 27945 } 27946 27947 this.displayEntryCaption($entry); 27948 }; 27949 27950 /** 27951 * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt' 27952 * or the 'title' attributes. 27953 * 27954 * @param {jQuery} $entry the entry to process 27955 */ 27956 JustifiedGallery.prototype.displayEntryCaption = function ($entry) { 27957 var $image = this.imgFromEntry($entry); 27958 if ($image !== null && this.settings.captions) { 27959 var $imgCaption = this.captionFromEntry($entry); 27960 27961 // Create it if it doesn't exists 27962 if ($imgCaption === null) { 27963 var caption = $image.attr('alt'); 27964 if (!this.isValidCaption(caption)) caption = $entry.attr('title'); 27965 if (this.isValidCaption(caption)) { // Create only we found something 27966 $imgCaption = $('<div class="jg-caption">' + caption + '</div>'); 27967 $entry.append($imgCaption); 27968 $entry.data('jg.createdCaption', true); 27969 } 27970 } 27971 27972 // Create events (we check again the $imgCaption because it can be still inexistent) 27973 if ($imgCaption !== null) { 27974 if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity); 27975 this.addCaptionEventsHandlers($entry); 27976 } 27977 } else { 27978 this.removeCaptionEventsHandlers($entry); 27979 } 27980 }; 27981 27982 /** 27983 * Validates the caption 27984 * 27985 * @param caption The caption that should be validated 27986 * @return {boolean} Validation result 27987 */ 27988 JustifiedGallery.prototype.isValidCaption = function (caption) { 27989 return (typeof caption !== 'undefined' && caption.length > 0); 27990 }; 27991 27992 /** 27993 * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry. 27994 * It shows the caption using jQuery (or using CSS if it is configured so) 27995 * 27996 * @param {Event} eventObject the event object 27997 */ 27998 JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) { 27999 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 28000 if (this.settings.cssAnimation) { 28001 $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden'); 28002 } else { 28003 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 28004 this.settings.captionSettings.visibleOpacity); 28005 } 28006 }; 28007 28008 /** 28009 * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry. 28010 * It hides the caption using jQuery (or using CSS if it is configured so) 28011 * 28012 * @param {Event} eventObject the event object 28013 */ 28014 JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) { 28015 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 28016 if (this.settings.cssAnimation) { 28017 $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden'); 28018 } else { 28019 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 28020 this.settings.captionSettings.nonVisibleOpacity); 28021 } 28022 }; 28023 28024 /** 28025 * Add the handlers of the entry for the caption 28026 * 28027 * @param $entry the entry to modify 28028 */ 28029 JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) { 28030 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28031 if (typeof captionMouseEvents === 'undefined') { 28032 captionMouseEvents = { 28033 mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this), 28034 mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this) 28035 }; 28036 $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter); 28037 $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave); 28038 $entry.data('jg.captionMouseEvents', captionMouseEvents); 28039 } 28040 }; 28041 28042 /** 28043 * Remove the handlers of the entry for the caption 28044 * 28045 * @param $entry the entry to modify 28046 */ 28047 JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) { 28048 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28049 if (typeof captionMouseEvents !== 'undefined') { 28050 $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter); 28051 $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave); 28052 $entry.removeData('jg.captionMouseEvents'); 28053 } 28054 }; 28055 28056 /** 28057 * Clear the building row data to be used for a new row 28058 */ 28059 JustifiedGallery.prototype.clearBuildingRow = function () { 28060 this.buildingRow.entriesBuff = []; 28061 this.buildingRow.aspectRatio = 0; 28062 this.buildingRow.width = 0; 28063 }; 28064 28065 /** 28066 * Justify the building row, preparing it to 28067 * 28068 * @param isLastRow 28069 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28070 * @returns a boolean to know if the row has been justified or not 28071 */ 28072 JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) { 28073 var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true; 28074 var minHeight = 0; 28075 var availableWidth = this.galleryWidth - 2 * this.border - ( 28076 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28077 var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode 28078 var defaultRowHeight = this.settings.rowHeight; 28079 var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold; 28080 28081 //Skip the last row if we can't justify it and the lastRow == 'hide' 28082 if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) { 28083 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28084 $entry = this.buildingRow.entriesBuff[i]; 28085 if (this.settings.cssAnimation) 28086 $entry.removeClass('jg-entry-visible'); 28087 else { 28088 $entry.stop().fadeTo(0, 0.1); 28089 $entry.find('> img, > a > img').fadeTo(0, 0); 28090 } 28091 } 28092 return -1; 28093 } 28094 28095 // With lastRow = nojustify, justify if is justificable (the images will not become too big) 28096 if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') { 28097 justify = false; 28098 28099 if (this.rows > 0) { 28100 defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows; 28101 justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold; 28102 } 28103 } 28104 28105 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28106 $entry = this.buildingRow.entriesBuff[i]; 28107 imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28108 28109 if (justify) { 28110 newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio; 28111 newImgH = rowHeight; 28112 } else { 28113 newImgW = defaultRowHeight * imgAspectRatio; 28114 newImgH = defaultRowHeight; 28115 } 28116 28117 availableWidth -= Math.round(newImgW); 28118 $entry.data('jg.jwidth', Math.round(newImgW)); 28119 $entry.data('jg.jheight', Math.ceil(newImgH)); 28120 if (i === 0 || minHeight > newImgH) minHeight = newImgH; 28121 } 28122 28123 this.buildingRow.height = minHeight; 28124 return justify; 28125 }; 28126 28127 /** 28128 * Flush a row: justify it, modify the gallery height accordingly to the row height 28129 * 28130 * @param isLastRow 28131 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28132 */ 28133 JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) { 28134 var settings = this.settings; 28135 var $entry, buildingRowRes, offX = this.border, i; 28136 28137 buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow); 28138 if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) { 28139 this.clearBuildingRow(); 28140 return; 28141 } 28142 28143 if (this.maxRowHeight) { 28144 if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight; 28145 } 28146 28147 //Align last (unjustified) row 28148 if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) { 28149 var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins; 28150 28151 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28152 $entry = this.buildingRow.entriesBuff[i]; 28153 availableWidth -= $entry.data('jg.jwidth'); 28154 } 28155 28156 if (settings.lastRow === 'center') 28157 offX += Math.round(availableWidth / 2); 28158 else if (settings.lastRow === 'right') 28159 offX += availableWidth; 28160 } 28161 28162 var lastEntryIdx = this.buildingRow.entriesBuff.length - 1; 28163 for (i = 0; i <= lastEntryIdx; i++) { 28164 $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i]; 28165 this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height); 28166 offX += $entry.data('jg.jwidth') + settings.margins; 28167 } 28168 28169 //Gallery Height 28170 this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border; 28171 this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight()); 28172 28173 if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) { 28174 //Ready for a new row 28175 this.offY += this.buildingRow.height + settings.margins; 28176 this.rows += 1; 28177 this.clearBuildingRow(); 28178 this.settings.triggerEvent.call(this, 'jg.rowflush'); 28179 } 28180 }; 28181 28182 28183 // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221 28184 var galleryPrevStaticHeight = 0; 28185 28186 JustifiedGallery.prototype.rememberGalleryHeight = function () { 28187 galleryPrevStaticHeight = this.$gallery.height(); 28188 this.$gallery.height(galleryPrevStaticHeight); 28189 }; 28190 28191 // grow only 28192 JustifiedGallery.prototype.setGalleryTempHeight = function (height) { 28193 galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight); 28194 this.$gallery.height(galleryPrevStaticHeight); 28195 }; 28196 28197 JustifiedGallery.prototype.setGalleryFinalHeight = function (height) { 28198 galleryPrevStaticHeight = height; 28199 this.$gallery.height(height); 28200 }; 28201 28202 /** 28203 * Checks the width of the gallery container, to know if a new justification is needed 28204 */ 28205 JustifiedGallery.prototype.checkWidth = function () { 28206 this.checkWidthIntervalId = setInterval($.proxy(function () { 28207 28208 // if the gallery is not currently visible, abort. 28209 if (!this.$gallery.is(":visible")) return; 28210 28211 var galleryWidth = parseFloat(this.$gallery.width()); 28212 if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) { 28213 this.galleryWidth = galleryWidth; 28214 this.rewind(); 28215 28216 this.rememberGalleryHeight(); 28217 28218 // Restart to analyze 28219 this.startImgAnalyzer(true); 28220 } 28221 }, this), this.settings.refreshTime); 28222 }; 28223 28224 /** 28225 * @returns {boolean} a boolean saying if the spinner is active or not 28226 */ 28227 JustifiedGallery.prototype.isSpinnerActive = function () { 28228 return this.spinner.intervalId !== null; 28229 }; 28230 28231 /** 28232 * @returns {int} the spinner height 28233 */ 28234 JustifiedGallery.prototype.getSpinnerHeight = function () { 28235 return this.spinner.$el.innerHeight(); 28236 }; 28237 28238 /** 28239 * Stops the spinner animation and modify the gallery height to exclude the spinner 28240 */ 28241 JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () { 28242 clearInterval(this.spinner.intervalId); 28243 this.spinner.intervalId = null; 28244 this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight()); 28245 this.spinner.$el.detach(); 28246 }; 28247 28248 /** 28249 * Starts the spinner animation 28250 */ 28251 JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () { 28252 var spinnerContext = this.spinner; 28253 var $spinnerPoints = spinnerContext.$el.find('span'); 28254 clearInterval(spinnerContext.intervalId); 28255 this.$gallery.append(spinnerContext.$el); 28256 this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight()); 28257 spinnerContext.intervalId = setInterval(function () { 28258 if (spinnerContext.phase < $spinnerPoints.length) { 28259 $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1); 28260 } else { 28261 $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0); 28262 } 28263 spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2); 28264 }, spinnerContext.timeSlot); 28265 }; 28266 28267 /** 28268 * Rewind the image analysis to start from the first entry. 28269 */ 28270 JustifiedGallery.prototype.rewind = function () { 28271 this.lastFetchedEntry = null; 28272 this.lastAnalyzedIndex = -1; 28273 this.offY = this.border; 28274 this.rows = 0; 28275 this.clearBuildingRow(); 28276 }; 28277 28278 /** 28279 * @returns {String} `settings.selector` rejecting spinner element 28280 */ 28281 JustifiedGallery.prototype.getSelectorWithoutSpinner = function () { 28282 return this.settings.selector + ', div:not(.jg-spinner)'; 28283 }; 28284 28285 /** 28286 * @returns {Array} all entries matched by `settings.selector` 28287 */ 28288 JustifiedGallery.prototype.getAllEntries = function () { 28289 var selector = this.getSelectorWithoutSpinner(); 28290 return this.$gallery.children(selector).toArray(); 28291 }; 28292 28293 /** 28294 * Update the entries searching it from the justified gallery HTML element 28295 * 28296 * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered) 28297 * @returns {boolean} true if some entries has been founded 28298 */ 28299 JustifiedGallery.prototype.updateEntries = function (norewind) { 28300 var newEntries; 28301 28302 if (norewind && this.lastFetchedEntry != null) { 28303 var selector = this.getSelectorWithoutSpinner(); 28304 newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray(); 28305 } else { 28306 this.entries = []; 28307 newEntries = this.getAllEntries(); 28308 } 28309 28310 if (newEntries.length > 0) { 28311 28312 // Sort or randomize 28313 if ($.isFunction(this.settings.sort)) { 28314 newEntries = this.sortArray(newEntries); 28315 } else if (this.settings.randomize) { 28316 newEntries = this.shuffleArray(newEntries); 28317 } 28318 this.lastFetchedEntry = newEntries[newEntries.length - 1]; 28319 28320 // Filter 28321 if (this.settings.filter) { 28322 newEntries = this.filterArray(newEntries); 28323 } else { 28324 this.resetFilters(newEntries); 28325 } 28326 28327 } 28328 28329 this.entries = this.entries.concat(newEntries); 28330 return true; 28331 }; 28332 28333 /** 28334 * Apply the entries order to the DOM, iterating the entries and appending the images 28335 * 28336 * @param entries the entries that has been modified and that must be re-ordered in the DOM 28337 */ 28338 JustifiedGallery.prototype.insertToGallery = function (entries) { 28339 var that = this; 28340 $.each(entries, function () { 28341 $(this).appendTo(that.$gallery); 28342 }); 28343 }; 28344 28345 /** 28346 * Shuffle the array using the Fisher-Yates shuffle algorithm 28347 * 28348 * @param a the array to shuffle 28349 * @return the shuffled array 28350 */ 28351 JustifiedGallery.prototype.shuffleArray = function (a) { 28352 var i, j, temp; 28353 for (i = a.length - 1; i > 0; i--) { 28354 j = Math.floor(Math.random() * (i + 1)); 28355 temp = a[i]; 28356 a[i] = a[j]; 28357 a[j] = temp; 28358 } 28359 this.insertToGallery(a); 28360 return a; 28361 }; 28362 28363 /** 28364 * Sort the array using settings.comparator as comparator 28365 * 28366 * @param a the array to sort (it is sorted) 28367 * @return the sorted array 28368 */ 28369 JustifiedGallery.prototype.sortArray = function (a) { 28370 a.sort(this.settings.sort); 28371 this.insertToGallery(a); 28372 return a; 28373 }; 28374 28375 /** 28376 * Reset the filters removing the 'jg-filtered' class from all the entries 28377 * 28378 * @param a the array to reset 28379 */ 28380 JustifiedGallery.prototype.resetFilters = function (a) { 28381 for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered'); 28382 }; 28383 28384 /** 28385 * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering. 28386 * 28387 * @param a the array to filter 28388 * @return the filtered array 28389 */ 28390 JustifiedGallery.prototype.filterArray = function (a) { 28391 var settings = this.settings; 28392 if ($.type(settings.filter) === 'string') { 28393 // Filter only keeping the entries passed in the string 28394 return a.filter(function (el) { 28395 var $el = $(el); 28396 if ($el.is(settings.filter)) { 28397 $el.removeClass('jg-filtered'); 28398 return true; 28399 } else { 28400 $el.addClass('jg-filtered').removeClass('jg-visible'); 28401 return false; 28402 } 28403 }); 28404 } else if ($.isFunction(settings.filter)) { 28405 // Filter using the passed function 28406 var filteredArr = a.filter(settings.filter); 28407 for (var i = 0; i < a.length; i++) { 28408 if (filteredArr.indexOf(a[i]) === -1) { 28409 $(a[i]).addClass('jg-filtered').removeClass('jg-visible'); 28410 } else { 28411 $(a[i]).removeClass('jg-filtered'); 28412 } 28413 } 28414 return filteredArr; 28415 } 28416 }; 28417 28418 /** 28419 * Revert the image src to the default value. 28420 */ 28421 JustifiedGallery.prototype.resetImgSrc = function ($img) { 28422 if ($img.data('jg.originalSrcLoc') === 'src') { 28423 $img.attr('src', $img.data('jg.originalSrc')); 28424 } else { 28425 $img.attr('src', ''); 28426 } 28427 }; 28428 28429 /** 28430 * Destroy the Justified Gallery instance. 28431 * 28432 * It clears all the css properties added in the style attributes. We doesn't backup the original 28433 * values for those css attributes, because it costs (performance) and because in general one 28434 * shouldn't use the style attribute for an uniform set of images (where we suppose the use of 28435 * classes). Creating a backup is also difficult because JG could be called multiple times and 28436 * with different style attributes. 28437 */ 28438 JustifiedGallery.prototype.destroy = function () { 28439 clearInterval(this.checkWidthIntervalId); 28440 this.stopImgAnalyzerStarter(); 28441 28442 // Get fresh entries list since filtered entries are absent in `this.entries` 28443 $.each(this.getAllEntries(), $.proxy(function (_, entry) { 28444 var $entry = $(entry); 28445 28446 // Reset entry style 28447 $entry.css('width', ''); 28448 $entry.css('height', ''); 28449 $entry.css('top', ''); 28450 $entry.css('left', ''); 28451 $entry.data('jg.loaded', undefined); 28452 $entry.removeClass('jg-entry jg-filtered jg-entry-visible'); 28453 28454 // Reset image style 28455 var $img = this.imgFromEntry($entry); 28456 if ($img) { 28457 $img.css('width', ''); 28458 $img.css('height', ''); 28459 $img.css('margin-left', ''); 28460 $img.css('margin-top', ''); 28461 this.resetImgSrc($img); 28462 $img.data('jg.originalSrc', undefined); 28463 $img.data('jg.originalSrcLoc', undefined); 28464 $img.data('jg.src', undefined); 28465 } 28466 28467 // Remove caption 28468 this.removeCaptionEventsHandlers($entry); 28469 var $caption = this.captionFromEntry($entry); 28470 if ($entry.data('jg.createdCaption')) { 28471 // remove also the caption element (if created by jg) 28472 $entry.data('jg.createdCaption', undefined); 28473 if ($caption !== null) $caption.remove(); 28474 } else { 28475 if ($caption !== null) $caption.fadeTo(0, 1); 28476 } 28477 28478 }, this)); 28479 28480 this.$gallery.css('height', ''); 28481 this.$gallery.removeClass('justified-gallery'); 28482 this.$gallery.data('jg.controller', undefined); 28483 this.settings.triggerEvent.call(this, 'jg.destroy'); 28484 }; 28485 28486 /** 28487 * Analyze the images and builds the rows. It returns if it found an image that is not loaded. 28488 * 28489 * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end 28490 */ 28491 JustifiedGallery.prototype.analyzeImages = function (isForResize) { 28492 for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) { 28493 var $entry = $(this.entries[i]); 28494 if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') { 28495 var availableWidth = this.galleryWidth - 2 * this.border - ( 28496 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28497 var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28498 28499 this.buildingRow.entriesBuff.push($entry); 28500 this.buildingRow.aspectRatio += imgAspectRatio; 28501 this.buildingRow.width += imgAspectRatio * this.settings.rowHeight; 28502 this.lastAnalyzedIndex = i; 28503 28504 if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) { 28505 this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28506 28507 if (++this.yield.flushed >= this.yield.every) { 28508 this.startImgAnalyzer(isForResize); 28509 return; 28510 } 28511 } 28512 } else if ($entry.data('jg.loaded') !== 'error') { 28513 return; 28514 } 28515 } 28516 28517 // Last row flush (the row is not full) 28518 if (this.buildingRow.entriesBuff.length > 0) { 28519 this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28520 } 28521 28522 if (this.isSpinnerActive()) { 28523 this.stopLoadingSpinnerAnimation(); 28524 } 28525 28526 /* Stop, if there is, the timeout to start the analyzeImages. 28527 This is because an image can be set loaded, and the timeout can be set, 28528 but this image can be analyzed yet. 28529 */ 28530 this.stopImgAnalyzerStarter(); 28531 28532 this.setGalleryFinalHeight(this.galleryHeightToSet); 28533 28534 //On complete callback 28535 this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete'); 28536 }; 28537 28538 /** 28539 * Stops any ImgAnalyzer starter (that has an assigned timeout) 28540 */ 28541 JustifiedGallery.prototype.stopImgAnalyzerStarter = function () { 28542 this.yield.flushed = 0; 28543 if (this.imgAnalyzerTimeout !== null) { 28544 clearTimeout(this.imgAnalyzerTimeout); 28545 this.imgAnalyzerTimeout = null; 28546 } 28547 }; 28548 28549 /** 28550 * Starts the image analyzer. It is not immediately called to let the browser to update the view 28551 * 28552 * @param isForResize specifies if the image analyzer must be called for resizing or not 28553 */ 28554 JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) { 28555 var that = this; 28556 this.stopImgAnalyzerStarter(); 28557 this.imgAnalyzerTimeout = setTimeout(function () { 28558 that.analyzeImages(isForResize); 28559 }, 0.001); // we can't start it immediately due to a IE different behaviour 28560 }; 28561 28562 /** 28563 * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property, 28564 * because some browsers, with a 404 set complete = true. 28565 * 28566 * @param imageSrc the image src to load 28567 * @param onLoad callback that is called when the image has been loaded 28568 * @param onError callback that is called in case of an error 28569 */ 28570 JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) { 28571 if (!onLoad && !onError) return; 28572 28573 var memImage = new Image(); 28574 var $memImage = $(memImage); 28575 if (onLoad) { 28576 $memImage.one('load', function () { 28577 $memImage.off('load error'); 28578 onLoad(memImage); 28579 }); 28580 } 28581 if (onError) { 28582 $memImage.one('error', function () { 28583 $memImage.off('load error'); 28584 onError(memImage); 28585 }); 28586 } 28587 memImage.src = imageSrc; 28588 }; 28589 28590 /** 28591 * Init of Justified Gallery controlled 28592 * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images) 28593 */ 28594 JustifiedGallery.prototype.init = function () { 28595 var imagesToLoad = false, skippedImages = false, that = this; 28596 $.each(this.entries, function (index, entry) { 28597 var $entry = $(entry); 28598 var $image = that.imgFromEntry($entry); 28599 28600 $entry.addClass('jg-entry'); 28601 28602 if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') { 28603 28604 // Link Rel global overwrite 28605 if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel); 28606 28607 // Link Target global overwrite 28608 if (that.settings.target !== null) $entry.attr('target', that.settings.target); 28609 28610 if ($image !== null) { 28611 28612 // Image src 28613 var imageSrc = that.extractImgSrcFromImage($image); 28614 28615 /* If we have the height and the width, we don't wait that the image is loaded, 28616 but we start directly with the justification */ 28617 if (that.settings.waitThumbnailsLoad === false || !imageSrc) { 28618 var width = parseFloat($image.attr('width')); 28619 var height = parseFloat($image.attr('height')); 28620 if ($image.prop('tagName') === 'svg') { 28621 width = parseFloat($image[0].getBBox().width); 28622 height = parseFloat($image[0].getBBox().height); 28623 } 28624 if (!isNaN(width) && !isNaN(height)) { 28625 $entry.data('jg.width', width); 28626 $entry.data('jg.height', height); 28627 $entry.data('jg.loaded', 'skipped'); 28628 skippedImages = true; 28629 that.startImgAnalyzer(false); 28630 return true; // continue 28631 } 28632 } 28633 28634 $entry.data('jg.loaded', false); 28635 imagesToLoad = true; 28636 28637 // Spinner start 28638 if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation(); 28639 28640 that.onImageEvent(imageSrc, function (loadImg) { // image loaded 28641 $entry.data('jg.width', loadImg.width); 28642 $entry.data('jg.height', loadImg.height); 28643 $entry.data('jg.loaded', true); 28644 that.startImgAnalyzer(false); 28645 }, function () { // image load error 28646 $entry.data('jg.loaded', 'error'); 28647 that.startImgAnalyzer(false); 28648 }); 28649 28650 } else { 28651 $entry.data('jg.loaded', true); 28652 $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1); 28653 $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1); 28654 } 28655 28656 } 28657 28658 }); 28659 28660 if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false); 28661 this.checkWidth(); 28662 }; 28663 28664 /** 28665 * Checks that it is a valid number. If a string is passed it is converted to a number 28666 * 28667 * @param settingContainer the object that contains the setting (to allow the conversion) 28668 * @param settingName the setting name 28669 */ 28670 JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) { 28671 if ($.type(settingContainer[settingName]) === 'string') { 28672 settingContainer[settingName] = parseFloat(settingContainer[settingName]); 28673 } 28674 28675 if ($.type(settingContainer[settingName]) === 'number') { 28676 if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName; 28677 } else { 28678 throw settingName + ' must be a number'; 28679 } 28680 }; 28681 28682 /** 28683 * Checks the sizeRangeSuffixes and, if necessary, converts 28684 * its keys from string (e.g. old settings with 'lt100') to int. 28685 */ 28686 JustifiedGallery.prototype.checkSizeRangesSuffixes = function () { 28687 if ($.type(this.settings.sizeRangeSuffixes) !== 'object') { 28688 throw 'sizeRangeSuffixes must be defined and must be an object'; 28689 } 28690 28691 var suffixRanges = []; 28692 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28693 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx); 28694 } 28695 28696 var newSizeRngSuffixes = { 0: '' }; 28697 for (var i = 0; i < suffixRanges.length; i++) { 28698 if ($.type(suffixRanges[i]) === 'string') { 28699 try { 28700 var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10); 28701 newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28702 } catch (e) { 28703 throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')'; 28704 } 28705 } else { 28706 newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28707 } 28708 } 28709 28710 this.settings.sizeRangeSuffixes = newSizeRngSuffixes; 28711 }; 28712 28713 /** 28714 * check and convert the maxRowHeight setting 28715 * requires rowHeight to be already set 28716 * TODO: should be always called when only rowHeight is changed 28717 * @return number or null 28718 */ 28719 JustifiedGallery.prototype.retrieveMaxRowHeight = function () { 28720 var newMaxRowHeight = null; 28721 var rowHeight = this.settings.rowHeight; 28722 28723 if ($.type(this.settings.maxRowHeight) === 'string') { 28724 if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) { 28725 newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100; 28726 } else { 28727 newMaxRowHeight = parseFloat(this.settings.maxRowHeight); 28728 } 28729 } else if ($.type(this.settings.maxRowHeight) === 'number') { 28730 newMaxRowHeight = this.settings.maxRowHeight; 28731 } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) { 28732 return null; 28733 } else { 28734 throw 'maxRowHeight must be a number or a percentage'; 28735 } 28736 28737 // check if the converted value is not a number 28738 if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight'; 28739 28740 // check values, maxRowHeight must be >= rowHeight 28741 if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight; 28742 28743 return newMaxRowHeight; 28744 }; 28745 28746 /** 28747 * Checks the settings 28748 */ 28749 JustifiedGallery.prototype.checkSettings = function () { 28750 this.checkSizeRangesSuffixes(); 28751 28752 this.checkOrConvertNumber(this.settings, 'rowHeight'); 28753 this.checkOrConvertNumber(this.settings, 'margins'); 28754 this.checkOrConvertNumber(this.settings, 'border'); 28755 this.checkOrConvertNumber(this.settings, 'maxRowsCount'); 28756 28757 var lastRowModes = [ 28758 'justify', 28759 'nojustify', 28760 'left', 28761 'center', 28762 'right', 28763 'hide' 28764 ]; 28765 if (lastRowModes.indexOf(this.settings.lastRow) === -1) { 28766 throw 'lastRow must be one of: ' + lastRowModes.join(', '); 28767 } 28768 28769 this.checkOrConvertNumber(this.settings, 'justifyThreshold'); 28770 if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) { 28771 throw 'justifyThreshold must be in the interval [0,1]'; 28772 } 28773 if ($.type(this.settings.cssAnimation) !== 'boolean') { 28774 throw 'cssAnimation must be a boolean'; 28775 } 28776 28777 if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean'; 28778 this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration'); 28779 28780 this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity'); 28781 if (this.settings.captionSettings.visibleOpacity < 0 || 28782 this.settings.captionSettings.visibleOpacity > 1) { 28783 throw 'captionSettings.visibleOpacity must be in the interval [0, 1]'; 28784 } 28785 28786 this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity'); 28787 if (this.settings.captionSettings.nonVisibleOpacity < 0 || 28788 this.settings.captionSettings.nonVisibleOpacity > 1) { 28789 throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]'; 28790 } 28791 28792 this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration'); 28793 this.checkOrConvertNumber(this.settings, 'refreshTime'); 28794 this.checkOrConvertNumber(this.settings, 'refreshSensitivity'); 28795 if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean'; 28796 if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string'; 28797 28798 if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) { 28799 throw 'sort must be false or a comparison function'; 28800 } 28801 28802 if (this.settings.filter !== false && !$.isFunction(this.settings.filter) && 28803 $.type(this.settings.filter) !== 'string') { 28804 throw 'filter must be false, a string or a filter function'; 28805 } 28806 }; 28807 28808 /** 28809 * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned. 28810 * @returns {Array} sorted suffix ranges 28811 */ 28812 JustifiedGallery.prototype.retrieveSuffixRanges = function () { 28813 var suffixRanges = []; 28814 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28815 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10)); 28816 } 28817 suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; }); 28818 return suffixRanges; 28819 }; 28820 28821 /** 28822 * Update the existing settings only changing some of them 28823 * 28824 * @param newSettings the new settings (or a subgroup of them) 28825 */ 28826 JustifiedGallery.prototype.updateSettings = function (newSettings) { 28827 // In this case Justified Gallery has been called again changing only some options 28828 this.settings = $.extend({}, this.settings, newSettings); 28829 this.checkSettings(); 28830 28831 // As reported in the settings: negative value = same as margins, 0 = disabled 28832 this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins; 28833 28834 this.maxRowHeight = this.retrieveMaxRowHeight(); 28835 this.suffixRanges = this.retrieveSuffixRanges(); 28836 }; 28837 28838 JustifiedGallery.prototype.defaults = { 28839 sizeRangeSuffixes: {}, /* e.g. Flickr configuration 28840 { 28841 100: '_t', // used when longest is less than 100px 28842 240: '_m', // used when longest is between 101px and 240px 28843 320: '_n', // ... 28844 500: '', 28845 640: '_z', 28846 1024: '_b' // used as else case because it is the last 28847 } 28848 */ 28849 thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the 28850 path relative to a specific thumbnail size. The function should accept respectively three arguments: 28851 current path, width and height */ 28852 rowHeight: 120, // required? required to be > 0? 28853 maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels, 28854 // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height 28855 // can't exceed 3 * rowHeight) 28856 maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled) 28857 margins: 1, 28858 border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border 28859 28860 lastRow: 'nojustify', // ⦠which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide' 28861 28862 justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified 28863 * (i.e. lastRow setting is not considered) */ 28864 waitThumbnailsLoad: true, 28865 captions: true, 28866 cssAnimation: true, 28867 imagesAnimationDuration: 500, // ignored with css animations 28868 captionSettings: { // ignored with css animations 28869 animationDuration: 500, 28870 visibleOpacity: 0.7, 28871 nonVisibleOpacity: 0.0 28872 },
28873 rel: null, // rewrite the rel of each analyzed links 28874 target: null, // rewrite the target of all links 28875 extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image 28876 refreshTime: 200, // time interval (in ms) to check if the page changes its width 28877 refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery 28878 randomize: false, 28879 rtl: false, // right-to-left mode 28880 sort: false, /* 28881 - false: to do not sort 28882 - function: to sort them using the function as comparator (see Array.prototype.sort()) 28883 */ 28884 filter: false, /* 28885 - false, null or undefined: for a disabled filter 28886 - a string: an entry is kept if entry.is(filter string) returns true 28887 see jQuery's .is() function for further information 28888 - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise. 28889 It follows the specifications of the Array.prototype.filter() function of JavaScript. 28890 */ 28891 selector: 'a', // The selector that is used to know what are the entries of the gallery 28892 imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry 28893 triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger 28894 this.$gallery.trigger(event); // Consider that 'this' is this set to the JustifiedGallery object, so it can 28895 } // access to fields such as $gallery, useful to trigger events with jQuery. 28896 }; 28897 28898 28899 /** 28900 * Justified Gallery plugin for jQuery 28901 * 28902 * Events 28903 * - jg.complete : called when all the gallery has been created 28904 * - jg.resize : called when the gallery has been resized 28905 * - jg.rowflush : when a new row appears 28906 * 28907 * @param arg the action (or the settings) passed when the plugin is called 28908 * @returns {*} the object itself 28909 */ 28910 $.fn.justifiedGallery = function (arg) { 28911 return this.each(function (index, gallery) { 28912 28913 var $gallery = $(gallery); 28914 $gallery.addClass('justified-gallery'); 28915 28916 var controller = $gallery.data('jg.controller'); 28917 if (typeof controller === 'undefined') { 28918 // Create controller and assign it to the object data 28919 if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') { 28920 if (arg === 'destroy') return; // Just a call to an unexisting object 28921 throw 'The argument must be an object'; 28922 } 28923 controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg)); 28924 $gallery.data('jg.controller', controller); 28925 } else if (arg === 'norewind') { 28926 // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row 28927 // ... left to be more readable 28928 } else if (arg === 'destroy') { 28929 controller.destroy(); 28930 return; 28931 } else { 28932 // In this case Justified Gallery has been called again changing only some options 28933 controller.updateSettings(arg); 28934 controller.rewind(); 28935 } 28936 28937 // Update the entries list 28938 if (!controller.updateEntries(arg === 'norewind')) return; 28939 28940 // Init justified gallery 28941 controller.init(); 28942 28943 }); 28944 }; 28945 28946})); 28947 28948/*! 28949* Customized version of iScroll.js 0.0.1 28950* It fixes bugs affecting its integration with fullpage.js 28951*/ 28952/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */ 28953(function (window, document, Math) { 28954var rAF = window.requestAnimationFrame || 28955 window.webkitRequestAnimationFrame || 28956 window.mozRequestAnimationFrame || 28957 window.oRequestAnimationFrame || 28958 window.msRequestAnimationFrame || 28959 function (callback) { window.setTimeout(callback, 1000 / 60); }; 28960 28961var utils = (function () { 28962 var me = {}; 28963 28964 var _elementStyle = document.createElement('div').style; 28965 var _vendor = (function () { 28966 var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], 28967 transform, 28968 i = 0, 28969 l = vendors.length; 28970 28971 for ( ; i < l; i++ ) { 28972 transform = vendors[i] + 'ransform'; 28973 if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); 28974 } 28975 28976 return false;
vendor: 5,154 bytes, lines 28977-29129
28977 })(); 28978 28979 function _prefixStyle (style) { 28980 if ( _vendor === false ) return false; 28981 if ( _vendor === '' ) return style; 28982 return _vendor + style.charAt(0).toUpperCase() + style.substr(1); 28983 } 28984 28985 me.getTime = Date.now || function getTime () { return new Date().getTime(); }; 28986 28987 me.extend = function (target, obj) { 28988 for ( var i in obj ) { 28989 target[i] = obj[i]; 28990 } 28991 }; 28992 28993 me.addEvent = function (el, type, fn, capture) { 28994 el.addEventListener(type, fn, !!capture); 28995 }; 28996 28997 me.removeEvent = function (el, type, fn, capture) { 28998 el.removeEventListener(type, fn, !!capture); 28999 }; 29000 29001 me.prefixPointerEvent = function (pointerEvent) { 29002 return window.MSPointerEvent ? 29003 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8): 29004 pointerEvent; 29005 }; 29006 29007 me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { 29008 var distance = current - start, 29009 speed = Math.abs(distance) / time, 29010 destination, 29011 duration; 29012 29013 deceleration = deceleration === undefined ? 0.0006 : deceleration; 29014 29015 destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); 29016 duration = speed / deceleration; 29017 29018 if ( destination < lowerMargin ) { 29019 destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; 29020 distance = Math.abs(destination - current); 29021 duration = distance / speed; 29022 } else if ( destination > 0 ) { 29023 destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; 29024 distance = Math.abs(current) + destination; 29025 duration = distance / speed; 29026 } 29027 29028 return { 29029 destination: Math.round(destination), 29030 duration: duration 29031 }; 29032 }; 29033 29034 var _transform = _prefixStyle('transform'); 29035 29036 me.extend(me, { 29037 hasTransform: _transform !== false, 29038 hasPerspective: _prefixStyle('perspective') in _elementStyle, 29039 hasTouch: 'ontouchstart' in window, 29040 hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed 29041 hasTransition: _prefixStyle('transition') in _elementStyle 29042 }); 29043 29044 /* 29045 This should find all Android browsers lower than build 535.19 (both stock browser and webview) 29046 - galaxy S2 is ok 29047 - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1` 29048 - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29049 - galaxy S3 is badAndroid (stock brower, webview) 29050 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29051 - galaxy S4 is badAndroid (stock brower, webview) 29052 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29053 - galaxy S5 is OK 29054 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29055 - galaxy S6 is OK 29056 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29057 */ 29058 me.isBadAndroid = (function() { 29059 var appVersion = window.navigator.appVersion; 29060 // Android browser is not a chrome browser. 29061 if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) { 29062 var safariVersion = appVersion.match(/Safari\/(\d+.\d)/); 29063 if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) { 29064 return parseFloat(safariVersion[1]) < 535.19; 29065 } else { 29066 return true; 29067 } 29068 } else { 29069 return false; 29070 } 29071 })(); 29072 29073 me.extend(me.style = {}, { 29074 transform: _transform, 29075 transitionTimingFunction: _prefixStyle('transitionTimingFunction'), 29076 transitionDuration: _prefixStyle('transitionDuration'), 29077 transitionDelay: _prefixStyle('transitionDelay'), 29078 transformOrigin: _prefixStyle('transformOrigin') 29079 }); 29080 29081 me.hasClass = function (e, c) { 29082 var re = new RegExp("(^|\\s)" + c + "(\\s|$)"); 29083 return re.test(e.className); 29084 }; 29085 29086 me.addClass = function (e, c) { 29087 if ( me.hasClass(e, c) ) { 29088 return; 29089 } 29090 29091 var newclass = e.className.split(' '); 29092 newclass.push(c); 29093 e.className = newclass.join(' '); 29094 }; 29095 29096 me.removeClass = function (e, c) { 29097 if ( !me.hasClass(e, c) ) { 29098 return; 29099 } 29100 29101 var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g'); 29102 e.className = e.className.replace(re, ' '); 29103 }; 29104 29105 me.offset = function (el) { 29106 var left = -el.offsetLeft, 29107 top = -el.offsetTop; 29108 29109 // jshint -W084 29110 while (el = el.offsetParent) { 29111 left -= el.offsetLeft; 29112 top -= el.offsetTop; 29113 } 29114 // jshint +W084 29115 29116 return { 29117 left: left, 29118 top: top 29119 }; 29120 }; 29121 29122 me.preventDefaultException = function (el, exceptions) { 29123 for ( var i in exceptions ) { 29124 if ( exceptions[i].test(el[i]) ) { 29125 return true; 29126 } 29127 } 29128 29129 return false;
vendor: 5,660 bytes, lines 29130-29295
29130 }; 29131 29132 me.extend(me.eventType = {}, { 29133 touchstart: 1, 29134 touchmove: 1, 29135 touchend: 1, 29136 29137 mousedown: 2, 29138 mousemove: 2, 29139 mouseup: 2, 29140 29141 pointerdown: 3, 29142 pointermove: 3, 29143 pointerup: 3, 29144 29145 MSPointerDown: 3, 29146 MSPointerMove: 3, 29147 MSPointerUp: 3 29148 }); 29149 29150 me.extend(me.ease = {}, { 29151 quadratic: { 29152 style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', 29153 fn: function (k) { 29154 return k * ( 2 - k ); 29155 } 29156 }, 29157 circular: { 29158 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) 29159 fn: function (k) { 29160 return Math.sqrt( 1 - ( --k * k ) ); 29161 } 29162 }, 29163 back: { 29164 style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', 29165 fn: function (k) { 29166 var b = 4; 29167 return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; 29168 } 29169 }, 29170 bounce: { 29171 style: '', 29172 fn: function (k) { 29173 if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { 29174 return 7.5625 * k * k; 29175 } else if ( k < ( 2 / 2.75 ) ) { 29176 return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; 29177 } else if ( k < ( 2.5 / 2.75 ) ) { 29178 return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; 29179 } else { 29180 return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; 29181 } 29182 } 29183 }, 29184 elastic: { 29185 style: '', 29186 fn: function (k) { 29187 var f = 0.22, 29188 e = 0.4; 29189 29190 if ( k === 0 ) { return 0; } 29191 if ( k == 1 ) { return 1; } 29192 29193 return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); 29194 } 29195 } 29196 }); 29197 29198 me.tap = function (e, eventName) { 29199 var ev = document.createEvent('Event'); 29200 ev.initEvent(eventName, true, true); 29201 ev.pageX = e.pageX; 29202 ev.pageY = e.pageY; 29203 e.target.dispatchEvent(ev); 29204 }; 29205 29206 me.click = function (e) { 29207 var target = e.target, 29208 ev; 29209 29210 if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { 29211 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent 29212 // initMouseEvent is deprecated. 29213 ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event'); 29214 ev.initEvent('click', true, true); 29215 ev.view = e.view || window; 29216 ev.detail = 1; 29217 ev.screenX = target.screenX || 0; 29218 ev.screenY = target.screenY || 0; 29219 ev.clientX = target.clientX || 0; 29220 ev.clientY = target.clientY || 0; 29221 ev.ctrlKey = !!e.ctrlKey; 29222 ev.altKey = !!e.altKey; 29223 ev.shiftKey = !!e.shiftKey; 29224 ev.metaKey = !!e.metaKey; 29225 ev.button = 0; 29226 ev.relatedTarget = null; 29227 ev._constructed = true; 29228 target.dispatchEvent(ev); 29229 } 29230 }; 29231 29232 return me; 29233})(); 29234function IScroll (el, options) { 29235 this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; 29236 this.scroller = this.wrapper.children[0]; 29237 this.scrollerStyle = this.scroller.style; // cache style for better performance 29238 29239 this.options = { 29240 29241 resizeScrollbars: true, 29242 29243 mouseWheelSpeed: 20, 29244 29245 snapThreshold: 0.334, 29246 29247// INSERT POINT: OPTIONS 29248 disablePointer : !utils.hasPointer, 29249 disableTouch : utils.hasPointer || !utils.hasTouch, 29250 disableMouse : utils.hasPointer || utils.hasTouch, 29251 startX: 0, 29252 startY: 0, 29253 scrollY: true, 29254 directionLockThreshold: 5, 29255 momentum: true, 29256 29257 bounce: true, 29258 bounceTime: 600, 29259 bounceEasing: '', 29260 29261 preventDefault: true, 29262 preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ }, 29263 29264 HWCompositing: true, 29265 useTransition: true, 29266 useTransform: true, 29267 bindToWrapper: typeof window.onmousedown === "undefined" 29268 }; 29269 29270 for ( var i in options ) { 29271 this.options[i] = options[i]; 29272 } 29273 29274 // Normalize options 29275 this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : ''; 29276 29277 this.options.useTransition = utils.hasTransition && this.options.useTransition; 29278 this.options.useTransform = utils.hasTransform && this.options.useTransform; 29279 29280 this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; 29281 this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; 29282 29283 // If you want eventPassthrough I have to lock one of the axes 29284 this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; 29285 this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; 29286 29287 // With eventPassthrough we also need lockDirection mechanism 29288 this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; 29289 this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; 29290 29291 this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; 29292 29293 this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; 29294 29295 if ( this.options.tap === true ) {
vendor: 4,893 bytes, lines 29296-29467
29296 this.options.tap = 'tap'; 29297 } 29298 29299 // https://github.com/cubiq/iscroll/issues/1029 29300 if (!this.options.useTransition && !this.options.useTransform) { 29301 if(!(/relative|absolute/i).test(this.scrollerStyle.position)) { 29302 this.scrollerStyle.position = "relative"; 29303 } 29304 } 29305 29306 if ( this.options.shrinkScrollbars == 'scale' ) { 29307 this.options.useTransition = false; 29308 } 29309 29310 this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; 29311 29312// INSERT POINT: NORMALIZATION 29313 29314 // Some defaults 29315 this.x = 0; 29316 this.y = 0; 29317 this.directionX = 0; 29318 this.directionY = 0; 29319 this._events = {}; 29320 29321// INSERT POINT: DEFAULTS 29322 29323 this._init(); 29324 this.refresh(); 29325 29326 this.scrollTo(this.options.startX, this.options.startY); 29327 this.enable(); 29328} 29329 29330IScroll.prototype = { 29331 version: '5.2.0', 29332 29333 _init: function () { 29334 this._initEvents(); 29335 29336 if ( this.options.scrollbars || this.options.indicators ) { 29337 this._initIndicators(); 29338 } 29339 29340 if ( this.options.mouseWheel ) { 29341 this._initWheel(); 29342 } 29343 29344 if ( this.options.snap ) { 29345 this._initSnap(); 29346 } 29347 29348 if ( this.options.keyBindings ) { 29349 this._initKeys(); 29350 } 29351 29352// INSERT POINT: _init 29353 29354 }, 29355 29356 destroy: function () { 29357 this._initEvents(true); 29358 clearTimeout(this.resizeTimeout); 29359 this.resizeTimeout = null; 29360 this._execEvent('destroy'); 29361 }, 29362 29363 _transitionEnd: function (e) { 29364 if ( e.target != this.scroller || !this.isInTransition ) { 29365 return; 29366 } 29367 29368 this._transitionTime(); 29369 if ( !this.resetPosition(this.options.bounceTime) ) { 29370 this.isInTransition = false; 29371 this._execEvent('scrollEnd'); 29372 } 29373 }, 29374 29375 _start: function (e) { 29376 // React to left mouse button only 29377 if ( utils.eventType[e.type] != 1 ) { 29378 // for button property 29379 // http://unixpapa.com/js/mouse.html 29380 var button; 29381 if (!e.which) { 29382 /* IE case */ 29383 button = (e.button < 2) ? 0 : 29384 ((e.button == 4) ? 1 : 2); 29385 } else { 29386 /* All others */ 29387 button = e.button; 29388 } 29389 if ( button !== 0 ) { 29390 return; 29391 } 29392 } 29393 29394 if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { 29395 return; 29396 } 29397 29398 if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29399 e.preventDefault(); 29400 } 29401 29402 var point = e.touches ? e.touches[0] : e, 29403 pos; 29404 29405 this.initiated = utils.eventType[e.type]; 29406 this.moved = false; 29407 this.distX = 0; 29408 this.distY = 0; 29409 this.directionX = 0; 29410 this.directionY = 0; 29411 this.directionLocked = 0; 29412 29413 this.startTime = utils.getTime(); 29414 29415 if ( this.options.useTransition && this.isInTransition ) { 29416 this._transitionTime(); 29417 this.isInTransition = false; 29418 pos = this.getComputedPosition(); 29419 this._translate(Math.round(pos.x), Math.round(pos.y)); 29420 this._execEvent('scrollEnd'); 29421 } else if ( !this.options.useTransition && this.isAnimating ) { 29422 this.isAnimating = false; 29423 this._execEvent('scrollEnd'); 29424 } 29425 29426 this.startX = this.x; 29427 this.startY = this.y; 29428 this.absStartX = this.x; 29429 this.absStartY = this.y; 29430 this.pointX = point.pageX; 29431 this.pointY = point.pageY; 29432 29433 this._execEvent('beforeScrollStart'); 29434 }, 29435 29436 _move: function (e) { 29437 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29438 return; 29439 } 29440 29441 if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! 29442 e.preventDefault(); 29443 } 29444 29445 var point = e.touches ? e.touches[0] : e, 29446 deltaX = point.pageX - this.pointX, 29447 deltaY = point.pageY - this.pointY, 29448 timestamp = utils.getTime(), 29449 newX, newY, 29450 absDistX, absDistY; 29451 29452 this.pointX = point.pageX; 29453 this.pointY = point.pageY; 29454 29455 this.distX += deltaX; 29456 this.distY += deltaY; 29457 absDistX = Math.abs(this.distX); 29458 absDistY = Math.abs(this.distY); 29459 29460 // We need to move at least 10 pixels for the scrolling to initiate 29461 if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { 29462 return; 29463 } 29464 29465 // If you are scrolling in one direction lock the other 29466 if ( !this.directionLocked && !this.options.freeScroll ) { 29467 if ( absDistX > absDistY + this.options.directionLockThreshold ) {
vendor: 6,057 bytes, lines 29468-29654
29468 this.directionLocked = 'h'; // lock horizontally 29469 } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { 29470 this.directionLocked = 'v'; // lock vertically 29471 } else { 29472 this.directionLocked = 'n'; // no lock 29473 } 29474 } 29475 29476 if ( this.directionLocked == 'h' ) { 29477 if ( this.options.eventPassthrough == 'vertical' ) { 29478 e.preventDefault(); 29479 } else if ( this.options.eventPassthrough == 'horizontal' ) { 29480 this.initiated = false; 29481 return; 29482 } 29483 29484 deltaY = 0; 29485 } else if ( this.directionLocked == 'v' ) { 29486 if ( this.options.eventPassthrough == 'horizontal' ) { 29487 e.preventDefault(); 29488 } else if ( this.options.eventPassthrough == 'vertical' ) { 29489 this.initiated = false; 29490 return; 29491 } 29492 29493 deltaX = 0; 29494 } 29495 29496 deltaX = this.hasHorizontalScroll ? deltaX : 0; 29497 deltaY = this.hasVerticalScroll ? deltaY : 0; 29498 29499 newX = this.x + deltaX; 29500 newY = this.y + deltaY; 29501 29502 // Slow down if outside of the boundaries 29503 if ( newX > 0 || newX < this.maxScrollX ) { 29504 newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; 29505 } 29506 if ( newY > 0 || newY < this.maxScrollY ) { 29507 newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; 29508 } 29509 29510 this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; 29511 this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; 29512 29513 if ( !this.moved ) { 29514 this._execEvent('scrollStart'); 29515 } 29516 29517 this.moved = true; 29518 29519 this._translate(newX, newY); 29520 29521/* REPLACE START: _move */ 29522 29523 if ( timestamp - this.startTime > 300 ) { 29524 this.startTime = timestamp; 29525 this.startX = this.x; 29526 this.startY = this.y; 29527 } 29528 29529/* REPLACE END: _move */ 29530 29531 }, 29532 29533 _end: function (e) { 29534 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29535 return; 29536 } 29537 29538 if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29539 e.preventDefault(); 29540 } 29541 29542 var point = e.changedTouches ? e.changedTouches[0] : e, 29543 momentumX, 29544 momentumY, 29545 duration = utils.getTime() - this.startTime, 29546 newX = Math.round(this.x), 29547 newY = Math.round(this.y), 29548 distanceX = Math.abs(newX - this.startX), 29549 distanceY = Math.abs(newY - this.startY), 29550 time = 0, 29551 easing = ''; 29552 29553 this.isInTransition = 0; 29554 this.initiated = 0; 29555 this.endTime = utils.getTime(); 29556 29557 // reset if we are outside of the boundaries 29558 if ( this.resetPosition(this.options.bounceTime) ) { 29559 return; 29560 } 29561 29562 this.scrollTo(newX, newY); // ensures that the last position is rounded 29563 29564 // we scrolled less than 10 pixels 29565 if ( !this.moved ) { 29566 if ( this.options.tap ) { 29567 utils.tap(e, this.options.tap); 29568 } 29569 29570 if ( this.options.click ) { 29571 utils.click(e); 29572 } 29573 29574 this._execEvent('scrollCancel'); 29575 return; 29576 } 29577 29578 if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) { 29579 this._execEvent('flick'); 29580 return; 29581 } 29582 29583 // start momentum animation if needed 29584 if ( this.options.momentum && duration < 300 ) { 29585 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 }; 29586 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 }; 29587 newX = momentumX.destination; 29588 newY = momentumY.destination; 29589 time = Math.max(momentumX.duration, momentumY.duration); 29590 this.isInTransition = 1; 29591 } 29592 29593 29594 if ( this.options.snap ) { 29595 var snap = this._nearestSnap(newX, newY); 29596 this.currentPage = snap; 29597 time = this.options.snapSpeed || Math.max( 29598 Math.max( 29599 Math.min(Math.abs(newX - snap.x), 1000), 29600 Math.min(Math.abs(newY - snap.y), 1000) 29601 ), 300); 29602 newX = snap.x; 29603 newY = snap.y; 29604 29605 this.directionX = 0; 29606 this.directionY = 0; 29607 easing = this.options.bounceEasing; 29608 } 29609 29610// INSERT POINT: _end 29611 29612 if ( newX != this.x || newY != this.y ) { 29613 // change easing function when scroller goes out of the boundaries 29614 if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { 29615 easing = utils.ease.quadratic; 29616 } 29617 29618 this.scrollTo(newX, newY, time, easing); 29619 return; 29620 } 29621 29622 this._execEvent('scrollEnd'); 29623 }, 29624 29625 _resize: function () { 29626 var that = this; 29627 29628 clearTimeout(this.resizeTimeout); 29629 29630 this.resizeTimeout = setTimeout(function () { 29631 that.refresh(); 29632 }, this.options.resizePolling); 29633 }, 29634 29635 resetPosition: function (time) { 29636 var x = this.x, 29637 y = this.y; 29638 29639 time = time || 0; 29640 29641 if ( !this.hasHorizontalScroll || this.x > 0 ) { 29642 x = 0; 29643 } else if ( this.x < this.maxScrollX ) { 29644 x = this.maxScrollX; 29645 } 29646 29647 if ( !this.hasVerticalScroll || this.y > 0 ) { 29648 y = 0; 29649 } else if ( this.y < this.maxScrollY ) { 29650 y = this.maxScrollY; 29651 } 29652 29653 if ( x == this.x && y == this.y ) { 29654 return false;
vendor: 5,509 bytes, lines 29655-29859
29655 } 29656 29657 this.scrollTo(x, y, time, this.options.bounceEasing); 29658 29659 return true; 29660 }, 29661 29662 disable: function () { 29663 this.enabled = false; 29664 }, 29665 29666 enable: function () { 29667 this.enabled = true; 29668 }, 29669 29670 refresh: function () { 29671 var rf = this.wrapper.offsetHeight; // Force reflow 29672 29673 this.wrapperWidth = this.wrapper.clientWidth; 29674 this.wrapperHeight = this.wrapper.clientHeight; 29675 29676/* REPLACE START: refresh */ 29677 29678 this.scrollerWidth = this.scroller.offsetWidth; 29679 this.scrollerHeight = this.scroller.offsetHeight; 29680 29681 this.maxScrollX = this.wrapperWidth - this.scrollerWidth; 29682 this.maxScrollY = this.wrapperHeight - this.scrollerHeight; 29683 29684/* REPLACE END: refresh */ 29685 29686 this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; 29687 this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; 29688 29689 if ( !this.hasHorizontalScroll ) { 29690 this.maxScrollX = 0; 29691 this.scrollerWidth = this.wrapperWidth; 29692 } 29693 29694 if ( !this.hasVerticalScroll ) { 29695 this.maxScrollY = 0; 29696 this.scrollerHeight = this.wrapperHeight; 29697 } 29698 29699 this.endTime = 0; 29700 this.directionX = 0; 29701 this.directionY = 0; 29702 29703 this.wrapperOffset = utils.offset(this.wrapper); 29704 29705 this._execEvent('refresh'); 29706 29707 this.resetPosition(); 29708 29709// INSERT POINT: _refresh 29710 29711 }, 29712 29713 29714 on: function (type, fn) { 29715 if ( !this._events[type] ) { 29716 this._events[type] = []; 29717 } 29718 29719 this._events[type].push(fn); 29720 }, 29721 29722 off: function (type, fn) { 29723 if ( !this._events[type] ) { 29724 return; 29725 } 29726 29727 var index = this._events[type].indexOf(fn); 29728 29729 if ( index > -1 ) { 29730 this._events[type].splice(index, 1); 29731 } 29732 }, 29733 29734 _execEvent: function (type) { 29735 if ( !this._events[type] ) { 29736 return; 29737 } 29738 29739 var i = 0, 29740 l = this._events[type].length; 29741 29742 if ( !l ) { 29743 return; 29744 } 29745 29746 for ( ; i < l; i++ ) { 29747 this._events[type][i].apply(this, [].slice.call(arguments, 1)); 29748 } 29749 }, 29750 29751 scrollBy: function (x, y, time, easing) { 29752 x = this.x + x; 29753 y = this.y + y; 29754 time = time || 0; 29755 29756 this.scrollTo(x, y, time, easing); 29757 }, 29758 29759 scrollTo: function (x, y, time, easing) { 29760 easing = easing || utils.ease.circular; 29761 29762 this.isInTransition = this.options.useTransition && time > 0; 29763 var transitionType = this.options.useTransition && easing.style; 29764 if ( !time || transitionType ) { 29765 if(transitionType) { 29766 this._transitionTimingFunction(easing.style); 29767 this._transitionTime(time); 29768 } 29769 this._translate(x, y); 29770 } else { 29771 this._animate(x, y, time, easing.fn); 29772 } 29773 }, 29774 29775 scrollToElement: function (el, time, offsetX, offsetY, easing) { 29776 el = el.nodeType ? el : this.scroller.querySelector(el); 29777 29778 if ( !el ) { 29779 return; 29780 } 29781 29782 var pos = utils.offset(el); 29783 29784 pos.left -= this.wrapperOffset.left; 29785 pos.top -= this.wrapperOffset.top; 29786 29787 // if offsetX/Y are true we center the element to the screen 29788 if ( offsetX === true ) { 29789 offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); 29790 } 29791 if ( offsetY === true ) { 29792 offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); 29793 } 29794 29795 pos.left -= offsetX || 0; 29796 pos.top -= offsetY || 0; 29797 29798 pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; 29799 pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; 29800 29801 time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; 29802 29803 this.scrollTo(pos.left, pos.top, time, easing); 29804 }, 29805 29806 _transitionTime: function (time) { 29807 if (!this.options.useTransition) { 29808 return; 29809 } 29810 time = time || 0; 29811 var durationProp = utils.style.transitionDuration; 29812 if(!durationProp) { 29813 return; 29814 } 29815 29816 this.scrollerStyle[durationProp] = time + 'ms'; 29817 29818 if ( !time && utils.isBadAndroid ) { 29819 this.scrollerStyle[durationProp] = '0.0001ms'; 29820 // remove 0.0001ms 29821 var self = this; 29822 rAF(function() { 29823 if(self.scrollerStyle[durationProp] === '0.0001ms') { 29824 self.scrollerStyle[durationProp] = '0s'; 29825 } 29826 }); 29827 } 29828 29829 29830 if ( this.indicators ) { 29831 for ( var i = this.indicators.length; i--; ) { 29832 this.indicators[i].transitionTime(time); 29833 } 29834 } 29835 29836 29837// INSERT POINT: _transitionTime 29838 29839 }, 29840 29841 _transitionTimingFunction: function (easing) { 29842 this.scrollerStyle[utils.style.transitionTimingFunction] = easing; 29843 29844 29845 if ( this.indicators ) { 29846 for ( var i = this.indicators.length; i--; ) { 29847 this.indicators[i].transitionTimingFunction(easing); 29848 } 29849 } 29850 29851 29852// INSERT POINT: _transitionTimingFunction 29853 29854 }, 29855 29856 _translate: function (x, y) { 29857 //Uncode addition 29858 if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 ) 29859 return false;
vendor: 9,939 bytes, lines 29860-30171
29860 29861 if ( this.options.useTransform ) { 29862 29863/* REPLACE START: _translate */ 29864 29865 this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ; 29866 29867/* REPLACE END: _translate */ 29868 29869 } else { 29870 x = Math.round(x); 29871 y = Math.round(y); 29872 this.scrollerStyle.left = x + 'px'; 29873 this.scrollerStyle.top = y + 'px'; 29874 } 29875 29876 this.x = x; 29877 this.y = y; 29878 29879 29880 if ( this.indicators ) { 29881 for ( var i = this.indicators.length; i--; ) { 29882 this.indicators[i].updatePosition(); 29883 } 29884 } 29885 29886 //Uncode addition 29887 var uncodevent = new CustomEvent('fp-slide-scroll'); 29888 window.dispatchEvent(uncodevent); 29889 29890// INSERT POINT: _translate 29891 29892 }, 29893 29894 _initEvents: function (remove) { 29895 var eventType = remove ? utils.removeEvent : utils.addEvent, 29896 target = this.options.bindToWrapper ? this.wrapper : window; 29897 29898 eventType(window, 'orientationchange', this); 29899 eventType(window, 'resize', this); 29900 29901 if ( this.options.click ) { 29902 eventType(this.wrapper, 'click', this, true); 29903 } 29904 29905 if ( !this.options.disableMouse ) { 29906 eventType(this.wrapper, 'mousedown', this); 29907 eventType(target, 'mousemove', this); 29908 eventType(target, 'mousecancel', this); 29909 eventType(target, 'mouseup', this); 29910 } 29911 29912 if ( utils.hasPointer && !this.options.disablePointer ) { 29913 eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); 29914 eventType(target, utils.prefixPointerEvent('pointermove'), this); 29915 eventType(target, utils.prefixPointerEvent('pointercancel'), this); 29916 eventType(target, utils.prefixPointerEvent('pointerup'), this); 29917 } 29918 29919 if ( utils.hasTouch && !this.options.disableTouch ) { 29920 eventType(this.wrapper, 'touchstart', this); 29921 eventType(target, 'touchmove', this); 29922 eventType(target, 'touchcancel', this); 29923 eventType(target, 'touchend', this); 29924 } 29925 29926 eventType(this.scroller, 'transitionend', this); 29927 eventType(this.scroller, 'webkitTransitionEnd', this); 29928 eventType(this.scroller, 'oTransitionEnd', this); 29929 eventType(this.scroller, 'MSTransitionEnd', this); 29930 }, 29931 29932 getComputedPosition: function () { 29933 var matrix = window.getComputedStyle(this.scroller, null), 29934 x, y; 29935 29936 if ( this.options.useTransform ) { 29937 matrix = matrix[utils.style.transform].split(')')[0].split(', '); 29938 x = +(matrix[12] || matrix[4]); 29939 y = +(matrix[13] || matrix[5]); 29940 } else { 29941 x = +matrix.left.replace(/[^-\d.]/g, ''); 29942 y = +matrix.top.replace(/[^-\d.]/g, ''); 29943 } 29944 29945 return { x: x, y: y }; 29946 }, 29947 _initIndicators: function () { 29948 var interactive = this.options.interactiveScrollbars, 29949 customStyle = typeof this.options.scrollbars != 'string', 29950 indicators = [], 29951 indicator; 29952 29953 var that = this; 29954 29955 this.indicators = []; 29956 29957 if ( this.options.scrollbars ) { 29958 // Vertical scrollbar 29959 if ( this.options.scrollY ) { 29960 indicator = { 29961 el: createDefaultScrollbar('v', interactive, this.options.scrollbars), 29962 interactive: interactive, 29963 defaultScrollbars: true, 29964 customStyle: customStyle, 29965 resize: this.options.resizeScrollbars, 29966 shrink: this.options.shrinkScrollbars, 29967 fade: this.options.fadeScrollbars, 29968 listenX: false 29969 }; 29970 29971 this.wrapper.appendChild(indicator.el); 29972 indicators.push(indicator); 29973 } 29974 29975 // Horizontal scrollbar 29976 if ( this.options.scrollX ) { 29977 indicator = { 29978 el: createDefaultScrollbar('h', interactive, this.options.scrollbars), 29979 interactive: interactive, 29980 defaultScrollbars: true, 29981 customStyle: customStyle, 29982 resize: this.options.resizeScrollbars, 29983 shrink: this.options.shrinkScrollbars, 29984 fade: this.options.fadeScrollbars, 29985 listenY: false 29986 }; 29987 29988 this.wrapper.appendChild(indicator.el); 29989 indicators.push(indicator); 29990 } 29991 } 29992 29993 if ( this.options.indicators ) { 29994 // TODO: check concat compatibility 29995 indicators = indicators.concat(this.options.indicators); 29996 } 29997 29998 for ( var i = indicators.length; i--; ) { 29999 this.indicators.push( new Indicator(this, indicators[i]) ); 30000 } 30001 30002 // TODO: check if we can use array.map (wide compatibility and performance issues) 30003 function _indicatorsMap (fn) { 30004 if (that.indicators) { 30005 for ( var i = that.indicators.length; i--; ) { 30006 fn.call(that.indicators[i]); 30007 } 30008 } 30009 } 30010 30011 if ( this.options.fadeScrollbars ) { 30012 this.on('scrollEnd', function () { 30013 _indicatorsMap(function () { 30014 this.fade(); 30015 }); 30016 }); 30017 30018 this.on('scrollCancel', function () { 30019 _indicatorsMap(function () { 30020 this.fade(); 30021 }); 30022 }); 30023 30024 this.on('scrollStart', function () { 30025 _indicatorsMap(function () { 30026 this.fade(1); 30027 }); 30028 }); 30029 30030 this.on('beforeScrollStart', function () { 30031 _indicatorsMap(function () { 30032 this.fade(1, true); 30033 }); 30034 }); 30035 } 30036 30037 30038 this.on('refresh', function () { 30039 _indicatorsMap(function () { 30040 this.refresh(); 30041 }); 30042 }); 30043 30044 this.on('destroy', function () { 30045 _indicatorsMap(function () { 30046 this.destroy(); 30047 }); 30048 30049 delete this.indicators; 30050 }); 30051 }, 30052 30053 _initWheel: function () { 30054 utils.addEvent(this.wrapper, 'wheel', this); 30055 utils.addEvent(this.wrapper, 'mousewheel', this); 30056 utils.addEvent(this.wrapper, 'DOMMouseScroll', this); 30057 30058 this.on('destroy', function () { 30059 clearTimeout(this.wheelTimeout); 30060 this.wheelTimeout = null; 30061 utils.removeEvent(this.wrapper, 'wheel', this); 30062 utils.removeEvent(this.wrapper, 'mousewheel', this); 30063 utils.removeEvent(this.wrapper, 'DOMMouseScroll', this); 30064 }); 30065 }, 30066 30067 _wheel: function (e) { 30068 if ( !this.enabled ) { 30069 return; 30070 } 30071 30072 var wheelDeltaX, wheelDeltaY, 30073 newX, newY, 30074 that = this; 30075 30076 if ( this.wheelTimeout === undefined ) { 30077 that._execEvent('scrollStart'); 30078 } 30079 30080 // Execute the scrollEnd event after 400ms the wheel stopped scrolling 30081 clearTimeout(this.wheelTimeout); 30082 this.wheelTimeout = setTimeout(function () { 30083 if(!that.options.snap) { 30084 that._execEvent('scrollEnd'); 30085 } 30086 that.wheelTimeout = undefined; 30087 }, 400); 30088 30089 if ( 'deltaX' in e ) { 30090 if (e.deltaMode === 1) { 30091 wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed; 30092 wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed; 30093 } else { 30094 wheelDeltaX = -e.deltaX; 30095 wheelDeltaY = -e.deltaY; 30096 } 30097 } else if ( 'wheelDeltaX' in e ) { 30098 wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed; 30099 wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed; 30100 } else if ( 'wheelDelta' in e ) { 30101 wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed; 30102 } else if ( 'detail' in e ) { 30103 wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed; 30104 } else { 30105 return; 30106 } 30107 30108 wheelDeltaX *= this.options.invertWheelDirection; 30109 wheelDeltaY *= this.options.invertWheelDirection; 30110 30111 if ( !this.hasVerticalScroll ) { 30112 wheelDeltaX = wheelDeltaY; 30113 wheelDeltaY = 0; 30114 } 30115 30116 if ( this.options.snap ) { 30117 newX = this.currentPage.pageX; 30118 newY = this.currentPage.pageY; 30119 30120 if ( wheelDeltaX > 0 ) { 30121 newX--; 30122 } else if ( wheelDeltaX < 0 ) { 30123 newX++; 30124 } 30125 30126 if ( wheelDeltaY > 0 ) { 30127 newY--; 30128 } else if ( wheelDeltaY < 0 ) { 30129 newY++; 30130 } 30131 30132 this.goToPage(newX, newY); 30133 30134 return; 30135 } 30136 30137 newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0); 30138 newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0); 30139 30140 this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0; 30141 this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0; 30142 30143 if ( newX > 0 ) { 30144 newX = 0; 30145 } else if ( newX < this.maxScrollX ) { 30146 newX = this.maxScrollX; 30147 } 30148 30149 if ( newY > 0 ) { 30150 newY = 0; 30151 } else if ( newY < this.maxScrollY ) { 30152 newY = this.maxScrollY; 30153 } 30154 30155 this.scrollTo(newX, newY, 0); 30156 30157// INSERT POINT: _wheel 30158 }, 30159 30160 _initSnap: function () { 30161 this.currentPage = {}; 30162 30163 if ( typeof this.options.snap == 'string' ) { 30164 this.options.snap = this.scroller.querySelectorAll(this.options.snap); 30165 } 30166 30167 this.on('refresh', function () { 30168 var i = 0, l, 30169 m = 0, n, 30170 cx, cy, 30171 x = 0, y,
vendor: 7,339 bytes, lines 30172-30425
30172 stepX = this.options.snapStepX || this.wrapperWidth, 30173 stepY = this.options.snapStepY || this.wrapperHeight, 30174 el; 30175 30176 this.pages = []; 30177 30178 if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) { 30179 return; 30180 } 30181 30182 if ( this.options.snap === true ) { 30183 cx = Math.round( stepX / 2 ); 30184 cy = Math.round( stepY / 2 ); 30185 30186 while ( x > -this.scrollerWidth ) { 30187 this.pages[i] = []; 30188 l = 0; 30189 y = 0; 30190 30191 while ( y > -this.scrollerHeight ) { 30192 this.pages[i][l] = { 30193 x: Math.max(x, this.maxScrollX), 30194 y: Math.max(y, this.maxScrollY), 30195 width: stepX, 30196 height: stepY, 30197 cx: x - cx, 30198 cy: y - cy 30199 }; 30200 30201 y -= stepY; 30202 l++; 30203 } 30204 30205 x -= stepX; 30206 i++; 30207 } 30208 } else { 30209 el = this.options.snap; 30210 l = el.length; 30211 n = -1; 30212 30213 for ( ; i < l; i++ ) { 30214 if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) { 30215 m = 0; 30216 n++; 30217 } 30218 30219 if ( !this.pages[m] ) { 30220 this.pages[m] = []; 30221 } 30222 30223 x = Math.max(-el[i].offsetLeft, this.maxScrollX); 30224 y = Math.max(-el[i].offsetTop, this.maxScrollY); 30225 cx = x - Math.round(el[i].offsetWidth / 2); 30226 cy = y - Math.round(el[i].offsetHeight / 2); 30227 30228 this.pages[m][n] = { 30229 x: x, 30230 y: y, 30231 width: el[i].offsetWidth, 30232 height: el[i].offsetHeight, 30233 cx: cx, 30234 cy: cy 30235 }; 30236 30237 if ( x > this.maxScrollX ) { 30238 m++; 30239 } 30240 } 30241 } 30242 30243 this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0); 30244 30245 // Update snap threshold if needed 30246 if ( this.options.snapThreshold % 1 === 0 ) { 30247 this.snapThresholdX = this.options.snapThreshold; 30248 this.snapThresholdY = this.options.snapThreshold; 30249 } else { 30250 this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold); 30251 this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold); 30252 } 30253 }); 30254 30255 this.on('flick', function () { 30256 var time = this.options.snapSpeed || Math.max( 30257 Math.max( 30258 Math.min(Math.abs(this.x - this.startX), 1000), 30259 Math.min(Math.abs(this.y - this.startY), 1000) 30260 ), 300); 30261 30262 this.goToPage( 30263 this.currentPage.pageX + this.directionX, 30264 this.currentPage.pageY + this.directionY, 30265 time 30266 ); 30267 }); 30268 }, 30269 30270 _nearestSnap: function (x, y) { 30271 if ( !this.pages.length ) { 30272 return { x: 0, y: 0, pageX: 0, pageY: 0 }; 30273 } 30274 30275 var i = 0, 30276 l = this.pages.length, 30277 m = 0; 30278 30279 // Check if we exceeded the snap threshold 30280 if ( Math.abs(x - this.absStartX) < this.snapThresholdX && 30281 Math.abs(y - this.absStartY) < this.snapThresholdY ) { 30282 return this.currentPage; 30283 } 30284 30285 if ( x > 0 ) { 30286 x = 0; 30287 } else if ( x < this.maxScrollX ) { 30288 x = this.maxScrollX; 30289 } 30290 30291 if ( y > 0 ) { 30292 y = 0; 30293 } else if ( y < this.maxScrollY ) { 30294 y = this.maxScrollY; 30295 } 30296 30297 for ( ; i < l; i++ ) { 30298 if ( x >= this.pages[i][0].cx ) { 30299 x = this.pages[i][0].x; 30300 break; 30301 } 30302 } 30303 30304 l = this.pages[i].length; 30305 30306 for ( ; m < l; m++ ) { 30307 if ( y >= this.pages[0][m].cy ) { 30308 y = this.pages[0][m].y; 30309 break; 30310 } 30311 } 30312 30313 if ( i == this.currentPage.pageX ) { 30314 i += this.directionX; 30315 30316 if ( i < 0 ) { 30317 i = 0; 30318 } else if ( i >= this.pages.length ) { 30319 i = this.pages.length - 1; 30320 } 30321 30322 x = this.pages[i][0].x; 30323 } 30324 30325 if ( m == this.currentPage.pageY ) { 30326 m += this.directionY; 30327 30328 if ( m < 0 ) { 30329 m = 0; 30330 } else if ( m >= this.pages[0].length ) { 30331 m = this.pages[0].length - 1; 30332 } 30333 30334 y = this.pages[0][m].y; 30335 } 30336 30337 return { 30338 x: x, 30339 y: y, 30340 pageX: i, 30341 pageY: m 30342 }; 30343 }, 30344 30345 goToPage: function (x, y, time, easing) { 30346 easing = easing || this.options.bounceEasing; 30347 30348 if ( x >= this.pages.length ) { 30349 x = this.pages.length - 1; 30350 } else if ( x < 0 ) { 30351 x = 0; 30352 } 30353 30354 if ( y >= this.pages[x].length ) { 30355 y = this.pages[x].length - 1; 30356 } else if ( y < 0 ) { 30357 y = 0; 30358 } 30359 30360 var posX = this.pages[x][y].x, 30361 posY = this.pages[x][y].y; 30362 30363 time = time === undefined ? this.options.snapSpeed || Math.max( 30364 Math.max( 30365 Math.min(Math.abs(posX - this.x), 1000), 30366 Math.min(Math.abs(posY - this.y), 1000) 30367 ), 300) : time; 30368 30369 this.currentPage = { 30370 x: posX, 30371 y: posY, 30372 pageX: x, 30373 pageY: y 30374 }; 30375 30376 this.scrollTo(posX, posY, time, easing); 30377 }, 30378 30379 next: function (time, easing) { 30380 var x = this.currentPage.pageX, 30381 y = this.currentPage.pageY; 30382 30383 x++; 30384 30385 if ( x >= this.pages.length && this.hasVerticalScroll ) { 30386 x = 0; 30387 y++; 30388 } 30389 30390 this.goToPage(x, y, time, easing); 30391 }, 30392 30393 prev: function (time, easing) { 30394 var x = this.currentPage.pageX, 30395 y = this.currentPage.pageY; 30396 30397 x--; 30398 30399 if ( x < 0 && this.hasVerticalScroll ) { 30400 x = 0; 30401 y--; 30402 } 30403 30404 this.goToPage(x, y, time, easing); 30405 }, 30406 30407 _initKeys: function (e) { 30408 // default key bindings 30409 var keys = { 30410 pageUp: 33, 30411 pageDown: 34, 30412 end: 35, 30413 home: 36, 30414 left: 37, 30415 up: 38, 30416 right: 39, 30417 down: 40 30418 }; 30419 var i; 30420 30421 // if you give me characters I give you keycode 30422 if ( typeof this.options.keyBindings == 'object' ) { 30423 for ( i in this.options.keyBindings ) { 30424 if ( typeof this.options.keyBindings[i] == 'string' ) { 30425 this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
vendor: 11,097 bytes, lines 30425-30778
30425deAt(0); 30426 } 30427 } 30428 } else { 30429 this.options.keyBindings = {}; 30430 } 30431 30432 for ( i in keys ) { 30433 this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i]; 30434 } 30435 30436 utils.addEvent(window, 'keydown', this); 30437 30438 this.on('destroy', function () { 30439 utils.removeEvent(window, 'keydown', this); 30440 }); 30441 }, 30442 30443 _key: function (e) { 30444 if ( !this.enabled ) { 30445 return; 30446 } 30447 30448 var snap = this.options.snap, // we are using this alot, better to cache it 30449 newX = snap ? this.currentPage.pageX : this.x, 30450 newY = snap ? this.currentPage.pageY : this.y, 30451 now = utils.getTime(), 30452 prevTime = this.keyTime || 0, 30453 acceleration = 0.250, 30454 pos; 30455 30456 if ( this.options.useTransition && this.isInTransition ) { 30457 pos = this.getComputedPosition(); 30458 30459 this._translate(Math.round(pos.x), Math.round(pos.y)); 30460 this.isInTransition = false; 30461 } 30462 30463 this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0; 30464 30465 switch ( e.keyCode ) { 30466 case this.options.keyBindings.pageUp: 30467 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30468 newX += snap ? 1 : this.wrapperWidth; 30469 } else { 30470 newY += snap ? 1 : this.wrapperHeight; 30471 } 30472 break; 30473 case this.options.keyBindings.pageDown: 30474 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30475 newX -= snap ? 1 : this.wrapperWidth; 30476 } else { 30477 newY -= snap ? 1 : this.wrapperHeight; 30478 } 30479 break; 30480 case this.options.keyBindings.end: 30481 newX = snap ? this.pages.length-1 : this.maxScrollX; 30482 newY = snap ? this.pages[0].length-1 : this.maxScrollY; 30483 break; 30484 case this.options.keyBindings.home: 30485 newX = 0; 30486 newY = 0; 30487 break; 30488 case this.options.keyBindings.left: 30489 newX += snap ? -1 : 5 + this.keyAcceleration>>0; 30490 break; 30491 case this.options.keyBindings.up: 30492 newY += snap ? 1 : 5 + this.keyAcceleration>>0; 30493 break; 30494 case this.options.keyBindings.right: 30495 newX -= snap ? -1 : 5 + this.keyAcceleration>>0; 30496 break; 30497 case this.options.keyBindings.down: 30498 newY -= snap ? 1 : 5 + this.keyAcceleration>>0; 30499 break; 30500 default: 30501 return; 30502 } 30503 30504 if ( snap ) { 30505 this.goToPage(newX, newY); 30506 return; 30507 } 30508 30509 if ( newX > 0 ) { 30510 newX = 0; 30511 this.keyAcceleration = 0; 30512 } else if ( newX < this.maxScrollX ) { 30513 newX = this.maxScrollX; 30514 this.keyAcceleration = 0; 30515 } 30516 30517 if ( newY > 0 ) { 30518 newY = 0; 30519 this.keyAcceleration = 0; 30520 } else if ( newY < this.maxScrollY ) { 30521 newY = this.maxScrollY; 30522 this.keyAcceleration = 0; 30523 } 30524 30525 this.scrollTo(newX, newY, 0); 30526 30527 this.keyTime = now; 30528 }, 30529 30530 _animate: function (destX, destY, duration, easingFn) { 30531 var that = this, 30532 startX = this.x, 30533 startY = this.y, 30534 startTime = utils.getTime(), 30535 destTime = startTime + duration; 30536 30537 function step () { 30538 var now = utils.getTime(), 30539 newX, newY, 30540 easing; 30541 30542 if ( now >= destTime ) { 30543 that.isAnimating = false; 30544 that._translate(destX, destY); 30545 30546 if ( !that.resetPosition(that.options.bounceTime) ) { 30547 that._execEvent('scrollEnd'); 30548 } 30549 30550 return; 30551 } 30552 30553 now = ( now - startTime ) / duration; 30554 easing = easingFn(now); 30555 newX = ( destX - startX ) * easing + startX; 30556 newY = ( destY - startY ) * easing + startY; 30557 that._translate(newX, newY); 30558 30559 if ( that.isAnimating ) { 30560 rAF(step); 30561 } 30562 } 30563 30564 this.isAnimating = true; 30565 step(); 30566 }, 30567 handleEvent: function (e) { 30568 switch ( e.type ) { 30569 case 'touchstart': 30570 case 'pointerdown': 30571 case 'MSPointerDown': 30572 case 'mousedown': 30573 this._start(e); 30574 break; 30575 case 'touchmove': 30576 case 'pointermove': 30577 case 'MSPointerMove': 30578 case 'mousemove': 30579 this._move(e); 30580 break; 30581 case 'touchend': 30582 case 'pointerup': 30583 case 'MSPointerUp': 30584 case 'mouseup': 30585 case 'touchcancel': 30586 case 'pointercancel': 30587 case 'MSPointerCancel': 30588 case 'mousecancel': 30589 this._end(e); 30590 break; 30591 case 'orientationchange': 30592 case 'resize': 30593 this._resize(); 30594 break; 30595 case 'transitionend': 30596 case 'webkitTransitionEnd': 30597 case 'oTransitionEnd': 30598 case 'MSTransitionEnd': 30599 this._transitionEnd(e); 30600 break; 30601 case 'wheel': 30602 case 'DOMMouseScroll': 30603 case 'mousewheel': 30604 this._wheel(e); 30605 break; 30606 case 'keydown': 30607 this._key(e); 30608 break; 30609 case 'click': 30610 if ( this.enabled && !e._constructed ) { 30611 e.preventDefault(); 30612 e.stopPropagation(); 30613 } 30614 break; 30615 } 30616 } 30617}; 30618function createDefaultScrollbar (direction, interactive, type) { 30619 var scrollbar = document.createElement('div'), 30620 indicator = document.createElement('div'); 30621 30622 if ( type === true ) { 30623 scrollbar.style.cssText = 'position:absolute;z-index:9999'; 30624 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'; 30625 } 30626 30627 indicator.className = 'iScrollIndicator'; 30628 30629 if ( direction == 'h' ) { 30630 if ( type === true ) { 30631 scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0'; 30632 indicator.style.height = '100%'; 30633 } 30634 scrollbar.className = 'iScrollHorizontalScrollbar'; 30635 } else { 30636 if ( type === true ) { 30637 scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px'; 30638 indicator.style.width = '100%'; 30639 } 30640 scrollbar.className = 'iScrollVerticalScrollbar'; 30641 } 30642 30643 scrollbar.style.cssText += ';overflow:hidden'; 30644 30645 if ( !interactive ) { 30646 scrollbar.style.pointerEvents = 'none'; 30647 } 30648 30649 scrollbar.appendChild(indicator); 30650 30651 return scrollbar; 30652} 30653 30654function Indicator (scroller, options) { 30655 this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; 30656 this.wrapperStyle = this.wrapper.style; 30657 this.indicator = this.wrapper.children[0]; 30658 this.indicatorStyle = this.indicator.style; 30659 this.scroller = scroller; 30660 30661 this.options = { 30662 listenX: true, 30663 listenY: true, 30664 interactive: false, 30665 resize: true, 30666 defaultScrollbars: false, 30667 shrink: false, 30668 fade: false, 30669 speedRatioX: 0, 30670 speedRatioY: 0 30671 }; 30672 30673 for ( var i in options ) { 30674 this.options[i] = options[i]; 30675 } 30676 30677 this.sizeRatioX = 1; 30678 this.sizeRatioY = 1; 30679 this.maxPosX = 0; 30680 this.maxPosY = 0; 30681 30682 if ( this.options.interactive ) { 30683 if ( !this.options.disableTouch ) { 30684 utils.addEvent(this.indicator, 'touchstart', this); 30685 utils.addEvent(window, 'touchend', this); 30686 } 30687 if ( !this.options.disablePointer ) { 30688 utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30689 utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this); 30690 } 30691 if ( !this.options.disableMouse ) { 30692 utils.addEvent(this.indicator, 'mousedown', this); 30693 utils.addEvent(window, 'mouseup', this); 30694 } 30695 } 30696 30697 if ( this.options.fade ) { 30698 this.wrapperStyle[utils.style.transform] = this.scroller.translateZ; 30699 var durationProp = utils.style.transitionDuration; 30700 if(!durationProp) { 30701 return; 30702 } 30703 this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms'; 30704 // remove 0.0001ms 30705 var self = this; 30706 if(utils.isBadAndroid) { 30707 rAF(function() { 30708 if(self.wrapperStyle[durationProp] === '0.0001ms') { 30709 self.wrapperStyle[durationProp] = '0s'; 30710 } 30711 }); 30712 } 30713 this.wrapperStyle.opacity = '0'; 30714 } 30715} 30716 30717Indicator.prototype = { 30718 handleEvent: function (e) { 30719 switch ( e.type ) { 30720 case 'touchstart': 30721 case 'pointerdown': 30722 case 'MSPointerDown': 30723 case 'mousedown': 30724 this._start(e); 30725 break; 30726 case 'touchmove': 30727 case 'pointermove': 30728 case 'MSPointerMove': 30729 case 'mousemove': 30730 this._move(e); 30731 break; 30732 case 'touchend': 30733 case 'pointerup': 30734 case 'MSPointerUp': 30735 case 'mouseup': 30736 case 'touchcancel': 30737 case 'pointercancel': 30738 case 'MSPointerCancel': 30739 case 'mousecancel': 30740 this._end(e); 30741 break; 30742 } 30743 }, 30744 30745 destroy: function () { 30746 if ( this.options.fadeScrollbars ) { 30747 clearTimeout(this.fadeTimeout); 30748 this.fadeTimeout = null; 30749 } 30750 if ( this.options.interactive ) { 30751 utils.removeEvent(this.indicator, 'touchstart', this); 30752 utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30753 utils.removeEvent(this.indicator, 'mousedown', this); 30754 30755 utils.removeEvent(window, 'touchmove', this); 30756 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30757 utils.removeEvent(window, 'mousemove', this); 30758 30759 utils.removeEvent(window, 'touchend', this); 30760 utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this); 30761 utils.removeEvent(window, 'mouseup', this); 30762 } 30763 30764 if ( this.options.defaultScrollbars ) { 30765 this.wrapper.parentNode.removeChild(this.wrapper); 30766 } 30767 }, 30768 30769 _start: function (e) { 30770 var point = e.touches ? e.touches[0] : e; 30771 30772 e.preventDefault(); 30773 e.stopPropagation(); 30774 30775 this.transitionTime(); 30776 30777 this.initiated = true; 30778 this.moved = false;
vendor: 9,615 bytes, lines 30779-31037
30779 this.lastPointX = point.pageX; 30780 this.lastPointY = point.pageY; 30781 30782 this.startTime = utils.getTime(); 30783 30784 if ( !this.options.disableTouch ) { 30785 utils.addEvent(window, 'touchmove', this); 30786 } 30787 if ( !this.options.disablePointer ) { 30788 utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this); 30789 } 30790 if ( !this.options.disableMouse ) { 30791 utils.addEvent(window, 'mousemove', this); 30792 } 30793 30794 this.scroller._execEvent('beforeScrollStart'); 30795 }, 30796 30797 _move: function (e) { 30798 var point = e.touches ? e.touches[0] : e, 30799 deltaX, deltaY, 30800 newX, newY, 30801 timestamp = utils.getTime(); 30802 30803 if ( !this.moved ) { 30804 this.scroller._execEvent('scrollStart'); 30805 } 30806 30807 this.moved = true; 30808 30809 deltaX = point.pageX - this.lastPointX; 30810 this.lastPointX = point.pageX; 30811 30812 deltaY = point.pageY - this.lastPointY; 30813 this.lastPointY = point.pageY; 30814 30815 newX = this.x + deltaX; 30816 newY = this.y + deltaY; 30817 30818 this._pos(newX, newY); 30819 30820// INSERT POINT: indicator._move 30821 30822 e.preventDefault(); 30823 e.stopPropagation(); 30824 }, 30825 30826 _end: function (e) { 30827 if ( !this.initiated ) { 30828 return; 30829 } 30830 30831 this.initiated = false; 30832 30833 e.preventDefault(); 30834 e.stopPropagation(); 30835 30836 utils.removeEvent(window, 'touchmove', this); 30837 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30838 utils.removeEvent(window, 'mousemove', this); 30839 30840 if ( this.scroller.options.snap ) { 30841 var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); 30842 30843 var time = this.options.snapSpeed || Math.max( 30844 Math.max( 30845 Math.min(Math.abs(this.scroller.x - snap.x), 1000), 30846 Math.min(Math.abs(this.scroller.y - snap.y), 1000) 30847 ), 300); 30848 30849 if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) { 30850 this.scroller.directionX = 0; 30851 this.scroller.directionY = 0; 30852 this.scroller.currentPage = snap; 30853 this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing); 30854 } 30855 } 30856 30857 if ( this.moved ) { 30858 this.scroller._execEvent('scrollEnd'); 30859 } 30860 }, 30861 30862 transitionTime: function (time) { 30863 time = time || 0; 30864 var durationProp = utils.style.transitionDuration; 30865 if(!durationProp) { 30866 return; 30867 } 30868 30869 this.indicatorStyle[durationProp] = time + 'ms'; 30870 30871 if ( !time && utils.isBadAndroid ) { 30872 this.indicatorStyle[durationProp] = '0.0001ms'; 30873 // remove 0.0001ms 30874 var self = this; 30875 rAF(function() { 30876 if(self.indicatorStyle[durationProp] === '0.0001ms') { 30877 self.indicatorStyle[durationProp] = '0s'; 30878 } 30879 }); 30880 } 30881 }, 30882 30883 transitionTimingFunction: function (easing) { 30884 this.indicatorStyle[utils.style.transitionTimingFunction] = easing; 30885 }, 30886 30887 refresh: function () { 30888 this.transitionTime(); 30889 30890 if ( this.options.listenX && !this.options.listenY ) { 30891 this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; 30892 } else if ( this.options.listenY && !this.options.listenX ) { 30893 this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; 30894 } else { 30895 this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; 30896 } 30897 30898 if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) { 30899 utils.addClass(this.wrapper, 'iScrollBothScrollbars'); 30900 utils.removeClass(this.wrapper, 'iScrollLoneScrollbar'); 30901 30902 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30903 if ( this.options.listenX ) { 30904 this.wrapper.style.right = '8px'; 30905 } else { 30906 this.wrapper.style.bottom = '8px'; 30907 } 30908 } 30909 } else { 30910 utils.removeClass(this.wrapper, 'iScrollBothScrollbars'); 30911 utils.addClass(this.wrapper, 'iScrollLoneScrollbar'); 30912 30913 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30914 if ( this.options.listenX ) { 30915 this.wrapper.style.right = '2px'; 30916 } else { 30917 this.wrapper.style.bottom = '2px'; 30918 } 30919 } 30920 } 30921 30922 var r = this.wrapper.offsetHeight; // force refresh 30923 30924 if ( this.options.listenX ) { 30925 this.wrapperWidth = this.wrapper.clientWidth; 30926 if ( this.options.resize ) { 30927 this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); 30928 this.indicatorStyle.width = this.indicatorWidth + 'px'; 30929 } else { 30930 this.indicatorWidth = this.indicator.clientWidth; 30931 } 30932 30933 this.maxPosX = this.wrapperWidth - this.indicatorWidth; 30934 30935 if ( this.options.shrink == 'clip' ) { 30936 this.minBoundaryX = -this.indicatorWidth + 8; 30937 this.maxBoundaryX = this.wrapperWidth - 8; 30938 } else { 30939 this.minBoundaryX = 0; 30940 this.maxBoundaryX = this.maxPosX; 30941 } 30942 30943 this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); 30944 } 30945 30946 if ( this.options.listenY ) { 30947 this.wrapperHeight = this.wrapper.clientHeight; 30948 if ( this.options.resize ) { 30949 this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); 30950 this.indicatorStyle.height = this.indicatorHeight + 'px'; 30951 } else { 30952 this.indicatorHeight = this.indicator.clientHeight; 30953 } 30954 30955 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 30956 30957 if ( this.options.shrink == 'clip' ) { 30958 this.minBoundaryY = -this.indicatorHeight + 8; 30959 this.maxBoundaryY = this.wrapperHeight - 8; 30960 } else { 30961 this.minBoundaryY = 0; 30962 this.maxBoundaryY = this.maxPosY; 30963 } 30964 30965 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 30966 this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); 30967 } 30968 30969 this.updatePosition(); 30970 }, 30971 30972 updatePosition: function () { 30973 var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, 30974 y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; 30975 30976 if ( !this.options.ignoreBoundaries ) { 30977 if ( x < this.minBoundaryX ) { 30978 if ( this.options.shrink == 'scale' ) { 30979 this.width = Math.max(this.indicatorWidth + x, 8); 30980 this.indicatorStyle.width = this.width + 'px'; 30981 } 30982 x = this.minBoundaryX; 30983 } else if ( x > this.maxBoundaryX ) { 30984 if ( this.options.shrink == 'scale' ) { 30985 this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); 30986 this.indicatorStyle.width = this.width + 'px'; 30987 x = this.maxPosX + this.indicatorWidth - this.width; 30988 } else { 30989 x = this.maxBoundaryX; 30990 } 30991 } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) { 30992 this.width = this.indicatorWidth; 30993 this.indicatorStyle.width = this.width + 'px'; 30994 } 30995 30996 if ( y < this.minBoundaryY ) { 30997 if ( this.options.shrink == 'scale' ) { 30998 this.height = Math.max(this.indicatorHeight + y * 3, 8); 30999 this.indicatorStyle.height = this.height + 'px'; 31000 } 31001 y = this.minBoundaryY; 31002 } else if ( y > this.maxBoundaryY ) { 31003 if ( this.options.shrink == 'scale' ) { 31004 this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); 31005 this.indicatorStyle.height = this.height + 'px'; 31006 y = this.maxPosY + this.indicatorHeight - this.height; 31007 } else { 31008 y = this.maxBoundaryY; 31009 } 31010 } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) { 31011 this.height = this.indicatorHeight; 31012 this.indicatorStyle.height = this.height + 'px'; 31013 } 31014 } 31015 31016 this.x = x; 31017 this.y = y; 31018 31019 if ( this.scroller.options.useTransform ) { 31020 this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ; 31021 } else { 31022 this.indicatorStyle.left = x + 'px'; 31023 this.indicatorStyle.top = y + 'px'; 31024 } 31025 }, 31026 31027 _pos: function (x, y) { 31028 if ( x < 0 ) { 31029 x = 0; 31030 } else if ( x > this.maxPosX ) { 31031 x = this.maxPosX; 31032 } 31033 31034 if ( y < 0 ) { 31035 y = 0; 31036 } else if ( y > this.maxPosY ) { 31037 y = this.maxPosY;
31038 } 31039 31040 x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x; 31041 y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y; 31042 31043 this.scroller.scrollTo(x, y); 31044 }, 31045 31046 fade: function (val, hold) { 31047 if ( hold && !this.visible ) { 31048 return; 31049 } 31050 31051 clearTimeout(this.fadeTimeout); 31052 this.fadeTimeout = null; 31053 31054 var time = val ? 250 : 500, 31055 delay = val ? 0 : 300; 31056 31057 val = val ? '1' : '0'; 31058 31059 this.wrapperStyle[utils.style.transitionDuration] = time + 'ms'; 31060 31061 this.fadeTimeout = setTimeout((function (val) { 31062 this.wrapperStyle.opacity = val; 31063 this.visible = +val; 31064 }).bind(this, val), delay); 31065 } 31066}; 31067 31068IScroll.utils = utils; 31069 31070if ( typeof module != 'undefined' && module.exports ) { 31071 module.exports = IScroll; 31072} else if ( typeof define == 'function' && define.amd ) { 31073 define( function () { return IScroll; } ); 31074} else { 31075 window.IScroll = IScroll; 31076} 31077 31078})(window, document, Math); 31079/*! 31080 * fullPage 2.9.4 31081 * https://github.com/alvarotrigo/fullPage.js 31082 * @license MIT licensed 31083 * 31084 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo 31085 */ 31086(function(global, factory) { 31087 'use strict'; 31088 if (typeof define === 'function' && define.amd) { 31089 define(['jquery'], function($) { 31090 return factory($, global, global.document, global.Math); 31091 }); 31092 } else if (typeof exports === "object" && exports) { 31093 module.exports = factory(require('jquery'), global, global.document, global.Math); 31094 } else { 31095 factory(jQuery, global, global.document, global.Math); 31096 } 31097})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { 31098 'use strict'; 31099 31100 // keeping central set of classnames and selectors 31101 var WRAPPER = 'fullpage-wrapper'; 31102 var WRAPPER_SEL = '.' + WRAPPER; 31103 31104 // slimscroll 31105 var SCROLLABLE = 'fp-scrollable'; 31106 var SCROLLABLE_SEL = '.' + SCROLLABLE; 31107 31108 // util 31109 var RESPONSIVE = 'fp-responsive'; 31110 var NO_TRANSITION = 'fp-notransition'; 31111 var DESTROYED = 'fp-destroyed'; 31112 var ENABLED = 'fp-enabled'; 31113 var VIEWING_PREFIX = 'fp-viewing'; 31114 var ACTIVE = 'active'; 31115 var ACTIVE_SEL = '.' + ACTIVE; 31116 var COMPLETELY = 'fp-completely'; 31117 var COMPLETELY_SEL = '.' + COMPLETELY; 31118 31119 // section 31120 var SECTION_DEFAULT_SEL = '.section'; 31121 var SECTION = 'fp-section'; 31122 var SECTION_SEL = '.' + SECTION; 31123 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 31124 var SECTION_FIRST_SEL = SECTION_SEL + ':first'; 31125 var SECTION_LAST_SEL = SECTION_SEL + ':last'; 31126 var TABLE_CELL = 'fp-tableCell'; 31127 var TABLE_CELL_SEL = '.' + TABLE_CELL; 31128 var AUTO_HEIGHT = 'fp-auto-height'; 31129 var AUTO_HEIGHT_SEL = '.fp-auto-height'; 31130 var NORMAL_SCROLL = 'fp-normal-scroll'; 31131 var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; 31132 31133 // section nav 31134 var SECTION_NAV = 'fp-nav'; 31135 var SECTION_NAV_SEL = '#' + SECTION_NAV; 31136 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 31137 var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; 31138 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; 31139 31140 // slide 31141 var SLIDE_DEFAULT_SEL = '.slide'; 31142 var SLIDE = 'fp-slide'; 31143 var SLIDE_SEL = '.' + SLIDE; 31144 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 31145 var SLIDES_WRAPPER = 'fp-slides'; 31146 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 31147 var SLIDES_CONTAINER = 'fp-slidesContainer'; 31148 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 31149 var TABLE = 'fp-table'; 31150 31151 // slide nav 31152 var SLIDES_NAV = 'fp-slidesNav'; 31153 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 31154 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 31155 var SLIDES_ARROW = 'fp-controlArrow'; 31156 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 31157 var SLIDES_PREV = 'fp-prev'; 31158 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 31159 var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; 31160 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 31161 var SLIDES_NEXT = 'fp-next';
31162 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 31163 var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; 31164 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 31165 31166 var $window = $(window); 31167 var $document = $(document); 31168 31169 // Default options for iScroll.js used when using scrollOverflow 31170 var iscrollOptions = { 31171 scrollbars: true, 31172 mouseWheel: true, 31173 hideScrollbars: false, 31174 fadeScrollbars: false, 31175 disableMouse: true, 31176 interactiveScrollbars: true, 31177 bounce: false, 31178 }; 31179 31180 $.fn.fullpage = function(options) { 31181 //only once my friend! 31182 if($('html').hasClass(ENABLED)){ displayWarnings(); return; } 31183 31184 // common jQuery objects 31185 var $htmlBody = $('html, body'); 31186 var $body = $('body'); 31187 31188 var FP = $.fn.fullpage; 31189 31190 // Creating some defaults, extending them with any options that were provided 31191 options = $.extend({ 31192 //navigation 31193 menu: false, 31194 anchors:[], 31195 lockAnchors: false, 31196 navigation: false, 31197 navigationPosition: 'right', 31198 navigationTooltips: [], 31199 showActiveTooltip: false, 31200 slidesNavigation: false, 31201 slidesNavPosition: 'bottom', 31202 scrollBar: false, 31203 hybrid: false, 31204 31205 //scrolling 31206 css3: true, 31207 scrollingSpeed: 700, 31208 autoScrolling: true, 31209 fitToSection: true, 31210 fitToSectionDelay: 1000, 31211 easing: 'easeInOutCubic', 31212 easingcss3: 'ease', 31213 loopBottom: false, 31214 loopTop: false, 31215 loopHorizontal: true, 31216 continuousVertical: false, 31217 continuousHorizontal: false, 31218 scrollHorizontally: false, 31219 interlockedSlides: false, 31220 dragAndMove: false, 31221 offsetSections: false, 31222 resetSliders: false, 31223 fadingEffect: false, 31224 normalScrollElements: null, 31225 scrollOverflow: false, 31226 scrollOverflowReset: false, 31227 scrollOverflowHandler: iscrollHandler, 31228 scrollOverflowOptions: null, 31229 touchSensitivity: 5, 31230 normalScrollElementTouchThreshold: 5, 31231 bigSectionsDestination: null, 31232 31233 //Accessibility 31234 keyboardScrolling: true, 31235 animateAnchor: true, 31236 recordHistory: true, 31237 31238 //design 31239 controlArrows: true, 31240 controlArrowColor: '#fff', 31241 verticalCentered: true, 31242 sectionsColor : [], 31243 paddingTop: 0, 31244 paddingBottom: 0, 31245 fixedElements: null, 31246 responsive: 0, //backwards compabitility with responsiveWiddth 31247 responsiveWidth: 0, 31248 responsiveHeight: 0, 31249 responsiveSlides: false, 31250 parallax: false, 31251 parallaxOptions: { 31252 type: 'reveal', 31253 percentage: 62, 31254 property: 'translate' 31255 }, 31256 31257 //Custom selectors 31258 sectionSelector: SECTION_DEFAULT_SEL, 31259 slideSelector: SLIDE_DEFAULT_SEL, 31260 31261 //events 31262 afterLoad: null, 31263 onLeave: null, 31264 afterRender: null, 31265 afterResize: null, 31266 afterReBuild: null, 31267 afterSlideLoad: null, 31268 onSlideLeave: null, 31269 afterResponsive: null, 31270 31271 lazyLoading: true 31272 }, options); 31273 31274 //flag to avoid very fast sliding for landscape sliders 31275 var slideMoving = false; 31276 31277 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 31278 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 31279 var container = $(this); 31280 var windowsHeight = $window.height(); 31281 var isResizing = false; 31282 var isWindowFocused = true; 31283 var lastScrolledDestiny; 31284 var lastScrolledSlide; 31285 var canScroll = true; 31286 var scrollings = []; 31287 var controlPressed; 31288 var startingSection; 31289 var isScrollAllowed = {}; 31290 isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; 31291 isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); 31292 var MSPointer = getMSPointer(); 31293 var events = { 31294 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer.move, 31295 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer.down 31296 }; 31297 31298 //cheks for passive event support 31299 //added by Uncode from new fullPage updates 31300 var g_supportsPassive = false;
31301 try { 31302 var opts = Object.defineProperty({}, 'passive', { 31303 get: function() { 31304 g_supportsPassive = true; 31305 } 31306 }); 31307 window.addEventListener("testPassive", null, opts); 31308 window.removeEventListener("testPassive", null, opts); 31309 } catch (e) {} 31310 31311 //timeouts 31312 var resizeId; 31313 var afterSectionLoadsId; 31314 var afterSlideLoadsId; 31315 var scrollId; 31316 var scrollId2; 31317 var keydownId; 31318 var originals = $.extend(true, {}, options); //deep copy 31319 31320 //Uncode addition 31321 var $masthead = $('#masthead'); 31322 var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false; 31323 var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight; 31324 var bodyBorder = UNCODE.bodyBorder; 31325 var adminBarHeight = UNCODE.adminBarHeight; 31326 31327 displayWarnings(); 31328 31329 //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783 31330 iscrollOptions.click = isTouch; // see #2035 31331 31332 //extending iScroll options with the user custom ones 31333 iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions); 31334 31335 //easeInOutCubic animation included in the plugin 31336 $.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;}}); 31337 31338 /** 31339 * Sets the autoScroll option. 31340 * It changes the scroll bar visibility and the history of the site as a result. 31341 */ 31342 function setAutoScrolling(value, type){ 31343 //removing the transformation 31344 if(!value){ 31345 silentScroll(0); 31346 } 31347 31348 setVariableState('autoScrolling', value, type); 31349 31350 var element = $(SECTION_ACTIVE_SEL); 31351 31352 if(options.autoScrolling && !options.scrollBar){ 31353 $htmlBody.css({ 31354 'overflow' : 'hidden !important', 31355 'height' : '100%' 31356 }); 31357 31358 //Uncode addition 31359 //setRecordHistory(originals.recordHistory, 'internal'); 31360 31361 //for IE touch devices 31362 container.css({ 31363 '-ms-touch-action': 'none', 31364 'touch-action': 'none' 31365 }); 31366 31367 if(element.length){ 31368 //moving the container up 31369 silentScroll(element.position().top); 31370 } 31371 31372 }else{ 31373 $htmlBody.css({ 31374 'overflow' : 'visible !important', 31375 'height' : 'initial' 31376 }); 31377 31378 //Uncode addition 31379 //setRecordHistory(false, 'internal'); 31380 31381 //for IE touch devices 31382 container.css({ 31383 '-ms-touch-action': '', 31384 'touch-action': '' 31385 }); 31386 31387 //scrolling the page to the section with no animation 31388 if (element.length) { 31389 $htmlBody.scrollTop(element.position().top); 31390 } 31391 } 31392 } 31393 31394 /** 31395 * Defines wheter to record the history for each hash change in the URL. 31396 */ 31397 function setRecordHistory(value, type){ 31398 setVariableState('recordHistory', value, type); 31399 } 31400 31401 /** 31402 * Defines the scrolling speed 31403 */ 31404 function setScrollingSpeed(value, type){ 31405 setVariableState('scrollingSpeed', value, type); 31406 } 31407 31408 /** 31409 * Sets fitToSection 31410 */ 31411 function setFitToSection(value, type){ 31412 setVariableState('fitToSection', value, type); 31413 } 31414 31415 /** 31416 * Sets lockAnchors 31417 */ 31418 function setLockAnchors(value){ 31419 options.lockAnchors = value; 31420 } 31421 31422 /** 31423 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. 31424 */ 31425 function setMouseWheelScrolling(value){ 31426 if(value){ 31427 addMouseWheelHandler(); 31428 addMiddleWheelHandler(); 31429 }else{ 31430 removeMouseWheelHandler(); 31431 removeMiddleWheelHandler(); 31432 } 31433 } 31434 31435 /** 31436 * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 31437 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 31438 * 31439 * @param directions string containing the direction or directions separated by comma. 31440 */ 31441 function setAllowScrolling(value, directions){ 31442 if(typeof directions !== 'undefined'){ 31443 directions = directions.replace(/ /g,'').split(','); 31444 31445 $.each(directions, function (index, direction){ 31446 setIsScrollAllowed(value, direction, 'm'); 31447 }); 31448 } 31449 else if(value){ 31450 setMouseWheelScrolling(true); 31451 addTouchHandler(); 31452 }else{ 31453 setMouseWheelScrolling(false); 31454 removeTouchHandler(); 31455 } 31456 } 31457 31458 /** 31459 * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys 31460 */ 31461 function setKeyboardScrolling(value, directions){ 31462 if(typeof directions !== 'undefined'){ 31463 directions = directions.replace(/ /g,'').split(','); 31464 31465 $.each(directions, function (index, direction){ 31466 setIsScrollAllowed(value, direction, 'k'); 31467 }); 31468 }else{ 31469 options.keyboardScrolling = value; 31470 } 31471 } 31472 31473 /** 31474 * Moves the page up one section. 31475 */ 31476 function moveSectionUp(){ 31477 var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); 31478 31479 //looping to the bottom if there's no more sections above 31480 if (!prev.length && (options.loopTop || options.continuousVertical)) {
31481 prev = $(SECTION_SEL).last(); 31482 } 31483 31484 if (prev.length) { 31485 scrollPage(prev, null, true); 31486 } 31487 } 31488 31489 /** 31490 * Moves the page down one section. 31491 */ 31492 function moveSectionDown(){ 31493 var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); 31494 31495 //looping to the top if there's no more sections below 31496 if(!next.length && 31497 (options.loopBottom || options.continuousVertical)){ 31498 next = $(SECTION_SEL).first(); 31499 } 31500 31501 if(next.length){ 31502 scrollPage(next, null, false); 31503 } 31504 } 31505 31506 /** 31507 * Moves the page to the given section and slide with no animation. 31508 * Anchors or index positions can be used as params. 31509 */ 31510 function silentMoveTo(sectionAnchor, slideAnchor){ 31511 setScrollingSpeed (0, 'internal'); 31512 moveTo(sectionAnchor, slideAnchor); 31513 setScrollingSpeed (originals.scrollingSpeed, 'internal'); 31514 } 31515 31516 /** 31517 * Moves the page to the given section and slide. 31518 * Anchors or index positions can be used as params. 31519 */ 31520 function moveTo(sectionAnchor, slideAnchor){ 31521 var destiny = getSectionByAnchor(sectionAnchor); 31522 31523 if (typeof slideAnchor !== 'undefined'){ 31524 scrollPageAndSlide(sectionAnchor, slideAnchor); 31525 }else if(destiny.length > 0){ 31526 scrollPage(destiny); 31527 } 31528 } 31529 31530 /** 31531 * Slides right the slider of the active section. 31532 * Optional `section` param. 31533 */ 31534 function moveSlideRight(section){ 31535 moveSlide('right', section); 31536 } 31537 31538 /** 31539 * Slides left the slider of the active section. 31540 * Optional `section` param. 31541 */ 31542 function moveSlideLeft(section){ 31543 moveSlide('left', section); 31544 } 31545 31546 /** 31547 * When resizing is finished, we adjust the slides sizes and positions 31548 */ 31549 function reBuild(resizing){ 31550 if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed 31551 31552 isResizing = true; 31553 31554 windowsHeight = $window.height(); //updating global var 31555 31556 $(SECTION_SEL).each(function(){ 31557 var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); 31558 var slides = $(this).find(SLIDE_SEL); 31559 31560 //adjusting the height of the table-cell for IE and Firefox 31561 if(options.verticalCentered){ 31562 $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); 31563 } 31564 31565 $(this).css('height', windowsHeight + 'px'); 31566 31567 //resizing the scrolling divs 31568 if(options.scrollOverflow){ 31569 if(slides.length){ 31570 slides.each(function(){ 31571 createScrollBar($(this)); 31572 }); 31573 }else{ 31574 createScrollBar($(this)); 31575 } 31576 } 31577 31578 //adjusting the position fo the FULL WIDTH slides... 31579 if (slides.length > 1) { 31580 landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); 31581 } 31582 }); 31583 31584 var activeSection = $(SECTION_ACTIVE_SEL); 31585 var sectionIndex = activeSection.index(SECTION_SEL); 31586 31587 //isn't it the first section? 31588 if(sectionIndex){ 31589 //adjusting the position for the current section 31590 silentMoveTo(sectionIndex + 1); 31591 } 31592 31593 isResizing = false; 31594 // Uncode change 31595 // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); 31596 $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight()); 31597 $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); 31598 } 31599 31600 /** 31601 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 31602 * are smaller than the set limit values. 31603 */ 31604 function setResponsive(active){ 31605 var isResponsive = $body.hasClass(RESPONSIVE); 31606 31607 if(active){ 31608 if(!isResponsive){ 31609 setAutoScrolling(false, 'internal'); 31610 setFitToSection(false, 'internal'); 31611 $(SECTION_NAV_SEL).hide(); 31612 $body.addClass(RESPONSIVE); 31613 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31614 } 31615 } 31616 else if(isResponsive){ 31617 setAutoScrolling(originals.autoScrolling, 'internal'); 31618 setFitToSection(originals.autoScrolling, 'internal'); 31619 $(SECTION_NAV_SEL).show(); 31620 $body.removeClass(RESPONSIVE); 31621 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31622 } 31623 } 31624 31625 if($(this).length){ 31626 //public functions 31627 FP.setAutoScrolling = setAutoScrolling; 31628 FP.setRecordHistory = setRecordHistory; 31629 FP.setScrollingSpeed = setScrollingSpeed; 31630 FP.setFitToSection = setFitToSection; 31631 FP.setLockAnchors = setLockAnchors; 31632 FP.setMouseWheelScrolling = setMouseWheelScrolling; 31633 FP.setAllowScrolling = setAllowScrolling; 31634 FP.setKeyboardScrolling = setKeyboardScrolling; 31635 FP.moveSectionUp = moveSectionUp; 31636 FP.moveSectionDown = moveSectionDown; 31637 FP.silentMoveTo = silentMoveTo; 31638 FP.moveTo = moveTo; 31639 FP.moveSlideRight = moveSlideRight; 31640 FP.moveSlideLeft = moveSlideLeft; 31641 FP.fitToSection = fitToSection; 31642 FP.reBuild = reBuild; 31643 FP.setResponsive = setResponsive; 31644 FP.destroy = destroy; 31645 31646 init(); 31647 31648 bindEvents(); 31649 } 31650
31651 function init(){ 31652 //if css3 is not supported, it will use jQuery animations 31653 if(options.css3){ 31654 options.css3 = support3d(); 31655 } 31656 31657 options.scrollBar = options.scrollBar || options.hybrid; 31658 31659 setOptionsFromDOM(); 31660 prepareDom(); 31661 setAllowScrolling(true); 31662 setAutoScrolling(options.autoScrolling, 'internal'); 31663 responsive(); 31664 31665 //setting the class for the body element 31666 setBodyClass(); 31667 31668 //Uncode addition 31669 // if(document.readyState === 'complete'){ 31670 // scrollToAnchor(); 31671 // } 31672 // $window.on('load', scrollToAnchor); 31673 } 31674 31675 function bindEvents(){ 31676 $window 31677 //when scrolling... 31678 //.on('scroll', scrollHandler) 31679 31680 //detecting any change on the URL to scroll to the given anchor link 31681 //(a way to detect back history button as we play with the hashes on the URL) 31682 .on('hashchange', hashChangeHandler) 31683 31684 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 31685 .blur(blurHandler) 31686 31687 //when resizing the site, we adjust the heights of the sections, slimScroll... 31688 .resize(resizeHandler); 31689 31690 $document 31691 //Sliding with arrow keys, both, vertical and horizontal 31692 .keydown(keydownHandler) 31693 31694 //to prevent scrolling while zooming 31695 .keyup(keyUpHandler) 31696 31697 //Scrolls to the section when clicking the navigation bullet 31698 .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) 31699 31700 //Scrolls the slider to the given slide destination for the given section 31701 .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) 31702 31703 .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); 31704 31705 //Scrolling horizontally when clicking on the slider controls. 31706 $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); 31707 31708 /** 31709 * Applying normalScroll elements. 31710 * Ignoring the scrolls over the specified selectors. 31711 */ 31712 if(options.normalScrollElements){ 31713 $document.on('mouseenter', options.normalScrollElements, function () { 31714 setMouseWheelScrolling(false); 31715 }); 31716 31717 $document.on('mouseleave', options.normalScrollElements, function(){ 31718 setMouseWheelScrolling(true); 31719 }); 31720 } 31721 } 31722 31723 /** 31724 * Setting options from DOM elements if they are not provided. 31725 */ 31726 function setOptionsFromDOM(){ 31727 var sections = container.find(options.sectionSelector); 31728 31729 //no anchors option? Checking for them in the DOM attributes 31730 if(!options.anchors.length){ 31731 options.anchors = sections.filter('[data-anchor]').map(function(){ 31732 return $(this).data('anchor').toString(); 31733 }).get(); 31734 } 31735 31736 //no tooltips option? Checking for them in the DOM attributes 31737 if(!options.navigationTooltips.length){ 31738 options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ 31739 return $(this).data('tooltip').toString(); 31740 }).get(); 31741 } 31742 } 31743 31744 /** 31745 * Works over the DOM structure to set it up for the current fullpage options. 31746 */ 31747 function prepareDom(){ 31748 container.css({ 31749 'height': '100%', 31750 'position': 'relative' 31751 }); 31752 31753 //adding a class to recognize the container internally in the code 31754 container.addClass(WRAPPER); 31755 $('html').addClass(ENABLED); 31756 31757 windowsHeight = $window.height(); 31758 31759 container.removeClass(DESTROYED); //in case it was destroyed before initializing it again 31760 31761 addInternalSelectors(); 31762 31763 //styling the sections / slides / menu 31764 $(SECTION_SEL).each(function(index){ 31765 var section = $(this); 31766 var slides = section.find(SLIDE_SEL); 31767 var numSlides = slides.length; 31768 31769 styleSection(section, index); 31770 styleMenu(section, index); 31771 31772 // if there's any slide 31773 if (numSlides > 0) { 31774 styleSlides(section, slides, numSlides); 31775 }else{ 31776 if(options.verticalCentered){ 31777 addTableClass(section); 31778 } 31779 } 31780 }); 31781 31782 //fixed elements need to be moved out of the plugin container due to problems with CSS3. 31783 if(options.fixedElements && options.css3){ 31784 $(options.fixedElements).appendTo($body); 31785 } 31786 31787 //vertical centered of the navigation + active bullet 31788 if(options.navigation){ 31789 addVerticalNavigation(); 31790 } 31791 31792 enableYoutubeAPI(); 31793 31794 if(options.scrollOverflow){ 31795 if(document.readyState === 'complete'){ 31796 createScrollBarHandler(); 31797 } 31798 //after DOM and images are loaded 31799 $window.on('load', createScrollBarHandler); 31800 }else{ 31801 afterRenderActions(); 31802 } 31803 } 31804 31805 /** 31806 * Styles the horizontal slides for a section. 31807 */ 31808 function styleSlides(section, slides, numSlides){ 31809 var sliderWidth = numSlides * 100; 31810 var slideWidth = 100 / numSlides; 31811 31812 slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />'); 31813 slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />'); 31814 31815 section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); 31816 31817 if(numSlides > 1){ 31818 if(options.controlArrows){ 31819 createSlideArrows(section); 31820 } 31821 31822 if(options.slidesNavigation){ 31823 addSlidesNavigation(section, numSlides); 31824 } 31825 } 31826 31827 slides.each(function(index) { 31828 $(this).css('width', slideWidth + '%'); 31829 31830 if(options.verticalCentered){ 31831 addTableClass($(this)); 31832 } 31833 }); 31834 31835 var startingSlide = section.find(SLIDE_ACTIVE_SEL); 31836 31837 //if the slide won't be an starting point, the default will be the first one 31838 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
31838ide by default. 31839 if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ 31840 silentLandscapeScroll(startingSlide, 'internal'); 31841 }else{ 31842 slides.eq(0).addClass(ACTIVE); 31843 } 31844 } 31845 31846 /** 31847 * Styling vertical sections 31848 */ 31849 function styleSection(section, index){ 31850 //if no active section is defined, the 1st one will be the default one 31851 if(!index && $(SECTION_ACTIVE_SEL).length === 0) { 31852 section.addClass(ACTIVE); 31853 } 31854 startingSection = $(SECTION_ACTIVE_SEL); 31855 31856 section.css('height', windowsHeight + 'px'); 31857 31858 if(options.paddingTop){ 31859 section.css('padding-top', options.paddingTop); 31860 } 31861 31862 if(options.paddingBottom){ 31863 section.css('padding-bottom', options.paddingBottom); 31864 } 31865 31866 if (typeof options.sectionsColor[index] !== 'undefined') { 31867 section.css('background-color', options.sectionsColor[index]); 31868 } 31869 31870 if (typeof options.anchors[index] !== 'undefined') { 31871 section.attr('data-anchor', options.anchors[index]); 31872 } 31873 } 31874 31875 /** 31876 * Sets the data-anchor attributes to the menu elements and activates the current one. 31877 */ 31878 function styleMenu(section, index){ 31879 if (typeof options.anchors[index] !== 'undefined') { 31880 //activating the menu / nav element on load 31881 if(section.hasClass(ACTIVE)){ 31882 activateMenuAndNav(options.anchors[index], index); 31883 } 31884 } 31885 31886 //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 31887 if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ 31888 $(options.menu).appendTo($body); 31889 } 31890 } 31891 31892 /** 31893 * Adds internal classes to be able to provide customizable selectors 31894 * keeping the link with the style sheet. 31895 */ 31896 function addInternalSelectors(){ 31897 container.find(options.sectionSelector).addClass(SECTION); 31898 container.find(options.slideSelector).addClass(SLIDE); 31899 } 31900 31901 /** 31902 * Creates the control arrows for the given section 31903 */ 31904 function createSlideArrows(section){ 31905 section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>'); 31906 31907 if(options.controlArrowColor!='#fff'){ 31908 section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); 31909 section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); 31910 } 31911 31912 if(!options.loopHorizontal){ 31913 section.find(SLIDES_ARROW_PREV_SEL).hide(); 31914 } 31915 } 31916 31917 /** 31918 * Creates a vertical navigation bar. 31919 */ 31920 function addVerticalNavigation(){ 31921 $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>'); 31922 var nav = $(SECTION_NAV_SEL); 31923 31924 nav.addClass(function() { 31925 return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; 31926 }); 31927 31928 for (var i = 0; i < $(SECTION_SEL).length; i++) { 31929 var link = ''; 31930 if (options.anchors.length) { 31931 link = options.anchors[i]; 31932 } 31933 31934 var li = '<li><a href="#' + link + '"><span></span></a>'; 31935 31936 // Only add tooltip if needed (defined by user) 31937 var tooltip = options.navigationTooltips[i]; 31938 31939 if (typeof tooltip !== 'undefined' && tooltip !== '') { 31940 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>'; 31941 } 31942 31943 li += '</li>'; 31944 31945 nav.find('ul').append(li); 31946 } 31947 31948 //centering it vertically 31949 $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px'); 31950 31951 //activating the current active section 31952 $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); 31953 } 31954 31955 /** 31956 * Creates the slim scroll scrollbar for the sections and slides inside them. 31957 */ 31958 function createScrollBarHandler(){ 31959 $(SECTION_SEL).each(function(){ 31960 var slides = $(this).find(SLIDE_SEL); 31961 31962 if(slides.length){ 31963 slides.each(function(){ 31964 createScrollBar($(this)); 31965 }); 31966 }else{ 31967 createScrollBar($(this)); 31968 } 31969 31970 }); 31971 afterRenderActions(); 31972 } 31973 31974 /*
31975 * Enables the Youtube videos API so we can control their flow if necessary. 31976 */ 31977 function enableYoutubeAPI(){ 31978 container.find('iframe[src*="youtube.com/embed/"]').each(function(){ 31979 addURLParam($(this), 'enablejsapi=1'); 31980 }); 31981 } 31982 31983 /** 31984 * Adds a new parameter and its value to the `src` of a given element 31985 */ 31986 function addURLParam(element, newParam){ 31987 var originalSrc = element.attr('src'); 31988 element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam); 31989 } 31990 31991 /* 31992 * Returns the prefix sign to use for a new parameter in an existen URL. 31993 * 31994 * @return {String} ? | & 31995 */ 31996 function getUrlParamSign(url){ 31997 return ( !/\?/.test( url ) ) ? '?' : '&'; 31998 } 31999 32000 /** 32001 * Actions and callbacks to fire afterRender 32002 */ 32003 function afterRenderActions(){ 32004 var section = $(SECTION_ACTIVE_SEL); 32005 32006 section.addClass(COMPLETELY); 32007 32008 if(options.scrollOverflowHandler.afterRender){ 32009 options.scrollOverflowHandler.afterRender(section); 32010 } 32011 lazyLoad(section); 32012 playMedia(section); 32013 options.scrollOverflowHandler.afterLoad(); 32014 32015 if(isDestinyTheStartingSection()){ 32016 $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); 32017 } 32018 32019 // Uncode change 32020 // $.isFunction( options.afterRender ) && options.afterRender.call(container); 32021 $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight()); 32022 } 32023 32024 /** 32025 * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization) 32026 */ 32027 function isDestinyTheStartingSection(){ 32028 var anchors = window.location.hash.replace('#', '').split('/'); 32029 var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0])); 32030 32031 return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index(); 32032 } 32033 32034 32035 var isScrolling = false; 32036 var lastScroll = 0; 32037 32038 //when scrolling... 32039 function scrollHandler(){ 32040 var currentSection; 32041 32042 if(!options.autoScrolling || options.scrollBar){ 32043 var currentScroll = $window.scrollTop(); 32044 var scrollDirection = getScrollDirection(currentScroll); 32045 var visibleSectionIndex = 0; 32046 var screen_mid = currentScroll + ($window.height() / 2.0); 32047 var isAtBottom = $body.height() - $window.height() === currentScroll; 32048 var sections = document.querySelectorAll(SECTION_SEL); 32049 32050 //when using `auto-height` for a small last section it won't be centered in the viewport 32051 if(isAtBottom){ 32052 visibleSectionIndex = sections.length - 1; 32053 } 32054 //is at top? when using `auto-height` for a small first section it won't be centered in the viewport 32055 else if(!currentScroll){ 32056 visibleSectionIndex = 0; 32057 } 32058 32059 //taking the section which is showing more content in the viewport 32060 else{ 32061 for (var i = 0; i < sections.length; ++i) { 32062 var section = sections[i]; 32063 32064 // Pick the the last section which passes the middle line of the screen. 32065 if (section.offsetTop <= screen_mid) 32066 { 32067 visibleSectionIndex = i; 32068 } 32069 } 32070 } 32071 32072 if(isCompletelyInViewPort(scrollDirection)){ 32073 if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ 32074 $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32075 } 32076 } 32077 32078 //geting the last one, the current one on the screen 32079 currentSection = $(sections).eq(visibleSectionIndex); 32080 32081 //setting the visible section as active when manually scrolling 32082 //executing only once the first time we reach the section 32083 if(!currentSection.hasClass(ACTIVE)){ 32084 isScrolling = true; 32085 var leavingSection = $(SECTION_ACTIVE_SEL); 32086 var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; 32087 var yMovement = getYmovement(currentSection); 32088 var anchorLink = currentSection.data('anchor'); 32089 var sectionIndex = currentSection.index(SECTION_SEL) + 1; 32090 var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); 32091 var slideIndex; 32092 var slideAnchorLink; 32093 32094 if(activeSlide.length){ 32095 slideAnchorLink = activeSlide.data('anchor'); 32096 slideIndex = activeSlide.index(); 32097 } 32098 32099 if(canScroll){ 32100 currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32101 32102 $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); 32103 $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); 32104 32105 stopMedia(leavingSection); 32106 lazyLoad(currentSection); 32107 playMedia(currentSection); 32108 32109 activateMenuAndNav(anchorLink, sectionIndex - 1); 32110 32111 if(options.anchors.length){ 32112 //needed to enter in hashChange event when using the menu with anchor links 32113 lastScrolledDestiny = anchorLink; 32114 } 32115 setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); 32116 } 32117 32118 //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 32119 clearTimeout(scrollId); 32120 scrollId = setTimeout(function(){ 32121 isScrolling = false;
32122 }, 100); 32123 } 32124 32125 if(options.fitToSection){ 32126 //for the auto adjust of the viewport to fit a whole section 32127 clearTimeout(scrollId2); 32128 32129 scrollId2 = setTimeout(function(){ 32130 //checking it again in case it changed during the delay 32131 if(options.fitToSection){ 32132 fitToSection(); 32133 } 32134 }, options.fitToSectionDelay); 32135 } 32136 } 32137 } 32138 32139 /** 32140 * Fits the site to the nearest active section 32141 */ 32142 function fitToSection(){ 32143 //checking fitToSection again in case it was set to false before the timeout delay 32144 if(canScroll){ 32145 //allows to scroll to an active section and 32146 //if the section is already active, we prevent firing callbacks 32147 isResizing = true; 32148 32149 scrollPage($(SECTION_ACTIVE_SEL)); 32150 isResizing = false; 32151 } 32152 } 32153 32154 /** 32155 * Determines whether the active section has seen in its whole or not. 32156 */ 32157 function isCompletelyInViewPort(movement){ 32158 var top = $(SECTION_ACTIVE_SEL).position().top; 32159 var bottom = top + $window.height(); 32160 32161 if(movement == 'up'){ 32162 return bottom >= ($window.scrollTop() + $window.height()); 32163 } 32164 return top <= $window.scrollTop(); 32165 } 32166 32167 /** 32168 * Gets the directon of the the scrolling fired by the scroll event. 32169 */ 32170 function getScrollDirection(currentScroll){ 32171 var direction = currentScroll > lastScroll ? 'down' : 'up'; 32172 32173 lastScroll = currentScroll; 32174 32175 //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination 32176 previousDestTop = currentScroll; 32177 32178 return direction; 32179 } 32180 32181 /** 32182 * Determines the way of scrolling up or down: 32183 * by 'automatically' scrolling a section or by using the default and normal scrolling. 32184 */ 32185 function scrolling(type, scrollable){ 32186 if (!isScrollAllowed.m[type]){ 32187 return; 32188 } 32189 var check = (type === 'down') ? 'bottom' : 'top'; 32190 var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp; 32191 32192 if(scrollable.length > 0 ){ 32193 //is the scrollbar at the start/end of the scroll? 32194 if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ 32195 scrollSection(); 32196 }else{ 32197 return true; 32198 } 32199 }else{ 32200 // moved up/down 32201 scrollSection(); 32202 } 32203 } 32204 32205 /* 32206 * Preventing bouncing in iOS #2285 32207 */ 32208 function preventBouncing(event){ 32209 var e = event.originalEvent; 32210 if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){ 32211 //preventing the easing on iOS devices 32212 event.preventDefault(); 32213 } 32214 } 32215 32216 var touchStartY = 0; 32217 var touchStartX = 0; 32218 var touchEndY = 0; 32219 var touchEndX = 0; 32220 32221 /* Detecting touch events 32222 32223 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 32224 * This way, the touchstart and the touch moves shows an small difference between them which is the 32225 * used one to determine the direction. 32226 */ 32227 function touchMoveHandler(event){ 32228 var e = event.originalEvent; 32229 var activeSection = $(e.target).closest(SECTION_SEL); 32230 32231 // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain 32232 if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) { 32233 32234 if(options.autoScrolling){ 32235 //preventing the easing on iOS devices 32236 event.preventDefault(); 32237 } 32238 32239 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32240 var touchEvents = getEventsPage(e); 32241 32242 touchEndY = touchEvents.y; 32243 touchEndX = touchEvents.x; 32244 32245 //if movement in the X axys is greater than in the Y and the currect section has slides... 32246 if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { 32247 32248 //is the movement greater than the minimum resistance to scroll? 32249 if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { 32250 if (touchStartX > touchEndX) { 32251 if(isScrollAllowed.m.right){ 32252 moveSlideRight(activeSection); //next 32253 } 32254 } else { 32255 if(isScrollAllowed.m.left){ 32256 moveSlideLeft(activeSection); //prev 32257 } 32258 } 32259 } 32260 } 32261 32262 //vertical scrolling (only when autoScrolling is enabled) 32263 else if(options.autoScrolling && canScroll){ 32264 32265 //is the movement greater than the minimum resistance to scroll? 32266 if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { 32267 if (touchStartY > touchEndY) { 32268 scrolling('down', scrollable); 32269 } else if (touchEndY > touchStartY) { 32270 scrolling('up', scrollable); 32271 } 32272 } 32273 } 32274 } 32275 } 32276 32277 /** 32278 * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements 32279 * Currently works well for iOS - Android might need some testing 32280 * @param {Element} el target element / jquery selector (in subsequent nodes) 32281 * @param {int} hop current hop compared to options.normalScrollElementTouchThreshold 32282 * @return {boolean} true if there is a match to options.normalScrollElements 32283 */ 32284 function checkParentForNormalScrollElement (el, hop) { 32285 hop = hop || 0; 32286 var parent = $(el).parent(); 32287 32288 if (hop < options.normalScrollElementTouchThreshold && 32289 parent.is(options.normalScrollElements) ) { 32290 return true; 32291 } else if (hop == options.normalScrollElementTouchThreshold) { 32292 return false;
32293 } else { 32294 return checkParentForNormalScrollElement(parent, ++hop); 32295 } 32296 } 32297 32298 /** 32299 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 32300 * this way we make sure that is really a touch event what IE is detecting. 32301 */ 32302 function isReallyTouch(e){ 32303 //if is not IE || IE is detecting `touch` or `pen` 32304 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 32305 } 32306 32307 /** 32308 * Handler for the touch start event. 32309 */ 32310 function touchStartHandler(event){ 32311 var e = event.originalEvent; 32312 32313 //stopping the auto scroll to adjust to a section 32314 if(options.fitToSection){ 32315 $htmlBody.stop(); 32316 } 32317 32318 if(isReallyTouch(e)){ 32319 var touchEvents = getEventsPage(e); 32320 touchStartY = touchEvents.y; 32321 touchStartX = touchEvents.x; 32322 } 32323 } 32324 32325 /** 32326 * Gets the average of the last `number` elements of the given array. 32327 */ 32328 function getAverage(elements, number){ 32329 var sum = 0; 32330 32331 //taking `number` elements from the end to make the average, if there are not enought, 1 32332 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 32333 32334 for(var i = 0; i < lastElements.length; i++){ 32335 sum = sum + lastElements[i]; 32336 } 32337 32338 return Math.ceil(sum/number); 32339 } 32340 32341 /** 32342 * Detecting mousewheel scrolling 32343 * 32344 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 32345 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 32346 */ 32347 var prevTime = new Date().getTime(); 32348 32349 function MouseWheelHandler(e) { 32350 var curTime = new Date().getTime(); 32351 var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); 32352 32353 //autoscrolling and not zooming? 32354 if(options.autoScrolling && !controlPressed && !isNormalScroll){ 32355 // cross-browser wheel delta 32356 e = e || window.event; 32357 var value = e.wheelDelta || -e.deltaY || -e.detail; 32358 var delta = Math.max(-1, Math.min(1, value)); 32359 32360 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 32361 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 32362 32363 //Limiting the array to 150 (lets not waste memory!) 32364 if(scrollings.length > 149){ 32365 scrollings.shift(); 32366 } 32367 32368 //keeping record of the previous scrollings 32369 scrollings.push(Math.abs(value)); 32370 32371 //preventing to scroll the site on mouse wheel when scrollbar is present 32372 if(options.scrollBar){ 32373 e.preventDefault ? e.preventDefault() : e.returnValue = false; 32374 } 32375 32376 var activeSection = $(SECTION_ACTIVE_SEL); 32377 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32378 32379 //time difference between the last scroll and the current one 32380 var timeDiff = curTime-prevTime; 32381 prevTime = curTime; 32382 32383 //haven't they scrolled in a while? 32384 //(enough to be consider a different scrolling action to scroll another section) 32385 if(timeDiff > 200){ 32386 //emptying the array, we dont care about old scrollings for our averages 32387 scrollings = []; 32388 } 32389 32390 if(canScroll){ 32391 var averageEnd = getAverage(scrollings, 10); 32392 var averageMiddle = getAverage(scrollings, 70); 32393 var isAccelerating = averageEnd >= averageMiddle; 32394 32395 //to avoid double swipes... 32396 if(isAccelerating && isScrollingVertically){ 32397 //scrolling down? 32398 if (delta < 0) { 32399 scrolling('down', scrollable); 32400 32401 //scrolling up? 32402 }else { 32403 scrolling('up', scrollable); 32404 } 32405 } 32406 } 32407 32408 return false;
32409 } 32410 32411 if(options.fitToSection){ 32412 //stopping the auto scroll to adjust to a section 32413 $htmlBody.stop(); 32414 } 32415 } 32416 32417 /** 32418 * Slides a slider to the given direction. 32419 * Optional `section` param. 32420 */ 32421 function moveSlide(direction, section){ 32422 var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; 32423 var slides = activeSection.find(SLIDES_WRAPPER_SEL); 32424 var numSlides = slides.find(SLIDE_SEL).length; 32425 32426 // more than one slide needed and nothing should be sliding 32427 if (!slides.length || slideMoving || numSlides < 2) { 32428 return; 32429 } 32430 32431 var currentSlide = slides.find(SLIDE_ACTIVE_SEL); 32432 var destiny = null; 32433 32434 if(direction === 'left'){ 32435 destiny = currentSlide.prev(SLIDE_SEL); 32436 }else{ 32437 destiny = currentSlide.next(SLIDE_SEL); 32438 } 32439 32440 //isn't there a next slide in the secuence? 32441 if(!destiny.length){ 32442 //respect loopHorizontal settin 32443 if (!options.loopHorizontal) return; 32444 32445 if(direction === 'left'){ 32446 destiny = currentSlide.siblings(':last'); 32447 }else{ 32448 destiny = currentSlide.siblings(':first'); 32449 } 32450 } 32451 32452 slideMoving = true; 32453 32454 landscapeScroll(slides, destiny, direction); 32455 } 32456 32457 /** 32458 * Maintains the active slides in the viewport 32459 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 32460 */ 32461 function keepSlidesPosition(){ 32462 $(SLIDE_ACTIVE_SEL).each(function(){ 32463 silentLandscapeScroll($(this), 'internal'); 32464 }); 32465 } 32466 32467 var previousDestTop = 0; 32468 /** 32469 * Returns the destination Y position based on the scrolling direction and 32470 * the height of the section. 32471 */ 32472 function getDestinationPosition(element){ 32473 var elemPosition = element.position(); 32474 32475 //top of the desination will be at the top of the viewport 32476 var position = elemPosition.top; 32477 var isScrollingDown = elemPosition.top > previousDestTop; 32478 var sectionBottom = position - windowsHeight + element.outerHeight(); 32479 var bigSectionsDestination = options.bigSectionsDestination; 32480 32481 //Uncode addition 32482 var containerH = container.outerHeight(); 32483 var containerPosition = container.offset(); 32484 32485 //########### Commented by Uncode - START ########### 32486 //is the destination element bigger than the viewport? 32487 // if(element.outerHeight() > windowsHeight){ 32488 // //scrolling up? 32489 // if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){ 32490 // position = sectionBottom; 32491 // } 32492 // } 32493 32494 // //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 32495 // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ 32496 // //The bottom of the destination will be at the bottom of the viewport 32497 // position = sectionBottom; 32498 // } 32499 //########### Commented by Uncode - END ########### 32500 32501 //Uncode addition 32502 if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') ) 32503 position += 18; 32504 if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) { 32505 position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight; 32506 } 32507 32508 /* 32509 Keeping record of the last scrolled position to determine the scrolling direction. 32510 No conventional methods can be used as the scroll bar might not be present 32511 AND the section might not be active if it is auto-height and didnt reach the middle 32512 of the viewport. 32513 */ 32514 previousDestTop = position; 32515 return position; 32516 } 32517 32518 /** 32519 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 32520 */ 32521 function scrollPage(element, callback, isMovementUp){ 32522 if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function 32523 32524 var dtop = getDestinationPosition(element); 32525 var slideAnchorLink; 32526 var slideIndex; 32527 32528 //local variables 32529 var v = { 32530 element: element, 32531 callback: callback, 32532 isMovementUp: isMovementUp, 32533 dtop: dtop, 32534 yMovement: getYmovement(element), 32535 anchorLink: element.data('anchor'), 32536 sectionIndex: element.index(SECTION_SEL), 32537 activeSlide: element.find(SLIDE_ACTIVE_SEL), 32538 activeSection: $(SECTION_ACTIVE_SEL), 32539 leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, 32540 32541 //caching the value of isResizing at the momment the function is called 32542 //because it will be checked later inside a setTimeout and the value might change 32543 localIsResizing: isResizing 32544 }; 32545 32546 //quiting when destination scroll is the same as the current one 32547 if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } 32548 32549 if(v.activeSlide.length){ 32550 slideAnchorLink = v.activeSlide.data('anchor'); 32551 slideIndex = v.activeSlide.index(); 32552 } 32553 32554 // If continuousVertical && we need to wrap around 32555 if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && 32556 ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or 32557 (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down 32558 32559 v = createInfiniteSections(v); 32560 } 32561 32562 //callback (onLeave) if the site is not just resizing and readjusting the slides 32563 if($.isFunction(options.onLeave) && !v.localIsResizing){ 32564 if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ 32565 return; 32566 } 32567 } 32568 32569 //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one) 32570 if(!v.localIsResizing){ 32571 stopMedia(v.activeSection); 32572 } 32573 32574 options.scrollOverflowHandler.beforeLeave(); 32575 element.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32576 lazyLoad(element); 32577 options.scrollOverflowHandler.onLeave(); 32578 32579 32580 //preventing from activating the MouseWheelHandler event 32581 //more than once if the page is scrolling 32582 canScroll = false;
32583 32584 setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); 32585 32586 performMovement(v); 32587 32588 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 32589 lastScrolledDestiny = v.anchorLink; 32590 32591 //avoid firing it twice (as it does also on scroll) 32592 activateMenuAndNav(v.anchorLink, v.sectionIndex); 32593 } 32594 32595 /** 32596 * Performs the vertical movement (by CSS3 or by jQuery) 32597 */ 32598 function performMovement(v){ 32599 // using CSS3 translate functionality 32600 if (options.css3 && options.autoScrolling && !options.scrollBar) { 32601 32602 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 32603 // that's why we round it to 0. 32604 var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; 32605 transformContainer(translate3d, true); 32606 32607 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 32608 //scrollingSpeed to change in case of using silentMoveTo(); 32609 if(options.scrollingSpeed){ 32610 clearTimeout(afterSectionLoadsId); 32611 afterSectionLoadsId = setTimeout(function () { 32612 afterSectionLoads(v); 32613 }, options.scrollingSpeed); 32614 }else{ 32615 afterSectionLoads(v); 32616 } 32617 } 32618 32619 // using jQuery animate 32620 else{ 32621 var scrollSettings = getScrollSettings(v); 32622 32623 $(scrollSettings.element).animate( 32624 scrollSettings.options, 32625 options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating `html, body` 32626 if(options.scrollBar){ 32627 32628 /* Hack! 32629 The timeout prevents setting the most dominant section in the viewport as "active" when the user 32630 scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. 32631 32632 When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. 32633 */ 32634 setTimeout(function(){ 32635 afterSectionLoads(v); 32636 },30); 32637 }else{ 32638 afterSectionLoads(v); 32639 } 32640 }); 32641 } 32642 } 32643 32644 /** 32645 * Gets the scrolling settings depending on the plugin autoScrolling option 32646 */ 32647 function getScrollSettings(v){ 32648 var scroll = {}; 32649 32650 if(options.autoScrolling && !options.scrollBar){ 32651 scroll.options = { 'top': -v.dtop}; 32652 scroll.element = WRAPPER_SEL; 32653 }else{ 32654 scroll.options = { 'scrollTop': v.dtop}; 32655 scroll.element = 'html, body'; 32656 } 32657 32658 return scroll; 32659 } 32660 32661 /** 32662 * Adds sections before or after the current one to create the infinite effect. 32663 */ 32664 function createInfiniteSections(v){ 32665 // Scrolling down 32666 if (!v.isMovementUp) { 32667 // Move all previous sections to after the active section 32668 $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); 32669 } 32670 else { // Scrolling up 32671 // Move all next sections to before the active section 32672 $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); 32673 } 32674 32675 // Maintain the displayed position (now that we changed the element order) 32676 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32677 32678 // Maintain the active slides visible in the viewport 32679 keepSlidesPosition(); 32680 32681 // save for later the elements that still need to be reordered 32682 v.wrapAroundElements = v.activeSection; 32683 32684 // Recalculate animation variables 32685 v.dtop = v.element.position().top; 32686 v.yMovement = getYmovement(v.element); 32687 32688 return v; 32689 } 32690 32691 /** 32692 * Fix section order after continuousVertical changes have been animated 32693 */ 32694 function continuousVerticalFixSectionOrder (v) {
32695 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 32696 // finish moving the elements around so the direct navigation will function more simply 32697 if (!v.wrapAroundElements || !v.wrapAroundElements.length) { 32698 return; 32699 } 32700 32701 if (v.isMovementUp) { 32702 $(SECTION_FIRST_SEL).before(v.wrapAroundElements); 32703 } 32704 else { 32705 $(SECTION_LAST_SEL).after(v.wrapAroundElements); 32706 } 32707 32708 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32709 32710 // Maintain the active slides visible in the viewport 32711 keepSlidesPosition(); 32712 } 32713 32714 32715 /** 32716 * Actions to do once the section is loaded. 32717 */ 32718 function afterSectionLoads (v){ 32719 continuousVerticalFixSectionOrder(v); 32720 32721 //callback (afterLoad) if the site is not just resizing and readjusting the slides 32722 $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); 32723 options.scrollOverflowHandler.afterLoad(); 32724 32725 if(!v.localIsResizing){ 32726 playMedia(v.element); 32727 } 32728 32729 v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32730 32731 canScroll = true; 32732 32733 $.isFunction(v.callback) && v.callback.call(this); 32734 } 32735 32736 /** 32737 * Sets the value for the given attribute from the `data-` attribute with the same suffix 32738 * ie: data-srcset ==> srcset | data-src ==> src 32739 */ 32740 function setSrc(element, attribute){ 32741 element 32742 .attr(attribute, element.data(attribute)) 32743 .removeAttr('data-' + attribute); 32744 } 32745 32746 /** 32747 * Lazy loads image, video and audio elements. 32748 */ 32749 function lazyLoad(destiny){ 32750 if (!options.lazyLoading){ 32751 return; 32752 } 32753 32754 var panel = getSlideOrSection(destiny); 32755 var element; 32756 32757 panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 32758 element = $(this); 32759 32760 $.each(['src', 'srcset'], function(index, type){ 32761 var attribute = element.attr('data-' + type); 32762 if(typeof attribute !== 'undefined' && attribute){ 32763 setSrc(element, type); 32764 } 32765 }); 32766 32767 if(element.is('source')){ 32768 element.closest('video').get(0).load(); 32769 } 32770 }); 32771 } 32772 32773 /** 32774 * Plays video and audio elements. 32775 */ 32776 function playMedia(destiny){ 32777 var panel = getSlideOrSection(destiny); 32778 32779 //playing HTML5 media elements 32780 panel.find('video, audio').each(function(){ 32781 var element = $(this).get(0); 32782 32783 if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) { 32784 element.play(); 32785 } 32786 }); 32787 32788 //youtube videos 32789 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32790 var element = $(this).get(0); 32791 32792 if ( element.hasAttribute('data-autoplay') ){ 32793 playYoutube(element); 32794 } 32795 32796 //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. 32797 element.onload = function() { 32798 if ( element.hasAttribute('data-autoplay') ){ 32799 playYoutube(element); 32800 } 32801 }; 32802 }); 32803 } 32804 32805 /** 32806 * Plays a youtube video 32807 */ 32808 function playYoutube(element){ 32809 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 32810 } 32811 32812 /** 32813 * Stops video and audio elements. 32814 */ 32815 function stopMedia(destiny){ 32816 var panel = getSlideOrSection(destiny); 32817 32818 //stopping HTML5 media elements 32819 panel.find('video, audio').each(function(){ 32820 var element = $(this).get(0); 32821 32822 if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { 32823 element.pause(); 32824 } 32825 }); 32826 32827 //youtube videos 32828 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32829 var element = $(this).get(0); 32830 32831 if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ 32832 $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); 32833 } 32834 }); 32835 } 32836 32837 /** 32838 * Gets the active slide (or section) for the given section 32839 */ 32840 function getSlideOrSection(destiny){ 32841 var slide = destiny.find(SLIDE_ACTIVE_SEL); 32842 if( slide.length ) { 32843 destiny = $(slide); 32844 } 32845 32846 return destiny; 32847 } 32848 32849 /**
32850 * Scrolls to the anchor in the URL when loading the site 32851 */ 32852 function scrollToAnchor(){ 32853 //getting the anchor link in the URL and deleting the `#` 32854 var value = window.location.hash.replace('#', '').split('/'); 32855 var sectionAnchor = decodeURIComponent(value[0]); 32856 var slideAnchor = decodeURIComponent(value[1]); 32857 32858 if(sectionAnchor){ //if theres any # 32859 if(options.animateAnchor){ 32860 scrollPageAndSlide(sectionAnchor, slideAnchor); 32861 }else{ 32862 silentMoveTo(sectionAnchor, slideAnchor); 32863 } 32864 } 32865 } 32866 32867 /** 32868 * Detecting any change on the URL to scroll to the given anchor link 32869 * (a way to detect back history button as we play with the hashes on the URL) 32870 */ 32871 function hashChangeHandler(){ 32872 if(!isScrolling && !options.lockAnchors){ 32873 var value = window.location.hash.replace('#', '').split('/'); 32874 var sectionAnchor = decodeURIComponent(value[0]); 32875 var slideAnchor = decodeURIComponent(value[1]); 32876 32877 //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 32878 var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); 32879 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving); 32880 32881 32882 if(sectionAnchor.length){ 32883 /*in order to call scrollpage() only once for each destination at a time 32884 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 32885 event is fired on every scroll too.*/ 32886 if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor )) { 32887 scrollPageAndSlide(sectionAnchor, slideAnchor); 32888 } 32889 } 32890 } 32891 } 32892 32893 //Sliding with arrow keys, both, vertical and horizontal 32894 function keydownHandler(e) { 32895 32896 clearTimeout(keydownId); 32897 32898 var activeElement = $(':focus'); 32899 32900 if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 32901 activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && 32902 options.keyboardScrolling && options.autoScrolling){ 32903 var keyCode = e.which; 32904 32905 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 32906 var keyControls = [40, 38, 32, 33, 34]; 32907 if($.inArray(keyCode, keyControls) > -1){ 32908 e.preventDefault(); 32909 } 32910 32911 controlPressed = e.ctrlKey; 32912 32913 keydownId = setTimeout(function(){ 32914 onkeydown(e); 32915 },150); 32916 } 32917 } 32918 32919 function tooltipTextHandler(){ 32920 $(this).prev().trigger('click'); 32921 } 32922 32923 //to prevent scrolling while zooming 32924 function keyUpHandler(e){ 32925 if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox 32926 controlPressed = e.ctrlKey; 32927 } 32928 } 32929 32930 //binding the mousemove when the mouse's middle button is released 32931 function mouseDownHandler(e){ 32932 //middle button 32933 if (e.which == 2){ 32934 oldPageY = e.pageY; 32935 container.on('mousemove', mouseMoveHandler); 32936 } 32937 } 32938 32939 //unbinding the mousemove when the mouse's middle button is released 32940 function mouseUpHandler(e){ 32941 //middle button 32942 if (e.which == 2){ 32943 container.off('mousemove'); 32944 } 32945 } 32946 32947 //Scrolling horizontally when clicking on the slider controls. 32948 function slideArrowHandler(){ 32949 var section = $(this).closest(SECTION_SEL); 32950 32951 if ($(this).hasClass(SLIDES_PREV)) { 32952 if(isScrollAllowed.m.left){ 32953 moveSlideLeft(section); 32954 } 32955 } else { 32956 if(isScrollAllowed.m.right){ 32957 moveSlideRight(section); 32958 } 32959 } 32960 } 32961 32962 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 32963 function blurHandler(){ 32964 isWindowFocused = false;
32965 controlPressed = false; 32966 } 32967 32968 //Scrolls to the section when clicking the navigation bullet 32969 function sectionBulletHandler(e){ 32970 e.preventDefault(); 32971 var index = $(this).parent().index(); 32972 scrollPage($(SECTION_SEL).eq(index)); 32973 } 32974 32975 //Scrolls the slider to the given slide destination for the given section 32976 function slideBulletHandler(e){ 32977 e.preventDefault(); 32978 var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); 32979 var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); 32980 32981 landscapeScroll(slides, destiny); 32982 } 32983 32984 /** 32985 * Keydown event 32986 */ 32987 function onkeydown(e){ 32988 var shiftPressed = e.shiftKey; 32989 32990 //do nothing if we can not scroll or we are not using horizotnal key arrows. 32991 if(!canScroll && [37,39].indexOf(e.which) < 0){ 32992 return; 32993 } 32994 32995 switch (e.which) { 32996 //up 32997 case 38: 32998 case 33: 32999 if(isScrollAllowed.k.up){ 33000 moveSectionUp(); 33001 } 33002 break; 33003 33004 //down 33005 case 32: //spacebar 33006 if(shiftPressed && isScrollAllowed.k.up){ 33007 moveSectionUp(); 33008 break; 33009 } 33010 /* falls through */ 33011 case 40: 33012 case 34: 33013 if(isScrollAllowed.k.down){ 33014 moveSectionDown(); 33015 } 33016 break; 33017 33018 //Home 33019 case 36: 33020 if(isScrollAllowed.k.up){ 33021 moveTo(1); 33022 } 33023 break; 33024 33025 //End 33026 case 35: 33027 if(isScrollAllowed.k.down){ 33028 moveTo( $(SECTION_SEL).length ); 33029 } 33030 break; 33031 33032 //left 33033 case 37: 33034 if(isScrollAllowed.k.left){ 33035 moveSlideLeft(); 33036 } 33037 break; 33038 33039 //right 33040 case 39: 33041 if(isScrollAllowed.k.right){ 33042 moveSlideRight(); 33043 } 33044 break; 33045 33046 default: 33047 return; // exit this handler for other keys 33048 } 33049 } 33050 33051 /** 33052 * Detecting the direction of the mouse movement. 33053 * Used only for the middle button of the mouse. 33054 */ 33055 var oldPageY = 0; 33056 function mouseMoveHandler(e){ 33057 if(canScroll){ 33058 // moving up 33059 if (e.pageY < oldPageY && isScrollAllowed.m.up){ 33060 moveSectionUp(); 33061 } 33062 33063 // moving down 33064 else if(e.pageY > oldPageY && isScrollAllowed.m.down){ 33065 moveSectionDown(); 33066 } 33067 } 33068 oldPageY = e.pageY; 33069 } 33070 33071 /** 33072 * Scrolls horizontal sliders. 33073 */ 33074 function landscapeScroll(slides, destiny, direction){ 33075 var section = slides.closest(SECTION_SEL); 33076 var v = { 33077 slides: slides, 33078 destiny: destiny, 33079 direction: direction, 33080 destinyPos: destiny.position(), 33081 slideIndex: destiny.index(), 33082 section: section, 33083 sectionIndex: section.index(SECTION_SEL), 33084 anchorLink: section.data('anchor'), 33085 slidesNav: section.find(SLIDES_NAV_SEL), 33086 slideAnchor: getAnchor(destiny), 33087 prevSlide: section.find(SLIDE_ACTIVE_SEL), 33088 prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(), 33089 33090 //caching the value of isResizing at the momment the function is called 33091 //because it will be checked later inside a setTimeout and the value might change 33092 localIsResizing: isResizing 33093 }; 33094 v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); 33095 v.direction = v.direction ? v.direction : v.xMovement; 33096 33097 //important!! Only do it when not resizing 33098 if(!v.localIsResizing){ 33099 //preventing from scrolling to the next/prev section when using scrollHorizontally 33100 canScroll = false;
33101 } 33102 33103 if(options.onSlideLeave){ 33104 33105 //if the site is not just resizing and readjusting the slides 33106 if(!v.localIsResizing && v.xMovement!=='none'){ 33107 if($.isFunction( options.onSlideLeave )){ 33108 if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){ 33109 slideMoving = false; 33110 return; 33111 } 33112 } 33113 } 33114 } 33115 33116 destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); 33117 33118 if(!v.localIsResizing){ 33119 stopMedia(v.prevSlide); 33120 lazyLoad(destiny); 33121 } 33122 33123 if(!options.loopHorizontal && options.controlArrows){ 33124 //hidding it for the fist slide, showing for the rest 33125 section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0); 33126 33127 //hidding it for the last slide, showing for the rest 33128 section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); 33129 } 33130 33131 //only changing the URL if the slides are in the current section (not for resize re-adjusting) 33132 if(section.hasClass(ACTIVE) && !v.localIsResizing){ 33133 setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex); 33134 } 33135 33136 performHorizontalMove(slides, v, true); 33137 } 33138 33139 33140 function afterSlideLoads(v){ 33141 activeSlidesNavigation(v.slidesNav, v.slideIndex); 33142 33143 //if the site is not just resizing and readjusting the slides 33144 if(!v.localIsResizing){ 33145 $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex); 33146 33147 //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally 33148 //and to prevent double scroll right after a windows resize 33149 canScroll = true; 33150 33151 playMedia(v.destiny); 33152 } 33153 33154 //letting them slide again 33155 slideMoving = false; 33156 } 33157 33158 /** 33159 * Performs the horizontal movement. (CSS3 or jQuery) 33160 * 33161 * @param fireCallback {Bool} - determines whether or not to fire the callback 33162 */ 33163 function performHorizontalMove(slides, v, fireCallback){ 33164 var destinyPos = v.destinyPos; 33165 33166 if(options.css3){ 33167 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 33168 33169 addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v); 33170 33171 afterSlideLoadsId = setTimeout(function(){ 33172 fireCallback && afterSlideLoads(v); 33173 }, options.scrollingSpeed, options.easing); 33174 }else{ 33175 slides.animate({ 33176 scrollLeft : Math.round(destinyPos.left) 33177 }, options.scrollingSpeed, options.easing, function() { 33178 33179 fireCallback && afterSlideLoads(v); 33180 }); 33181 } 33182 } 33183 33184 /** 33185 * Sets the state for the horizontal bullet navigations. 33186 */ 33187 function activeSlidesNavigation(slidesNav, slideIndex){ 33188 slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); 33189 slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); 33190 } 33191 33192 var previousHeight = windowsHeight; 33193 33194 //when resizing the site, we adjust the heights of the sections, slimScroll... 33195 function resizeHandler(){ 33196 //checking if it needs to get responsive 33197 responsive(); 33198 33199 // rebuild immediately on touch devices 33200 if (isTouchDevice) { 33201 var activeElement = $(document.activeElement); 33202 33203 //if the keyboard is NOT visible 33204 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 33205 var currentHeight = $window.height(); 33206 33207 //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) 33208 if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 33209 reBuild(true); 33210 previousHeight = currentHeight; 33211 } 33212 } 33213 }else{ 33214 //in order to call the functions only when the resize is finished 33215 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 33216 clearTimeout(resizeId); 33217 33218 resizeId = setTimeout(function(){ 33219 reBuild(true); 33220 }, 350); 33221 } 33222 } 33223 33224 /** 33225 * Checks if the site needs to get responsive and disables autoScrolling if so. 33226 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 33227 */ 33228 function responsive(){ 33229 var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity 33230 var heightLimit = options.responsiveHeight; 33231 33232 //only calculating what we need. Remember its called on the resize event. 33233 var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; 33234 var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; 33235 33236 if(widthLimit && heightLimit){ 33237 setResponsive(isBreakingPointWidth || isBreakingPointHeight); 33238 } 33239 else if(widthLimit){ 33240 setResponsive(isBreakingPointWidth); 33241 } 33242 else if(heightLimit){ 33243 setResponsive(isBreakingPointHeight); 33244 } 33245 } 33246 33247 /** 33248 * Adds transition animations for the given element 33249 */ 33250 function addAnimation(container, element){ 33251 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 33252 33253 container.removeClass(NO_TRANSITION); 33254 return container.css({
33255 '-webkit-transition': transition, 33256 'transition': transition 33257 }); 33258 } 33259 33260 /** 33261 * Remove transition animations for the given element 33262 */ 33263 function removeAnimation(element){ 33264 return element.addClass(NO_TRANSITION); 33265 } 33266 33267 /** 33268 * Activating the vertical navigation bullets according to the given slide name. 33269 */ 33270 function activateNavDots(name, sectionIndex){ 33271 if(options.navigation){ 33272 $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); 33273 if(name){ 33274 $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); 33275 }else{ 33276 $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); 33277 } 33278 } 33279 } 33280 33281 /** 33282 * Activating the website main menu elements according to the given slide name. 33283 */ 33284 function activateMenuElement(name){ 33285 if(options.menu){ 33286 $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); 33287 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); 33288 } 33289 } 33290 33291 /** 33292 * Sets to active the current menu and vertical nav items. 33293 */ 33294 function activateMenuAndNav(anchor, index){ 33295 activateMenuElement(anchor); 33296 activateNavDots(anchor, index); 33297 } 33298 33299 /** 33300 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 33301 * from the current section. 33302 */ 33303 function getYmovement(destiny){ 33304 var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); 33305 var toIndex = destiny.index(SECTION_SEL); 33306 if( fromIndex == toIndex){ 33307 return 'none'; 33308 } 33309 if(fromIndex > toIndex){ 33310 return 'up'; 33311 } 33312 return 'down'; 33313 } 33314 33315 /** 33316 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 33317 * from the current slide. 33318 */ 33319 function getXmovement(fromIndex, toIndex){ 33320 if( fromIndex == toIndex){ 33321 return 'none'; 33322 } 33323 if(fromIndex > toIndex){ 33324 return 'left'; 33325 } 33326 return 'right'; 33327 } 33328 33329 /** 33330 * Checks if the element needs scrollbar and if the user wants to apply it. 33331 * If so it creates it. 33332 * 33333 * @param {Object} element jQuery object of the section or slide 33334 */ 33335 function createScrollBar(element){ 33336 //User doesn't want scrollbar here? Sayonara baby! 33337 if(element.hasClass('fp-noscroll')) return; 33338 33339 //needed to make `scrollHeight` work under Opera 12 33340 element.css('overflow', 'hidden'); 33341 33342 var scrollOverflowHandler = options.scrollOverflowHandler; 33343 var wrap = scrollOverflowHandler.wrapContent(); 33344 //in case element is a slide 33345 var section = element.closest(SECTION_SEL); 33346 var scrollable = scrollOverflowHandler.scrollable(element); 33347 var contentHeight; 33348 33349 //if there was scroll, the contentHeight will be the one in the scrollable section 33350 if(scrollable.length){ 33351 contentHeight = scrollOverflowHandler.scrollHeight(element); 33352 }else{ 33353 contentHeight = element.get(0).scrollHeight; 33354 if(options.verticalCentered){ 33355 contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight; 33356 } 33357 } 33358 33359 var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top')); 33360 33361 //needs scroll? 33362 if ( contentHeight > scrollHeight) { 33363 //did we already have an scrollbar ? Updating it 33364 if(scrollable.length){ 33365 scrollOverflowHandler.update(element, scrollHeight); 33366 } 33367 //creating the scrolling 33368 else{ 33369 if(options.verticalCentered){ 33370 element.find(TABLE_CELL_SEL).wrapInner(wrap); 33371 }else{ 33372 element.wrapInner(wrap); 33373 } 33374 scrollOverflowHandler.create(element, scrollHeight); 33375 } 33376 } 33377 //removing the scrolling when it is not necessary anymore 33378 else{ 33379 scrollOverflowHandler.remove(element); 33380 } 33381 33382 //undo 33383 element.css('overflow', ''); 33384 } 33385 33386 function addTableClass(element){ 33387 //In case we are styling for the 2nd time as in with reponsiveSlides 33388 if(!element.hasClass(TABLE)){ 33389 element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 33390 } 33391 } 33392 33393 function getTableHeight(element){ 33394 var sectionHeight = windowsHeight; 33395 33396 if(options.paddingTop || options.paddingBottom){ 33397 var section = element; 33398 if(!section.hasClass(SECTION)){ 33399 section = element.closest(SECTION_SEL); 33400 } 33401 33402 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 33403 sectionHeight = (windowsHeight - paddings); 33404 } 33405 33406 return sectionHeight; 33407 } 33408 33409 /** 33410 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 33411 */ 33412 function transformContainer(translate3d, animated){ 33413 if(animated){ 33414 addAnimation(container); 33415 }else{ 33416 removeAnimation(container); 33417 } 33418 33419 container.css(getTransforms(translate3d)); 33420 33421 //syncronously removing the class after the animation has been applied. 33422 setTimeout(function(){ 33423 container.removeClass(NO_TRANSITION); 33424 },10); 33425 } 33426 33427 /** 33428 * Gets a section by its anchor / index 33429 */ 33430 function getSectionByAnchor(sectionAnchor){ 33431 if(!sectionAnchor) return []; 33432 33433 var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); 33434 if(!section.length){ 33435 section = $(SECTION_SEL).eq( sectionAnchor -1); 33436 } 33437 33438 return section; 33439 } 33440 33441 /** 33442 * Gets a slide inside a given section by its anchor / index 33443 */ 33444 function getSlideByAnchor(slideAnchor, section){ 33445 var slides = section.find(SLIDES_WRAPPER_SEL); 33446 var slide = slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]'); 33447
33448 if(!slide.length){ 33449 slide = slides.find(SLIDE_SEL).eq(slideAnchor); 33450 } 33451 33452 return slide; 33453 } 33454 33455 /** 33456 * Scrolls to the given section and slide anchors 33457 */ 33458 function scrollPageAndSlide(destiny, slide){ 33459 var section = getSectionByAnchor(destiny); 33460 33461 //do nothing if there's no section with the given anchor name 33462 if(!section.length) return; 33463 33464 //default slide 33465 if (typeof slide === 'undefined') { 33466 slide = 0; 33467 } 33468 33469 //we need to scroll to the section and then to the slide 33470 if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ 33471 scrollPage(section, function(){ 33472 scrollSlider(section, slide); 33473 }); 33474 } 33475 //if we were already in the section 33476 else{ 33477 scrollSlider(section, slide); 33478 } 33479 } 33480 33481 /** 33482 * Scrolls the slider to the given slide destination for the given section 33483 */ 33484 function scrollSlider(section, slideAnchor){ 33485 if(typeof slideAnchor !== 'undefined'){ 33486 var slides = section.find(SLIDES_WRAPPER_SEL); 33487 var destiny = getSlideByAnchor(slideAnchor, section); 33488 33489 if(destiny.length){ 33490 landscapeScroll(slides, destiny); 33491 } 33492 } 33493 } 33494 33495 /** 33496 * Creates a landscape navigation bar with dots for horizontal sliders. 33497 */ 33498 function addSlidesNavigation(section, numSlides){ 33499 section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>'); 33500 var nav = section.find(SLIDES_NAV_SEL); 33501 33502 //top or bottom 33503 nav.addClass(options.slidesNavPosition); 33504 33505 for(var i=0; i< numSlides; i++){ 33506 nav.find('ul').append('<li><a href="#"><span></span></a></li>'); 33507 } 33508 33509 //centering it 33510 nav.css('margin-left', '-' + (nav.width()/2) + 'px'); 33511 33512 nav.find('li').first().find('a').addClass(ACTIVE); 33513 } 33514 33515 33516 /** 33517 * Sets the state of the website depending on the active section/slide. 33518 * It changes the URL hash when needed and updates the body class. 33519 */ 33520 function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ 33521 var sectionHash = ''; 33522 33523 if(options.anchors.length && !options.lockAnchors){ 33524 33525 //isn't it the first slide? 33526 if(slideIndex){ 33527 if(typeof anchorLink !== 'undefined'){ 33528 sectionHash = anchorLink; 33529 } 33530 33531 //slide without anchor link? We take the index instead. 33532 if(typeof slideAnchor === 'undefined'){ 33533 slideAnchor = slideIndex; 33534 } 33535 33536 lastScrolledSlide = slideAnchor; 33537 setUrlHash(sectionHash + '/' + slideAnchor); 33538 33539 //first slide won't have slide anchor, just the section one 33540 }else if(typeof slideIndex !== 'undefined'){ 33541 lastScrolledSlide = slideAnchor; 33542 setUrlHash(anchorLink); 33543 } 33544 33545 //section without slides 33546 else{ 33547 setUrlHash(anchorLink); 33548 } 33549 } 33550 33551 setBodyClass(); 33552 } 33553 33554 /** 33555 * Sets the URL hash. 33556 */ 33557 function setUrlHash(url){ 33558 //Uncode addition 33559 if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer ) 33560 return false; 33561 33562 if(options.recordHistory){ 33563 location.hash = url; 33564 }else{ 33565 //Uncode addition 33566 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 33567 // if(isTouchDevice || isTouch){ 33568 // window.history.replaceState(undefined, undefined, '#' + url); 33569 // }else{ 33570 // var baseUrl = window.location.href.split('#')[0]; 33571 // window.location.replace( baseUrl + '#' + url ); 33572 // } 33573 return false;
33574 } 33575 } 33576 33577 /** 33578 * Gets the anchor for the given slide / section. Its index will be used if there's none. 33579 */ 33580 function getAnchor(element){ 33581 var anchor = element.data('anchor'); 33582 var index = element.index(); 33583 33584 //Slide without anchor link? We take the index instead. 33585 if(typeof anchor === 'undefined'){ 33586 anchor = index; 33587 } 33588 33589 return anchor; 33590 } 33591 33592 /** 33593 * Sets a class for the body of the page depending on the active section / slide 33594 */ 33595 function setBodyClass(){ 33596 var section = $(SECTION_ACTIVE_SEL); 33597 var slide = section.find(SLIDE_ACTIVE_SEL); 33598 33599 var sectionAnchor = getAnchor(section); 33600 var slideAnchor = getAnchor(slide); 33601 33602 var text = String(sectionAnchor); 33603 33604 if(slide.length){ 33605 text = text + '-' + slideAnchor; 33606 } 33607 33608 //changing slash for dash to make it a valid CSS style 33609 text = text.replace('/', '-').replace('#',''); 33610 33611 //removing previous anchor classes 33612 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 33613 $body[0].className = $body[0].className.replace(classRe, ''); 33614 33615 //adding the current anchor 33616 $body.addClass(VIEWING_PREFIX + '-' + text); 33617 } 33618 33619 /** 33620 * Checks for translate3d support 33621 * @return boolean 33622 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 33623 */ 33624 function support3d() { 33625 var el = document.createElement('p'), 33626 has3d, 33627 transforms = { 33628 'webkitTransform':'-webkit-transform', 33629 'OTransform':'-o-transform', 33630 'msTransform':'-ms-transform', 33631 'MozTransform':'-moz-transform', 33632 'transform':'transform' 33633 }; 33634 33635 // Add it to the body to get the computed style. 33636 document.body.insertBefore(el, null); 33637 33638 for (var t in transforms) { 33639 if (el.style[t] !== undefined) { 33640 el.style[t] = 'translate3d(1px,1px,1px)'; 33641 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 33642 } 33643 } 33644 33645 document.body.removeChild(el); 33646 33647 return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); 33648 } 33649 33650 /** 33651 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 33652 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 33653 */ 33654 function removeMouseWheelHandler(){ 33655 if (document.addEventListener) { 33656 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 33657 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 33658 document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 33659 } else { 33660 document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 33661 } 33662 } 33663 33664 /** 33665 * Adds the auto scrolling action for the mouse wheel and trackpad. 33666 * After this function is called, the mousewheel and trackpad movements will scroll through sections 33667 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 33668 */ 33669 function addMouseWheelHandler(){ 33670 var prefix = ''; 33671 var _addEventListener; 33672 33673 if (window.addEventListener){ 33674 _addEventListener = "addEventListener"; 33675 }else{ 33676 _addEventListener = "attachEvent"; 33677 prefix = 'on'; 33678 } 33679 33680 // detect available wheel event 33681 var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 33682 document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 33683 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 33684 var passiveEvent = g_supportsPassive ? {passive: false }
33684: false; 33685 33686 33687 if(support == 'DOMMouseScroll'){ 33688 document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent); 33689 } 33690 33691 //handle MozMousePixelScroll in older Firefox 33692 else{ 33693 document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent); 33694 } 33695 } 33696 33697 /** 33698 * Binding the mousemove when the mouse's middle button is pressed 33699 */ 33700 function addMiddleWheelHandler(){ 33701 container 33702 .on('mousedown', mouseDownHandler) 33703 .on('mouseup', mouseUpHandler); 33704 } 33705 33706 /** 33707 * Unbinding the mousemove when the mouse's middle button is released 33708 */ 33709 function removeMiddleWheelHandler(){ 33710 container 33711 .off('mousedown', mouseDownHandler) 33712 .off('mouseup', mouseUpHandler); 33713 } 33714 33715 /** 33716 * Adds the possibility to auto scroll through sections on touch devices. 33717 */ 33718 function addTouchHandler(){ 33719 if(isTouchDevice || isTouch){ 33720 if(options.autoScrolling){ 33721 $body.off(events.touchmove).on(events.touchmove, preventBouncing); 33722 } 33723 33724 $(WRAPPER_SEL) 33725 .off(events.touchstart).on(events.touchstart, touchStartHandler) 33726 .off(events.touchmove).on(events.touchmove, touchMoveHandler); 33727 } 33728 } 33729 33730 /** 33731 * Removes the auto scrolling for touch devices. 33732 */ 33733 function removeTouchHandler(){ 33734 if(isTouchDevice || isTouch){ 33735 $(WRAPPER_SEL) 33736 .off(events.touchstart) 33737 .off(events.touchmove); 33738 } 33739 } 33740 33741 /* 33742 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11) 33743 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 33744 */ 33745 function getMSPointer(){ 33746 var pointer; 33747 33748 //IE >= 11 & rest of browsers 33749 if(window.PointerEvent){ 33750 pointer = { down: 'pointerdown', move: 'pointermove'}; 33751 } 33752 33753 //IE < 11 33754 else{ 33755 pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; 33756 } 33757 33758 return pointer; 33759 } 33760 33761 /** 33762 * Gets the pageX and pageY properties depending on the browser. 33763 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 33764 */ 33765 function getEventsPage(e){ 33766 var events = []; 33767 33768 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 33769 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 33770 33771 //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 33772 if(isTouch && isReallyTouch(e) && options.scrollBar){ 33773 events.y = e.touches[0].pageY; 33774 events.x = e.touches[0].pageX; 33775 } 33776 33777 return events; 33778 } 33779 33780 /** 33781 * Slides silently (with no animation) the active slider to the given slide. 33782 * @param noCallback {bool} true or defined -> no callbacks 33783 */ 33784 function silentLandscapeScroll(activeSlide, noCallbacks){ 33785 setScrollingSpeed (0, 'internal'); 33786 33787 if(typeof noCallbacks !== 'undefined'){ 33788 //preventing firing callbacks afterSlideLoad etc. 33789 isResizing = true; 33790 } 33791 33792 landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); 33793 33794 if(typeof noCallbacks !== 'undefined'){ 33795 isResizing = false; 33796 } 33797 33798 setScrollingSpeed(originals.scrollingSpeed, 'internal'); 33799 } 33800 33801 /** 33802 * Scrolls silently (with no animation) the page to the given Y position. 33803 */ 33804 function silentScroll(top){ 33805 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 33806 // that's why we round it to 0. 33807 var roundedTop = Math.round(top); 33808 33809 if (options.css3 && options.autoScrolling && !options.scrollBar){ 33810 var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; 33811 transformContainer(translate3d, false); 33812 } 33813 else if(options.autoScrolling && !options.scrollBar){ 33814 container.css('top', -roundedTop); 33815 } 33816 else{ 33817 $htmlBody.scrollTop(roundedTop); 33818 } 33819 } 33820 33821 /** 33822 * Returns the cross-browser transform string. 33823 */ 33824 function getTransforms(translate3d){ 33825 return {
33826 '-webkit-transform': translate3d, 33827 '-moz-transform': translate3d, 33828 '-ms-transform':translate3d, 33829 'transform': translate3d 33830 }; 33831 } 33832 33833 /** 33834 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 33835 * @type m (mouse) or k (keyboard) 33836 */ 33837 function setIsScrollAllowed(value, direction, type){ 33838 switch (direction){ 33839 case 'up': isScrollAllowed[type].up = value; break; 33840 case 'down': isScrollAllowed[type].down = value; break; 33841 case 'left': isScrollAllowed[type].left = value; break; 33842 case 'right': isScrollAllowed[type].right = value; break; 33843 case 'all': 33844 if(type == 'm'){ 33845 setAllowScrolling(value); 33846 }else{ 33847 setKeyboardScrolling(value); 33848 } 33849 } 33850 } 33851 33852 /* 33853 * Destroys fullpage.js plugin events and optinally its html markup and styles 33854 */ 33855 function destroy(all){ 33856 setAutoScrolling(false, 'internal'); 33857 setAllowScrolling(false); 33858 setKeyboardScrolling(false); 33859 container.addClass(DESTROYED); 33860 33861 clearTimeout(afterSlideLoadsId); 33862 clearTimeout(afterSectionLoadsId); 33863 clearTimeout(resizeId); 33864 clearTimeout(scrollId); 33865 clearTimeout(scrollId2); 33866 33867 $window 33868 .off('scroll', scrollHandler) 33869 .off('hashchange', hashChangeHandler) 33870 .off('resize', resizeHandler); 33871 33872 $document 33873 .off('click touchstart', SECTION_NAV_SEL + ' a') 33874 .off('mouseenter', SECTION_NAV_SEL + ' li') 33875 .off('mouseleave', SECTION_NAV_SEL + ' li') 33876 .off('click touchstart', SLIDES_NAV_LINK_SEL) 33877 .off('mouseover', options.normalScrollElements) 33878 .off('mouseout', options.normalScrollElements); 33879 33880 $(SECTION_SEL) 33881 .off('click touchstart', SLIDES_ARROW_SEL); 33882 33883 clearTimeout(afterSlideLoadsId); 33884 clearTimeout(afterSectionLoadsId); 33885 33886 //lets make a mess! 33887 if(all){ 33888 destroyStructure(); 33889 } 33890 } 33891 33892 /* 33893 * Removes inline styles added by fullpage.js 33894 */ 33895 function destroyStructure(){ 33896 //reseting the `top` or `translate` properties to 0 33897 silentScroll(0); 33898 33899 //loading all the lazy load content 33900 container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 33901 setSrc($(this), 'src'); 33902 }); 33903 33904 container.find('img[data-srcset]').each(function(){ 33905 setSrc($(this), 'srcset'); 33906 }); 33907 33908 $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); 33909 33910 //removing inline styles 33911 $(SECTION_SEL).css( { 33912 'height': '', 33913 'background-color' : '', 33914 'padding': '' 33915 }); 33916 33917 $(SLIDE_SEL).css( { 33918 'width': '' 33919 }); 33920 33921 container.css({ 33922 'height': '', 33923 'position': '', 33924 '-ms-touch-action': '', 33925 'touch-action': '' 33926 }); 33927 33928 $htmlBody.css({ 33929 'overflow': '', 33930 'height': '' 33931 }); 33932 33933 // remove .fp-enabled class 33934 $('html').removeClass(ENABLED); 33935 33936 // remove .fp-responsive class 33937 $body.removeClass(RESPONSIVE); 33938 33939 // remove all of the .fp-viewing- classes 33940 $.each($body.get(0).className.split(/\s+/), function (index, className) { 33941 if (className.indexOf(VIEWING_PREFIX) === 0) { 33942 $body.removeClass(className); 33943 } 33944 }); 33945 33946 //removing added classes 33947 $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ 33948 options.scrollOverflowHandler.remove($(this)); 33949 $(this).removeClass(TABLE + ' ' + ACTIVE); 33950 }); 33951 33952 removeAnimation(container); 33953 33954 //Unwrapping content 33955 container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ 33956 //unwrap not being use in case there's no child element inside and its just text 33957 $(this).replaceWith(this.childNodes); 33958 }); 33959 33960 //removing the applied transition from the fullpage wrapper 33961 container.css({
33962 '-webkit-transition': 'none', 33963 'transition': 'none' 33964 }); 33965 33966 //scrolling the page to the top with no animation 33967 $htmlBody.scrollTop(0); 33968 33969 //removing selectors 33970 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 33971 $.each(usedSelectors, function(index, value){ 33972 $('.' + value).removeClass(value); 33973 }); 33974 } 33975 33976 /* 33977 * Sets the state for a variable with multiple states (original, and temporal) 33978 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 33979 * This function is used to keep track of both states, the original and the temporal one. 33980 * If type is not 'internal', then we assume the user is globally changing the variable. 33981 */ 33982 function setVariableState(variable, value, type){ 33983 options[variable] = value; 33984 if(type !== 'internal'){ 33985 originals[variable] = value; 33986 } 33987 } 33988 33989 /** 33990 * Displays warnings 33991 */ 33992 function displayWarnings(){ 33993 var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax']; 33994 //UNCODE.addition 33995 // if($('html').hasClass(ENABLED)){ 33996 // showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 33997 // return; 33998 // } 33999 34000 // Disable mutually exclusive settings 34001 //UNCODE.addition 34002 // if (options.continuousVertical && 34003 // (options.loopTop || options.loopBottom)) { 34004 // options.continuousVertical = false;
34005 // showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34006 // } 34007 34008 // if(options.scrollBar && options.scrollOverflow){ 34009 // showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); 34010 // } 34011 34012 // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){ 34013 // options.continuousVertical = false; 34014 // showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34015 // } 34016 34017 //using extensions? Wrong file! 34018 $.each(extensions, function(index, extension){ 34019 //is the option set to true? 34020 if(options[extension]){ 34021 showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension); 34022 } 34023 }); 34024 34025 //anchors can not have the same value as any element ID or NAME 34026 $.each(options.anchors, function(index, name){ 34027 34028 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 34029 var nameAttr = $document.find('[name]').filter(function() { 34030 return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); 34031 }); 34032 34033 var idAttr = $document.find('[id]').filter(function() { 34034 return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); 34035 }); 34036 34037 if(idAttr.length || nameAttr.length ){ 34038 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); 34039 idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); 34040 nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); 34041 } 34042 }); 34043 } 34044 34045 /** 34046 * Shows a message in the console of the given type. 34047 */ 34048 function showError(type, text){ 34049 console && console[type] && console[type]('fullPage: ' + text); 34050 } 34051 34052 }; //end of $.fn.fullpage 34053 34054 if(typeof IScroll !== 'undefined'){ 34055 /* 34056 * Turns iScroll `mousewheel` option off dynamically 34057 * https://github.com/cubiq/iscroll/issues/1036 34058 */ 34059 IScroll.prototype.wheelOn = function () { 34060 this.wrapper.addEventListener('wheel', this); 34061 this.wrapper.addEventListener('mousewheel', this); 34062 this.wrapper.addEventListener('DOMMouseScroll', this); 34063 }; 34064 34065 /* 34066 * Turns iScroll `mousewheel` option on dynamically 34067 * https://github.com/cubiq/iscroll/issues/1036 34068 */ 34069 IScroll.prototype.wheelOff = function () { 34070 this.wrapper.removeEventListener('wheel', this); 34071 this.wrapper.removeEventListener('mousewheel', this); 34072 this.wrapper.removeEventListener('DOMMouseScroll', this); 34073 }; 34074 } 34075 34076 /** 34077 * An object to handle overflow scrolling. 34078 * This uses jquery.slimScroll to accomplish overflow scrolling. 34079 * It is possible to pass in an alternate scrollOverflowHandler 34080 * to the fullpage.js option that implements the same functions 34081 * as this handler. 34082 * 34083 * @type {Object} 34084 */ 34085 var iscrollHandler = { 34086 refreshId: null, 34087 iScrollInstances: [], 34088 34089 // Enables or disables the mouse wheel for the active section or all slides in it 34090 toggleWheel: function(value){ 34091 var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL); 34092 scrollable.each(function(){ 34093 var iScrollInstance = $(this).data('iscrollInstance'); 34094 if(typeof iScrollInstance !== 'undefined' && iScrollInstance){ 34095 if(value){ 34096 iScrollInstance.wheelOn(); 34097 } 34098 else{ 34099 iScrollInstance.wheelOff(); 34100 } 34101 } 34102 }); 34103 }, 34104 34105 /** 34106 * Turns off iScroll for the destination section. 34107 * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
34108 * scroll the destination section/slide before the sections animations ends. 34109 */ 34110 onLeave: function(){ 34111 iscrollHandler.toggleWheel(false); 34112 }, 34113 34114 // Turns off iScroll for the leaving section 34115 beforeLeave: function(){ 34116 iscrollHandler.onLeave() 34117 }, 34118 34119 // Turns on iScroll on section load 34120 afterLoad: function(){ 34121 iscrollHandler.toggleWheel(true); 34122 }, 34123 34124 /** 34125 * Called when overflow scrolling is needed for a section. 34126 * 34127 * @param {Object} element jQuery object containing current section 34128 * @param {Number} scrollHeight Current window height in pixels 34129 */ 34130 create: function(element, scrollHeight) { 34131 var scrollable = element.find(SCROLLABLE_SEL); 34132 34133 scrollable.height(scrollHeight); 34134 scrollable.each(function() { 34135 var $this = $(this); 34136 var iScrollInstance = $this.data('iscrollInstance'); 34137 if (iScrollInstance) { 34138 $.each(iscrollHandler.iScrollInstances, function(){ 34139 $(this).destroy(); 34140 }); 34141 } 34142 34143 iScrollInstance = new IScroll($this.get(0), iscrollOptions); 34144 iscrollHandler.iScrollInstances.push(iScrollInstance); 34145 34146 //off by default until the section gets active 34147 iScrollInstance.wheelOff(); 34148 34149 $this.data('iscrollInstance', iScrollInstance); 34150 }); 34151 }, 34152 34153 /** 34154 * Return a boolean depending on whether the scrollable element is a 34155 * the end or at the start of the scrolling depending on the given type. 34156 * 34157 * @param {String} type Either 'top' or 'bottom' 34158 * @param {Object} scrollable jQuery object for the scrollable element 34159 * @return {Boolean} 34160 */ 34161 isScrolled: function(type, scrollable) { 34162 var scroller = scrollable.data('iscrollInstance'); 34163 34164 //no scroller? 34165 if (!scroller) { 34166 return true; 34167 } 34168 34169 //Uncode addition 34170 var uncode_body_borders = parseFloat($('.body-borders').attr('data-border')) || 0; 34171 //End Uncode addition 34172 34173 if (type === 'top') { 34174 return scroller.y >= 0 && !scrollable.scrollTop(); 34175 } else if (type === 'bottom') { 34176 //Uncode change 34177 // return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34178 return (0 - scroller.y) + scrollable.scrollTop() + 1 + ( uncode_body_borders * 2 ) + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34179 //End Uncode change 34180 } 34181 }, 34182 34183 /** 34184 * Returns the scrollable element for the given section. 34185 * If there are landscape slides, will only return a scrollable element 34186 * if it is in the active slide. 34187 * 34188 * @param {Object} activeSection jQuery object containing current section 34189 * @return {Boolean} 34190 */ 34191 scrollable: function(activeSection){ 34192 // if there are landscape slides, we check if the scrolling bar is in the current one or not 34193 if (activeSection.find(SLIDES_WRAPPER_SEL).length) { 34194 return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL); 34195 } 34196 return activeSection.find(SCROLLABLE_SEL); 34197 }, 34198 34199 /** 34200 * Returns the scroll height of the wrapped content. 34201 * If this is larger than the window height minus section padding, 34202 * overflow scrolling is needed. 34203 * 34204 * @param {Object} element jQuery object containing current section 34205 * @return {Number} 34206 */ 34207 scrollHeight: function(element) { 34208 return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight; 34209 }, 34210 34211 /** 34212 * Called when overflow scrolling is no longer needed for a section. 34213 * 34214 * @param {Object}
34214 element jQuery object containing current section 34215 */ 34216 remove: function(element) { 34217 var scrollable = element.find(SCROLLABLE_SEL); 34218 if (scrollable.length) { 34219 var iScrollInstance = scrollable.data('iscrollInstance'); 34220 iScrollInstance.destroy(); 34221 34222 scrollable.data('iscrollInstance', null); 34223 } 34224 element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap(); 34225 }, 34226 34227 /** 34228 * Called when overflow scrolling has already been setup but the 34229 * window height has potentially changed. 34230 * 34231 * @param {Object} element jQuery object containing current section 34232 * @param {Number} scrollHeight Current window height in pixels 34233 */ 34234 update: function(element, scrollHeight) { 34235 //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a 34236 //short period of time. 34237 //it also comes on handy because iScroll requires the use of timeout when using `refresh`. 34238 clearTimeout(iscrollHandler.refreshId); 34239 iscrollHandler.refreshId = setTimeout(function(){ 34240 $.each(iscrollHandler.iScrollInstances, function(){ 34241 $(this).get(0).refresh(); 34242 }); 34243 }, 150); 34244 34245 //updating the wrappers height 34246 element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px'); 34247 }, 34248 34249 /** 34250 * Called to get any additional elements needed to wrap the section 34251 * content in order to facilitate overflow scrolling. 34252 * 34253 * @return {String|Object} Can be a string containing HTML, 34254 * a DOM element, or jQuery object. 34255 */ 34256 wrapContent: function() { 34257 return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>'; 34258 } 34259 }; 34260}); 34261 34262(function (global, factory) { 34263 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 34264 typeof define === 'function' && define.amd ? define(['exports'], factory) : 34265 (global = global || self, factory(global.window = global.window || {})); 34266}(this, (function (exports) { 'use strict'; 34267 34268 /*! 34269 * ScrollTrigger 3.8.0 34270 * https://greensock.com 34271 * 34272 * @license Copyright 2008-2021, GreenSock. All rights reserved. 34273 * Subject to the terms at https://greensock.com/standard-license or for 34274 * Club GreenSock members, the agreement issued with that membership. 34275 * @author: Jack Doyle, [email protected] 34276 */ 34277 var gsap, 34278 _coreInitted, 34279 _win, 34280 _doc, 34281 _docEl, 34282 _body, 34283 _root, 34284 _resizeDelay, 34285 _raf, 34286 _request, 34287 _toArray, 34288 _clamp, 34289 _time2, 34290 _syncInterval, 34291 _refreshing, 34292 _pointerIsDown, 34293 _transformProp, 34294 _i, 34295 _prevWidth, 34296 _prevHeight, 34297 _autoRefresh, 34298 _sort, 34299 _suppressOverwrites, 34300 _ignoreResize, 34301 _limitCallbacks, 34302 _startup = 1, 34303 _proxies = [], 34304 _scrollers = [], 34305 _getTime = Date.now, 34306 _time1 = _getTime(), 34307 _lastScrollTime = 0, 34308 _enabled = 1, 34309 _passThrough = function _passThrough(v) { 34310 return v; 34311 }, 34312 _getTarget = function _getTarget(t) { 34313 return _toArray(t)[0] || (_isString(t) ? console.warn("Element not found:", t) : null); 34314 }, 34315 _round = function _round(value) { 34316 return Math.round(value * 100000) / 100000 || 0; 34317 }, 34318 _windowExists = function _windowExists() { 34319 return typeof window !== "undefined"; 34320 }, 34321 _getGSAP = function _getGSAP() { 34322 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 34323 }, 34324 _isViewport = function _isViewport(e) { 34325 return !!~_root.indexOf(e); 34326 }, 34327 _getProxyProp = function _getProxyProp(element, property) { 34328 return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; 34329 }, 34330 _getScrollFunc = function _getScrollFunc(element, _ref) { 34331 var s = _ref.s, 34332 sc = _ref.sc; 34333 34334 var i = _scrollers.indexOf(element), 34335 offset = sc === _vertical.sc ? 1 : 2; 34336 34337 !~i && (i = _scrollers.push(element) - 1); 34338 return _scrollers[i + offset] || (_scrollers[i + offset] = _getProxyProp(element, s) || (_isViewport(element) ? sc : function (value) { 34339 return arguments.length ? element[s] = value : element[s]; 34340 })); 34341 }, 34342 _getBoundsFunc = function _getBoundsFunc(element) { 34343 return _getProxyProp(element, "getBoundingClientRect") || (_isViewport(element) ? function () { 34344 _winOffsets.width = _win.innerWidth; 34345 _winOffsets.height = _win.innerHeight; 34346 return _winOffsets; 34347 } : function () { 34348 return _getBounds(element); 34349 }); 34350 }, 34351 _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref2) { 34352 var d = _ref2.d, 34353 d2 = _ref2.d2, 34354 a = _ref2.a; 34355 return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () { 34356 return a()[d]; 34357 } : function () { 34358 return (isViewport ? _win["inner" + d2] : scroller["client" + d2]) || 0; 34359 }; 34360 }, 34361 _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) { 34362 return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () { 34363 return _winOffsets; 34364 }; 34365 }, 34366 _maxScroll = function _maxScroll(element, _ref3) { 34367 var s = _ref3.s, 34368 d2 = _ref3.d2, 34369 d = _ref3.d, 34370 a = _ref3.a; 34371 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]; 34372 }, 34373 _iterateAutoRefresh = function _iterateAutoRefresh(func, events) { 34374 for (var i = 0; i < _autoRefresh.length; i += 3) {
vendor: 5,689 bytes, lines 34375-34579
34375 (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]); 34376 } 34377 }, 34378 _isString = function _isString(value) { 34379 return typeof value === "string"; 34380 }, 34381 _isFunction = function _isFunction(value) { 34382 return typeof value === "function"; 34383 }, 34384 _isNumber = function _isNumber(value) { 34385 return typeof value === "number"; 34386 }, 34387 _isObject = function _isObject(value) { 34388 return typeof value === "object"; 34389 }, 34390 _callIfFunc = function _callIfFunc(value) { 34391 return _isFunction(value) && value(); 34392 }, 34393 _combineFunc = function _combineFunc(f1, f2) { 34394 return function () { 34395 var result1 = _callIfFunc(f1), 34396 result2 = _callIfFunc(f2); 34397 34398 return function () { 34399 _callIfFunc(result1); 34400 34401 _callIfFunc(result2); 34402 }; 34403 }; 34404 }, 34405 _endAnimation = function _endAnimation(animation, reversed, pause) { 34406 return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause(); 34407 }, 34408 _callback = function _callback(self, func) { 34409 var result = func(self); 34410 result && result.totalTime && (self.callbackAnimation = result); 34411 }, 34412 _abs = Math.abs, 34413 _scrollLeft = "scrollLeft", 34414 _scrollTop = "scrollTop", 34415 _left = "left", 34416 _top = "top", 34417 _right = "right", 34418 _bottom = "bottom", 34419 _width = "width", 34420 _height = "height", 34421 _Right = "Right", 34422 _Left = "Left", 34423 _Top = "Top", 34424 _Bottom = "Bottom", 34425 _padding = "padding", 34426 _margin = "margin", 34427 _Width = "Width", 34428 _Height = "Height", 34429 _px = "px", 34430 _horizontal = { 34431 s: _scrollLeft, 34432 p: _left, 34433 p2: _Left, 34434 os: _right, 34435 os2: _Right, 34436 d: _width, 34437 d2: _Width, 34438 a: "x", 34439 sc: function sc(value) { 34440 return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; 34441 } 34442 }, 34443 _vertical = { 34444 s: _scrollTop, 34445 p: _top, 34446 p2: _Top, 34447 os: _bottom, 34448 os2: _Bottom, 34449 d: _height, 34450 d2: _Height, 34451 a: "y", 34452 op: _horizontal, 34453 sc: function sc(value) { 34454 return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; 34455 } 34456 }, 34457 _getComputedStyle = function _getComputedStyle(element) { 34458 return _win.getComputedStyle(element); 34459 }, 34460 _makePositionable = function _makePositionable(element) { 34461 var position = _getComputedStyle(element).position; 34462 34463 element.style.position = position === "absolute" || position === "fixed" ? position : "relative"; 34464 }, 34465 _setDefaults = function _setDefaults(obj, defaults) { 34466 for (var p in defaults) { 34467 p in obj || (obj[p] = defaults[p]); 34468 } 34469 34470 return obj; 34471 }, 34472 _getBounds = function _getBounds(element, withoutTransforms) { 34473 var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap.to(element, { 34474 x: 0, 34475 y: 0, 34476 xPercent: 0, 34477 yPercent: 0, 34478 rotation: 0, 34479 rotationX: 0, 34480 rotationY: 0, 34481 scale: 1, 34482 skewX: 0, 34483 skewY: 0 34484 }).progress(1), 34485 bounds = element.getBoundingClientRect(); 34486 tween && tween.progress(0).kill(); 34487 return bounds; 34488 }, 34489 _getSize = function _getSize(element, _ref4) { 34490 var d2 = _ref4.d2; 34491 return element["offset" + d2] || element["client" + d2] || 0; 34492 }, 34493 _getLabelRatioArray = function _getLabelRatioArray(timeline) { 34494 var a = [], 34495 labels = timeline.labels, 34496 duration = timeline.duration(), 34497 p; 34498 34499 for (p in labels) { 34500 a.push(labels[p] / duration); 34501 } 34502 34503 return a; 34504 }, 34505 _getClosestLabel = function _getClosestLabel(animation) { 34506 return function (value) { 34507 return gsap.utils.snap(_getLabelRatioArray(animation), value); 34508 }; 34509 }, 34510 _snapDirectional = function _snapDirectional(snapIncrementOrArray) { 34511 var snap = gsap.utils.snap(snapIncrementOrArray), 34512 a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) { 34513 return a - b; 34514 }); 34515 return a ? function (value, direction) { 34516 var i; 34517 34518 if (!direction) { 34519 return snap(value); 34520 } 34521 34522 if (direction > 0) { 34523 value -= 1e-4; 34524 34525 for (i = 0; i < a.length; i++) { 34526 if (a[i] >= value) { 34527 return a[i]; 34528 } 34529 } 34530 34531 return a[i - 1]; 34532 } else { 34533 i = a.length; 34534 value += 1e-4; 34535 34536 while (i--) { 34537 if (a[i] <= value) { 34538 return a[i]; 34539 } 34540 } 34541 } 34542 34543 return a[0]; 34544 } : function (value, direction) { 34545 var snapped = snap(value); 34546 return !direction || Math.abs(snapped - value) < 0.001 || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray); 34547 }; 34548 }, 34549 _getLabelAtDirection = function _getLabelAtDirection(timeline) { 34550 return function (value, st) { 34551 return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction); 34552 }; 34553 }, 34554 _multiListener = function _multiListener(func, element, types, callback) { 34555 return types.split(",").forEach(function (type) { 34556 return func(element, type, callback); 34557 }); 34558 }, 34559 _addListener = function _addListener(element, type, func) { 34560 return element.addEventListener(type, func, { 34561 passive: true 34562 }); 34563 }, 34564 _removeListener = function _removeListener(element, type, func) { 34565 return element.removeEventListener(type, func); 34566 }, 34567 _markerDefaults = { 34568 startColor: "green", 34569 endColor: "red", 34570 indent: 0, 34571 fontSize: "16px", 34572 fontWeight: "normal" 34573 }, 34574 _defaults = { 34575 toggleActions: "play", 34576 anticipatePin: 0 34577 }, 34578 _keywords = { 34579 top: 0,
34580 left: 0, 34581 center: 0.5, 34582 bottom: 1, 34583 right: 1 34584 }, 34585 _offsetToPx = function _offsetToPx(value, size) { 34586 if (_isString(value)) { 34587 var eqIndex = value.indexOf("="), 34588 relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0; 34589 34590 if (~eqIndex) { 34591 value.indexOf("%") > eqIndex && (relative *= size / 100); 34592 value = value.substr(0, eqIndex - 1); 34593 } 34594 34595 value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0); 34596 } 34597 34598 return value; 34599 }, 34600 _createMarker = function _createMarker(type, name, container, direction, _ref5, offset, matchWidthEl, containerAnimation) { 34601 var startColor = _ref5.startColor, 34602 endColor = _ref5.endColor, 34603 fontSize = _ref5.fontSize, 34604 indent = _ref5.indent, 34605 fontWeight = _ref5.fontWeight; 34606 34607 var e = _doc.createElement("div"), 34608 useFixedPosition = _isViewport(container) || _getProxyProp(container, "pinType") === "fixed", 34609 isScroller = type.indexOf("scroller") !== -1, 34610 parent = useFixedPosition ? _body : container, 34611 isStart = type.indexOf("start") !== -1, 34612 color = isStart ? startColor : endColor, 34613 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;"; 34614 34615 css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;"); 34616 (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;"); 34617 matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;"); 34618 e._isStart = isStart; 34619 e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : "")); 34620 e.style.cssText = css; 34621 e.innerText = name || name === 0 ? type + "-" + name : type; 34622 parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e); 34623 e._offset = e["offset" + direction.op.d2]; 34624 34625 _positionMarker(e, 0, direction, isStart); 34626 34627 return e; 34628 }, 34629 _positionMarker = function _positionMarker(marker, start, direction, flipped) { 34630 var vars = { 34631 display: "block" 34632 }, 34633 side = direction[flipped ? "os2" : "p2"], 34634 oppositeSide = direction[flipped ? "p2" : "os2"]; 34635 marker._isFlipped = flipped; 34636 vars[direction.a + "Percent"] = flipped ? -100 : 0; 34637 vars[direction.a] = flipped ? "1px" : 0; 34638 vars["border" + side + _Width] = 1; 34639 vars["border" + oppositeSide + _Width] = 0; 34640 vars[direction.p] = start + "px"; 34641 gsap.set(marker, vars); 34642 }, 34643 _triggers = [], 34644 _ids = {}, 34645 _sync = function _sync() { 34646 return _getTime() - _lastScrollTime > 20 && _updateAll(); 34647 }, 34648 _onScroll = function _onScroll() { 34649 var time = _getTime(); 34650 34651 if (_lastScrollTime !== time) { 34652 _updateAll(); 34653 34654 _lastScrollTime || _dispatch("scrollStart"); 34655 _lastScrollTime = time; 34656 } else if (!_request) { 34657 _request = _raf(_updateAll); 34658 } 34659 }, 34660 _onResize = function _onResize() { 34661 return !_refreshing && !_ignoreResize && !_doc.fullscreenElement && _resizeDelay.restart(true); 34662 }, 34663 _listeners = {}, 34664 _emptyArray = [], 34665 _media = [], 34666 _creatingMedia, 34667 _lastMediaTick, 34668 _onMediaChange = function _onMediaChange(e) { 34669 var tick = gsap.ticker.frame, 34670 matches = [], 34671 i = 0, 34672 index; 34673 34674 if (_lastMediaTick !== tick || _startup) { 34675 _revertAll(); 34676 34677 for (; i < _media.length; i += 4) { 34678 index = _win.matchMedia(_media[i]).matches; 34679 34680 if (index !== _media[i + 3]) { 34681 _media[i + 3] = index; 34682 index ? matches.push(i) : _revertAll(1, _media[i]) || _isFunction(_media[i + 2]) && _media[i + 2](); 34683 } 34684 } 34685 34686 _revertRecorded(); 34687 34688 for (i = 0; i < matches.length; i++) { 34689 index = matches[i]; 34690 _creatingMedia = _media[index]; 34691 _media[index + 2] = _media[index + 1](e); 34692 } 34693 34694 _creatingMedia = 0; 34695 _coreInitted && _refreshAll(0, 1); 34696 _lastMediaTick = tick; 34697 34698 _dispatch("matchMedia"); 34699 } 34700 }, 34701 _softRefresh = function _softRefresh() { 34702 return _removeListener(ScrollTrigger, "scrollEnd", _softRefresh) || _refreshAll(true); 34703 }, 34704 _dispatch = function _dispatch(type) { 34705 return _listeners[type] && _listeners[type].map(function (f) { 34706 return f(); 34707 }) || _emptyArray; 34708 }, 34709 _savedStyles = [], 34710 _revertRecorded = function _revertRecorded(media) { 34711 for (var i = 0; i < _savedStyles.length; i += 5) { 34712 if (!media || _savedStyles[i + 4] === media) { 34713 _savedStyles[i].style.cssText = _savedStyles[i + 1]; 34714 _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || ""); 34715 _savedStyles[i + 3].uncache = 1; 34716 } 34717 } 34718 }, 34719 _revertAll = function _revertAll(kill, media) { 34720 var trigger; 34721 34722 for (_i = 0; _i < _triggers.length; _i++) { 34723 trigger = _triggers[_i]; 34724 34725 if (!media || trigger.media === media) { 34726 if (kill) { 34727 trigger.kill(1); 34728 } else { 34729 trigger.revert(); 34730 } 34731 } 34732 } 34733 34734 media && _revertRecorded(media); 34735 media || _dispatch("revert"); 34736 }, 34737 _clearScrollMemory = function _clearScrollMemory() {
vendor: 10,266 bytes, lines 34738-35072
34738 return _scrollers.forEach(function (obj) { 34739 return typeof obj === "function" && (obj.rec = 0); 34740 }); 34741 }, 34742 _refreshingAll, 34743 _refreshAll = function _refreshAll(force, skipRevert) { 34744 if (_lastScrollTime && !force) { 34745 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 34746 34747 return; 34748 } 34749 34750 _refreshingAll = true; 34751 34752 var refreshInits = _dispatch("refreshInit"); 34753 34754 _sort && ScrollTrigger.sort(); 34755 skipRevert || _revertAll(); 34756 34757 _triggers.forEach(function (t) { 34758 return t.refresh(); 34759 }); 34760 34761 refreshInits.forEach(function (result) { 34762 return result && result.render && result.render(-1); 34763 }); 34764 34765 _clearScrollMemory(); 34766 34767 _resizeDelay.pause(); 34768 34769 _refreshingAll = false; 34770 34771 _dispatch("refresh"); 34772 }, 34773 _lastScroll = 0, 34774 _direction = 1, 34775 _updateAll = function _updateAll() { 34776 if (!_refreshingAll) { 34777 var l = _triggers.length, 34778 time = _getTime(), 34779 recordVelocity = time - _time1 >= 50, 34780 scroll = l && _triggers[0].scroll(); 34781 34782 _direction = _lastScroll > scroll ? -1 : 1; 34783 _lastScroll = scroll; 34784 34785 if (recordVelocity) { 34786 if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) { 34787 _lastScrollTime = 0; 34788 34789 _dispatch("scrollEnd"); 34790 } 34791 34792 _time2 = _time1; 34793 _time1 = time; 34794 } 34795 34796 if (_direction < 0) { 34797 _i = l; 34798 34799 while (_i-- > 0) { 34800 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34801 } 34802 34803 _direction = 1; 34804 } else { 34805 for (_i = 0; _i < l; _i++) { 34806 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34807 } 34808 } 34809 34810 _request = 0; 34811 } 34812 }, 34813 _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"], 34814 _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]), 34815 _swapPinOut = function _swapPinOut(pin, spacer, state) { 34816 _setState(state); 34817 34818 var cache = pin._gsap; 34819 34820 if (cache.spacerIsNative) { 34821 _setState(cache.spacerState); 34822 } else if (pin.parentNode === spacer) { 34823 var parent = spacer.parentNode; 34824 34825 if (parent) { 34826 parent.insertBefore(pin, spacer); 34827 parent.removeChild(spacer); 34828 } 34829 } 34830 }, 34831 _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) { 34832 if (pin.parentNode !== spacer) { 34833 var i = _propNamesToCopy.length, 34834 spacerStyle = spacer.style, 34835 pinStyle = pin.style, 34836 p; 34837 34838 while (i--) { 34839 p = _propNamesToCopy[i]; 34840 spacerStyle[p] = cs[p]; 34841 } 34842 34843 spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative"; 34844 cs.display === "inline" && (spacerStyle.display = "inline-block"); 34845 pinStyle[_bottom] = pinStyle[_right] = "auto"; 34846 spacerStyle.overflow = "visible"; 34847 spacerStyle.boxSizing = "border-box"; 34848 spacerStyle[_width] = _getSize(pin, _horizontal) + _px; 34849 spacerStyle[_height] = _getSize(pin, _vertical) + _px; 34850 spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0"; 34851 34852 _setState(spacerState); 34853 34854 pinStyle[_width] = pinStyle["max" + _Width] = cs[_width]; 34855 pinStyle[_height] = pinStyle["max" + _Height] = cs[_height]; 34856 pinStyle[_padding] = cs[_padding]; 34857 pin.parentNode.insertBefore(spacer, pin); 34858 spacer.appendChild(pin); 34859 } 34860 }, 34861 _capsExp = /([A-Z])/g, 34862 _setState = function _setState(state) { 34863 if (state) { 34864 var style = state.t.style, 34865 l = state.length, 34866 i = 0, 34867 p, 34868 value; 34869 (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; 34870 34871 for (; i < l; i += 2) { 34872 value = state[i + 1]; 34873 p = state[i]; 34874 34875 if (value) { 34876 style[p] = value; 34877 } else if (style[p]) { 34878 style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 34879 } 34880 } 34881 } 34882 }, 34883 _getState = function _getState(element) { 34884 var l = _stateProps.length, 34885 style = element.style, 34886 state = [], 34887 i = 0; 34888 34889 for (; i < l; i++) { 34890 state.push(_stateProps[i], style[_stateProps[i]]); 34891 } 34892 34893 state.t = element; 34894 return state; 34895 }, 34896 _copyState = function _copyState(state, override, omitOffsets) { 34897 var result = [], 34898 l = state.length, 34899 i = omitOffsets ? 8 : 0, 34900 p; 34901 34902 for (; i < l; i += 2) { 34903 p = state[i]; 34904 result.push(p, p in override ? override[p] : state[i + 1]); 34905 } 34906 34907 result.t = state.t; 34908 return result; 34909 }, 34910 _winOffsets = { 34911 left: 0, 34912 top: 0 34913 }, 34914 _parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation) { 34915 _isFunction(value) && (value = value(self)); 34916 34917 if (_isString(value) && value.substr(0, 3) === "max") { 34918 value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0); 34919 } 34920 34921 var time = containerAnimation ? containerAnimation.time() : 0, 34922 p1, 34923 p2, 34924 element; 34925 containerAnimation && containerAnimation.seek(0); 34926 34927 if (!_isNumber(value)) { 34928 _isFunction(trigger) && (trigger = trigger(self)); 34929 var offsets = value.split(" "), 34930 bounds, 34931 localOffset, 34932 globalOffset, 34933 display; 34934 element = _getTarget(trigger) || _body; 34935 bounds = _getBounds(element) || {}; 34936 34937 if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") { 34938 display = element.style.display; 34939 element.style.display = "block"; 34940 bounds = _getBounds(element); 34941 display ? element.style.display = display : element.style.removeProperty("display"); 34942 } 34943 34944 localOffset = _offsetToPx(offsets[0], bounds[direction.d]); 34945 globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize); 34946 value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset; 34947 markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20); 34948 scrollerSize -= scrollerSize - globalOffset; 34949 } else if (markerScroller) { 34950 _positionMarker(markerScroller, scrollerSize, direction, true); 34951 } 34952 34953 if (marker) { 34954 var position = value + scrollerSize, 34955 isStart = marker._isStart; 34956 p1 = "scroll" + direction.d2; 34957 34958 _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[p1], _docEl[p1]) : marker.parentNode[p1]) <= position + 1); 34959 34960 if (useFixedPosition) { 34961 scrollerBounds = _getBounds(markerScroller); 34962 useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px); 34963 } 34964 } 34965 34966 if (containerAnimation && element) { 34967 p1 = _getBounds(element); 34968 containerAnimation.seek(scrollerMax); 34969 p2 = _getBounds(element); 34970 containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p]; 34971 value = value / containerAnimation._caScrollDist * scrollerMax; 34972 } 34973 34974 containerAnimation && containerAnimation.seek(time); 34975 return containerAnimation ? value : Math.round(value); 34976 }, 34977 _prefixExp = /(?:webkit|moz|length|cssText|inset)/i, 34978 _reparent = function _reparent(element, parent, top, left) { 34979 if (element.parentNode !== parent) { 34980 var style = element.style, 34981 p, 34982 cs; 34983 34984 if (parent === _body) { 34985 element._stOrig = style.cssText; 34986 cs = _getComputedStyle(element); 34987 34988 for (p in cs) { 34989 if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") { 34990 style[p] = cs[p]; 34991 } 34992 } 34993 34994 style.top = top; 34995 style.left = left; 34996 } else { 34997 style.cssText = element._stOrig; 34998 } 34999 35000 gsap.core.getCache(element).uncache = 1; 35001 parent.appendChild(element); 35002 } 35003 }, 35004 _getTweenCreator = function _getTweenCreator(scroller, direction) { 35005 var getScroll = _getScrollFunc(scroller, direction), 35006 prop = "_scroll" + direction.p2, 35007 lastScroll1, 35008 lastScroll2, 35009 getTween = function getTween(scrollTo, vars, initialValue, change1, change2) { 35010 var tween = getTween.tween, 35011 onComplete = vars.onComplete, 35012 modifiers = {}; 35013 tween && tween.kill(); 35014 lastScroll1 = Math.round(initialValue); 35015 vars[prop] = scrollTo; 35016 vars.modifiers = modifiers; 35017 35018 modifiers[prop] = function (value) { 35019 value = _round(getScroll()); 35020 35021 if (value !== lastScroll1 && value !== lastScroll2 && Math.abs(value - lastScroll1) > 2) { 35022 tween.kill(); 35023 getTween.tween = 0; 35024 } else { 35025 value = initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio; 35026 } 35027 35028 lastScroll2 = lastScroll1; 35029 return lastScroll1 = _round(value); 35030 }; 35031 35032 vars.onComplete = function () { 35033 getTween.tween = 0; 35034 onComplete && onComplete.call(tween); 35035 }; 35036 35037 tween = getTween.tween = gsap.to(scroller, vars); 35038 return tween; 35039 }; 35040 35041 scroller[prop] = getScroll; 35042 scroller.addEventListener("wheel", function () { 35043 return getTween.tween && getTween.tween.kill() && (getTween.tween = 0); 35044 }, { 35045 passive: true 35046 }); 35047 return getTween; 35048 }; 35049 35050 _horizontal.op = _vertical; 35051 var ScrollTrigger = function () { 35052 function ScrollTrigger(vars, animation) { 35053 _coreInitted || ScrollTrigger.register(gsap) || console.warn("Please gsap.registerPlugin(ScrollTrigger)"); 35054 this.init(vars, animation); 35055 } 35056 35057 var _proto = ScrollTrigger.prototype; 35058 35059 _proto.init = function init(vars, animation) { 35060 this.progress = this.start = 0; 35061 this.vars && this.kill(1); 35062 35063 if (!_enabled) { 35064 this.update = this.refresh = this.kill = _passThrough; 35065 return; 35066 } 35067 35068 vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? { 35069 trigger: vars 35070 } : vars, _defaults); 35071 35072 var _vars = vars,
35073 onUpdate = _vars.onUpdate, 35074 toggleClass = _vars.toggleClass, 35075 id = _vars.id, 35076 onToggle = _vars.onToggle, 35077 onRefresh = _vars.onRefresh, 35078 scrub = _vars.scrub, 35079 trigger = _vars.trigger, 35080 pin = _vars.pin, 35081 pinSpacing = _vars.pinSpacing, 35082 invalidateOnRefresh = _vars.invalidateOnRefresh, 35083 anticipatePin = _vars.anticipatePin, 35084 onScrubComplete = _vars.onScrubComplete, 35085 onSnapComplete = _vars.onSnapComplete, 35086 once = _vars.once, 35087 snap = _vars.snap, 35088 pinReparent = _vars.pinReparent, 35089 pinSpacer = _vars.pinSpacer, 35090 containerAnimation = _vars.containerAnimation, 35091 fastScrollEnd = _vars.fastScrollEnd, 35092 preventOverlaps = _vars.preventOverlaps, 35093 direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical, 35094 isToggle = !scrub && scrub !== 0, 35095 scroller = _getTarget(vars.scroller || _win), 35096 scrollerCache = gsap.core.getCache(scroller), 35097 isViewport = _isViewport(scroller), 35098 useFixedPosition = ("pinType" in vars ? vars.pinType : _getProxyProp(scroller, "pinType") || isViewport && "fixed") === "fixed", 35099 callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack], 35100 toggleActions = isToggle && vars.toggleActions.split(" "), 35101 markers = "markers" in vars ? vars.markers : _defaults.markers, 35102 borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 35103 self = this, 35104 onRefreshInit = vars.onRefreshInit && function () { 35105 return vars.onRefreshInit(self); 35106 }, 35107 getScrollerSize = _getSizeFunc(scroller, isViewport, direction), 35108 getScrollerOffsets = _getOffsetsFunc(scroller, isViewport), 35109 lastSnap = 0, 35110 scrollFunc = _getScrollFunc(scroller, direction), 35111 tweenTo, 35112 pinCache, 35113 snapFunc, 35114 scroll1, 35115 scroll2, 35116 start, 35117 end, 35118 markerStart, 35119 markerEnd, 35120 markerStartTrigger, 35121 markerEndTrigger, 35122 markerVars, 35123 change, 35124 pinOriginalState, 35125 pinActiveState, 35126 pinState, 35127 spacer, 35128 offset, 35129 pinGetter, 35130 pinSetter, 35131 pinStart, 35132 pinChange, 35133 spacingStart, 35134 spacerState, 35135 markerStartSetter, 35136 markerEndSetter, 35137 cs, 35138 snap1, 35139 snap2, 35140 scrubTween, 35141 scrubSmooth, 35142 snapDurClamp, 35143 snapDelayedCall, 35144 prevProgress, 35145 prevScroll, 35146 prevAnimProgress, 35147 caMarkerSetter; 35148 35149 self.media = _creatingMedia; 35150 anticipatePin *= 45; 35151 self.scroller = scroller; 35152 self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc; 35153 scroll1 = scrollFunc(); 35154 self.vars = vars; 35155 animation = animation || vars.animation; 35156 "refreshPriority" in vars && (_sort = 1); 35157 scrollerCache.tweenScroll = scrollerCache.tweenScroll || { 35158 top: _getTweenCreator(scroller, _vertical), 35159 left: _getTweenCreator(scroller, _horizontal) 35160 }; 35161 self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p]; 35162 35163 if (animation) { 35164 animation.vars.lazy = false; 35165 animation._initted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.render(0, true, true); 35166 self.animation = animation.pause(); 35167 animation.scrollTrigger = self; 35168 scrubSmooth = _isNumber(scrub) && scrub; 35169 scrubSmooth && (scrubTween = gsap.to(animation, { 35170 ease: "power3", 35171 duration: scrubSmooth, 35172 onComplete: function onComplete() { 35173 return onScrubComplete && onScrubComplete(self); 35174 } 35175 })); 35176 snap1 = 0; 35177 id || (id = animation.vars.id); 35178 } 35179 35180 _triggers.push(self); 35181 35182 if (snap) { 35183 if (!_isObject(snap) || snap.push) { 35184 snap = { 35185 snapTo: snap 35186 }; 35187 } 35188 35189 "scrollBehavior" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, { 35190 scrollBehavior: "auto" 35191 }); 35192 snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) { 35193 return _snapDirectional(snap.snapTo)(value, st.direction); 35194 } : gsap.utils.snap(snap.snapTo); 35195 snapDurClamp = snap.duration || { 35196 min: 0.1, 35197 max: 2 35198 }; 35199 snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp); 35200 snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () { 35201 if (Math.abs(self.getVelocity()) < 10 && !_pointerIsDown && lastSnap !== scrollFunc()) { 35202 var totalProgress = animation && !isToggle ? animation.totalProgress() : self.progress, 35203 velocity = (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0, 35204 change1 = gsap.utils.clamp(-self.progress, 1 - self.progress, _abs(velocity / 2) * velocity / 0.185), 35205 naturalEnd = self.progress + (snap.inertia === false ? 0 : change1), 35206 endValue = _clamp(0, 1, snapFunc(naturalEnd, self)), 35207 scroll = scrollFunc(), 35208 endScroll = Math.round(start + endValue * change), 35209 _snap = snap, 35210 onStart = _snap.onStart, 35211 _onInterrupt = _snap.onInterrupt, 35212 _onComplete = _snap.onComplete, 35213 tween = tweenTo.tween; 35214 35215 if (scroll <= end && scroll >= start && endScroll !== scroll) { 35216 if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) { 35217 return; 35218 } 35219 35220 if (snap.inertia === false) { 35221 change1 = endValue - self.progress; 35222 } 35223 35224 tweenTo(endScroll, { 35225 duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)), 35226 ease: snap.ease || "power3", 35227 data: _abs(endScroll - scroll), 35228 onInterrupt: function onInterrupt() { 35229 return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self); 35230 }, 35231 onComplete: function onComplete() { 35232 lastSnap = scrollFunc(); 35233 snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress; 35234 onSnapComplete && onSnapComplete(self); 35235 _onComplete && _onComplete(self); 35236 } 35237 }, scroll, change1 * change, endScroll - scroll - change1 * change); 35238 onStart && onStart(self, tweenTo.tween); 35239 } 35240 } else if (self.isActive) { 35241 snapDelayedCall.restart(true); 35242 } 35243 }).pause(); 35244 } 35245 35246 id && (_ids[id] = self); 35247 trigger = self.trigger = _getTarget(trigger || pin); 35248 pin = pin === true ? trigger : _getTarget(pin); 35249 _isString(toggleClass) && (toggleClass = { 35250 targets: trigger, 35251 className: toggleClass 35252 }); 35253 35254 if (pin) { 35255 pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding); 35256 self.pin = pin; 35257 vars.force3D !== false && gsap.set(pin, {
35258 force3D: true 35259 }); 35260 pinCache = gsap.core.getCache(pin); 35261 35262 if (!pinCache.spacer) { 35263 if (pinSpacer) { 35264 pinSpacer = _getTarget(pinSpacer); 35265 pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); 35266 pinCache.spacerIsNative = !!pinSpacer; 35267 pinSpacer && (pinCache.spacerState = _getState(pinSpacer)); 35268 } 35269 35270 pinCache.spacer = spacer = pinSpacer || _doc.createElement("div"); 35271 spacer.classList.add("pin-spacer"); 35272 id && spacer.classList.add("pin-spacer-" + id); 35273 pinCache.pinState = pinOriginalState = _getState(pin); 35274 } else { 35275 pinOriginalState = pinCache.pinState; 35276 } 35277 35278 self.spacer = spacer = pinCache.spacer; 35279 cs = _getComputedStyle(pin); 35280 spacingStart = cs[pinSpacing + direction.os2]; 35281 pinGetter = gsap.getProperty(pin); 35282 pinSetter = gsap.quickSetter(pin, direction.a, _px); 35283 35284 _swapPinIn(pin, spacer, cs); 35285 35286 pinState = _getState(pin); 35287 } 35288 35289 if (markers) { 35290 markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults; 35291 markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0); 35292 markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger); 35293 offset = markerStartTrigger["offset" + direction.op.d2]; 35294 markerStart = _createMarker("start", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35295 markerEnd = _createMarker("end", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35296 containerAnimation && (caMarkerSetter = gsap.quickSetter([markerStart, markerEnd], direction.a, _px)); 35297 35298 if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, "fixedMarkers") === true)) { 35299 _makePositionable(isViewport ? _body : scroller); 35300 35301 gsap.set([markerStartTrigger, markerEndTrigger], { 35302 force3D: true 35303 }); 35304 markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px); 35305 markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px); 35306 } 35307 } 35308 35309 if (containerAnimation) { 35310 var oldOnUpdate = containerAnimation.vars.onUpdate, 35311 oldParams = containerAnimation.vars.onUpdateParams; 35312 containerAnimation.eventCallback("onUpdate", function () { 35313 self.update(0, 0, 1); 35314 oldOnUpdate && oldOnUpdate.apply(oldParams || []); 35315 }); 35316 } 35317 35318 self.previous = function () { 35319 return _triggers[_triggers.indexOf(self) - 1]; 35320 }; 35321 35322 self.next = function () { 35323 return _triggers[_triggers.indexOf(self) + 1]; 35324 }; 35325 35326 self.revert = function (revert) { 35327 var r = revert !== false || !self.enabled, 35328 prevRefreshing = _refreshing; 35329 35330 if (r !== self.isReverted) { 35331 if (r) { 35332 self.scroll.rec || (self.scroll.rec = scrollFunc()); 35333 prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0); 35334 prevProgress = self.progress; 35335 prevAnimProgress = animation && animation.progress(); 35336 } 35337 35338 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35339 return m.style.display = r ? "none" : "block"; 35340 }); 35341 r && (_refreshing = 1); 35342 self.update(r); 35343 _refreshing = prevRefreshing; 35344 pin && (r ? _swapPinOut(pin, spacer, pinOriginalState) : (!pinReparent || !self.isActive) && _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState)); 35345 self.isReverted = r; 35346 } 35347 }; 35348 35349 self.refresh = function (soft, force) { 35350 if ((_refreshing || !self.enabled) && !force) { 35351 return; 35352 } 35353 35354 if (pin && soft && _lastScrollTime) { 35355 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 35356 35357 return; 35358 } 35359 35360 _refreshing = 1; 35361 scrubTween && scrubTween.pause(); 35362 invalidateOnRefresh && animation && animation.progress(0).invalidate(); 35363 self.isReverted || self.revert(); 35364 35365 var size = getScrollerSize(), 35366 scrollerBounds = getScrollerOffsets(),
35367 max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction), 35368 offset = 0, 35369 otherPinOffset = 0, 35370 parsedEnd = vars.end, 35371 parsedEndTrigger = vars.endTrigger || trigger, 35372 parsedStart = vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"), 35373 pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer), 35374 triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0, 35375 i = triggerIndex, 35376 cs, 35377 bounds, 35378 scroll, 35379 isVertical, 35380 override, 35381 curTrigger, 35382 curPin, 35383 oppositeScroll, 35384 initted, 35385 revertedPins; 35386 35387 while (i--) { 35388 curTrigger = _triggers[i]; 35389 curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = 1); 35390 curPin = curTrigger.pin; 35391 35392 if (curPin && (curPin === trigger || curPin === pin) && !curTrigger.isReverted) { 35393 revertedPins || (revertedPins = []); 35394 revertedPins.unshift(curTrigger); 35395 curTrigger.revert(); 35396 } 35397 } 35398 35399 _isFunction(parsedStart) && (parsedStart = parsedStart(self)); 35400 start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation) || (pin ? -0.001 : 0); 35401 _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self)); 35402 35403 if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) { 35404 if (~parsedEnd.indexOf(" ")) { 35405 parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd; 35406 } else { 35407 offset = _offsetToPx(parsedEnd.substr(2), size); 35408 parsedEnd = _isString(parsedStart) ? parsedStart : start + offset; 35409 parsedEndTrigger = trigger; 35410 } 35411 } 35412 35413 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; 35414 change = end - start || (start -= 0.01) && 0.001; 35415 offset = 0; 35416 i = triggerIndex; 35417 35418 while (i--) { 35419 curTrigger = _triggers[i]; 35420 curPin = curTrigger.pin; 35421 35422 if (curPin && curTrigger.start - curTrigger._pinPush < start && !containerAnimation) { 35423 cs = curTrigger.end - curTrigger.start; 35424 (curPin === trigger || curPin === pinnedContainer) && !_isNumber(parsedStart) && (offset += cs); 35425 curPin === pin && (otherPinOffset += cs); 35426 } 35427 } 35428 35429 start += offset; 35430 end += offset; 35431 self._pinPush = otherPinOffset; 35432 35433 if (markerStart && offset) { 35434 cs = {}; 35435 cs[direction.a] = "+=" + offset; 35436 pinnedContainer && (cs[direction.p] = "-=" + scrollFunc()); 35437 gsap.set([markerStart, markerEnd], cs); 35438 } 35439 35440 if (pin) { 35441 cs = _getComputedStyle(pin); 35442 isVertical = direction === _vertical; 35443 scroll = scrollFunc(); 35444 pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset; 35445 !max && end > 1 && ((isViewport ? _body : scroller).style["overflow-" + direction.a] = "scroll"); 35446 35447 _swapPinIn(pin, spacer, cs); 35448 35449 pinState = _getState(pin); 35450 bounds = _getBounds(pin, true); 35451 oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)(); 35452 35453 if (pinSpacing) { 35454 spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px]; 35455 spacerState.t = spacer; 35456 i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0; 35457 i && spacerState.push(direction.d, i + _px); 35458 35459 _setState(spacerState); 35460 35461 useFixedPosition && scrollFunc(prevScroll); 35462 } 35463 35464 if (useFixedPosition) { 35465 override = { 35466 top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px, 35467 left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px, 35468 boxSizing: "border-box", 35469 position: "fixed" 35470 }; 35471 override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px; 35472 override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px; 35473 override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0"; 35474 override[_padding] = cs[_padding]; 35475 override[_padding + _Top] = cs[_padding + _Top]; 35476 override[_padding + _Right] = cs[_padding + _Right]; 35477 override[_padding + _Bottom] = cs[_padding + _Bottom]; 35478 override[_padding + _Left] = cs[_padding + _Left]; 35479 pinActiveState = _copyState(pinOriginalState, override, pinReparent); 35480 } 35481 35482 if (animation) { 35483 initted = animation._initted; 35484 35485 _suppressOverwrites(1); 35486 35487 animation.render(animation.duration(), true, true); 35488 pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset; 35489 change !== pinChange && pinActiveState.splice(pinActiveState.length - 2, 2); 35490 animation.render(0, true, true); 35491 initted || animation.invalidate(); 35492 35493 _suppressOverwrites(0); 35494 } else { 35495 pinChange = change; 35496 } 35497 } else if (trigger && scrollFunc() && !containerAnimation) { 35498 bounds = trigger.parentNode; 35499 35500 while (bounds && bounds !== _body) { 35501 if (bounds._pinOffset) { 35502 start -= bounds._pinOffset; 35503 end -= bounds._pinOffset; 35504 } 35505 35506 bounds = bounds.parentNode; 35507 } 35508 } 35509 35510 revertedPins && revertedPins.forEach(function (t) { 35511 return t.revert(false); 35512 }); 35513 self.start = start; 35514 self.end = end; 35515 scroll1 = scroll2 = scrollFunc(); 35516 35517 if (!containerAnimation) { 35518 scroll1 < prevScroll && scrollFunc(prevScroll); 35519 self.scroll.rec = 0; 35520 } 35521 35522 self.revert(false); 35523 _refreshing = 0; 35524 animation && isToggle && animation._initted && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress, true).render(animation.time(), true, true); 35525 35526 if (prevProgress !== self.progress) { 35527 animation && !isToggle && animation.totalProgress(prevProgress, true); 35528 self.progress = prevProgress; 35529 self.update(0, 0, 1); 35530 } 35531 35532 pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange)); 35533 onRefresh && onRefresh(self); 35534 }; 35535 35536 self.getVelocity = function () { 35537 return (scrollFunc() - scroll2) / (_getTime() - _time2) * 1000 || 0; 35538 }; 35539 35540 self.endAnimation = function () {
vendor: 8,601 bytes, lines 35541-35779
35541 _endAnimation(self.callbackAnimation); 35542 35543 if (animation) { 35544 scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1); 35545 } 35546 }; 35547 35548 self.getTrailing = function (name) { 35549 var i = _triggers.indexOf(self), 35550 a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1); 35551 35552 return _isString(name) ? a.filter(function (t) { 35553 return t.vars.preventOverlaps === name; 35554 }) : a; 35555 }; 35556 35557 self.update = function (reset, recordVelocity, forceFake) { 35558 if (containerAnimation && !forceFake && !reset) { 35559 return; 35560 } 35561 35562 var scroll = self.scroll(), 35563 p = reset ? 0 : (scroll - start) / change, 35564 clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0, 35565 prevProgress = self.progress, 35566 isActive, 35567 wasActive, 35568 toggleState, 35569 action, 35570 stateChanged, 35571 toggled, 35572 isAtMax, 35573 isTakingAction; 35574 35575 if (recordVelocity) { 35576 scroll2 = scroll1; 35577 scroll1 = containerAnimation ? scrollFunc() : scroll; 35578 35579 if (snap) { 35580 snap2 = snap1; 35581 snap1 = animation && !isToggle ? animation.totalProgress() : clipped; 35582 } 35583 } 35584 35585 anticipatePin && !clipped && pin && !_refreshing && !_startup && _lastScrollTime && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin && (clipped = 0.0001); 35586 35587 if (clipped !== prevProgress && self.enabled) { 35588 isActive = self.isActive = !!clipped && clipped < 1; 35589 wasActive = !!prevProgress && prevProgress < 1; 35590 toggled = isActive !== wasActive; 35591 stateChanged = toggled || !!clipped !== !!prevProgress; 35592 self.direction = clipped > prevProgress ? 1 : -1; 35593 self.progress = clipped; 35594 35595 if (stateChanged && !_refreshing) { 35596 toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; 35597 35598 if (isToggle) { 35599 action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState]; 35600 isTakingAction = animation && (action === "complete" || action === "reset" || action in animation); 35601 } 35602 } 35603 35604 preventOverlaps && toggled && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) { 35605 return t.endAnimation(); 35606 })); 35607 35608 if (!isToggle) { 35609 if (scrubTween && !_refreshing && !_startup) { 35610 scrubTween.vars.totalProgress = clipped; 35611 scrubTween.invalidate().restart(); 35612 } else if (animation) { 35613 animation.totalProgress(clipped, !!_refreshing); 35614 } 35615 } 35616 35617 if (pin) { 35618 reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart); 35619 35620 if (!useFixedPosition) { 35621 pinSetter(pinStart + pinChange * clipped); 35622 } else if (stateChanged) { 35623 isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); 35624 35625 if (pinReparent) { 35626 if (!reset && (isActive || isAtMax)) { 35627 var bounds = _getBounds(pin, true), 35628 _offset = scroll - start; 35629 35630 _reparent(pin, _body, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px); 35631 } else { 35632 _reparent(pin, spacer); 35633 } 35634 } 35635 35636 _setState(isActive || isAtMax ? pinActiveState : pinState); 35637 35638 pinChange !== change && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0)); 35639 } 35640 } 35641 35642 snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true); 35643 toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) { 35644 return el.classList[isActive || once ? "add" : "remove"](toggleClass.className); 35645 }); 35646 onUpdate && !isToggle && !reset && onUpdate(self); 35647 35648 if (stateChanged && !_refreshing) { 35649 if (isToggle) { 35650 if (isTakingAction) { 35651 if (action === "complete") { 35652 animation.pause().totalProgress(1); 35653 } else if (action === "reset") { 35654 animation.restart(true).pause(); 35655 } else if (action === "restart") { 35656 animation.restart(true); 35657 } else { 35658 animation[action](); 35659 } 35660 } 35661 35662 onUpdate && onUpdate(self); 35663 } 35664 35665 if (toggled || !_limitCallbacks) { 35666 onToggle && toggled && _callback(self, onToggle); 35667 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35668 once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); 35669 35670 if (!toggled) { 35671 toggleState = clipped === 1 ? 1 : 3; 35672 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35673 } 35674 } 35675 35676 if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) { 35677 _endAnimation(self.callbackAnimation); 35678 35679 scrubTween ? scrubTween.progress(1) : _endAnimation(animation, !clipped, 1); 35680 } 35681 } else if (isToggle && onUpdate && !_refreshing) { 35682 onUpdate(self); 35683 } 35684 } 35685 35686 if (markerEndSetter) { 35687 var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll; 35688 markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0)); 35689 markerEndSetter(n); 35690 } 35691 35692 caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0)); 35693 }; 35694 35695 self.enable = function (reset, refresh) { 35696 if (!self.enabled) { 35697 self.enabled = true; 35698 35699 _addListener(scroller, "resize", _onResize); 35700 35701 _addListener(scroller, "scroll", _onScroll); 35702 35703 onRefreshInit && _addListener(ScrollTrigger, "refreshInit", onRefreshInit); 35704 35705 if (reset !== false) { 35706 self.progress = prevProgress = 0; 35707 scroll1 = scroll2 = lastSnap = scrollFunc(); 35708 } 35709 35710 refresh !== false && self.refresh(); 35711 } 35712 }; 35713 35714 self.getTween = function (snap) { 35715 return snap && tweenTo ? tweenTo.tween : scrubTween; 35716 }; 35717 35718 self.disable = function (reset, allowAnimation) { 35719 if (self.enabled) { 35720 reset !== false && self.revert(); 35721 self.enabled = self.isActive = false; 35722 allowAnimation || scrubTween && scrubTween.pause(); 35723 prevScroll = 0; 35724 pinCache && (pinCache.uncache = 1); 35725 onRefreshInit && _removeListener(ScrollTrigger, "refreshInit", onRefreshInit); 35726 35727 if (snapDelayedCall) { 35728 snapDelayedCall.pause(); 35729 tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0); 35730 } 35731 35732 if (!isViewport) { 35733 var i = _triggers.length; 35734 35735 while (i--) { 35736 if (_triggers[i].scroller === scroller && _triggers[i] !== self) { 35737 return; 35738 } 35739 } 35740 35741 _removeListener(scroller, "resize", _onResize); 35742 35743 _removeListener(scroller, "scroll", _onScroll); 35744 } 35745 } 35746 }; 35747 35748 self.kill = function (revert, allowAnimation) { 35749 self.disable(revert, allowAnimation); 35750 scrubTween && scrubTween.kill(); 35751 id && delete _ids[id]; 35752 35753 var i = _triggers.indexOf(self); 35754 35755 _triggers.splice(i, 1); 35756 35757 i === _i && _direction > 0 && _i--; 35758 i = 0; 35759 35760 _triggers.forEach(function (t) { 35761 return t.scroller === self.scroller && (i = 1); 35762 }); 35763 35764 i || (self.scroll.rec = 0); 35765 35766 if (animation) { 35767 animation.scrollTrigger = null; 35768 revert && animation.render(-1); 35769 allowAnimation || animation.kill(); 35770 } 35771 35772 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35773 return m.parentNode && m.parentNode.removeChild(m); 35774 }); 35775 35776 if (pin) { 35777 pinCache && (pinCache.uncache = 1); 35778 i = 0; 35779
35780 _triggers.forEach(function (t) { 35781 return t.pin === pin && i++; 35782 }); 35783 35784 i || (pinCache.spacer = 0); 35785 } 35786 }; 35787 35788 self.enable(false, false); 35789 !animation || !animation.add || change ? self.refresh() : gsap.delayedCall(0.01, function () { 35790 return start || end || self.refresh(); 35791 }) && (change = 0.01) && (start = end = 0); 35792 }; 35793 35794 ScrollTrigger.register = function register(core) { 35795 if (!_coreInitted) { 35796 gsap = core || _getGSAP(); 35797 35798 if (_windowExists() && window.document) { 35799 _win = window; 35800 _doc = document; 35801 _docEl = _doc.documentElement; 35802 _body = _doc.body; 35803 } 35804 35805 if (gsap) { 35806 _toArray = gsap.utils.toArray; 35807 _clamp = gsap.utils.clamp; 35808 _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough; 35809 gsap.core.globals("ScrollTrigger", ScrollTrigger); 35810 35811 if (_body) { 35812 _raf = _win.requestAnimationFrame || function (f) { 35813 return setTimeout(f, 16); 35814 }; 35815 35816 _addListener(_win, "wheel", _onScroll); 35817 35818 _root = [_win, _doc, _docEl, _body]; 35819 35820 _addListener(_doc, "scroll", _onScroll); 35821 35822 var bodyStyle = _body.style, 35823 border = bodyStyle.borderTopStyle, 35824 bounds; 35825 bodyStyle.borderTopStyle = "solid"; 35826 bounds = _getBounds(_body); 35827 _vertical.m = Math.round(bounds.top + _vertical.sc()) || 0; 35828 _horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0; 35829 border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style"); 35830 _syncInterval = setInterval(_sync, 200); 35831 gsap.delayedCall(0.5, function () { 35832 return _startup = 0; 35833 }); 35834 35835 _addListener(_doc, "touchcancel", _passThrough); 35836 35837 _addListener(_body, "touchstart", _passThrough); 35838 35839 _multiListener(_addListener, _doc, "pointerdown,touchstart,mousedown", function () { 35840 return _pointerIsDown = 1; 35841 }); 35842 35843 _multiListener(_addListener, _doc, "pointerup,touchend,mouseup", function () { 35844 return _pointerIsDown = 0; 35845 }); 35846 35847 _transformProp = gsap.utils.checkPrefix("transform"); 35848 35849 _stateProps.push(_transformProp); 35850 35851 _coreInitted = _getTime(); 35852 _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause(); 35853 _autoRefresh = [_doc, "visibilitychange", function () { 35854 var w = _win.innerWidth, 35855 h = _win.innerHeight; 35856 35857 if (_doc.hidden) { 35858 _prevWidth = w; 35859 _prevHeight = h; 35860 } else if (_prevWidth !== w || _prevHeight !== h) { 35861 _onResize(); 35862 } 35863 }, _doc, "DOMContentLoaded", _refreshAll, _win, "load", function () { 35864 return _lastScrollTime || _refreshAll(); 35865 }, _win, "resize", _onResize]; 35866 35867 _iterateAutoRefresh(_addListener); 35868 } 35869 } 35870 } 35871 35872 return _coreInitted; 35873 }; 35874 35875 ScrollTrigger.defaults = function defaults(config) { 35876 for (var p in config) { 35877 _defaults[p] = config[p]; 35878 } 35879 }; 35880 35881 ScrollTrigger.kill = function kill() { 35882 _enabled = 0; 35883 35884 _triggers.slice(0).forEach(function (trigger) { 35885 return trigger.kill(1); 35886 }); 35887 }; 35888 35889 ScrollTrigger.config = function config(vars) { 35890 "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks); 35891 var ms = vars.syncInterval; 35892 ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms); 35893 35894 if ("autoRefreshEvents" in vars) { 35895 _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || "none"); 35896 _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1; 35897 } 35898 }; 35899 35900 ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) { 35901 var t = _getTarget(target), 35902 i = _scrollers.indexOf(t), 35903 isViewport = _isViewport(t); 35904 35905 if (~i) { 35906 _scrollers.splice(i, isViewport ? 6 : 2); 35907 } 35908 35909 isViewport ? _proxies.unshift(_win, vars, _body, vars, _docEl, vars) : _proxies.unshift(t, vars); 35910 }; 35911 35912 ScrollTrigger.matchMedia = function matchMedia(vars) { 35913 var mq, p, i, func, result; 35914 35915 for (p in vars) { 35916 i = _media.indexOf(p); 35917 func = vars[p]; 35918 _creatingMedia = p; 35919 35920 if (p === "all") { 35921 func(); 35922 } else { 35923 mq = _win.matchMedia(p); 35924 35925 if (mq) { 35926 mq.matches && (result = func()); 35927 35928 if (~i) { 35929 _media[i + 1] = _combineFunc(_media[i + 1], func); 35930 _media[i + 2] = _combineFunc(_media[i + 2], result); 35931 } else { 35932 i = _media.length; 35933 35934 _media.push(p, func, result); 35935 35936 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 35937 } 35938 35939 _media[i + 3] = mq.matches; 35940 } 35941 } 35942 35943 _creatingMedia = 0; 35944 } 35945 35946 return _media; 35947 }; 35948 35949 ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) { 35950 query || (_media.length = 0); 35951 query = _media.indexOf(query); 35952 query >= 0 && _media.splice(query, 4); 35953 }; 35954 35955 ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) { 35956 var bounds = (_isString(element) ? _getTarget(element) : element).getBoundingClientRect(), 35957 offset = bounds[horizontal ? _width : _height] * ratio || 0; 35958 return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win.innerHeight; 35959 }; 35960 35961 ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) { 35962 _isString(element) && (element = _getTarget(element)); 35963 var bounds = element.getBoundingClientRect(), 35964 size = bounds[horizontal ? _width : _height], 35965 offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0; 35966 return horizontal ? (bounds.left + offset) / _win.innerWidth : (bounds.top + offset) / _win.innerHeight; 35967 }; 35968 35969 return ScrollTrigger; 35970 }(); 35971 ScrollTrigger.version = "3.8.0"; 35972 35973 ScrollTrigger.saveStyles = function (targets) {
35974 return targets ? _toArray(targets).forEach(function (target) { 35975 if (target && target.style) { 35976 var i = _savedStyles.indexOf(target); 35977 35978 i >= 0 && _savedStyles.splice(i, 5); 35979 35980 _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap.core.getCache(target), _creatingMedia); 35981 } 35982 }) : _savedStyles; 35983 }; 35984 35985 ScrollTrigger.revert = function (soft, media) { 35986 return _revertAll(!soft, media); 35987 }; 35988 35989 ScrollTrigger.create = function (vars, animation) { 35990 return new ScrollTrigger(vars, animation); 35991 }; 35992 35993 ScrollTrigger.refresh = function (safe) { 35994 return safe ? _onResize() : (_coreInitted || ScrollTrigger.register()) && _refreshAll(true); 35995 }; 35996 35997 ScrollTrigger.update = _updateAll; 35998 ScrollTrigger.clearScrollMemory = _clearScrollMemory; 35999 36000 ScrollTrigger.maxScroll = function (element, horizontal) { 36001 return _maxScroll(element, horizontal ? _horizontal : _vertical); 36002 }; 36003 36004 ScrollTrigger.getScrollFunc = function (element, horizontal) { 36005 return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical); 36006 }; 36007 36008 ScrollTrigger.getById = function (id) { 36009 return _ids[id]; 36010 }; 36011 36012 ScrollTrigger.getAll = function () { 36013 return _triggers.slice(0); 36014 }; 36015 36016 ScrollTrigger.isScrolling = function () { 36017 return !!_lastScrollTime; 36018 }; 36019 36020 ScrollTrigger.snapDirectional = _snapDirectional; 36021 36022 ScrollTrigger.addEventListener = function (type, callback) { 36023 var a = _listeners[type] || (_listeners[type] = []); 36024 ~a.indexOf(callback) || a.push(callback); 36025 }; 36026 36027 ScrollTrigger.removeEventListener = function (type, callback) { 36028 var a = _listeners[type], 36029 i = a && a.indexOf(callback); 36030 i >= 0 && a.splice(i, 1); 36031 }; 36032 36033 ScrollTrigger.batch = function (targets, vars) { 36034 var result = [], 36035 varsCopy = {}, 36036 interval = vars.interval || 0.016, 36037 batchMax = vars.batchMax || 1e9, 36038 proxyCallback = function proxyCallback(type, callback) { 36039 var elements = [], 36040 triggers = [], 36041 delay = gsap.delayedCall(interval, function () { 36042 callback(elements, triggers); 36043 elements = []; 36044 triggers = []; 36045 }).pause(); 36046 return function (self) { 36047 elements.length || delay.restart(true); 36048 elements.push(self.trigger); 36049 triggers.push(self); 36050 batchMax <= elements.length && delay.progress(1); 36051 }; 36052 }, 36053 p; 36054 36055 for (p in vars) { 36056 varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p]; 36057 } 36058 36059 if (_isFunction(batchMax)) { 36060 batchMax = batchMax(); 36061 36062 _addListener(ScrollTrigger, "refresh", function () { 36063 return batchMax = vars.batchMax(); 36064 }); 36065 } 36066 36067 _toArray(targets).forEach(function (target) { 36068 var config = {}; 36069 36070 for (p in varsCopy) { 36071 config[p] = varsCopy[p]; 36072 } 36073 36074 config.trigger = target; 36075 result.push(ScrollTrigger.create(config)); 36076 }); 36077 36078 return result; 36079 }; 36080 36081 ScrollTrigger.sort = function (func) { 36082 return _triggers.sort(func || function (a, b) { 36083 return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6); 36084 }); 36085 }; 36086 36087 _getGSAP() && gsap.registerPlugin(ScrollTrigger); 36088 36089 exports.ScrollTrigger = ScrollTrigger; 36090 exports.default = ScrollTrigger; 36091 36092 Object.defineProperty(exports, '__esModule', { value: true }); 36093 36094}))); 36095 36096/* ======================================================================== 36097 * Bootstrap: collapse.js v3.1.1 36098 * http://getbootstrap.com/javascript/#collapse 36099 * ======================================================================== 36100 * Copyright 2011-2014 Twitter, Inc. 36101 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36102 * ======================================================================== */ 36103 36104 36105+function ($) { 36106 'use strict'; 36107 36108 // COLLAPSE PUBLIC CLASS DEFINITION 36109 // ================================ 36110 36111 var Collapse = function (element, options) { 36112 this.$element = $(element) 36113 this.options = $.extend({}, Collapse.DEFAULTS, options) 36114 this.transitioning = null 36115 36116 if (this.options.parent) this.$parent = $(this.options.parent) 36117 if (this.options.toggle) this.toggle() 36118 } 36119 36120 Collapse.DEFAULTS = { 36121 toggle: true 36122 } 36123 36124 Collapse.prototype.dimension = function () { 36125 var hasWidth = this.$element.hasClass('width') 36126 return hasWidth ? 'width' : 'height' 36127 } 36128 36129 Collapse.prototype.show = function () { 36130 if (this.transitioning || this.$element.hasClass('in')) return 36131 36132 var startEvent = $.Event('show.bs.collapse') 36133 this.$element.trigger(startEvent) 36134 if (startEvent.isDefaultPrevented()) return 36135 36136 var actives = this.$parent && this.$parent.find('> .panel > .in') 36137 36138 if (actives && actives.length) { 36139 var hasData = actives.data('bs.collapse') 36140 if (hasData && hasData.transitioning) return 36141 //START UNCODE EDIT 36142 var parentNoToggle = this.$parent.data('no-toggle') 36143 if (!parentNoToggle) { 36144 actives.collapse('hide') 36145 } 36146 //END UNCODE EDIT 36147 hasData || actives.data('bs.collapse', null) 36148 } 36149 36150 var dimension = this.dimension() 36151 36152 this.$element 36153 .removeClass('collapse') 36154 .addClass('collapsing')[dimension](0) 36155 36156 this.transitioning = 1 36157 36158 var complete = function (e) { 36159 if (e && e.target != this.$element[0]) return 36160 this.$element 36161 .removeClass('collapsing') 36162 .addClass('collapse in')[dimension]('auto') 36163 this.transitioning = 0 36164 this.$element.trigger('shown.bs.collapse') 36165 } 36166 36167 if (!$.support.transition) return complete.call(this) 36168 36169 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 36170 36171 this.$element 36172 .one($.support.transition.end, $.proxy(complete, this)) 36173 .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) 36174 } 36175 36176 Collapse.prototype.hide = function () { 36177 if (this.transitioning || !this.$element.hasClass('in')) return 36178 36179 var startEvent = $.Event('hide.bs.collapse') 36180 this.$element.trigger(startEvent) 36181 if (startEvent.isDefaultPrevented()) return 36182 36183 var dimension = this.dimension() 36184 36185 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 36186 36187 this.$element 36188 .addClass('collapsing') 36189 .removeClass('collapse') 36190 .removeClass('in') 36191 36192 this.transitioning = 1 36193 36194 var complete = function (e) { 36195 if (e && e.target != this.$element[0]) return 36196 this.transitioning = 0 36197 this.$element 36198 .trigger('hidden.bs.collapse') 36199 .removeClass('collapsing') 36200 .addClass('collapse') 36201 } 36202 36203 if (!$.support.transition) return complete.call(this) 36204 36205 this.$element 36206 [dimension](0) 36207 .one($.support.transition.end, $.proxy(complete, this)) 36208 .emulateTransitionEnd(350) 36209 } 36210 36211 Collapse.prototype.toggle = function () { 36212 this[this.$element.hasClass('in') ? 'hide' : 'show']() 36213 } 36214 36215 36216 // COLLAPSE PLUGIN DEFINITION 36217 // ========================== 36218 36219 var old = $.fn.collapse 36220 36221 $.fn.collapse = function (option) { 36222 return this.each(function () { 36223 var $this = $(this) 36224 var data = $this.data('bs.collapse') 36225 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 36226 36227 if (!data && options.toggle && option == 'show') option = !option 36228 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 36229 if (typeof option == 'string') data[option]() 36230 }) 36231 } 36232 36233 $.fn.collapse.Constructor = Collapse 36234 36235 36236 // COLLAPSE NO CONFLICT 36237 // ==================== 36238 36239 $.fn.collapse.noConflict = function () { 36240 $.fn.collapse = old 36241 return this 36242 } 36243 36244 36245 // COLLAPSE DATA-API 36246 // ================= 36247 36248 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 36249 var $this = $(this), href 36250 var target = $this.attr('data-target') 36251 || e.preventDefault() 36252 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 36253 //Edited by Uncode to replace ID in panel [START] 36254 var _target = href.replace(/^#/, ""); 36255 if ( $('[data-id="' + _target + '"]').length ) { 36256 var $target = $('[data-id="' + _target + '"]') 36257 } else { 36258 var $target = $(target) 36259 } 36260 //Edited by Uncode to replace ID in panel [END] 36261 var data = $target.data('bs.collapse') 36262 var option = data ? 'toggle' : $this.data() 36263 var parent = $this.attr('data-parent') 36264 var $parent = parent && $(parent) 36265 36266 if (!data || !data.transitioning) { 36267 if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') 36268 $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 36269 } 36270 36271 $target.collapse(option) 36272 }) 36273 36274}(jQuery); 36275 36276/* ======================================================================== 36277 * Bootstrap: tab.js v3.1.1 36278 * http://getbootstrap.com/javascript/#tabs 36279 * ======================================================================== 36280 * Copyright 2011-2014 Twitter, Inc. 36281 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36282 * ======================================================================== */ 36283 36284 36285+function ($) { 36286 'use strict'; 36287 36288 // TAB CLASS DEFINITION 36289 // ==================== 36290 36291 var Tab = function (element) { 36292 this.element = $(element) 36293 } 36294 36295 Tab.prototype.show = function () { 36296 var $this = this.element 36297 var $ul = $this.closest('ul:not(.dropdown-menu)') 36298 var selector = $this.data('target') 36299 36300 if (!selector) { 36301 selector = $this.attr('href') 36302 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 36303 } 36304 36305 if ($this.parent('li').hasClass('active')) return 36306 36307 var previous = $ul.find('.active:last a')[0] 36308 var e = $.Event('show.bs.tab', { 36309 relatedTarget: previous 36310 }) 36311 36312 $this.trigger(e) 36313 36314 if (e.isDefaultPrevented()) return 36315 36316 //Edited by Uncode to replace ID in panel [START] 36317 var _target = selector.replace(/^#/, ""); 36318 if ( $('[data-id="' + _target + '"]').length ) 36319 var $target = $('[data-id="' + _target + '"]') 36320 else 36321 var $target = $(selector) 36322 //Edited by Uncode to replace ID in panel [END] 36323 36324 this.activate($this.parent('li'), $ul) 36325 this.activate($target, $target.parent(), function () { 36326 $this.trigger({ 36327 type: 'shown.bs.tab', 36328 relatedTarget: previous 36329 }) 36330 }) 36331 } 36332 36333 Tab.prototype.activate = function (element, container, callback) { 36334 var $active = container.find('> .active').add(container.find('> .active > .active')) 36335 var transition = callback 36336 && $.support.transition 36337 && $active.hasClass('fade') 36338 36339 function next() { 36340 $active 36341 .removeClass('active') 36342 .find('> .dropdown-menu > .active') 36343 .removeClass('active') 36344 36345 $active 36346 .find('.tab-excerpt').slideUp(); 36347 36348 element.addClass('active') 36349 $('.tab-excerpt', element).slideDown(); 36350 36351 //if (transition) { 36352 element[0].offsetWidth // reflow for transition 36353 element.add($active).addClass('in') 36354 /*} else { 36355 element.removeClass('fade') 36356 }*/ 36357 36358 if (element.parent('.dropdown-menu')) { 36359 element.closest('li.dropdown').addClass('active') 36360 } 36361 36362 callback && callback() 36363 } 36364 36365 transition ? 36366 $active 36367 .one($.support.transition.end, next) 36368 .emulateTransitionEnd(150) : 36369 next() 36370 36371 $active.removeClass('in') 36372 } 36373 36374 36375 // TAB PLUGIN DEFINITION 36376 // ===================== 36377 36378 var old = $.fn.tab 36379 36380 $.fn.tab = function ( option ) { 36381 return this.each(function () { 36382 var $this = $(this) 36383 var data = $this.data('bs.tab') 36384 36385 if (!data) $this.data('bs.tab', (data = new Tab(this))) 36386 if (typeof option == 'string') data[option]() 36387 }) 36388 } 36389 36390 $.fn.tab.Constructor = Tab 36391 36392 36393 // TAB NO CONFLICT 36394 // =============== 36395 36396 $.fn.tab.noConflict = function () { 36397 $.fn.tab = old 36398 return this 36399 } 36400 36401 36402 // TAB DATA-API 36403 // ============ 36404 36405 $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 36406 e.preventDefault() 36407 $(this).tab('show') 36408 }) 36409 36410}(jQuery); 36411 36412/* ======================================================================== 36413 * Bootstrap: tooltip.js v3.1.1 36414 * http://getbootstrap.com/javascript/#tooltip 36415 * Inspired by the original jQuery.tipsy by Jason Frame 36416 * ======================================================================== 36417 * Copyright 2011-2014 Twitter, Inc. 36418 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36419 * ======================================================================== */ 36420 36421 36422+function ($) { 36423 'use strict'; 36424 36425 // TOOLTIP PUBLIC CLASS DEFINITION 36426 // =============================== 36427 36428 var Tooltip = function (element, options) { 36429 this.type = 36430 this.options = 36431 this.enabled = 36432 this.timeout = 36433 this.hoverState = 36434 this.$element = null 36435 36436 this.init('tooltip', element, options) 36437 } 36438 36439 Tooltip.DEFAULTS = { 36440 animation: true, 36441 placement: 'top', 36442 selector: false, 36443 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 36444 trigger: 'hover focus', 36445 title: '', 36446 delay: 0, 36447 html: false, 36448 container: false, 36449 viewport: { 36450 selector: 'body', 36451 padding: 0 36452 } 36453 } 36454 36455 Tooltip.prototype.init = function (type, element, options) { 36456 this.enabled = true 36457 this.type = type 36458 this.$element = $(element) 36459 this.options = this.getOptions(options) 36460 this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) 36461 36462 var triggers = this.options.trigger.split(' ') 36463 36464 for (var i = triggers.length; i--;) { 36465 var trigger = triggers[i] 36466 36467 if (trigger == 'click') { 36468 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 36469 } else if (trigger != 'manual') { 36470 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 36471 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 36472 36473 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 36474 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 36475 } 36476 } 36477 36478 this.options.selector ? 36479 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 36480 this.fixTitle() 36481 } 36482 36483 Tooltip.prototype.getDefaults = function () { 36484 return Tooltip.DEFAULTS 36485 } 36486 36487 Tooltip.prototype.getOptions = function (options) { 36488 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 36489 36490 if (options.delay && typeof options.delay == 'number') { 36491 options.delay = { 36492 show: options.delay, 36493 hide: options.delay 36494 } 36495 } 36496 36497 return options 36498 } 36499 36500 Tooltip.prototype.getDelegateOptions = function () { 36501 var options = {} 36502 var defaults = this.getDefaults() 36503 36504 this._options && $.each(this._options, function (key, value) { 36505 if (defaults[key] != value) options[key] = value 36506 }) 36507 36508 return options 36509 } 36510 36511 Tooltip.prototype.enter = function (obj) { 36512 var self = obj instanceof this.constructor ? 36513 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36514 36515 clearTimeout(self.timeout) 36516 36517 self.hoverState = 'in' 36518 36519 if (!self.options.delay || !self.options.delay.show) return self.show() 36520 36521 self.timeout = setTimeout(function () { 36522 if (self.hoverState == 'in') self.show() 36523 }, self.options.delay.show) 36524 } 36525 36526 Tooltip.prototype.leave = function (obj) { 36527 var self = obj instanceof this.constructor ? 36528 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36529 36530 clearTimeout(self.timeout) 36531 36532 self.hoverState = 'out' 36533 36534 if (!self.options.delay || !self.options.delay.hide) return self.hide() 36535 36536 self.timeout = setTimeout(function () { 36537 if (self.hoverState == 'out') self.hide() 36538 }, self.options.delay.hide) 36539 } 36540 36541 Tooltip.prototype.show = function () { 36542 var e = $.Event('show.bs.' + this.type) 36543 36544 if (this.hasContent() && this.enabled) { 36545 this.$element.trigger(e) 36546 36547 if (e.isDefaultPrevented()) return 36548 var that = this; 36549 36550 var $tip = this.tip() 36551 36552 this.setContent() 36553 36554 if (this.options.animation) $tip.addClass('fade') 36555 36556 var placement = typeof this.options.placement == 'function' ? 36557 this.options.placement.call(this, $tip[0], this.$element[0]) : 36558 this.options.placement 36559 36560 var autoToken = /\s?auto?\s?/i 36561 var autoPlace = autoToken.test(placement) 36562 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 36563 36564 $tip 36565 .detach() 36566 .cs
36566s({ top: 0, left: 0, display: 'block' }) 36567 .addClass(placement) 36568 36569 this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) 36570 36571 var pos = this.getPosition() 36572 var actualWidth = $tip[0].offsetWidth 36573 var actualHeight = $tip[0].offsetHeight 36574 36575 if (autoPlace) { 36576 var orgPlacement = placement 36577 var $parent = this.$element.parent() 36578 var parentDim = this.getPosition($parent) 36579 36580 placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : 36581 placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : 36582 placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : 36583 placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : 36584 placement 36585 36586 $tip 36587 .removeClass(orgPlacement) 36588 .addClass(placement) 36589 } 36590 36591 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 36592 36593 this.applyPlacement(calculatedOffset, placement) 36594 this.hoverState = null 36595 36596 var complete = function() { 36597 that.$element.trigger('shown.bs.' + that.type) 36598 } 36599 36600 $.support.transition && this.$tip.hasClass('fade') ? 36601 $tip 36602 .one($.support.transition.end, complete) 36603 .emulateTransitionEnd(150) : 36604 complete() 36605 } 36606 } 36607 36608 Tooltip.prototype.applyPlacement = function (offset, placement) { 36609 var $tip = this.tip() 36610 var width = $tip[0].offsetWidth 36611 var height = $tip[0].offsetHeight 36612 36613 // manually read margins because getBoundingClientRect includes difference 36614 var marginTop = parseInt($tip.css('margin-top'), 10) 36615 var marginLeft = parseInt($tip.css('margin-left'), 10) 36616 36617 // we must check for NaN for ie 8/9 36618 if (isNaN(marginTop)) marginTop = 0 36619 if (isNaN(marginLeft)) marginLeft = 0 36620 36621 offset.top = offset.top + marginTop 36622 offset.left = offset.left + marginLeft 36623 36624 // $.fn.offset doesn't round pixel values 36625 // so we use setOffset directly with our own function B-0 36626 $.offset.setOffset($tip[0], $.extend({ 36627 using: function (props) { 36628 $tip.css({ 36629 top: Math.round(props.top), 36630 left: Math.round(props.left) 36631 }) 36632 } 36633 }, offset), 0) 36634 36635 $tip.addClass('in') 36636 36637 // check to see if placing tip in new offset caused the tip to resize itself 36638 var actualWidth = $tip[0].offsetWidth 36639 var actualHeight = $tip[0].offsetHeight 36640 36641 if (placement == 'top' && actualHeight != height) { 36642 offset.top = offset.top + height - actualHeight 36643 } 36644 36645 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 36646 36647 if (delta.left) offset.left += delta.left 36648 else offset.top += delta.top 36649 36650 var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 36651 var arrowPosition = delta.left ? 'left' : 'top' 36652 var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' 36653 36654 $tip.offset(offset) 36655 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) 36656 } 36657 36658 Tooltip.prototype.replaceArrow = function (delta, dimension, position) { 36659 this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '') 36660 } 36661 36662 Tooltip.prototype.setContent = function () { 36663 var $tip = this.tip() 36664 var title = this.getTitle() 36665 36666 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 36667 $tip.removeClass('fade in top bottom left right') 36668 } 36669 36670 Tooltip.prototype.hide = function () { 36671 var that = this 36672 var $tip = this.tip() 36673 var e = $.Event('hide.bs.' + this.type) 36674 36675 function complete() { 36676 if (that.hoverState != 'in') $tip.detach() 36677 that.$element.trigger('hidden.bs.' + that.type) 36678 } 36679 36680 this.$element.trigger(e) 36681 36682 if (e.isDefaultPrevented()) return 36683 36684 $tip.removeClass('in') 36685 36686 $.support.transition && this.$tip.hasClass('fade') ? 36687 $tip 36688 .one($.support.transition.end, complete) 36689 .emulateTransitionEnd(150) : 36690 complete() 36691 36692 this.hoverState = null 36693 36694 return this 36695 } 36696 36697 Tooltip.prototype.fixTitle = function () { 36698 var $e = this.$element 36699 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { 36700 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 36701 } 36702 } 36703 36704 Tooltip.prototype.hasContent = function () { 36705 return this.getTitle() 36706 } 36707 36708 Tooltip.prototype.getPosition = function ($element) { 36709 $element = $element || this.$element 36710 var el = $element[0] 36711 var isBody = el.tagName == 'BODY' 36712 return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, { 36713 scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), 36714 width: isBody ? $(window).width() : $element.outerWidth(), 36715 height: isBody ? $(window).height() : $element.outerHeight() 36716 }, isBody ? {top: 0, left: 0} : $element.offset()) 36717 } 36718 36719 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 36720 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36721 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36722 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 36723 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 36724 36725 } 36726 36727 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 36728 var delta = { top: 0, left: 0 } 36729 if (!this.$viewport) return delta 36730 36731 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 36732 var viewportDimensions = this.getPosition(this.$viewport) 36733 36734 if (/right|left/.test(placement)) { 36735 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 36736 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 36737 if (topEdgeOffset < viewportDimensions.top) { // top overflow 36738 delta.top = viewportDimensions.top - topEdgeOffset 36739 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 36740 delta.top = viewportDimensions.top + viewportDimensions.height - bottom
36740EdgeOffset 36741 } 36742 } else { 36743 var leftEdgeOffset = pos.left - viewportPadding 36744 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 36745 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 36746 delta.left = viewportDimensions.left - leftEdgeOffset 36747 } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow 36748 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 36749 } 36750 } 36751 36752 return delta 36753 } 36754 36755 Tooltip.prototype.getTitle = function () { 36756 var title 36757 var $e = this.$element 36758 var o = this.options 36759 36760 title = $e.attr('data-original-title') 36761 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 36762 36763 return title 36764 } 36765 36766 Tooltip.prototype.tip = function () { 36767 return this.$tip = this.$tip || $(this.options.template) 36768 } 36769 36770 Tooltip.prototype.arrow = function () { 36771 return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow') 36772 } 36773 36774 Tooltip.prototype.validate = function () { 36775 if (!this.$element[0].parentNode) { 36776 this.hide() 36777 this.$element = null 36778 this.options = null 36779 } 36780 } 36781 36782 Tooltip.prototype.enable = function () { 36783 this.enabled = true 36784 } 36785 36786 Tooltip.prototype.disable = function () { 36787 this.enabled = false 36788 } 36789 36790 Tooltip.prototype.toggleEnabled = function () { 36791 this.enabled = !this.enabled 36792 } 36793 36794 Tooltip.prototype.toggle = function (e) { 36795 var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this 36796 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 36797 } 36798 36799 Tooltip.prototype.destroy = function () { 36800 clearTimeout(this.timeout) 36801 this.hide().$element.off('.' + this.type).removeData('bs.' + this.type) 36802 } 36803 36804 36805 // TOOLTIP PLUGIN DEFINITION 36806 // ========================= 36807 36808 var old = $.fn.tooltip 36809 36810 $.fn.tooltip = function (option) { 36811 return this.each(function () { 36812 var $this = $(this) 36813 var data = $this.data('bs.tooltip') 36814 var options = typeof option == 'object' && option 36815 36816 if (!data && option == 'destroy') return 36817 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 36818 if (typeof option == 'string') data[option]() 36819 }) 36820 } 36821 36822 $.fn.tooltip.Constructor = Tooltip 36823 36824 36825 // TOOLTIP NO CONFLICT 36826 // =================== 36827 36828 $.fn.tooltip.noConflict = function () { 36829 $.fn.tooltip = old 36830 return this 36831 } 36832 36833}(jQuery); 36834 36835/* ======================================================================== 36836 * Bootstrap: transition.js v3.1.1 36837 * http://getbootstrap.com/javascript/#transitions 36838 * ======================================================================== 36839 * Copyright 2011-2014 Twitter, Inc. 36840 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36841 * ======================================================================== */ 36842 36843 36844+function ($) { 36845 'use strict'; 36846 36847 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 36848 // ============================================================ 36849 36850 function transitionEnd() { 36851 var el = document.createElement('bootstrap') 36852 36853 var transEndEventNames = { 36854 WebkitTransition : 'webkitTransitionEnd', 36855 MozTransition : 'transitionend', 36856 OTransition : 'oTransitionEnd otransitionend', 36857 transition : 'transitionend' 36858 } 36859 36860 for (var name in transEndEventNames) { 36861 if (el.style[name] !== undefined) { 36862 return { end: transEndEventNames[name] } 36863 } 36864 } 36865 36866 return false // explicit for ie8 ( ._.) 36867 } 36868 36869 // http://blog.alexmaccaw.com/css-transitions 36870 $.fn.emulateTransitionEnd = function (duration) { 36871 var called = false, $el = this 36872 $(this).one($.support.transition.end, function () { called = true }) 36873 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 36874 setTimeout(callback, duration) 36875 return this 36876 } 36877 36878 $(function () { 36879 $.support.transition = transitionEnd() 36880 }) 36881 36882}(jQuery); 36883 36884 36885// ------------------------------------------ 36886// Rellax.js 36887// Buttery smooth parallax library 36888// Copyright (c) 2016 Moe Amaya (@moeamaya) 36889// MIT license 36890// 36891// Thanks to Paraxify.js and Jaime Cabllero 36892// for parallax concepts 36893// ------------------------------------------ 36894 36895(function (root, factory) { 36896 if (typeof define === 'function' && define.amd) { 36897 // AMD. Register as an anonymous module. 36898 define([], factory); 36899 } else if (typeof module === 'object' && module.exports) { 36900 // Node. Does not work with strict CommonJS, but 36901 // only CommonJS-like environments that support module.exports, 36902 // like Node. 36903 module.exports = factory(); 36904 } else { 36905 // Browser globals (root is window) 36906 root.Rellax = factory(); 36907 } 36908}(typeof window !== "undefined" ? window : global, function () { 36909 var Rellax = function(el, options){ 36910 "use strict"; 36911 36912 var self = Object.create(Rellax.prototype); 36913 36914 var posY = 0; 36915 var screenY = 0; 36916 var posX = 0; 36917 var screenX = 0; 36918 var blocks = []; 36919 var pause = true; 36920 36921 // check what requestAnimationFrame to use, and if 36922 // it's not supported, use the onscroll event 36923 var loop = window.requestAnimationFrame || 36924 window.webkitRequestAnimationFrame || 36925 window.mozRequestAnimationFrame || 36926 window.msRequestAnimationFrame || 36927 window.oRequestAnimationFrame || 36928 function(callback){ return setTimeout(callback, 1000 / 60); }; 36929 36930 // store the id for later use 36931 var loopId = null; 36932 36933 // Test via a getter in the options object to see if the passive property is accessed 36934 var supportsPassive = false;
vendor: 10,724 bytes, lines 36935-37236
36935 try { 36936 var opts = Object.defineProperty({}, 'passive', { 36937 get: function() { 36938 supportsPassive = true; 36939 } 36940 }); 36941 window.addEventListener("testPassive", null, opts); 36942 window.removeEventListener("testPassive", null, opts); 36943 } catch (e) {} 36944 36945 // check what cancelAnimation method to use 36946 var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout; 36947 36948 // check which transform property to use 36949 var transformProp = window.transformProp || (function(){ 36950 var testEl = document.createElement('div'); 36951 if (testEl.style.transform === null) { 36952 var vendors = ['Webkit', 'Moz', 'ms']; 36953 for (var vendor in vendors) { 36954 if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) { 36955 return vendors[vendor] + 'Transform'; 36956 } 36957 } 36958 } 36959 return 'transform'; 36960 })(); 36961 36962 // Default Settings 36963 self.options = { 36964 speed: -2, 36965 verticalSpeed: null, 36966 horizontalSpeed: null, 36967 breakpoints: [576, 768, 1201], 36968 center: false, 36969 wrapper: null, 36970 relativeToWrapper: false, 36971 round: true, 36972 vertical: true, 36973 horizontal: false, 36974 verticalScrollAxis: "y", 36975 horizontalScrollAxis: "x", 36976 callback: function() {}, 36977 }; 36978 36979 // User defined options (might have more in the future) 36980 if (options){ 36981 Object.keys(options).forEach(function(key){ 36982 self.options[key] = options[key]; 36983 }); 36984 } 36985 36986 function validateCustomBreakpoints () { 36987 if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) { 36988 var isAscending = true; 36989 var isNumerical = true; 36990 var lastVal; 36991 self.options.breakpoints.forEach(function (i) { 36992 if (typeof i !== 'number') isNumerical = false; 36993 if (lastVal !== null) { 36994 if (i < lastVal) isAscending = false; 36995 } 36996 lastVal = i; 36997 }); 36998 if (isAscending && isNumerical) return; 36999 } 37000 // revert defaults if set incorrectly 37001 self.options.breakpoints = [576, 768, 1201]; 37002 console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted"); 37003 } 37004 37005 if (options && options.breakpoints) { 37006 validateCustomBreakpoints(); 37007 } 37008 37009 // By default, rellax class 37010 if (!el) { 37011 el = '.rellax'; 37012 } 37013 37014 // check if el is a className or a node 37015 var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el]; 37016 37017 // Now query selector 37018 if (elements.length > 0) { 37019 self.elems = elements; 37020 } 37021 37022 // The elements don't exist 37023 else { 37024 console.warn("Rellax: The elements you're trying to select don't exist."); 37025 return; 37026 } 37027 37028 // Has a wrapper and it exists 37029 if (self.options.wrapper) { 37030 if (!self.options.wrapper.nodeType) { 37031 var wrapper = document.querySelector(self.options.wrapper); 37032 37033 if (wrapper) { 37034 self.options.wrapper = wrapper; 37035 } else { 37036 console.warn("Rellax: The wrapper you're trying to use doesn't exist."); 37037 return; 37038 } 37039 } 37040 } 37041 37042 // set a placeholder for the current breakpoint 37043 var currentBreakpoint; 37044 37045 // helper to determine current breakpoint 37046 var getCurrentBreakpoint = function (w) { 37047 var bp = self.options.breakpoints; 37048 if (w < bp[0]) return 'xs'; 37049 if (w >= bp[0] && w < bp[1]) return 'sm'; 37050 if (w >= bp[1] && w < bp[2]) return 'md'; 37051 return 'lg'; 37052 }; 37053 37054 // Get and cache initial position of all elements 37055 var cacheBlocks = function() { 37056 for (var i = 0; i < self.elems.length; i++){ 37057 var block = createBlock(self.elems[i]); 37058 blocks.push(block); 37059 } 37060 }; 37061 37062 37063 // Let's kick this script off 37064 // Build array for cached element values 37065 var init = function() { 37066 for (var i = 0; i < blocks.length; i++){ 37067 self.elems[i].style.cssText = blocks[i].style; 37068 } 37069 37070 blocks = []; 37071 37072 screenY = window.innerHeight; 37073 screenX = window.innerWidth; 37074 currentBreakpoint = getCurrentBreakpoint(screenX); 37075 37076 setPosition(); 37077 37078 cacheBlocks(); 37079 37080 animate(); 37081 37082 // If paused, unpause and set listener for window resizing events 37083 if (pause) { 37084 window.addEventListener('resize', init); 37085 pause = false; 37086 // Start the loop 37087 update(); 37088 } 37089 }; 37090 37091 // We want to cache the parallax blocks' 37092 // values: base, top, height, speed 37093 // el: is dom object, return: el cache values 37094 var createBlock = function(el) { 37095 var dataPercentage = el.getAttribute( 'data-rellax-percentage' ); 37096 var dataSpeed = el.getAttribute( 'data-rellax-speed' ); 37097 var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' ); 37098 var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' ); 37099 var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' ); 37100 var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' ); 37101 var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed'); 37102 var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed'); 37103 var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis'); 37104 var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis'); 37105 var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0; 37106 var dataMin = el.getAttribute( 'data-rellax-min' ); 37107 var dataMax = el.getAttribute( 'data-rellax-max' ); 37108 var dataMinX = el.getAttribute('data-rellax-min-x'); 37109 var dataMaxX = el.getAttribute('data-rellax-max-x'); 37110 var dataMinY = el.getAttribute('data-rellax-min-y'); 37111 var dataMaxY = el.getAttribute('data-rellax-max-y'); 37112 var mapBreakpoints; 37113 var breakpoints = true; 37114 37115 if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) { 37116 breakpoints = false; 37117 } else { 37118 mapBreakpoints = { 37119 'xs': dataXsSpeed, 37120 'sm': dataMobileSpeed, 37121 'md': dataTabletSpeed, 37122 'lg': dataDesktopSpeed 37123 }; 37124 } 37125 37126 // initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser) 37127 // ensures elements are positioned based on HTML layout. 37128 // 37129 // If the element has the percentage attribute, the posY and posX needs to be 37130 // the current scroll position's value, so that the elements are still positioned based on HTML layout 37131 var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37132 // If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll. 37133 if (self.options.relativeToWrapper) { 37134 var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37135 wrapperPosY = scrollPosY - self.options.wrapper.offsetTop; 37136 } 37137 var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0; 37138 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; 37139 37140 var blockTop = posY + el.getBoundingClientRect().top; 37141 var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight; 37142 37143 var blockLeft = posX + el.getBoundingClientRect().left; 37144 var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth; 37145 37146 // apparently parallax equation everyone uses 37147 var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY); 37148 var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX); 37149 if(self.options.center){ percentageX = 0.5; percentageY = 0.5; } 37150 37151 // Optional individual block speed as data attr, otherwise global speed 37152 var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed); 37153 var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed; 37154 var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed; 37155 37156 // Optional individual block movement axis direction as data attr, otherwise global movement direction 37157 var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis; 37158 var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis; 37159 37160 var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed); 37161 37162 // ~~Store non-translate3d transforms~~ 37163 // Store inline styles and extract transforms 37164 var style = el.style.cssText; 37165 var transform = ''; 37166 37167 // Check if there's an inline styled transform 37168 var searchResult = /transform\s*:/i.exec(style); 37169 if (searchResult) { 37170 // Get the index of the transform 37171 var index = searchResult.index; 37172 37173 // Trim the style to the transform point and get the following semi-colon index 37174 var trimmedStyle = style.slice(index); 37175 var delimiter = trimmedStyle.indexOf(';'); 37176 37177 // Remove "transform" string and save the attribute 37178 if (delimiter) { 37179 transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,''); 37180 } else { 37181 transform = " " + trimmedStyle.slice(11).replace(/\s/g,''); 37182 } 37183 } 37184 37185 return { 37186 baseX: bases.x, 37187 baseY: bases.y, 37188 top: blockTop, 37189 left: blockLeft, 37190 height: blockHeight, 37191 width: blockWidth, 37192 speed: speed, 37193 verticalSpeed: verticalSpeed, 37194 horizontalSpeed: horizontalSpeed, 37195 verticalScrollAxis: verticalScrollAxis, 37196 horizontalScrollAxis: horizontalScrollAxis, 37197 style: style, 37198 transform: transform, 37199 zindex: dataZindex, 37200 min: dataMin, 37201 max: dataMax, 37202 minX: dataMinX, 37203 maxX: dataMaxX, 37204 minY: dataMinY, 37205 maxY: dataMaxY 37206 }; 37207 }; 37208 37209 // set scroll position (posY, posX) 37210 // side effect method is not ideal, but okay for now 37211 // returns true if the scroll changed, false if nothing happened 37212 var setPosition = function() { 37213 var oldY = posY; 37214 var oldX = posX; 37215 37216 posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37217 posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset; 37218 // If option relativeToWrapper is true, use relative wrapper value instead. 37219 if (self.options.relativeToWrapper) { 37220 var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37221 posY = scrollPosY - self.options.wrapper.offsetTop; 37222 } 37223 37224 37225 if (oldY != posY && self.options.vertical) { 37226 // scroll changed, return true 37227 return true; 37228 } 37229 37230 if (oldX != posX && self.options.horizontal) { 37231 // scroll changed, return true 37232 return true; 37233 } 37234 37235 // scroll did not change 37236 return false;
37237 }; 37238 37239 // Ahh a pure function, gets new transform value 37240 // based on scrollPosition and speed 37241 // Allow for decimal pixel values 37242 var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) { 37243 var result = {}; 37244 var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX))); 37245 var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY))); 37246 37247 result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100; 37248 result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100; 37249 37250 return result; 37251 }; 37252 37253 // Remove event listeners and loop again 37254 var deferredUpdate = function() { 37255 window.removeEventListener('resize', deferredUpdate); 37256 window.removeEventListener('orientationchange', deferredUpdate); 37257 (self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate); 37258 (self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate); 37259 37260 // loop again 37261 loopId = loop(update); 37262 }; 37263 37264 // Loop 37265 var update = function() { 37266 if (setPosition() && pause === false) { 37267 animate(); 37268 37269 // loop again 37270 loopId = loop(update); 37271 } else { 37272 loopId = null; 37273 37274 // Don't animate until we get a position updating event 37275 window.addEventListener('resize', deferredUpdate); 37276 window.addEventListener('orientationchange', deferredUpdate); 37277 (self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false); 37278 (self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false); 37279 } 37280 }; 37281 37282 // Transform3d on parallax element 37283 var animate = function() { 37284 var positions; 37285 for (var i = 0; i < self.elems.length; i++){ 37286 // Determine relevant movement directions 37287 var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase(); 37288 var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase(); 37289 var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0; 37290 var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0; 37291 var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0; 37292 var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0; 37293 37294 var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY)); 37295 var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX)); 37296 37297 // Subtracting initialize value, so element stays in same spot as HTML 37298 positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed); 37299 var positionY = positions.y - blocks[i].baseY; 37300 var positionX = positions.x - blocks[i].baseX; 37301 37302 // The next two "if" blocks go like this: 37303 // Check if a limit is defined (first "min", then "max"); 37304 // Check if we need to change the Y or the X 37305 // (Currently working only if just one of the axes is enabled) 37306 // Then, check if the new position is inside the allowed limit 37307 // If so, use new position. If not, set position to limit. 37308 37309 // Check if a min limit is defined 37310 if (blocks[i].min !== null) { 37311 if (self.options.vertical && !self.options.horizontal) { 37312 positionY = positionY <= blocks[i].min ? blocks[i].min : positionY; 37313 } 37314 if (self.options.horizontal && !self.options.vertical) { 37315 positionX = positionX <= blocks[i].min ? blocks[i].min : positionX; 37316 } 37317 } 37318 37319 // Check if directional min limits are defined 37320 if (blocks[i].minY != null) { 37321 positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY; 37322 } 37323 if (blocks[i].minX != null) { 37324 positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX; 37325 } 37326 37327 // Check if a max limit is defined 37328 if (blocks[i].max !== null) { 37329 if (self.options.vertical && !self.options.horizontal) { 37330 positionY = positionY >= blocks[i].max ? blocks[i].max : positionY; 37331 } 37332 if (self.options.horizontal && !self.options.vertical) { 37333 positionX = positionX >= blocks[i].max ? blocks[i].max : positionX; 37334 } 37335 } 37336 37337 // Check if directional max limits are defined 37338 if (blocks[i].maxY != null) { 37339 positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY; 37340 } 37341 if (blocks[i].maxX != null) { 37342 positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX; 37343 } 37344 37345 var zindex = blocks[i].zindex; 37346 37347 // Move that element 37348 // (Set the new translation and append initial inline transforms.) 37349 var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform; 37350 self.elems[i].style[transformProp] = translate; 37351 } 37352 self.options.callback(positions); 37353 }; 37354 37355 self.destroy = function() { 37356 for (var i = 0; i < self.elems.length; i++){ 37357 self.elems[i].style.cssText = blocks[i].style; 37358 } 37359 37360 // Remove resize event listener if not pause, and pause 37361 if (!pause) { 37362 window.removeEventListener('resize', init); 37363 pause = true; 37364 } 37365 37366 // Clear the animation loop to prevent possible memory leak 37367 clearLoop(loopId); 37368 loopId = null; 37369 }; 37370 37371 // Init 37372 init(); 37373 37374 // Allow to recalculate the initial values whenever we want 37375 self.refresh = init; 37376 37377 return self; 37378 }; 37379 return Rellax; 37380})); 37381 37382/* 37383 * OKVideo by OKFocus v2.3.2 37384 * http://okfoc.us 37385 * 37386 * Copyright 2014, OKFocus 37387 * Licensed under the MIT license. 37388 * 37389 */ 37390var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array(); 37391// youtube player ready 37392function onYouTubeIframeAPIReady() { 37393 YTplayers = new Array(); 37394 jQuery('.uncode-video-container.video').each(function() { 37395 var playerY; 37396 if (jQuery(this).attr('data-provider') == 'youtube') { 37397 var id = jQuery(this).attr('data-id'), 37398 start = jQuery(this).attr('data-start'), 37399 end = jQuery(this).attr('data-end'); 37400 start = typeof start && start !== null ? start : 0; 37401 end = typeof end && end !== null ? end : 0; 37402 options = jQuery(window).data('okoptions-' + id); 37403 if ( typeof options === 'undefined' ) { 37404 return true; 37405 } 37406 options.time = jQuery(this).attr('data-t'); 37407 playerY = new YT.Player('okplayer-' + id, { 37408 videoId: options.video ? options.video.id : null, 37409 playerVars: { 37410 'autohide': 1, 37411 'autoplay': jQuery(this).hasClass('is-no-control') ? options.autoplay : 0, //options.autoplay, 37412 'disablekb': 1, 37413 'cc_load_policy': options.captions, 37414 'controls': 0, 37415 'enablejsapi': 1, 37416 'fs': 0, 37417 'modestbranding': 1, 37418 'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname), 37419 'iv_load_policy': options.annotations, 37420 'loop': options.loop, 37421 'showinfo': 0, 37422 'rel': 0, 37423 'wmode': 'opaque', 37424 'hd': options.hd, 37425 'mute': 1, 37426 'start': start, 37427 'end': end 37428 }, 37429 events: { 37430 'onReady': OKEvents.yt.ready, 37431 'onStateChange': OKEvents.yt.onStateChange, 37432 'onError': OKEvents.yt.error 37433 } 37434 }); 37435 YTplayers[id] = playerY; 37436 playerY.videoId = id; 37437 } 37438 37439 }); 37440} 37441// vimeo player ready 37442function vimeoPlayerReady(id) { 37443 options = jQuery(window).data('okoptions-' + id); 37444 if ( typeof options === 'undefined' ) { 37445 return true; 37446 }
37447 var jIframe = options.jobject, 37448 iframe = jIframe[0]; 37449 37450 jIframe.attr('src', jIframe.data('src')); 37451 var playerV = new Vimeo.Player(iframe); 37452 // hide player until Vimeo hides controls... 37453 playerV.on('loaded', function(e) { 37454 OKEvents.v.onReady(iframe); 37455 var carouselContainer = jQuery(iframe).closest('.owl-carousel'); 37456 if (carouselContainer.length) { 37457 UNCODE.owlPlayVideo(carouselContainer); 37458 } 37459 // "Do not try to add listeners or call functions before receiving this event." 37460 if (OKEvents.utils.isMobile()) { 37461 // mobile devices cannot listen for play event 37462 OKEvents.v.onPlay(playerV); 37463 } else { 37464 playerV.on('play', function(){ 37465 OKEvents.v.onPlay(playerV); 37466 jQuery(window).trigger('okevents.v.play', [playerV]); 37467 }); 37468 playerV.on('pause', function(){ 37469 OKEvents.v.onPause; 37470 jQuery(window).trigger('okevents.v.pause', [playerV]); 37471 }); 37472 playerV.on('ended', function(){ 37473 OKEvents.v.onFinish 37474 jQuery(window).trigger('okevents.v.ended', [playerV]); 37475 }); 37476 } 37477 if (options.time != null) { 37478 var optsTimeStr = (options.time).replace('t=', ''), 37479 timeV = ''; 37480 37481 if ( /[a-zA-Z]/g.test(optsTimeStr) ) { 37482 var timeArr = optsTimeStr.split(/([^\d.-])/); 37483 for ( var i = 0; i < timeArr.length; i++ ) { 37484 if ( timeArr[i] === 'h' ) { 37485 timeV += parseFloat(timeArr[i-1]) * 3600; 37486 } else if ( timeArr[i] === 'm' ) { 37487 timeV += parseFloat(timeArr[i-1]) * 60; 37488 } else if ( timeArr[i] === 's' ) { 37489 timeV += parseFloat(timeArr[i-1]); 37490 } 37491 } 37492 } else { 37493 timeV = optsTimeStr; 37494 } 37495 37496 playerV.setCurrentTime(timeV); 37497 } 37498 37499 playerV.setVolume(0); 37500 playerV.play(); 37501 jQuery(iframe).css({ 37502 visibility: 'visible', 37503 opacity: 1 37504 }); 37505 jQuery(iframe).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37506 jQuery(iframe).closest('#page-header').addClass('video-started'); 37507 jQuery(iframe).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37508 37509 jQuery(window).trigger('okevents.v.loaded', [playerV]); 37510 }); 37511} 37512OKEvents = { 37513 yt: { 37514 ready: function(event) { 37515 var id = event.target.videoId, 37516 $video = jQuery('#okplayer-' + id), 37517 options = jQuery(window).data('okoptions-' + id); 37518 if ( typeof options === 'undefined' ) { 37519 return true; 37520 } 37521 youtubePlayers[id] = event.target; 37522 event.target.setVolume(options.volume); 37523 if (options.autoplay === 1) { 37524 if (options.playlist.list) { 37525 player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality); 37526 } else { 37527 var inCarousel = $video.closest('.owl-item'); 37528 if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) { 37529 if (options.time != null) { 37530 event.target.seekTo(parseInt(options.time)); 37531 } 37532 event.target.playVideo(); 37533 } else { 37534 event.target.pauseVideo(); 37535 } 37536 } 37537 } 37538 OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target); 37539 37540 $video.closest('[data-provider]').on('uncode-resume', function(){ 37541 if (options.time != null) { 37542 event.target.seekTo(parseInt(options.time)).playVideo(); 37543 } else { 37544 event.target.seekTo(0).playVideo(); 37545 } 37546 }); 37547 37548 $video.closest('[data-provider]').on('uncode-pause', function(){ 37549 if (options.time != null) { 37550 event.target.seekTo(parseInt(options.time)).pauseVideo(); 37551 } else { 37552 event.target.seekTo(0).pauseVideo(); 37553 } 37554 }); 37555 jQuery(window).trigger('okevents.y.loaded', [event]); 37556 }, 37557 onStateChange: function(event) { 37558 var id = event.target.videoId, 37559 $video = jQuery('#okplayer-' + id), 37560 options = jQuery(window).data('okoptions-' + id); 37561 if ( typeof options === 'undefined' ) { 37562 return true; 37563 } 37564 youtubePlayers[id] = event.target; 37565 event.target.setVolume(options.volume); 37566 var $fluid = $video.closest('.fluid-object'), 37567 $tmb = $video.closest('.tmb'), 37568 setTime; 37569 switch (event.data) { 37570 case -1: 37571 OKEvents.utils.isFunction(options.unstarted) && options.unstarted(); 37572 break; 37573 case 0: 37574 OKEvents.utils.isFunction(options.onFinished) && options.onFinished(); 37575 options.loop && event.target.playVideo(); 37576 break; 37577 case 1: 37578 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37579 setTimeout(function() { 37580 UNCODE.initVideoComponent(document.body, '.uncode-video-container.video:not(.drop-move), .uncode-video-container.self-video:not(.drop-move)'); 37581 jQuery('#okplayer-' + id).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37582 jQuery('#okplayer-' + id).closest('#page-header').addClass('video-started'); 37583 jQuery('#okplayer-' + id).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37584 }, 300); 37585 break; 37586 case 2: 37587 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37588 break; 37589 case 3: 37590 OKEvents.utils.isFunction(options.buffering) && options.buffering(); 37591 break; 37592 case 5: 37593 OKEvents.utils.isFunction(options.cued) && options.cued(); 37594 break; 37595 default:
37596 throw "OKVideo: received invalid data from YT player."; 37597 } 37598 37599 jQuery(window).trigger('okevents.y.change', [event]); 37600 }, 37601 error: function(event) { 37602 throw event; 37603 } 37604 }, 37605 v: { 37606 onReady: function(target) { 37607 if ( typeof options === 'undefined' ) { 37608 return true; 37609 } 37610 OKEvents.utils.isFunction(options.onReady) && options.onReady(target); 37611 }, 37612 onPlay: function(player) { 37613 if ( typeof options === 'undefined' ) { 37614 return true; 37615 } 37616 if (!OKEvents.utils.isMobile()) player.setVolume(options.volume); 37617 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37618 jQuery(player.element).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37619 jQuery(player.element).closest('#page-header').addClass('video-started'); 37620 jQuery(player.element).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37621 }, 37622 onPause: function() { 37623 if ( typeof options === 'undefined' ) { 37624 return true; 37625 } 37626 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37627 }, 37628 onFinish: function() { 37629 if ( typeof options === 'undefined' ) { 37630 return true; 37631 } 37632 OKEvents.utils.isFunction(options.onFinish) && options.onFinish(); 37633 } 37634 }, 37635 utils: { 37636 isFunction: function(func) { 37637 if (typeof func === 'function') { 37638 return true; 37639 } else { 37640 return false; 37641 } 37642 }, 37643 isMobile: function() { 37644 if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) { 37645 return true; 37646 } else { 37647 return false; 37648 } 37649 } 37650 } 37651}; 37652 37653/** 37654 * vivus - JavaScript library to make drawing animation on SVG 37655 * @version v0.4.4 37656 * @link https://github.com/maxwellito/vivus 37657 * @license MIT 37658 */ 37659 37660'use strict'; 37661 37662(function () { 37663 37664 'use strict'; 37665 37666/** 37667 * Pathformer 37668 * Beta version 37669 * 37670 * Take any SVG version 1.1 and transform 37671 * child elements to 'path' elements 37672 * 37673 * This code is purely forked from 37674 * https://github.com/Waest/SVGPathConverter 37675 */ 37676 37677/** 37678 * Class constructor 37679 * 37680 * @param {DOM|String} element Dom element of the SVG or id of it 37681 */ 37682function Pathformer(element) { 37683 // Test params 37684 if (typeof element === 'undefined') { 37685 throw new Error('Pathformer [constructor]: "element" parameter is required'); 37686 } 37687 37688 // Set the element 37689 if (element.constructor === String) { 37690 element = document.getElementById(element); 37691 if (!element) { 37692 throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID'); 37693 } 37694 } 37695 if (element instanceof window.SVGElement || 37696 element instanceof window.SVGGElement || 37697 /^svg$/i.test(element.nodeName)) { 37698 this.el = element; 37699 } else { 37700 throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'); 37701 } 37702 37703 // Start 37704 this.scan(element); 37705} 37706 37707/** 37708 * List of tags which can be transformed 37709 * to path elements 37710 * 37711 * @type {Array} 37712 */ 37713Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect']; 37714 37715/** 37716 * List of attribute names which contain 37717 * data. This array list them to check if 37718 * they contain bad values, like percentage. 37719 * 37720 * @type {Array} 37721 */ 37722Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
vendor: 24,640 bytes, lines 37722-38520
37722y1', 'y2']; 37723 37724/** 37725 * Finds the elements compatible for transform 37726 * and apply the liked method 37727 * 37728 * @param {object} options Object from the constructor 37729 */ 37730Pathformer.prototype.scan = function (svg) { 37731 var fn, element, pathData, pathDom, 37732 elements = svg.querySelectorAll(this.TYPES.join(',')); 37733 37734 for (var i = 0; i < elements.length; i++) { 37735 element = elements[i]; 37736 fn = this[element.tagName.toLowerCase() + 'ToPath']; 37737 pathData = fn(this.parseAttr(element.attributes)); 37738 pathDom = this.pathMaker(element, pathData); 37739 element.parentNode.replaceChild(pathDom, element); 37740 } 37741}; 37742 37743 37744/** 37745 * Read `line` element to extract and transform 37746 * data, to make it ready for a `path` object. 37747 * 37748 * @param {DOMelement} element Line element to transform 37749 * @return {object} Data for a `path` element 37750 */ 37751Pathformer.prototype.lineToPath = function (element) { 37752 var newElement = {}, 37753 x1 = element.x1 || 0, 37754 y1 = element.y1 || 0, 37755 x2 = element.x2 || 0, 37756 y2 = element.y2 || 0; 37757 37758 newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2; 37759 return newElement; 37760}; 37761 37762/** 37763 * Read `rect` element to extract and transform 37764 * data, to make it ready for a `path` object. 37765 * The radius-border is not taken in charge yet. 37766 * (your help is more than welcomed) 37767 * 37768 * @param {DOMelement} element Rect element to transform 37769 * @return {object} Data for a `path` element 37770 */ 37771Pathformer.prototype.rectToPath = function (element) { 37772 var newElement = {}, 37773 x = parseFloat(element.x) || 0, 37774 y = parseFloat(element.y) || 0, 37775 width = parseFloat(element.width) || 0, 37776 height = parseFloat(element.height) || 0; 37777 37778 if (element.rx || element.ry) { 37779 var rx = parseInt(element.rx, 10) || -1, 37780 ry = parseInt(element.ry, 10) || -1; 37781 rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2); 37782 ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2); 37783 37784 newElement.d = 'M ' + (x + rx) + ',' + y + ' ' + 37785 'L ' + (x + width - rx) + ',' + y + ' ' + 37786 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' + 37787 'L ' + (x + width) + ',' + (y + height - ry) + ' ' + 37788 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' + 37789 'L ' + (x + rx) + ',' + (y + height) + ' ' + 37790 'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' + 37791 'L ' + x + ',' + (y + ry) + ' ' + 37792 'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y; 37793 } 37794 else { 37795 newElement.d = 'M' + x + ' ' + y + ' ' + 37796 'L' + (x + width) + ' ' + y + ' ' + 37797 'L' + (x + width) + ' ' + (y + height) + ' ' + 37798 'L' + x + ' ' + (y + height) + ' Z'; 37799 } 37800 return newElement; 37801}; 37802 37803/** 37804 * Read `polyline` element to extract and transform 37805 * data, to make it ready for a `path` object. 37806 * 37807 * @param {DOMelement} element Polyline element to transform 37808 * @return {object} Data for a `path` element 37809 */ 37810Pathformer.prototype.polylineToPath = function (element) { 37811 var newElement = {}, 37812 points = element.points.trim().split(' '), 37813 i, path; 37814 37815 // Reformatting if points are defined without commas 37816 if (element.points.indexOf(',') === -1) { 37817 var formattedPoints = []; 37818 for (i = 0; i < points.length; i+=2) { 37819 formattedPoints.push(points[i] + ',' + points[i+1]); 37820 } 37821 points = formattedPoints; 37822 } 37823 37824 // Generate the path.d value 37825 path = 'M' + points[0]; 37826 for(i = 1; i < points.length; i++) { 37827 if (points[i].indexOf(',') !== -1) { 37828 path += 'L' + points[i]; 37829 } 37830 } 37831 newElement.d = path; 37832 return newElement; 37833}; 37834 37835/** 37836 * Read `polygon` element to extract and transform 37837 * data, to make it ready for a `path` object. 37838 * This method rely on polylineToPath, because the 37839 * logic is similar. The path created is just closed, 37840 * so it needs an 'Z' at the end. 37841 * 37842 * @param {DOMelement} element Polygon element to transform 37843 * @return {object} Data for a `path` element 37844 */ 37845Pathformer.prototype.polygonToPath = function (element) { 37846 var newElement = Pathformer.prototype.polylineToPath(element); 37847 37848 newElement.d += 'Z'; 37849 return newElement; 37850}; 37851 37852/** 37853 * Read `ellipse` element to extract and transform 37854 * data, to make it ready for a `path` object. 37855 * 37856 * @param {DOMelement} element ellipse element to transform 37857 * @return {object} Data for a `path` element 37858 */ 37859Pathformer.prototype.ellipseToPath = function (element) { 37860 var newElement = {}, 37861 rx = parseFloat(element.rx) || 0, 37862 ry = parseFloat(element.ry) || 0, 37863 cx = parseFloat(element.cx) || 0, 37864 cy = parseFloat(element.cy) || 0, 37865 startX = cx - rx, 37866 startY = cy, 37867 endX = parseFloat(cx) + parseFloat(rx), 37868 endY = cy; 37869 37870 newElement.d = 'M' + startX + ',' + startY + 37871 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY + 37872 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY; 37873 return newElement; 37874}; 37875 37876/** 37877 * Read `circle` element to extract and transform 37878 * data, to make it ready for a `path` object. 37879 * 37880 * @param {DOMelement} element Circle element to transform 37881 * @return {object} Data for a `path` element 37882 */ 37883Pathformer.prototype.circleToPath = function (element) { 37884 var newElement = {}, 37885 r = parseFloat(element.r) || 0, 37886 cx = parseFloat(element.cx) || 0, 37887 cy = parseFloat(element.cy) || 0, 37888 startX = cx - r, 37889 startY = cy, 37890 endX = parseFloat(cx) + parseFloat(r), 37891 endY = cy; 37892 37893 newElement.d = 'M' + startX + ',' + startY + 37894 'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY + 37895 'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY; 37896 return newElement; 37897}; 37898 37899/** 37900 * Create `path` elements form original element 37901 * and prepared objects 37902 * 37903 * @param {DOMelement} element Original element to transform 37904 * @param {object} pathData Path data (from `toPath` methods) 37905 * @return {DOMelement} Path element 37906 */ 37907Pathformer.prototype.pathMaker = function (element, pathData) { 37908 var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path'); 37909 for(i = 0; i < element.attributes.length; i++) { 37910 attr = element.attributes[i]; 37911 if (this.ATTR_WATCH.indexOf(attr.name) === -1) { 37912 pathTag.setAttribute(attr.name, attr.value); 37913 } 37914 } 37915 for(i in pathData) { 37916 pathTag.setAttribute(i, pathData[i]); 37917 } 37918 return pathTag; 37919}; 37920 37921/** 37922 * Parse attributes of a DOM element to 37923 * get an object of attribute => value 37924 * 37925 * @param {NamedNodeMap} attributes Attributes object from DOM element to parse 37926 * @return {object} Object of attributes 37927 */ 37928Pathformer.prototype.parseAttr = function (element) { 37929 var attr, output = {}; 37930 for (var i = 0; i < element.length; i++) { 37931 attr = element[i]; 37932 // Check if no data attribute contains '%', or the transformation is impossible 37933 if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) { 37934 throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.'); 37935 } 37936 output[attr.name] = attr.value; 37937 } 37938 return output; 37939}; 37940 37941 'use strict'; 37942 37943var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt; 37944 37945/** 37946 * Vivus 37947 * Beta version 37948 * 37949 * Take any SVG and make the animation 37950 * to give give the impression of live drawing 37951 * 37952 * This in more than just inspired from codrops 37953 * At that point, it's a pure fork. 37954 */ 37955 37956/** 37957 * Class constructor 37958 * option structure 37959 * type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed) 37960 * duration: <int> (in frames) 37961 * start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport) 37962 * delay: <int> (delay between the drawing of first and last path) 37963 * dashGap <integer> whitespace extra margin between dashes 37964 * pathTimingFunction <function> timing animation function for each path element of the SVG 37965 * animTimingFunction <function> timing animation function for the complete SVG 37966 * forceRender <boolean> force the browser to re-render all updated path items 37967 * selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original 37968 * 37969 * The attribute 'type' is by default on 'delayed'. 37970 * - 'delayed' 37971 * all paths are draw at the same time but with a 37972 * little delay between them before start 37973 * - 'sync' 37974 * all path are start and finish at the same time 37975 * - 'oneByOne' 37976 * only one path is draw at the time 37977 * the end of the first one will trigger the draw 37978 * of the next one 37979 * 37980 * All these values can be overwritten individually 37981 * for each path item in the SVG 37982 * The value of frames will always take the advantage of 37983 * the duration value. 37984 * If you fail somewhere, an error will be thrown. 37985 * Good luck. 37986 * 37987 * @constructor 37988 * @this {Vivus} 37989 * @param {DOM|String} element Dom element of the SVG or id of it 37990 * @param {Object} options Options about the animation 37991 * @param {Function} callback Callback for the end of the animation 37992 */ 37993function Vivus (element, options, callback) { 37994 37995 setupEnv(); 37996 37997 // Setup 37998 this.isReady = false; 37999 this.setElement(element, options); 38000 this.setOptions(options); 38001 this.setCallback(callback); 38002 38003 if (this.isReady) { 38004 this.init(); 38005 } 38006} 38007 38008/** 38009 * Timing functions 38010 ************************************** 38011 * 38012 * Default functions to help developers. 38013 * It always take a number as parameter (between 0 to 1) then 38014 * return a number (between 0 and 1) 38015 */ 38016Vivus.LINEAR = function (x) {return x;}; 38017Vivus.EASE = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;}; 38018Vivus.EASE_OUT = function (x) {return 1 - Math.pow(1-x, 3);}; 38019Vivus.EASE_IN = function (x) {return Math.pow(x, 3);}; 38020Vivus.EASE_OUT_BOUNCE = function (x) { 38021 var base = -Math.cos(x * (0.5 * Math.PI)) + 1, 38022 rate = Math.pow(base,1.5), 38023 rateR = Math.pow(1 - x, 2), 38024 progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1; 38025 return (1- rateR) + (progress * rateR); 38026}; 38027 38028 38029/** 38030 * Setters 38031 ************************************** 38032 */ 38033 38034/** 38035 * Check and set the element in the instance 38036 * The method will not return anything, but will throw an 38037 * error if the parameter is invalid 38038 * 38039 * @param {DOM|String} element SVG Dom element or id of it 38040 */ 38041Vivus.prototype.setElement = function (element, options) { 38042 var onLoad, self; 38043 38044 // Basic check 38045 if (typeof element === 'undefined') { 38046 throw new Error('Vivus [constructor]: "element" parameter is required'); 38047 } 38048 38049 // Set the element 38050 if (element.constructor === String) { 38051 element = document.getElementById(element); 38052 if (!element) { 38053 throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID'); 38054 } 38055 } 38056 this.parentEl = element; 38057 38058 // Load the SVG with XMLHttpRequest and extract the SVG 38059 if (options && options.file) { 38060 var self = this; 38061 onLoad = function (e) { 38062 var domSandbox = document.createElement('div'); 38063 domSandbox.innerHTML = this.responseText; 38064 38065 var svgTag = domSandbox.querySelector('svg'); 38066 if (!svgTag) { 38067 throw new Error('Vivus [load]: Cannot find the SVG in the loaded file : ' + options.file); 38068 } 38069 38070 self.el = svgTag 38071 self.el.setAttribute('width', '100%'); 38072 self.el.setAttribute('height', '100%'); 38073 self.parentEl.appendChild(self.el) 38074 self.isReady = true; 38075 self.init(); 38076 self = null; 38077 } 38078 38079 var oReq = new window.XMLHttpRequest(); 38080 oReq.addEventListener('load', onLoad); 38081 oReq.open('GET', options.file); 38082 oReq.send(); 38083 return; 38084 } 38085 38086 switch (element.constructor) { 38087 case window.SVGSVGElement: 38088 case window.SVGElement: 38089 case window.SVGGElement: 38090 this.el = element; 38091 this.isReady = true; 38092 break; 38093 38094 case window.HTMLObjectElement: 38095 self = this; 38096 onLoad = function (e) { 38097 if (self.isReady) { 38098 return; 38099 } 38100 self.el = element.contentDocument && element.contentDocument.querySelector('svg'); 38101 if (!self.el && e) { 38102 throw new Error('Vivus [constructor]: object loaded does not contain any SVG'); 38103 } 38104 else if (self.el) { 38105 if (element.getAttribute('built-by-vivus')) { 38106 self.parentEl.insertBefore(self.el, element); 38107 self.parentEl.removeChild(element); 38108 self.el.setAttribute('width', '100%'); 38109 self.el.setAttribute('height', '100%'); 38110 } 38111 self.isReady = true; 38112 self.init(); 38113 self = null; 38114 } 38115 }; 38116 38117 if (!onLoad()) { 38118 element.addEventListener('load', onLoad); 38119 } 38120 break; 38121 38122 default: 38123 throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'); 38124 } 38125}; 38126 38127/** 38128 * Set up user option to the instance 38129 * The method will not return anything, but will throw an 38130 * error if the parameter is invalid 38131 * 38132 * @param {object} options Object from the constructor 38133 */ 38134Vivus.prototype.setOptions = function (options) { 38135 var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync']; 38136 var allowedStarts = ['inViewport', 'manual', 'autostart']; 38137 38138 // Basic check 38139 if (options !== undefined && options.constructor !== Object) { 38140 throw new Error('Vivus [constructor]: "options" parameter must be an object'); 38141 } 38142 else { 38143 options = options || {}; 38144 } 38145 38146 // Set the animation type 38147 if (options.type && allowedTypes.indexOf(options.type) === -1) { 38148 throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`'); 38149 } 38150 else { 38151 this.type = options.type || allowedTypes[0]; 38152 } 38153 38154 // Set the start type 38155 if (options.start && allowedStarts.indexOf(options.start) === -1) { 38156 throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option'); 38157 } 38158 else { 38159 this.start = options.start || allowedStarts[0]; 38160 } 38161 38162 this.isIE = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 ); 38163 this.duration = parsePositiveInt(options.duration, 120); 38164 this.delay = parsePositiveInt(options.delay, null); 38165 //Uncode addition 38166 this.delayStart = parsePositiveInt(options.delayStart, null); 38167 //#END 38168 this.dashGap = parsePositiveInt(options.dashGap, 1); 38169 this.forceRender = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE; 38170 this.reverseStack = !!options.reverseStack; 38171 this.selfDestroy = !!options.selfDestroy; 38172 this.onReady = options.onReady; 38173 this.map = []; 38174 this.frameLength = this.currentFrame = this.delayUnit = this.speed = this.handle = null; 38175 38176 this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false; 38177 38178 this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR; 38179 this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR; 38180 38181 if (this.delay >= this.duration) { 38182 throw new Error('Vivus [constructor]: delay must be shorter than duration'); 38183 } 38184}; 38185 38186/** 38187 * Set up callback to the instance 38188 * The method will not return enything, but will throw an 38189 * error if the parameter is invalid 38190 * 38191 * @param {Function} callback Callback for the animation end 38192 */ 38193Vivus.prototype.setCallback = function (callback) { 38194 // Basic check 38195 if (!!callback && callback.constructor !== Function) { 38196 throw new Error('Vivus [constructor]: "callback" parameter must be a function'); 38197 } 38198 this.callback = callback || function () {}; 38199}; 38200 38201 38202/** 38203 * Core 38204 ************************************** 38205 */ 38206 38207/** 38208 * Map the svg, path by path. 38209 * The method return nothing, it just fill the 38210 * `map` array. Each item in this array represent 38211 * a path element from the SVG, with informations for 38212 * the animation. 38213 * 38214 * ``` 38215 * [ 38216 * { 38217 * el: <DOMobj> the path element 38218 * length: <number> length of the path line 38219 * startAt: <number> time start of the path animation (in frames) 38220 * duration: <number> path animation duration (in frames) 38221 * }, 38222 * ... 38223 * ] 38224 * ``` 38225 * 38226 */ 38227Vivus.prototype.mapping = function () { 38228 var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint; 38229 timePoint = totalLength = lengthMeter = 0; 38230 paths = this.el.querySelectorAll('path'); 38231 38232 for (i = 0; i < paths.length; i++) { 38233 path = paths[i]; 38234 if (this.isInvisible(path)) { 38235 continue; 38236 } 38237 pathObj = { 38238 el: path, 38239 length: Math.ceil(path.getTotalLength()) 38240 }; 38241 // Test if the path length is correct 38242 if (isNaN(pathObj.length)) { 38243 if (window.console && console.warn) { 38244 console.warn('Vivus [mapping]: cannot retrieve a path element length', path); 38245 } 38246 continue; 38247 } 38248 this.map.push(pathObj); 38249 path.style.strokeDasharray = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2); 38250 path.style.strokeDashoffset = pathObj.length + this.dashGap; 38251 pathObj.length += this.dashGap; 38252 totalLength += pathObj.length; 38253 38254 this.renderPath(i); 38255 } 38256 38257 totalLength = totalLength === 0 ? 1 : totalLength; 38258 this.delay = this.delay === null ? this.duration / 3 : this.delay; 38259 this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1); 38260 38261 // Reverse stack if asked 38262 if (this.reverseStack) { 38263 this.map.reverse(); 38264 } 38265 38266 for (i = 0; i < this.map.length; i++) { 38267 pathObj = this.map[i]; 38268 38269 switch (this.type) { 38270 case 'delayed': 38271 pathObj.startAt = this.delayUnit * i; 38272 pathObj.duration = this.duration - this.delay; 38273 break; 38274 38275 case 'oneByOne': 38276 pathObj.startAt = lengthMeter / totalLength * this.duration; 38277 pathObj.duration = pathObj.length / totalLength * this.duration; 38278 break; 38279 38280 case 'sync': 38281 case 'async': 38282 case 'nsync': 38283 pathObj.startAt = 0; 38284 pathObj.duration = this.duration; 38285 break; 38286 38287 case 'scenario-sync': 38288 path = pathObj.el; 38289 pAttrs = this.parseAttr(path); 38290 pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0); 38291 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38292 timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration; 38293 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38294 break; 38295 38296 case 'scenario': 38297 path = pathObj.el; 38298 pAttrs = this.parseAttr(path); 38299 pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0; 38300 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38301 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38302 break; 38303 } 38304 lengthMeter += pathObj.length; 38305 this.frameLength = this.frameLength || this.duration; 38306 } 38307}; 38308 38309/** 38310 * Interval method to draw the SVG from current 38311 * position of the animation. It update the value of 38312 * `currentFrame` and re-trace the SVG. 38313 * 38314 * It use this.handle to store the requestAnimationFrame 38315 * and clear it one the animation is stopped. So this 38316 * attribute can be used to know if the animation is 38317 * playing. 38318 * 38319 * Once the animation at the end, this method will 38320 * trigger the Vivus callback. 38321 * 38322 */ 38323Vivus.prototype.drawer = function () { 38324 var self = this; 38325 this.currentFrame += this.speed; 38326 38327 if (this.currentFrame <= 0) { 38328 this.stop(); 38329 this.reset(); 38330 } else if (this.currentFrame >= this.frameLength) { 38331 this.stop(); 38332 this.currentFrame = this.frameLength; 38333 this.trace(); 38334 if (this.selfDestroy) { 38335 this.destroy(); 38336 } 38337 } else { 38338 this.trace(); 38339 this.handle = requestAnimFrame(function () { 38340 self.drawer(); 38341 }); 38342 return; 38343 } 38344 38345 this.callback(this); 38346 if (this.instanceCallback) { 38347 this.instanceCallback(this); 38348 this.instanceCallback = null; 38349 } 38350}; 38351 38352/** 38353 * Draw the SVG at the current instant from the 38354 * `currentFrame` value. Here is where most of the magic is. 38355 * The trick is to use the `strokeDashoffset` style property. 38356 * 38357 * For optimisation reasons, a new property called `progress` 38358 * is added in each item of `map`. This one contain the current 38359 * progress of the path element. Only if the new value is different 38360 * the new value will be applied to the DOM element. This 38361 * method save a lot of resources to re-render the SVG. And could 38362 * be improved if the animation couldn't be played forward. 38363 * 38364 */ 38365Vivus.prototype.trace = function () { 38366 var i, progress, path, currentFrame; 38367 currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength; 38368 for (i = 0; i < this.map.length; i++) { 38369 path = this.map[i]; 38370 progress = (currentFrame - path.startAt) / path.duration; 38371 progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress))); 38372 if (path.progress !== progress) { 38373 path.progress = progress; 38374 path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress)); 38375 this.renderPath(i); 38376 } 38377 } 38378}; 38379 38380/** 38381 * Method forcing the browser to re-render a path element 38382 * from it's index in the map. Depending on the `forceRender` 38383 * value. 38384 * The trick is to replace the path element by it's clone. 38385 * This practice is not recommended because it's asking more 38386 * ressources, too much DOM manupulation.. 38387 * but it's the only way to let the magic happen on IE. 38388 * By default, this fallback is only applied on IE. 38389 * 38390 * @param {Number} index Path index 38391 */ 38392Vivus.prototype.renderPath = function (index) { 38393 if (this.forceRender && this.map && this.map[index]) { 38394 var pathObj = this.map[index], 38395 newPath = pathObj.el.cloneNode(true); 38396 pathObj.el.parentNode.replaceChild(newPath, pathObj.el); 38397 pathObj.el = newPath; 38398 } 38399}; 38400 38401/** 38402 * When the SVG object is loaded and ready, 38403 * this method will continue the initialisation. 38404 * 38405 * This this mainly due to the case of passing an 38406 * object tag in the constructor. It will wait 38407 * the end of the loading to initialise. 38408 * 38409 */ 38410Vivus.prototype.init = function () { 38411 // Set object variables 38412 this.frameLength = 0; 38413 this.currentFrame = 0; 38414 this.map = []; 38415 38416 // Start 38417 new Pathformer(this.el); 38418 this.mapping(); 38419 this.starter(); 38420 38421 if (this.onReady) { 38422 this.onReady(this); 38423 } 38424}; 38425 38426/** 38427 * Trigger to start of the animation. 38428 * Depending on the `start` value, a different script 38429 * will be applied. 38430 * 38431 * If the `start` value is not valid, an error will be thrown. 38432 * Even if technically, this is impossible. 38433 * 38434 */ 38435Vivus.prototype.starter = function () { 38436 switch (this.start) { 38437 case 'manual': 38438 return; 38439 38440 case 'autostart': 38441 this.play(); 38442 break; 38443 38444 case 'inViewport': 38445 var self = this, 38446 listener = function () { 38447 if (self.isInViewport(self.parentEl, 1)) { 38448 self.play(); 38449 window.removeEventListener('scroll', listener); 38450 //Uncode addition 38451 window.removeEventListener('fp-slide-changed', listener); 38452 window.removeEventListener('fp-slide-scroll', listener); 38453 //#END 38454 } 38455 }; 38456 window.addEventListener('scroll', listener); 38457 //Uncode addition 38458 window.addEventListener('fp-slide-changed', listener); 38459 window.addEventListener('fp-slide-scroll', listener); 38460 //#END 38461 listener(); 38462 break; 38463 } 38464}; 38465 38466 38467/** 38468 * Controls 38469 ************************************** 38470 */ 38471 38472/** 38473 * Get the current status of the animation between 38474 * three different states: 'start', 'progress', 'end'. 38475 * @return {string} Instance status 38476 */ 38477Vivus.prototype.getStatus = function () { 38478 return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress'; 38479}; 38480 38481/** 38482 * Reset the instance to the initial state : undraw 38483 * Be careful, it just reset the animation, if you're 38484 * playing the animation, this won't stop it. But just 38485 * make it start from start. 38486 * 38487 */ 38488Vivus.prototype.reset = function () { 38489 return this.setFrameProgress(0); 38490}; 38491 38492/** 38493 * Set the instance to the final state : drawn 38494 * Be careful, it just set the animation, if you're 38495 * playing the animation on rewind, this won't stop it. 38496 * But just make it start from the end. 38497 * 38498 */ 38499Vivus.prototype.finish = function () { 38500 return this.setFrameProgress(1); 38501}; 38502 38503/** 38504 * Set the level of progress of the drawing. 38505 * 38506 * @param {number} progress Level of progress to set 38507 */ 38508Vivus.prototype.setFrameProgress = function (progress) { 38509 progress = Math.min(1, Math.max(0, progress)); 38510 this.currentFrame = Math.round(this.frameLength * progress); 38511 this.trace(); 38512 return this; 38513}; 38514 38515/** 38516 * Play the animation at the desired speed. 38517 * Speed must be a valid number (no zero). 38518 * By default, the speed value is 1. 38519 * But a negative value is accepted to go forward. 38520 *
38521 * And works with float too. 38522 * But don't forget we are in JavaScript, se be nice 38523 * with him and give him a 1/2^x value. 38524 * 38525 * @param {number} speed Animation speed [optional] 38526 */ 38527Vivus.prototype.play = function (speed, callback) { 38528 this.instanceCallback = null; 38529 38530 if (speed && typeof speed === 'function') { 38531 this.instanceCallback = speed; // first parameter is actually the callback function 38532 speed = null; 38533 } 38534 else if (speed && typeof speed !== 'number') { 38535 throw new Error('Vivus [play]: invalid speed'); 38536 } 38537 // if the first parameter wasn't the callback, check if the seconds was 38538 if (callback && typeof(callback) === 'function' && !this.instanceCallback) { 38539 this.instanceCallback = callback; 38540 } 38541 38542 38543 this.speed = speed || 1; 38544 //Uncode addition 38545 if (!this.handle) { 38546 var $this = this, 38547 delay = (this.delayStart != null) ? this.delayStart : 0; 38548 setTimeout(function() { 38549 $this.drawer(); 38550 }, delay); 38551 } 38552 //#END 38553 return this; 38554}; 38555 38556/** 38557 * Stop the current animation, if on progress. 38558 * Should not trigger any error. 38559 * 38560 */ 38561Vivus.prototype.stop = function () { 38562 if (this.handle) { 38563 cancelAnimFrame(this.handle); 38564 this.handle = null; 38565 } 38566 return this; 38567}; 38568 38569/** 38570 * Destroy the instance. 38571 * Remove all bad styling attributes on all 38572 * path tags 38573 * 38574 */ 38575Vivus.prototype.destroy = function () { 38576 this.stop(); 38577 var i, path; 38578 for (i = 0; i < this.map.length; i++) { 38579 path = this.map[i]; 38580 path.el.style.strokeDashoffset = null; 38581 path.el.style.strokeDasharray = null; 38582 this.renderPath(i); 38583 } 38584}; 38585 38586 38587/** 38588 * Utils methods 38589 * include methods from Codrops 38590 ************************************** 38591 */ 38592 38593/** 38594 * Method to best guess if a path should added into 38595 * the animation or not. 38596 * 38597 * 1. Use the `data-vivus-ignore` attribute if set 38598 * 2. Check if the instance must ignore invisible paths 38599 * 3. Check if the path is visible 38600 * 38601 * For now the visibility checking is unstable. 38602 * It will be used for a beta phase. 38603 * 38604 * Other improvments are planned. Like detecting 38605 * is the path got a stroke or a valid opacity. 38606 */ 38607Vivus.prototype.isInvisible = function (el) { 38608 var rect, 38609 ignoreAttr = el.getAttribute('data-ignore'); 38610 38611 if (ignoreAttr !== null) { 38612 return ignoreAttr !== 'false'; 38613 } 38614 38615 if (this.ignoreInvisible) { 38616 rect = el.getBoundingClientRect(); 38617 return !rect.width && !rect.height; 38618 } 38619 else { 38620 return false; 38621 } 38622}; 38623 38624/** 38625 * Parse attributes of a DOM element to 38626 * get an object of {attributeName => attributeValue} 38627 * 38628 * @param {object} element DOM element to parse 38629 * @return {object} Object of attributes 38630 */ 38631Vivus.prototype.parseAttr = function (element) { 38632 var attr, output = {}; 38633 if (element && element.attributes) { 38634 for (var i = 0; i < element.attributes.length; i++) { 38635 attr = element.attributes[i]; 38636 output[attr.name] = attr.value; 38637 } 38638 } 38639 return output; 38640}; 38641 38642/** 38643 * Reply if an element is in the page viewport 38644 * 38645 * @param {object} el Element to observe 38646 * @param {number} h Percentage of height 38647 * @return {boolean} 38648 */ 38649Vivus.prototype.isInViewport = function (el, h) { 38650 var scrolled = this.scrollY(), 38651 viewed = scrolled + this.getViewportH(), 38652 elBCR = el.getBoundingClientRect(), 38653 elHeight = elBCR.height, 38654 elTop = scrolled + elBCR.top, 38655 elBottom = elTop + elHeight; 38656 38657 // if 0, the element is considered in the viewport as soon as it enters. 38658 // if 1, the element is considered in the viewport only when it's fully inside 38659 // value in percentage (1 >= h >= 0) 38660 h = h || 0; 38661 38662 return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled; 38663}; 38664 38665 38666/** 38667 * Get the viewport height in pixels 38668 * 38669 * @return {integer} Viewport height 38670 */ 38671Vivus.prototype.getViewportH = function () { 38672 var client = this.docElem.clientHeight, 38673 inner = window.innerHeight; 38674 38675 if (client < inner) { 38676 return inner; 38677 } 38678 else { 38679 return client; 38680 } 38681}; 38682 38683/** 38684 * Get the page Y offset 38685 * 38686 * @return {integer} Page Y offset 38687 */ 38688Vivus.prototype.scrollY = function () { 38689 return window.pageYOffset || this.docElem.scrollTop; 38690}; 38691 38692setupEnv = function () { 38693 38694 if (Vivus.prototype.docElem) { 38695 return; 38696 } 38697 38698 /** 38699 * Alias for document element 38700 * 38701 * @type {DOMelement} 38702 */ 38703 Vivus.prototype.docElem = window.document.documentElement; 38704 38705 /** 38706 * Alias for `requestAnimationFrame` or 38707 * `setTimeout` function for deprecated browsers. 38708 * 38709 */ 38710 requestAnimFrame = (function () { 38711 return ( 38712 window.requestAnimationFrame || 38713 window.webkitRequestAnimationFrame || 38714 window.mozRequestAnimationFrame || 38715 window.oRequestAnimationFrame || 38716 window.msRequestAnimationFrame || 38717 function(/* function */ callback){ 38718 return window.setTimeout(callback, 1000 / 60); 38719 } 38720 ); 38721 })(); 38722 38723 /** 38724 * Alias for `cancelAnimationFrame` or 38725 * `cancelTimeout` function for deprecated browsers. 38726 * 38727 */ 38728 cancelAnimFrame = (function () { 38729 return ( 38730 window.cancelAnimationFrame || 38731 window.webkitCancelAnimationFrame || 38732 window.mozCancelAnimationFrame || 38733 window.oCancelAnimationFrame || 38734 window.msCancelAnimationFrame || 38735 function(id){ 38736 return window.clearTimeout(id); 38737 } 38738 ); 38739 })(); 38740}; 38741 38742/** 38743 * Parse string to integer. 38744 * If the number is not positive or null 38745 * the method will return the default value 38746 * or 0 if undefined 38747 * 38748 * @param {string} value String to parse 38749 * @param {*}
38749 defaultValue Value to return if the result parsed is invalid 38750 * @return {number} 38751 * 38752 */ 38753parsePositiveInt = function (value, defaultValue) { 38754 var output = parseInt(value, 10); 38755 return (output >= 0) ? output : defaultValue; 38756}; 38757 38758 38759 if (typeof define === 'function' && define.amd) { 38760 // AMD. Register as an anonymous module. 38761 define([], function() { 38762 return Vivus; 38763 }); 38764 } else if (typeof exports === 'object') { 38765 // Node. Does not work with strict CommonJS, but 38766 // only CommonJS-like environments that support module.exports, 38767 // like Node. 38768 module.exports = Vivus; 38769 } else { 38770 // Browser globals 38771 window.Vivus = Vivus; 38772 } 38773 38774}());
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.