1/*! 2 * SmartMenus jQuery Plugin - v1.2.1 - November 3, 2022 3 * http://www.smartmenus.org/ 4 * 5 * Copyright Vasil Dinkov, Vadikom Web Ltd. 6 * http://vadikom.com 7 * 8 * Licensed MIT 9 */ 10 11(function(factory) { 12 if (typeof define === 'function' && define.amd) { 13 // AMD 14 define(['jquery'], factory); 15 } else if (typeof module === 'object' && typeof module.exports === 'object') { 16 // CommonJS 17 module.exports = factory(require('jquery')); 18 } else { 19 // Global jQuery 20 factory(jQuery); 21 } 22} (function($) { 23 24 var menuTrees = [], 25 mouse = false, // optimize for touch by default - we will detect for mouse input 26 touchEvents = 'ontouchstart' in window, // we use this just to choose between toucn and pointer events, not for touch screen detection 27 mouseDetectionEnabled = false, 28 requestAnimationFrame = window.requestAnimationFrame || function(callback) { return setTimeout(callback, 1000 / 60); }, 29 cancelAnimationFrame = window.cancelAnimationFrame || function(id) { clearTimeout(id); }, 30 canAnimate = !!$.fn.animate; 31 32 // Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.) 33 function initMouseDetection(disable) { 34 var eNS = '.smartmenus_mouse'; 35 if (!mouseDetectionEnabled && !disable) { 36 // if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present 37 // 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) 38 var firstTime = true, 39 lastMove = null, 40 events = { 41 'mousemove': function(e) { 42 var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() }; 43 if (lastMove) { 44 var deltaX = Math.abs(lastMove.x - thisMove.x), 45 deltaY = Math.abs(lastMove.y - thisMove.y); 46 if ((deltaX > 0 || deltaY > 0) && deltaX <= 4 && deltaY <= 4 && thisMove.timeStamp - lastMove.timeStamp <= 300) { 47 mouse = true; 48 // 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 49 if (firstTime) { 50 var $a = $(e.target).closest('a'); 51 if ($a.is('a')) { 52 $.each(menuTrees, function() { 53 if ($.contains(this.$root[0], $a[0])) { 54 this.itemEnter({ currentTarget: $a[0] }); 55 return false; 56 } 57 }); 58 } 59 firstTime = false; 60 } 61 } 62 } 63 lastMove = thisMove; 64 } 65 }; 66 events[touchEvents ? 'touchstart' : 'pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut'] = function(e) { 67 if (isTouchEvent(e.originalEvent)) { 68 mouse = false; 69 } 70 }; 71 $(document).on(getEventsNS(events, eNS)); 72 mouseDetectionEnabled = true; 73 } else if (mouseDetectionEnabled && disable) { 74 $(document).off(eNS); 75 mouseDetectionEnabled = false; 76 } 77 } 78 79 function isTouchEvent(e) { 80 return !/^(4|mouse)$/.test(e.pointerType); 81 } 82 83 // returns a jQuery on() ready object 84 function getEventsNS(events, eNS) { 85 if (!eNS) { 86 eNS = ''; 87 } 88 var eventsNS = {}; 89 for (var i in events) { 90 eventsNS[i.split(' ').join(eNS + ' ') + eNS] = events[i]; 91 } 92 return eventsNS; 93 } 94 95 $.SmartMenus = function(elm, options) { 96 this.$root = $(elm); 97 this.opts = options; 98 this.rootId = ''; // internal 99 this.accessIdPrefix = ''; 100 this.$subArrow = null; 101 this.activatedItems = []; // stores last activated A's for each level 102 this.visibleSubMenus = []; // stores visible sub menus UL's (might be in no particular order) 103 this.showTimeout = 0; 104 this.hideTimeout = 0; 105 this.scrollTimeout = 0; 106 this.clickActivated = false; 107 this.focusActivated = false; 108 this.zIndexInc = 0; 109 this.idInc = 0; 110 this.$firstLink = null; // we'll use these for some tests 111 this.$firstSub = null; // at runtime so we'll cache them 112 this.disabled = false; 113 this.$disableOverlay = null; 114 this.$touchScrollingSub = null; 115 this.cssTransforms3d = 'perspective' in elm.style || 'webkitPerspective' in elm.style; 116 this.wasCollapsible = false;
117 this.init(); 118 }; 119 120 $.extend($.SmartMenus, { 121 hideAll: function() { 122 $.each(menuTrees, function() { 123 this.menuHideAll(); 124 }); 125 }, 126 destroy: function() { 127 while (menuTrees.length) { 128 menuTrees[0].destroy(); 129 } 130 initMouseDetection(true); 131 }, 132 prototype: { 133 init: function(refresh) { 134 var self = this; 135 136 if (!refresh) { 137 menuTrees.push(this); 138 139 this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, ''); 140 this.accessIdPrefix = 'sm-' + this.rootId + '-'; 141 142 if (this.$root.hasClass('sm-rtl')) { 143 this.opts.rightToLeftSubMenus = true; 144 } 145 146 // init root (main menu) 147 var eNS = '.smartmenus'; 148 this.$root 149 .data('smartmenus', this) 150 .attr('data-smartmenus-id', this.rootId) 151 .dataSM('level', 1) 152 .on(getEventsNS({ 153 'mouseover focusin': $.proxy(this.rootOver, this), 154 'mouseout focusout': $.proxy(this.rootOut, this), 155 'keydown': $.proxy(this.rootKeyDown, this) 156 }, eNS)) 157 .on(getEventsNS({ 158 'mouseenter': $.proxy(this.itemEnter, this), 159 'mouseleave': $.proxy(this.itemLeave, this), 160 'mousedown': $.proxy(this.itemDown, this), 161 'focus': $.proxy(this.itemFocus, this), 162 'blur': $.proxy(this.itemBlur, this), 163 'click': $.proxy(this.itemClick, this) 164 }, eNS), 'a'); 165 166 // hide menus on tap or click outside the root UL 167 eNS += this.rootId; 168 if (this.opts.hideOnClick) { 169 $(document).on(getEventsNS({ 170 'touchstart': $.proxy(this.docTouchStart, this), 171 'touchmove': $.proxy(this.docTouchMove, this), 172 'touchend': $.proxy(this.docTouchEnd, this), 173 // for Opera Mobile < 11.5, webOS browser, etc. we'll check click too 174 'click': $.proxy(this.docClick, this) 175 }, eNS)); 176 } 177 // hide sub menus on resize 178 $(window).on(getEventsNS({ 'resize orientationchange': $.proxy(this.winResize, this) }, eNS)); 179 180 if (this.opts.subIndicators) { 181 this.$subArrow = $('<span/>').addClass('sub-arrow'); 182 if (this.opts.subIndicatorsText) { 183 this.$subArrow.html(this.opts.subIndicatorsText); 184 } 185 } 186 187 // make sure mouse detection is enabled 188 initMouseDetection(); 189 } 190 191 // init sub menus 192 this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0); 193 194 this.$firstLink = this.$root.find('a').eq(0); 195 196 // find current item 197 if (this.opts.markCurrentItem) { 198 var reDefaultDoc = /(index|default)\.[^#\?\/]*/i, 199 reHash = /#.*/, 200 locHref = window.location.href.replace(reDefaultDoc, ''), 201 locHrefNoHash = locHref.replace(reHash, ''); 202 this.$root.find('a:not(.mega-menu a)').each(function() { 203 var href = this.href.replace(reDefaultDoc, ''), 204 $this = $(this); 205 if (href == locHref || href == locHrefNoHash) { 206 $this.addClass('current'); 207 if (self.opts.markCurrentTree) { 208 $this.parentsUntil('[data-smartmenus-id]', 'ul').each(function() { 209 $(this).dataSM('parent-a').addClass('current'); 210 }); 211 } 212 } 213 }); 214 } 215 216 // save initial state 217 this.wasCollapsible = this.isCollapsible(); 218 }, 219 destroy: function(refresh) { 220 if (!refresh) { 221 var eNS = '.smartmenus'; 222 this.$root 223 .removeData('smartmenus') 224 .removeAttr('data-smartmenus-id') 225 .removeDataSM('level') 226 .off(eNS); 227 eNS += this.rootId; 228 $(document).off(eNS); 229 $(window).off(eNS); 230 if (this.opts.subIndicators) { 231 this.$subArrow = null; 232 } 233 } 234 this.menuHideAll(); 235 var self = this; 236 this.$root.find('ul').each(function() { 237 var $this = $(this); 238 if ($this.dataSM('scroll-arrows')) { 239 $this.dataSM('scroll-arrows').remove(); 240 } 241 if ($this.dataSM('shown-before')) { 242 if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) { 243 $this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap'); 244 } 245 if ($this.dataSM('scroll-arrows')) { 246 $this.dataSM('scroll-arrows').remove(); 247 } 248 $this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' }); 249 } 250 if (($this.attr('id') || '').indexOf(self.accessIdPrefix) == 0) { 251 $this.removeAttr('id'); 252 } 253 }) 254 .removeDataSM('in-mega') 255 .removeDataSM('shown-before') 256 .removeDataSM('scroll-arrows') 257 .removeDataSM('parent-a') 258 .removeDataSM('level') 259 .removeDataSM('beforefirstshowfired') 260 .removeAttr('role') 261 .removeAttr('aria-hidden') 262 .removeAttr('aria-labelledby') 263 .removeAttr('aria-expanded'); 264 this.$root.find('a.has-submenu').each(function() { 265 var $this = $(this); 266 if ($this.attr('id').indexOf(self.accessIdPrefix) == 0) { 267 $this.removeAttr('id'); 268 } 269 }) 270 .removeClass('has-submenu') 271 .removeDataSM('sub') 272 .removeAttr('aria-haspopup') 273 .removeAttr('aria-controls') 274 .removeAttr('aria-expanded') 275 .closest('li').removeDataSM('sub'); 276 if (this.opts.subIndicators) { 277 this.$root.find('span.sub-arrow').remove(); 278 } 279 if (this.opts.markCurrentItem) { 280 this.$root.find('a.current').removeClass('current'); 281 } 282 if (!refresh) { 283 this.$root = null; 284 this.$firstLink = null; 285 this.$firstSub = null; 286 if (this.$disableOverlay) { 287 this.$disableOverlay.remove(); 288 this.$disableOverlay = null; 289 } 290 menuTrees.splice($.inArray(this, menuTrees), 1); 291 } 292 }, 293 disable: function(noOverlay) { 294 if (!this.disabled) { 295 this.menuHideAll(); 296 // display overlay over the menu to prevent interaction 297 if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) { 298 var pos = this.$root.offset(); 299 this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({ 300 position: 'absolute', 301 top: pos.top, 302 left: pos.left, 303 width: this.$root.outerWidth(), 304 height: this.$root.outerHeight(),
305 zIndex: this.getStartZIndex(true), 306 opacity: 0 307 }).appendTo(document.body); 308 } 309 this.disabled = true; 310 } 311 }, 312 docClick: function(e) { 313 if (this.$touchScrollingSub) { 314 this.$touchScrollingSub = null; 315 return; 316 } 317 // hide on any click outside the menu or on a menu link 318 if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).closest('a').length) { 319 this.menuHideAll(); 320 } 321 }, 322 docTouchEnd: function(e) { 323 if (!this.lastTouch) { 324 return; 325 } 326 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))) { 327 if (this.hideTimeout) { 328 clearTimeout(this.hideTimeout); 329 this.hideTimeout = 0; 330 } 331 // hide with a delay to prevent triggering accidental unwanted click on some page element 332 var self = this; 333 this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, 350); 334 } 335 this.lastTouch = null; 336 }, 337 docTouchMove: function(e) { 338 if (!this.lastTouch) { 339 return; 340 } 341 var touchPoint = e.originalEvent.touches[0]; 342 this.lastTouch.x2 = touchPoint.pageX; 343 this.lastTouch.y2 = touchPoint.pageY; 344 }, 345 docTouchStart: function(e) { 346 var touchPoint = e.originalEvent.touches[0]; 347 this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target }; 348 }, 349 enable: function() { 350 if (this.disabled) { 351 if (this.$disableOverlay) { 352 this.$disableOverlay.remove(); 353 this.$disableOverlay = null; 354 } 355 this.disabled = false; 356 } 357 }, 358 getClosestMenu: function(elm) { 359 var $closestMenu = $(elm).closest('ul'); 360 while ($closestMenu.dataSM('in-mega')) { 361 $closestMenu = $closestMenu.parent().closest('ul'); 362 } 363 return $closestMenu[0] || null; 364 }, 365 getHeight: function($elm) { 366 return this.getOffset($elm, true); 367 }, 368 // returns precise width/height float values 369 getOffset: function($elm, height) { 370 var old; 371 if ($elm.css('display') == 'none') { 372 old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility }; 373 $elm.css({ position: 'absolute', visibility: 'hidden' }).show(); 374 } 375 var box = $elm[0].getBoundingClientRect && $elm[0].getBoundingClientRect(), 376 val = box && (height ? box.height || box.bottom - box.top : box.width || box.right - box.left); 377 if (!val && val !== 0) { 378 val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth; 379 } 380 if (old) { 381 $elm.hide().css(old); 382 } 383 return val; 384 }, 385 getStartZIndex: function(root) { 386 var zIndex = parseInt(this[root ? '$root' : '$firstSub'].css('z-index')); 387 if (!root && isNaN(zIndex)) { 388 zIndex = parseInt(this.$root.css('z-index')); 389 } 390 return !isNaN(zIndex) ? zIndex : 1; 391 }, 392 getTouchPoint: function(e) { 393 return e.touches && e.touches[0] || e.changedTouches && e.changedTouches[0] || e; 394 }, 395 getViewport: function(height) { 396 var name = height ? 'Height' : 'Width', 397 val = document.documentElement['client' + name], 398 val2 = window['inner' + name]; 399 if (val2) { 400 val = Math.min(val, val2); 401 } 402 return val; 403 }, 404 getViewportHeight: function() { 405 return this.getViewport(true); 406 }, 407 getViewportWidth: function() { 408 return this.getViewport(); 409 }, 410 getWidth: function($elm) { 411 return this.getOffset($elm); 412 }, 413 handleEvents: function() { 414 return !this.disabled && this.isCSSOn(); 415 }, 416 handleItemEvents: function($a) { 417 return this.handleEvents() && !this.isLinkInMegaMenu($a); 418 }, 419 isCollapsible: function() { 420 return this.$firstSub.css('position') == 'static'; 421 }, 422 isCSSOn: function() { 423 return this.$firstLink.css('display') != 'inline'; 424 }, 425 isFixed: function() { 426 var isFixed = this.$root.css('position') == 'fixed'; 427 if (!isFixed) { 428 this.$root.parentsUntil('body').each(function() { 429 if ($(this).css('position') == 'fixed') { 430 isFixed = true; 431 return false;
432 } 433 }); 434 } 435 return isFixed; 436 }, 437 isLinkInMegaMenu: function($a) { 438 return $(this.getClosestMenu($a[0])).hasClass('mega-menu'); 439 }, 440 isTouchMode: function() { 441 return !mouse || this.opts.noMouseOver || this.isCollapsible(); 442 }, 443 itemActivate: function($a, hideDeeperSubs) { 444 var $ul = $a.closest('ul'), 445 level = $ul.dataSM('level'); 446 // 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 447 if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) { 448 var self = this; 449 $($ul.parentsUntil('[data-smartmenus-id]', 'ul').get().reverse()).add($ul).each(function() { 450 self.itemActivate($(this).dataSM('parent-a')); 451 }); 452 } 453 // hide any visible deeper level sub menus 454 if (!this.isCollapsible() || hideDeeperSubs) { 455 this.menuHideSubMenus(!this.activatedItems[level - 1] || this.activatedItems[level - 1][0] != $a[0] ? level - 1 : level); 456 } 457 // save new active item for this level 458 this.activatedItems[level - 1] = $a; 459 if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) { 460 return; 461 } 462 // show the sub menu if this item has one 463 var $sub = $a.dataSM('sub'); 464 if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) { 465 this.menuShow($sub); 466 } 467 }, 468 itemBlur: function(e) { 469 var $a = $(e.currentTarget); 470 if (!this.handleItemEvents($a)) { 471 return; 472 } 473 this.$root.triggerHandler('blur.smapi', $a[0]); 474 }, 475 itemClick: function(e) { 476 var $a = $(e.currentTarget); 477 if (!this.handleItemEvents($a)) { 478 return; 479 } 480 if (this.$touchScrollingSub && this.$touchScrollingSub[0] == $a.closest('ul')[0]) { 481 this.$touchScrollingSub = null; 482 e.stopPropagation(); 483 return false; 484 } 485 if (this.$root.triggerHandler('click.smapi', $a[0]) === false) { 486 return false; 487 } 488 var $sub = $a.dataSM('sub'), 489 firstLevelSub = $sub ? $sub.dataSM('level') == 2 : false; 490 if ($sub) { 491 var subArrowClicked = $(e.target).is('.sub-arrow'), 492 collapsible = this.isCollapsible(), 493 behaviorToggle = /toggle$/.test(this.opts.collapsibleBehavior), 494 behaviorLink = /link$/.test(this.opts.collapsibleBehavior), 495 behaviorAccordion = /^accordion/.test(this.opts.collapsibleBehavior); 496 // if the sub is hidden, try to show it 497 if (!$sub.is(':visible')) { 498 if (!behaviorLink || !collapsible || subArrowClicked) { 499 if (!collapsible && this.opts.showOnClick && firstLevelSub) { 500 this.clickActivated = true; 501 } 502 // try to activate the item and show the sub 503 this.itemActivate($a, behaviorAccordion); 504 // if "itemActivate" showed the sub, prevent the click so that the link is not loaded 505 // 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 506 if ($sub.is(':visible')) { 507 this.focusActivated = true; 508 return false; 509 } 510 } 511 // if the sub is visible and showOnClick: true, hide the sub 512 } else if (!collapsible && this.opts.showOnClick && firstLevelSub) { 513 this.menuHide($sub); 514 this.clickActivated = false; 515 this.focusActivated = false; 516 return false; 517 // if the sub is visible and we are in collapsible mode 518 } else if (collapsible && (behaviorToggle || subArrowClicked)) { 519 this.itemActivate($a, behaviorAccordion); 520 this.menuHide($sub); 521 return false; 522 } 523 } 524 if (!collapsible && this.opts.showOnClick && firstLevelSub || $a.hasClass('disabled') || this.$root.triggerHandler('select.smapi', $a[0]) === false) { 525 return false; 526 } 527 }, 528 itemDown: function(e) { 529 var $a = $(e.currentTarget); 530 if (!this.handleItemEvents($a)) { 531 return; 532 } 533 $a.dataSM('mousedown', true); 534 }, 535 itemEnter: function(e) { 536 var $a = $(e.currentTarget); 537 if (!this.handleItemEvents($a)) { 538 return; 539 } 540 if (!this.isTouchMode()) { 541 if (this.showTimeout) { 542 clearTimeout(this.showTimeout); 543 this.showTimeout = 0; 544 } 545 var self = this; 546 this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.closest('ul').dataSM('level') == 1 ? 1 : this.opts.showTimeout); 547 } 548 this.$root.triggerHandler('mouseenter.smapi', $a[0]); 549 }, 550 itemFocus: function(e) { 551 var $a = $(e.currentTarget); 552 if (!this.handleItemEvents($a)) { 553 return; 554 } 555 // 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 556 if (this.focusActivated && (!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) { 557 this.itemActivate($a, true); 558 } 559 this.$root.triggerHandler('focus.smapi', $a[0]); 560 }, 561 itemLeave: function(e) { 562 var $a = $(e.currentTarget); 563 if (!this.handleItemEvents($a)) { 564 return; 565 } 566 if (!this.isTouchMode()) { 567 $a[0].blur(); 568 if (this.showTimeout) { 569 clearTimeout(this.showTimeout); 570 this.showTimeout = 0; 571 } 572 } 573 $a.removeDataSM('mousedown');
574 this.$root.triggerHandler('mouseleave.smapi', $a[0]); 575 }, 576 menuHide: function($sub) { 577 if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) { 578 return; 579 } 580 if (canAnimate) { 581 $sub.stop(true, true); 582 } 583 if ($sub.css('display') != 'none') { 584 var complete = function() { 585 // unset z-index 586 $sub.css('z-index', ''); 587 }; 588 // if sub is collapsible (mobile view) 589 if (this.isCollapsible()) { 590 if (canAnimate && this.opts.collapsibleHideFunction) { 591 this.opts.collapsibleHideFunction.call(this, $sub, complete); 592 } else { 593 $sub.hide(this.opts.collapsibleHideDuration, complete); 594 } 595 } else { 596 if (canAnimate && this.opts.hideFunction) { 597 this.opts.hideFunction.call(this, $sub, complete); 598 } else { 599 $sub.hide(this.opts.hideDuration, complete); 600 } 601 } 602 // deactivate scrolling if it is activated for this sub 603 if ($sub.dataSM('scroll')) { 604 this.menuScrollStop($sub); 605 $sub.css({ 'touch-action': '', '-ms-touch-action': '', '-webkit-transform': '', transform: '' }) 606 .off('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide(); 607 } 608 // unhighlight parent item + accessibility 609 $sub.dataSM('parent-a').removeClass('highlighted').attr('aria-expanded', 'false'); 610 $sub.attr({ 611 'aria-expanded': 'false', 612 'aria-hidden': 'true' 613 }); 614 var level = $sub.dataSM('level'); 615 this.activatedItems.splice(level - 1, 1); 616 this.visibleSubMenus.splice($.inArray($sub, this.visibleSubMenus), 1); 617 this.$root.triggerHandler('hide.smapi', $sub[0]); 618 } 619 }, 620 menuHideAll: function() { 621 if (this.showTimeout) { 622 clearTimeout(this.showTimeout); 623 this.showTimeout = 0; 624 } 625 // hide all subs 626 // if it's a popup, this.visibleSubMenus[0] is the root UL 627 var level = this.opts.isPopup ? 1 : 0; 628 for (var i = this.visibleSubMenus.length - 1; i >= level; i--) { 629 this.menuHide(this.visibleSubMenus[i]); 630 } 631 // hide root if it's popup 632 if (this.opts.isPopup) { 633 if (canAnimate) { 634 this.$root.stop(true, true); 635 } 636 if (this.$root.is(':visible')) { 637 if (canAnimate && this.opts.hideFunction) { 638 this.opts.hideFunction.call(this, this.$root); 639 } else { 640 this.$root.hide(this.opts.hideDuration); 641 } 642 } 643 } 644 this.activatedItems = []; 645 this.visibleSubMenus = []; 646 this.clickActivated = false; 647 this.focusActivated = false; 648 // reset z-index increment 649 this.zIndexInc = 0; 650 this.$root.triggerHandler('hideAll.smapi'); 651 }, 652 menuHideSubMenus: function(level) { 653 for (var i = this.activatedItems.length - 1; i >= level; i--) { 654 var $sub = this.activatedItems[i].dataSM('sub'); 655 if ($sub) { 656 this.menuHide($sub); 657 } 658 } 659 }, 660 menuInit: function($ul) { 661 if (!$ul.dataSM('in-mega')) { 662 // mark UL's in mega drop downs (if any) so we can neglect them 663 if ($ul.hasClass('mega-menu')) { 664 $ul.find('ul').dataSM('in-mega', true); 665 } 666 // get level (much faster than, for example, using parentsUntil) 667 var level = 2, 668 par = $ul[0]; 669 while ((par = par.parentNode.parentNode) != this.$root[0]) { 670 level++; 671 } 672 // cache stuff for quick access 673 var $a = $ul.prevAll('a').eq(-1); 674 // if the link is nested (e.g. in a heading) 675 if (!$a.length) { 676 $a = $ul.prevAll().find('a').eq(-1); 677 } 678 $a.addClass('has-submenu').dataSM('sub', $ul); 679 $ul.dataSM('parent-a', $a) 680 .dataSM('level', level) 681 .parent().dataSM('sub', $ul); 682 // accessibility 683 var aId = $a.attr('id') || this.accessIdPrefix + (++this.idInc), 684 ulId = $ul.attr('id') || this.accessIdPrefix + (++this.idInc); 685 $a.attr({ 686 id: aId, 687 'aria-haspopup': 'true', 688 'aria-controls': ulId, 689 'aria-expanded': 'false' 690 }); 691 $ul.attr({ 692 id: ulId, 693 'role': 'group', 694 'aria-hidden': 'true', 695 'aria-labelledby': aId, 696 'aria-expanded': 'false' 697 }); 698 // add sub indicator to parent item 699 if (this.opts.subIndicators) { 700 $a[this.opts.subIndicatorsPos](this.$subArrow.clone()); 701 } 702 } 703 }, 704 menuPosition: function($sub) { 705 var $a = $sub.dataSM('parent-a'), 706 $li = $a.closest('li'), 707 $ul = $li.parent(), 708 level = $sub.dataSM('level'), 709 subW = this.getWidth($sub), 710 subH = this.getHeight($sub), 711 itemOffset = $a.offset(), 712 itemX = itemOffset.left, 713 itemY = itemOffset.top, 714 itemW = this.getWidth($a), 715 itemH = this.getHeight($a), 716 $win = $(window), 717 winX = $win.scrollLeft(), 718 winY = $win.scrollTop(), 719 winW = this.getViewportWidth(),
720 winH = this.getViewportHeight(), 721 horizontalParent = $ul.parent().is('[data-sm-horizontal-sub]') || level == 2 && !$ul.hasClass('sm-vertical'), 722 rightToLeft = this.opts.rightToLeftSubMenus && !$li.is('[data-sm-reverse]') || !this.opts.rightToLeftSubMenus && $li.is('[data-sm-reverse]'), 723 subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX, 724 subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY, 725 x, y; 726 if (horizontalParent) { 727 x = rightToLeft ? itemW - subW - subOffsetX : subOffsetX; 728 y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY; 729 } else { 730 x = rightToLeft ? subOffsetX - subW : itemW - subOffsetX; 731 y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY; 732 } 733 if (this.opts.keepInViewport) { 734 var absX = itemX + x, 735 absY = itemY + y; 736 if (rightToLeft && absX < winX) { 737 x = horizontalParent ? winX - absX + x : itemW - subOffsetX; 738 } else if (!rightToLeft && absX + subW > winX + winW) { 739 x = horizontalParent ? winX + winW - subW - absX + x : subOffsetX - subW; 740 } 741 if (!horizontalParent) { 742 if (subH < winH && absY + subH > winY + winH) { 743 y += winY + winH - subH - absY; 744 } else if (subH >= winH || absY < winY) { 745 y += winY - absY; 746 } 747 } 748 // do we need scrolling? 749 // 0.49 used for better precision when dealing with float values 750 if (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49) { 751 var self = this; 752 if (!$sub.dataSM('scroll-arrows')) { 753 $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]]) 754 .on({ 755 mouseenter: function() { 756 $sub.dataSM('scroll').up = $(this).hasClass('scroll-up'); 757 self.menuScroll($sub); 758 }, 759 mouseleave: function(e) { 760 self.menuScrollStop($sub); 761 self.menuScrollOut($sub, e); 762 }, 763 'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); } 764 }) 765 .insertAfter($sub) 766 ); 767 } 768 // bind scroll events and save scroll data for this sub 769 var eNS = '.smartmenus_scroll'; 770 $sub.dataSM('scroll', { 771 y: this.cssTransforms3d ? 0 : y - itemH, 772 step: 1, 773 // cache stuff for faster recalcs later 774 itemH: itemH, 775 subH: subH, 776 arrowDownH: this.getHeight($sub.dataSM('scroll-arrows').eq(1)) 777 }) 778 .on(getEventsNS({ 779 'mouseover': function(e) { self.menuScrollOver($sub, e); }, 780 'mouseout': function(e) { self.menuScrollOut($sub, e); }, 781 'mousewheel DOMMouseScroll': function(e) { self.menuScrollMousewheel($sub, e); } 782 }, eNS)) 783 .dataSM('scroll-arrows').css({ top: 'auto', left: '0', marginLeft: x + (parseInt($sub.css('border-left-width')) || 0), width: subW - (parseInt($sub.css('border-left-width')) || 0) - (parseInt($sub.css('border-right-width')) || 0), zIndex: $sub.css('z-index') }) 784 .eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show(); 785 // when a menu tree is fixed positioned we allow scrolling via touch too 786 // since there is no other way to access such long sub menus if no mouse is present 787 if (this.isFixed()) { 788 var events = {}; 789 events[touchEvents ? 'touchstart touchmove touchend' : 'pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp'] = function(e) { 790 self.menuScrollTouch($sub, e); 791 }; 792 $sub.css({ 'touch-action': 'none', '-ms-touch-action': 'none' }).on(getEventsNS(events, eNS)); 793 } 794 } 795 } 796 $sub.css({ top: 'auto', left: '0', marginLeft: x, marginTop: y - itemH }); 797 }, 798 menuScroll: function($sub, once, step) { 799 var data = $sub.dataSM('scroll'), 800 $arrows = $sub.dataSM('scroll-arrows'), 801 end = data.up ? data.upEnd : data.downEnd, 802 diff; 803 if (!once && data.momentum) { 804 data.momentum *= 0.92; 805 diff = data.momentum; 806 if (diff < 0.5) { 807 this.menuScrollStop($sub); 808 return; 809 } 810 } else { 811 diff = step || (once || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor(data.step)); 812 } 813 // hide any visible deeper level sub menus 814 var level = $sub.dataSM('level'); 815 if (this.activatedItems[level - 1] && this.activatedItems[level - 1].dataSM('sub') && this.activatedItems[level - 1].dataSM('sub').is(':visible')) {
816 this.menuHideSubMenus(level - 1); 817 } 818 data.y = data.up && end <= data.y || !data.up && end >= data.y ? data.y : (Math.abs(end - data.y) > diff ? data.y + (data.up ? diff : -diff) : end); 819 $sub.css(this.cssTransforms3d ? { '-webkit-transform': 'translate3d(0, ' + data.y + 'px, 0)', transform: 'translate3d(0, ' + data.y + 'px, 0)' } : { marginTop: data.y }); 820 // show opposite arrow if appropriate 821 if (mouse && (data.up && data.y > data.downEnd || !data.up && data.y < data.upEnd)) { 822 $arrows.eq(data.up ? 1 : 0).show(); 823 } 824 // if we've reached the end 825 if (data.y == end) { 826 if (mouse) { 827 $arrows.eq(data.up ? 0 : 1).hide(); 828 } 829 this.menuScrollStop($sub); 830 } else if (!once) { 831 if (this.opts.scrollAccelerate && data.step < this.opts.scrollStep) { 832 data.step += 0.2; 833 } 834 var self = this; 835 this.scrollTimeout = requestAnimationFrame(function() { self.menuScroll($sub); }); 836 } 837 }, 838 menuScrollMousewheel: function($sub, e) { 839 if (this.getClosestMenu(e.target) == $sub[0]) { 840 e = e.originalEvent; 841 var up = (e.wheelDelta || -e.detail) > 0; 842 if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) { 843 $sub.dataSM('scroll').up = up; 844 this.menuScroll($sub, true); 845 } 846 } 847 e.preventDefault(); 848 }, 849 menuScrollOut: function($sub, e) { 850 if (mouse) { 851 if (!/^scroll-(up|down)/.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || this.getClosestMenu(e.relatedTarget) != $sub[0])) { 852 $sub.dataSM('scroll-arrows').css('visibility', 'hidden'); 853 } 854 } 855 }, 856 menuScrollOver: function($sub, e) { 857 if (mouse) { 858 if (!/^scroll-(up|down)/.test(e.target.className) && this.getClosestMenu(e.target) == $sub[0]) { 859 this.menuScrollRefreshData($sub); 860 var data = $sub.dataSM('scroll'), 861 upEnd = $(window).scrollTop() - $sub.dataSM('parent-a').offset().top - data.itemH; 862 $sub.dataSM('scroll-arrows').eq(0).css('margin-top', upEnd).end() 863 .eq(1).css('margin-top', upEnd + this.getViewportHeight() - data.arrowDownH).end() 864 .css('visibility', 'visible'); 865 } 866 } 867 }, 868 menuScrollRefreshData: function($sub) { 869 var data = $sub.dataSM('scroll'), 870 upEnd = $(window).scrollTop() - $sub.dataSM('parent-a').offset().top - data.itemH; 871 if (this.cssTransforms3d) { 872 upEnd = -(parseFloat($sub.css('margin-top')) - upEnd); 873 } 874 $.extend(data, { 875 upEnd: upEnd, 876 downEnd: upEnd + this.getViewportHeight() - data.subH 877 }); 878 }, 879 menuScrollStop: function($sub) { 880 if (this.scrollTimeout) { 881 cancelAnimationFrame(this.scrollTimeout); 882 this.scrollTimeout = 0; 883 $sub.dataSM('scroll').step = 1; 884 return true; 885 } 886 }, 887 menuScrollTouch: function($sub, e) { 888 e = e.originalEvent; 889 if (isTouchEvent(e)) { 890 var touchPoint = this.getTouchPoint(e); 891 // neglect event if we touched a visible deeper level sub menu 892 if (this.getClosestMenu(touchPoint.target) == $sub[0]) { 893 var data = $sub.dataSM('scroll'); 894 if (/(start|down)$/i.test(e.type)) { 895 if (this.menuScrollStop($sub)) { 896 // if we were scrolling, just stop and don't activate any link on the first touch 897 e.preventDefault(); 898 this.$touchScrollingSub = $sub; 899 } else { 900 this.$touchScrollingSub = null; 901 } 902 // update scroll data since the user might have zoomed, etc. 903 this.menuScrollRefreshData($sub); 904 // extend it with the touch properties 905 $.extend(data, { 906 touchStartY: touchPoint.pageY, 907 touchStartTime: e.timeStamp 908 }); 909 } else if (/move$/i.test(e.type)) { 910 var prevY = data.touchY !== undefined ? data.touchY : data.touchStartY; 911 if (prevY !== undefined && prevY != touchPoint.pageY) { 912 this.$touchScrollingSub = $sub; 913 var up = prevY < touchPoint.pageY; 914 // changed direction? reset... 915 if (data.up !== undefined && data.up != up) { 916 $.extend(data, { 917 touchStartY: touchPoint.pageY, 918 touchStartTime: e.timeStamp 919 }); 920 } 921 $.extend(data, { 922 up: up, 923 touchY: touchPoint.pageY 924 }); 925 this.menuScroll($sub, true, Math.abs(touchPoint.pageY - prevY)); 926 } 927 e.preventDefault(); 928 } else { // touchend/pointerup 929 if (data.touchY !== undefined) { 930 if (data.momentum = Math.pow(Math.abs(touchPoint.pageY - data.touchStartY) / (e.timeStamp - data.touchStartTime), 2) * 15) { 931 this.menuScrollStop($sub); 932 this.menuScroll($sub); 933 e.preventDefault(); 934 } 935 delete data.touchY; 936 } 937 } 938 } 939 } 940 }, 941 menuShow: function($sub) { 942 if (!$sub.dataSM('beforefirstshowfired')) { 943 $sub.dataSM('beforefirstshowfired', true); 944 if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) { 945 return; 946 } 947 } 948 if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) { 949 return; 950 } 951 $sub.dataSM('shown-before', true); 952 if (canAnimate) { 953 $sub.stop(true, true); 954 } 955 if (!$sub.is(':visible')) { 956 // highlight parent item 957 var $a = $sub.dataSM('parent-a'), 958 collapsible = this.isCollapsible(); 959 if (this.opts.keepHighlighted || collapsible) { 960 $a.addClass('highlighted'); 961 } 962 if (collapsible) { 963 $sub.removeClass('sm-nowrap').css({ zIndex: '', width: 'auto', minWidth: '', maxWidth: '', top: '', left: '', marginLeft: '', marginTop: '' }); 964 } else { 965 // set z-index 966 $sub.css('z-index', this.zIndexInc = (this.zIndexInc || this.get
966StartZIndex()) + 1); 967 // min/max-width fix - no way to rely purely on CSS as all UL's are nested 968 if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) { 969 $sub.css({ width: 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 970 if (this.opts.subMenusMinWidth) { 971 $sub.css('min-width', this.opts.subMenusMinWidth); 972 } 973 if (this.opts.subMenusMaxWidth) { 974 var noMaxWidth = this.getWidth($sub); 975 $sub.css('max-width', this.opts.subMenusMaxWidth); 976 if (noMaxWidth > this.getWidth($sub)) { 977 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 978 } 979 } 980 } 981 this.menuPosition($sub); 982 } 983 var complete = function() { 984 // fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used 985 $sub.css('overflow', ''); 986 }; 987 // if sub is collapsible (mobile view) 988 if (collapsible) { 989 if (canAnimate && this.opts.collapsibleShowFunction) { 990 this.opts.collapsibleShowFunction.call(this, $sub, complete); 991 } else { 992 $sub.show(this.opts.collapsibleShowDuration, complete); 993 } 994 } else { 995 if (canAnimate && this.opts.showFunction) { 996 this.opts.showFunction.call(this, $sub, complete); 997 } else { 998 $sub.show(this.opts.showDuration, complete); 999 } 1000 } 1001 // accessibility 1002 $a.attr('aria-expanded', 'true'); 1003 $sub.attr({ 1004 'aria-expanded': 'true', 1005 'aria-hidden': 'false' 1006 }); 1007 // store sub menu in visible array 1008 this.visibleSubMenus.push($sub); 1009 this.$root.triggerHandler('show.smapi', $sub[0]); 1010 } 1011 }, 1012 popupHide: function(noHideTimeout) { 1013 if (this.hideTimeout) { 1014 clearTimeout(this.hideTimeout); 1015 this.hideTimeout = 0; 1016 } 1017 var self = this; 1018 this.hideTimeout = setTimeout(function() { 1019 self.menuHideAll(); 1020 }, noHideTimeout ? 1 : this.opts.hideTimeout); 1021 }, 1022 popupShow: function(left, top) { 1023 if (!this.opts.isPopup) { 1024 alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'); 1025 return; 1026 } 1027 if (this.hideTimeout) { 1028 clearTimeout(this.hideTimeout); 1029 this.hideTimeout = 0; 1030 } 1031 this.$root.dataSM('shown-before', true); 1032 if (canAnimate) { 1033 this.$root.stop(true, true); 1034 } 1035 if (!this.$root.is(':visible')) { 1036 this.$root.css({ left: left, top: top }); 1037 // show menu 1038 var self = this, 1039 complete = function() { 1040 self.$root.css('overflow', ''); 1041 }; 1042 if (canAnimate && this.opts.showFunction) { 1043 this.opts.showFunction.call(this, this.$root, complete); 1044 } else { 1045 this.$root.show(this.opts.showDuration, complete); 1046 } 1047 this.visibleSubMenus[0] = this.$root; 1048 } 1049 }, 1050 refresh: function() { 1051 this.destroy(true); 1052 this.init(true); 1053 }, 1054 rootKeyDown: function(e) { 1055 if (!this.handleEvents()) { 1056 return; 1057 } 1058 switch (e.keyCode) { 1059 case 27: // reset on Esc 1060 var $activeTopItem = this.activatedItems[0]; 1061 if ($activeTopItem) { 1062 this.menuHideAll(); 1063 $activeTopItem[0].focus(); 1064 var $sub = $activeTopItem.dataSM('sub'); 1065 if ($sub) { 1066 this.menuHide($sub); 1067 } 1068 } 1069 break; 1070 case 32: // activate item's sub on Space 1071 var $target = $(e.target); 1072 if ($target.is('a') && this.handleItemEvents($target)) { 1073 var $sub = $target.dataSM('sub'); 1074 if ($sub && !$sub.is(':visible')) { 1075 this.itemClick({ currentTarget: e.target }); 1076 e.preventDefault(); 1077 } 1078 } 1079 break; 1080 } 1081 }, 1082 rootOut: function(e) { 1083 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 1084 return; 1085 } 1086 if (this.hideTimeout) { 1087 clearTimeout(this.hideTimeout); 1088 this.hideTimeout = 0; 1089 } 1090 if (!this.opts.showOnClick || !this.opts.hideOnClick) { 1091 var self = this; 1092 this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout); 1093 } 1094 }, 1095 rootOver: function(e) { 1096 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 1097 return; 1098 } 1099 if (this.hideTimeout) { 1100 clearTimeout(this.hideTimeout); 1101 this.hideTimeout = 0; 1102 } 1103 }, 1104 winResize: function(e) { 1105 if (!this.handleEvents()) { 1106 // we still need to resize the disable overlay if it's visible 1107 if (this.$disableOverlay) { 1108 var pos = this.$root.offset(); 1109 this.$disableOverlay.css({ 1110 top: pos.top, 1111 left: pos.left, 1112 width: this.$root.outerWidth(), 1113 height: this.$root.outerHeight() 1114 }); 1115 } 1116 return; 1117 } 1118 // hide sub menus on resize - on mobile do it only on orientation change 1119 if (!('onorientationchange' in window) || e.type == 'orientationchange') { 1120 var collapsible = this.isCollapsible(); 1121 // if it was collapsible before resize and still is, don't do it 1122 if (!(this.wasCollapsible && collapsible)) { 1123 if (this.activatedItems.length) { 1124 this.activatedItems[this.activatedItems.length - 1][0].blur(); 1125 } 1126 this.menuHideAll(); 1127 } 1128 this.wasCollapsible = collapsible; 1129 } 1130 } 1131 } 1132 }); 1133 1134 $.fn.dataSM = function(key, val) { 1135 if (val) { 1136 return this.data(key + '_smartmenus', val); 1137 } 1138 return this.data(key + '_smartmenus'); 1139 }; 1140 1141 $.fn.removeDataSM = function(key) { 1142 return this.removeData(key + '_smartmenus'); 1143 }; 1144 1145 $.fn.smartmenus = function(options) { 1146 if (typeof options == 'string') { 1147 var args = arguments, 1148 method = options; 1149 Array.prototype.shift.call(args); 1150 return this.each(function() { 1151 var smartmenus = $(this).data('smartmenus'); 1152 if (smartmenus && smartmenus[method]) { 1153 smartmenus[method].apply(smartmenus, args); 1154 } 1155 }); 1156 } 1157 return this.each(function() { 1158 // [data-sm-options] attribute on the root UL 1159 var dataOpts = $(this).data('sm-options') || null; 1160 if (dataOpts && typeof dataOpts != 'object') { 1161 dataOpts = null; 1162 alert('ERROR\n\nSmartMenus jQuery init:\nThe value of the "data-sm-options" attribute must be valid JSON.'); 1163 } 1164 // do not support function options 1165 if (dataOpts) { 1166 $.each(['showFunction', 'hideFunction', 'collapsibleShowFunction', 'collapsibleHideFunction'], function() { 1167 if (this in dataOpts) { 1168 delete dataOpts[this]; 1169 } 1170 }); 1171 } 1172 new $.SmartMenus(this, $.extend({}, $.fn.smartmenus.defaults, options, dataOpts)); 1173 }); 1174 }; 1175 1176 // default settings 1177 $.fn.smartmenus.defaults = { 1178 isPopup: false, // is this a popup menu (can be shown via the popupS
1178how/popupHide methods) or a permanent menu bar 1179 mainMenuSubOffsetX: 0, // pixels offset from default position 1180 mainMenuSubOffsetY: 0, // pixels offset from default position 1181 subMenusSubOffsetX: 0, // pixels offset from default position 1182 subMenusSubOffsetY: 0, // pixels offset from default position 1183 subMenusMinWidth: '10em', // min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 1184 subMenusMaxWidth: '20em', // max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 1185 subIndicators: true, // create sub menu indicators - creates a SPAN and inserts it in the A 1186 subIndicatorsPos: 'append', // position of the SPAN relative to the menu item content ('append', 'prepend') 1187 subIndicatorsText: '', // [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too) 1188 scrollStep: 30, // pixels step when scrolling long sub menus that do not fit in the viewport height 1189 scrollAccelerate: true, // accelerate scrolling or use a fixed step 1190 showTimeout: 250, // timeout before showing the sub menus 1191 hideTimeout: 500, // timeout before hiding the sub menus 1192 showDuration: 0, // duration for show animation - set to 0 for no animation - matters only if showFunction:null 1193 showFunction: null, // custom function to use when showing a sub menu (the default is the jQuery 'show') 1194 // don't forget to call complete() at the end of whatever you do 1195 // e.g.: function($ul, complete) { $ul.fadeIn(250, complete); } 1196 hideDuration: 0, // duration for hide animation - set to 0 for no animation - matters only if hideFunction:null 1197 hideFunction: function($ul, complete) { $ul.fadeOut(200, complete); }, // custom function to use when hiding a sub menu (the default is the jQuery 'hide') 1198 // don't forget to call complete() at the end of whatever you do 1199 // e.g.: function($ul, complete) { $ul.fadeOut(250, complete); } 1200 collapsibleShowDuration:0, // duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null 1201 collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); }, // custom function to use when showing a collapsible sub menu 1202 // (i.e. when mobile styles are used to make the sub menus collapsible) 1203 collapsibleHideDuration:0, // duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null 1204 collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); }, // custom function to use when hiding a collapsible sub menu 1205 // (i.e. when mobile styles are used to make the sub menus collapsible) 1206 showOnClick: false, // show the first-level sub menus onclick instead of onmouseover (i.e. mimic desktop app menus) (matters only for mouse input) 1207 hideOnClick: true, // hide the sub menus on click/tap anywhere on the page 1208 noMouseOver: false, // disable sub menus activation onmouseover (i.e. behave like in touch mode - use just mouse clicks) (matters only for mouse input) 1209 keepInViewport: true, // reposition the sub menus if needed to make sure they always appear inside the viewport 1210 keepHighlighted: true, // keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's) 1211 markCurrentItem: false, // automatically add the 'current' class to the A element of the item linking to the current URL 1212 markCurrentTree: true, // add the 'current' class also to the A elements of all ancestor items of the current item 1213 rightToLeftSubMenus: false, // right to left display of the sub menus (check the CSS for the sub indicators' position) 1214 bottomToTopSubMenus: false, // bottom to top display of the sub menus 1215 collapsibleBehavior: 'default' // parent items behavior in collapsible (mobile) view ('default', 'toggle', 'link', 'accordion', 'accordion-toggle', 'accordion-link') 1216 // 'default' - first tap on parent item expands sub, second tap loads its link 1217 // 'toggle' - the whole parent item acts just as a toggle button for its sub menu (expands/collapses on each tap) 1218 // 'link' - the parent item acts as a regular item (first tap loads its link), the sub menu can be expanded only via the +/- button 1219 // 'accordion' - like 'default' but on expand also resets any visible sub menus from deeper levels or other branches 1220 // 'accordion-toggle' - like 'toggle' but on expand also resets any visible sub menus from deeper levels or other branches 1221 // 'accordion-link' - like 'link' but on expand also resets any visible sub menus from deeper levels or other branches 1222 }; 1223 1224 return $; 1225})); 1226; 1227;(function($) { 1228 1229 PPAdvancedMenu = function( $scope, elementSettings ) { 1230 this.node = $scope; 1231 this.menu_wrap = $scope.find( '.pp-advanced-menu-main-wrapper' ); 1232 this.wrap = $scope.find( '.pp-advanced-menu__container' ); 1233 this.menu = $scope.find( '.pp-advanced-menu' ); 1234 this.dropdownMenu = $scope.find( '.pp-advanced-menu__container.pp-advanced-menu--dropdown' );
1235 this.anchorLink = $scope.find( '.pp-advanced-menu--main .pp-menu-item-anchor' ); 1236 this.menuToggle = $scope.find( '.pp-menu-toggle' ); // hamburger icon 1237 this.settings = $scope.find( '.pp-advanced-menu__container' ).data( 'settings' ); 1238 1239 if ( ! this.settings ) { 1240 return; 1241 } 1242 1243 this.menuId = this.settings.menu_id; 1244 this.menuType = elementSettings.menu_type; 1245 this.fullWidth = elementSettings.full_width; 1246 this.menuLayout = elementSettings.layout; 1247 this.showSubmenuOn = elementSettings.show_submenu_on; 1248 this.showSubmenuOnClick = ( this.showSubmenuOn == 'click' ); 1249 this.onepage_menu = elementSettings.onepage_menu; 1250 this.duration = 400; 1251 1252 //this.iconValue = this.settings.submenu_icon.value; 1253 this.iconValue = elementSettings.submenu_icon.value; 1254 this.subIndicatorsContent = ''; 1255 1256 if ( this.iconValue ) { 1257 this.subIndicatorsContent = this.iconValue.indexOf( '<' ) > -1 ? this.iconValue : `<i class="${this.iconValue}"></i>`; 1258 } 1259 1260 this.init(); 1261 }; 1262 1263 PPAdvancedMenu.prototype = { 1264 stretchElement: null, 1265 1266 init: function () { 1267 1268 if ( ! this.menu.length ) { 1269 return; 1270 } 1271 1272 if ( jQuery.fn.smartmenus ) { 1273 // Override the default stupid detection 1274 jQuery.SmartMenus.prototype.isCSSOn = function() { 1275 return true; 1276 }; 1277 1278 if ( elementorFrontend.config.is_rtl ) { 1279 jQuery.fn.smartmenus.defaults.rightToLeftSubMenus = true; 1280 } 1281 } 1282 1283 if ( 'horizontal' === this.menuLayout ) { 1284 if ('undefined' !== typeof $.fn.smartmenus) { 1285 this.menu.smartmenus( 1286 { 1287 subIndicators: '' !== this.subIndicatorsContent, 1288 subIndicatorsText: this.subIndicatorsContent, 1289 subIndicatorsPos: 'append', 1290 subMenusMaxWidth: '1000px', 1291 subMenusMinWidth: '', 1292 showOnClick: this.showSubmenuOnClick, 1293 collapsibleBehavior: 'link', 1294 } 1295 ).on('click', 'span.sub-arrow', function(e) { 1296 var ppanchorsubMenuObj = $(this).closest( 'a.has-submenu' ); 1297 ppanchorsubMenuObj.toggleClass( 'highlighted' ); 1298 ppanchorsubMenuObj.attr( 'aria-expanded', 1299 ppanchorsubMenuObj.attr( 'aria-expanded' ) == 'false' ? 'true' : 'false' 1300 ); 1301 var ppsubMenuObj = ppanchorsubMenuObj.siblings( 'ul' ); 1302 ppsubMenuObj.attr( 'aria-hidden', 1303 ppsubMenuObj.attr( 'aria-hidden' ) == 'false' ? 'true' : 'false' 1304 ); 1305 ppsubMenuObj.attr( 'aria-expanded', 1306 ppsubMenuObj.attr( 'aria-expanded' ) == 'false' ? 'true' : 'false' 1307 ); 1308 if ( 'true' === ppsubMenuObj.attr( 'aria-expanded' ) ) { 1309 ppsubMenuObj.css( { width: 'auto', display: 'block' } ); 1310 } else { 1311 ppsubMenuObj.css( { width: 'auto', display: 'none' } ); 1312 } 1313 e.preventDefault(); 1314 e.stopPropagation(); 1315 }); 1316 } 1317 } 1318 1319 if ( 'vertical' === this.menuLayout ) { 1320 if ('undefined' !== typeof $.fn.smartmenus) { 1321 this.menu.smartmenus( 1322 { 1323 subIndicators: '' !== this.subIndicatorsContent, 1324 subIndicatorsText: this.subIndicatorsContent, 1325 subIndicatorsPos: 'append', 1326 subMenusMaxWidth: '', 1327 subMenusMinWidth: '', 1328 mainMenuSubOffsetX: '0px', 1329 mainMenuSubOffsetY: '0px', 1330 subMenusSubOffsetX: '0px', 1331 subMenusSubOffsetY: '0px', 1332 showOnClick: this.showSubmenuOnClick, 1333 collapsibleBehavior: 'link', 1334 } 1335 ).on('click', 'span.sub-arrow', function(e) { 1336 var ppanchorsubMenuObj = $(this).closest( 'a.has-submenu' ); 1337 ppanchorsubMenuObj.toggleClass( 'highlighted' ); 1338 ppanchorsubMenuObj.attr( 'aria-expanded', 1339 ppanchorsubMenuObj.attr( 'aria-expanded' ) == 'false' ? 'true' : 'false' 1340 ); 1341 var ppsubMenuObj = ppanchorsubMenuObj.siblings( 'ul' ); 1342 ppsubMenuObj.attr( 'aria-hidden', 1343 ppsubMenuObj.attr( 'aria-hidden' ) == 'false' ? 'true' : 'false' 1344 ); 1345 ppsubMenuObj.attr( 'aria-expanded', 1346 ppsubMenuObj.attr( 'aria-expanded' ) == 'false' ? 'true' : 'false' 1347 ); 1348 if ( 'true' === ppsubMenuObj.attr( 'aria-expanded' ) ) { 1349 ppsubMenuObj.css( { width: 'auto', display: 'block' } ); 1350 } else { 1351 ppsubMenuObj.css( { width: 'auto', display: 'none' } ); 1352 } 1353 e.preventDefault(); 1354 e.stopPropagation(); 1355 }); 1356 } 1357 } 1358 1359 if ( 'default' === this.menuType ) { 1360 this.initStretchElement();
1361 this.stretchMenu(); 1362 } 1363 1364 if ('off-canvas' === this.menuType) { 1365 this.initOffCanvas(); 1366 } 1367 1368 if ('full-screen' === this.menuType) { 1369 this.initFullScreen(); 1370 } 1371 1372 this.bindEvents(); 1373 1374 if ( ! elementorFrontend.isEditMode() ) { 1375 this.followMenuAnchors(); 1376 } 1377 1378 $( window ).on( 'load', $.proxy( this.resetDimensions, this ) ); 1379 1380 this.menu.smartmenus( 'refresh' ); 1381 }, 1382 1383 getElementSettings: function( setting ) { 1384 if ( 'undefined' !== typeof this.settings[setting] ) { 1385 return this.settings[setting]; 1386 } 1387 1388 return false; 1389 }, 1390 1391 bindEvents: function () { 1392 var self = this; 1393 1394 if ( ! this.menu.length ) { 1395 return; 1396 } 1397 1398 this.menuToggle.on( 'click', $.proxy( this.toggleMenu, this ) ); 1399 1400 if ( 'yes' === this.onepage_menu ) { 1401 this.menu.on( 1402 'click', 1403 '.menu-item > a[href*="#"]', 1404 function(e) { 1405 1406 var $href = $( this ).attr( 'href' ), 1407 $targetID = ''; 1408 1409 if ( $href !== '#' ) { 1410 $targetID = $href.split( '#' )[1]; 1411 1412 if ( $( 'body' ).find( '#' + $targetID ).length > 0 ) { 1413 e.preventDefault(); 1414 $( this ).toggleClass( 'pp-active' ); 1415 /* setTimeout(function() { 1416 $('html, body').animate({ 1417 scrollTop: $('#'+ $targetID).offset().top 1418 }, 200, 'linear', function() { 1419 window.location.hash = $targetID; 1420 }); 1421 }, 500); */ 1422 } 1423 1424 self.closeMenu(); 1425 } 1426 } 1427 ); 1428 } 1429 1430 if ('default' === this.menuType) { 1431 elementorFrontend.addListenerOnce( this.node.data( 'model-cid' ), 'resize', $.proxy( this.stretchMenu, this ) ); 1432 } 1433 1434 //self.panelUpdate(); 1435 1436 this.closeMenuESC(); 1437 }, 1438 1439 panelUpdate: function() { 1440 var self = this; 1441 1442 if ('undefined' !== typeof elementor && $( 'body' ).hasClass( 'elementor-editor-active' )) { 1443 elementor.hooks.addAction( 1444 'panel/open_editor/widget/pp-advanced-menu', 1445 function (panel, model, view) { 1446 panel.$el.find( 'select[data-setting="dropdown"]' ).on( 1447 'change', 1448 function () { 1449 if (model.attributes.id === self.menuId) { 1450 if ($( this ).val() === 'all') { 1451 self.node.find( '.pp-advanced-menu--main' ).hide(); 1452 } 1453 if ($( this ).val() !== 'all') { 1454 self.node.find( '.pp-advanced-menu--main' ).show(); 1455 } 1456 } 1457 } 1458 ); 1459 1460 if (model.attributes.id === self.menuId && 'all' === self.settings.breakpoint) { 1461 self.toggleMenu(); 1462 } 1463 } 1464 ); 1465 } 1466 }, 1467 1468 initStretchElement: function () { 1469 this.stretchElement = new elementorFrontend.modules.StretchElement( { element: this.dropdownMenu } ); 1470 }, 1471 1472 stretchMenu: function () { 1473 if ( 'stretch' == this.fullWidth ) { 1474 this.stretchElement.stretch(); 1475 1476 this.dropdownMenu.css( 'top', this.menuToggle.outerHeight() ); 1477 } else { 1478 this.stretchElement.reset(); 1479 } 1480 }, 1481 1482 initOffCanvas: function () { 1483 $( '.pp-menu-' + this.settings.menu_id ).each( 1484 function(id, el) { 1485 if ($( el ).parent().is( 'body' ) ) { 1486 $( el ).remove(); 1487 } 1488 } 1489 ); 1490 1491 /* if ( $('.pp-offcanvas-container').length === 0 ) { 1492 $('body').wrapInner( '<div class="pp-offcanvas-container" />' ); 1493 this.node.find( '.pp-menu-' + this.settings.menu_id ).insertBefore('.pp-offcanvas-container'); 1494 } */ 1495 1496 if ( this.menu_wrap.find( '.pp-menu-off-canvas' ).length > 0 ) { 1497 if ( $( '.pp-offcanvas-container > .pp-menu-' + this.settings.menu_id ).length > 0 ) { 1498 $( '.pp-offcanvas-container > .pp-menu-' + this.settings.menu_id ).remove(); 1499 } 1500 if ( $( 'body > .pp-menu-' + this.settings.menu_id ).length > 0 ) { 1501 $( 'body > .pp-menu-' + this.settings.menu_id ).remove(); 1502 } 1503 $( 'body' ).prepend( this.node.find( '.pp-menu-' + this.settings.menu_id ) ); 1504 } 1505 1506 $( '.pp-menu-clear' ).fadeOut( 1507 400, 1508 function() { 1509 $( this ).remove(); 1510 } 1511 ); 1512 1513 $( '.pp-menu-' + this.settings.menu_id ).css( 'height', window.innerHeight + 150 + 'px' ); 1514 $( '.pp-menu-' + this.settings.menu_id ).find( '.pp-menu-close' ).on( 'click', $.proxy( this.closeMenu, this ) ); 1515 }, 1516 1517 initFullScreen: function () { 1518 $( 'body' ).addClass( 'pp-menu--full-screen' ); 1519 $( '.pp-menu-' + this.settings.menu_id ).css( 'height', window.innerHeight + 150 + 'px' ); 1520 $( '.pp-menu-' + this.settings.menu_id ).find( '.pp-menu-close' ).on( 'click', $.proxy( this.closeMenu, this ) ); 1521 //$('.pp-menu-' + this.settings.menu_id).find('.menu-item a').on('click', $.proxy(this.closeMenu, this)); 1522 }, 1523 1524 resetDimensions: function() { 1525 if ( 'full-screen' === this.menuType ) { 1526 $( '.pp-menu-' + this.settings.menu_id ).css( 'height', window.innerHeight + 150 + 'px' ); 1527 } 1528 }, 1529 1530 toggleMenu: function () { 1531 this.menuToggle.toggleClass( 'pp-active' ); 1532 1533 var menuType = this.menuType; 1534 var isActive = this.menuToggle.hasClass( 'pp-active' ); 1535 1536 $( 'html' ).removeClass( 'pp-menu-toggle-open' ); 1537 1538 if ( isActive ) { 1539 $( 'html' ).addClass( 'pp-menu-toggle-open' ); 1540 } 1541 1542 if ('default' === menuType) { 1543 var $dropdownMenu = this.dropdownMenu; 1544 1545 if (isActive) { 1546 $dropdownMenu.hide().slideDown( 1547 250, 1548 function () { 1549 $dropdownMenu.css( 'display', '' ); 1550 } 1551 ); 1552
1553 this.stretchMenu(); 1554 } else { 1555 $dropdownMenu.show().slideUp( 1556 250, 1557 function () { 1558 $dropdownMenu.css( 'display', '' ); 1559 } 1560 ); 1561 } 1562 } 1563 1564 if ('off-canvas' === menuType) { 1565 this.toggleOffCanvas(); 1566 } 1567 if ('full-screen' === menuType) { 1568 this.toggleFullScreen(); 1569 } 1570 }, 1571 1572 toggleOffCanvas: function() { 1573 var isActive = this.menuToggle.hasClass( 'pp-active' ), 1574 element = $( 'body' ).find( '.pp-menu-' + this.menuId ), 1575 time = this.duration, 1576 self = this; 1577 1578 $( 'html' ).removeClass( 'pp-menu-toggle-open' ); 1579 1580 if ( isActive ) { 1581 $( 'body' ).addClass( 'pp-menu--off-canvas' ); 1582 $( 'html' ).addClass( 'pp-menu-toggle-open' ); 1583 time = 0; 1584 } else { 1585 time = this.duration; 1586 } 1587 1588 $( '.pp-menu-open' ).removeClass( 'pp-menu-open' ); 1589 $( '.pp-advanced-menu--toggle .pp-menu-toggle' ).not( this.menuToggle ).removeClass( 'pp-active' ); 1590 1591 setTimeout( 1592 function() { 1593 $( '.pp-menu-off-canvas' ).removeAttr( 'style' ); 1594 1595 if (isActive) { 1596 $( 'body' ).addClass( 'pp-menu-open' ); 1597 element.addClass( 'pp-menu-open' ).css( 'z-index', '999999' ); 1598 if ( $( '.pp-menu-clear' ).length === 0 ) { 1599 $( 'body' ).append( '<div class="pp-menu-clear" style="transition: none !important;"></div>' ); 1600 } 1601 $( '.pp-menu-clear' ).off( 'click' ).on( 'click', $.proxy( self.closeMenu, self ) ); 1602 $( '.pp-menu-clear' ).fadeIn(); 1603 } else { 1604 $( '.pp-menu-open' ).removeClass( 'pp-menu-open' ); 1605 $( 'body' ).removeClass( 'pp-menu--off-canvas' ); 1606 $( 'html' ).removeClass( 'pp-menu-toggle-open' ); 1607 $( '.pp-menu-clear' ).fadeOut(); 1608 } 1609 }, 1610 time 1611 ); 1612 }, 1613 1614 toggleFullScreen: function() { 1615 var isActive = this.menuToggle.hasClass( 'pp-active' ), 1616 element = $( 'body' ).find( '.pp-menu-' + this.menuId ); 1617 1618 $( 'html' ).removeClass( 'pp-menu-toggle-open' ); 1619 1620 if ( isActive ) { 1621 $( 'html' ).addClass( 'pp-menu-toggle-open' ); 1622 this.node.find( '.pp-menu-full-screen' ).addClass( 'pp-menu-open' ); 1623 /* this.node.find('.pp-menu-full-screen').attr('data-scroll', $(window).scrollTop()); 1624 $(window).scrollTop(0); */ 1625 } 1626 }, 1627 1628 closeMenu: function() { 1629 if ( 'default' !== this.menuType ) { 1630 $( '.pp-menu-open' ).removeClass( 'pp-menu-open' ); 1631 this.menuToggle.removeClass( 'pp-active' ); 1632 1633 $( 'html' ).removeClass( 'pp-menu-toggle-open' ); 1634 1635 if ( 'full-screen' === this.menuType ) { 1636 var scrollTop = this.node.find( '.pp-menu-full-screen' ).data( 'scroll' ); 1637 $( window ).scrollTop( scrollTop ); 1638 } 1639 1640 $( '.pp-menu-clear' ).fadeOut(); 1641 } 1642 }, 1643 1644 closeMenuESC: function() { 1645 var self = this; 1646 1647 // menu close on ESC key 1648 $( document ).on( 1649 'keydown', 1650 function (e) { 1651 if (e.keyCode === 27) { // ESC 1652 self.closeMenu(); 1653 } 1654 } 1655 ); 1656 }, 1657 1658 followMenuAnchors: function() { 1659 var self = this; 1660 this.anchorLink.each( function () { 1661 if (location.pathname === this.pathname && '' !== this.hash) { 1662 self.followMenuAnchorEle( $( this ) ); 1663 } 1664 } ); 1665 }, 1666 1667 followMenuAnchorEle: function( element ) { 1668 const anchorSelector = element[0].hash; 1669 let offset = -300, 1670 $anchor; 1671 1672 try { 1673 // `decodeURIComponent` for UTF8 characters in the hash. 1674 $anchor = $( decodeURIComponent( anchorSelector ) ); 1675 } catch ( e ) { 1676 return; 1677 } 1678 1679 if ( ! $anchor.length ) { 1680 return; 1681 } 1682 1683 if ( ! $anchor.hasClass( 'pp-menu-anchor' ) ) { 1684 var halfViewport = jQuery( window ).height() / 2; 1685 offset = -$anchor.outerHeight() + halfViewport; 1686 } 1687 1688 elementorFrontend.waypoint( $anchor, function ( direction ) { 1689 if ('down' === direction) { 1690 element.addClass( 'pp-menu-item-active' ); 1691 } else { 1692 element.removeClass( 'pp-menu-item-active' ); 1693 } 1694 }, { 1695 offset: '50%', 1696 triggerOnce: false 1697 }); 1698 elementorFrontend.waypoint( $anchor, function ( direction ) { 1699 if ('down' === direction) { 1700 element.removeClass( 'pp-menu-item-active' ); 1701 } else { 1702 element.addClass( 'pp-menu-item-active' ); 1703 } 1704 }, { 1705 offset, 1706 triggerOnce: false 1707 }); 1708 } 1709 }; 1710 1711 var isEditMode = false;
1712 1713 var getElementSettings = function( $element ) { 1714 var elementSettings = {}, 1715 modelCID = $element.data( 'model-cid' ); 1716 1717 if ( isEditMode && modelCID ) { 1718 var settings = elementorFrontend.config.elements.data[ modelCID ], 1719 settingsKeys = elementorFrontend.config.elements.keys[ settings.attributes.widgetType || settings.attributes.elType ]; 1720 1721 jQuery.each( settings.getActiveControls(), function( controlKey ) { 1722 if ( -1 !== settingsKeys.indexOf( controlKey ) ) { 1723 elementSettings[ controlKey ] = settings.attributes[ controlKey ]; 1724 } 1725 } ); 1726 } else { 1727 elementSettings = $element.data('settings') || {}; 1728 } 1729 1730 return elementSettings; 1731 }; 1732 1733 var AdvancedMenuHandler = function ($scope) { 1734 var elementSettings = getElementSettings( $scope ); 1735 1736 new PPAdvancedMenu( $scope, elementSettings ); 1737 1738 }; 1739 1740 $(window).on('elementor/frontend/init', function () { 1741 if ( elementorFrontend.isEditMode() ) { 1742 isEditMode = true; 1743 } 1744 1745 elementorFrontend.hooks.addAction( 'frontend/element_ready/pp-advanced-menu.default', AdvancedMenuHandler ); 1746 }); 1747 1748})( jQuery ); 1749; 1750/* 1751 * By Elementor Team 1752 */ 1753( function( $ ) { 1754 var Sticky = function( element, userSettings ) { 1755 var $element, 1756 isSticky = false, 1757 isFollowingParent = false, 1758 isReachedEffectsPoint = false, 1759 elements = {}, 1760 settings, 1761 elementOffsetValue, 1762 elementWidth; 1763 1764 var defaultSettings = { 1765 to: 'top', 1766 offset: 0, 1767 effectsOffset: 0, 1768 parent: false, 1769 classes: { 1770 sticky: 'sticky', 1771 stickyActive: 'sticky-active', 1772 stickyEffects: 'sticky-effects', 1773 spacer: 'sticky-spacer', 1774 }, 1775 isRTL: false, 1776 isScrollSnapActive: false, 1777 handleScrollbarWidth: false, 1778 }; 1779 1780 var initElements = function() { 1781 $element = $( element ).addClass( settings.classes.sticky ); 1782 1783 elements.$window = $( window ); 1784 elements.$body = $( document ).find( 'body' ); 1785 1786 if ( settings.parent ) { 1787 elements.$parent = $element.parent(); 1788 1789 if ( 'parent' !== settings.parent ) { 1790 elements.$parent = elements.$parent.closest( settings.parent ); 1791 } 1792 } 1793 }; 1794 1795 var initSettings = function() { 1796 settings = jQuery.extend( true, defaultSettings, userSettings ); 1797 }; 1798 1799 var bindEvents = function() { 1800 elements.$window.on( 'resize', onWindowResize ); 1801 1802 if ( settings.isScrollSnapActive ) { 1803 elements.$body.on( 'scroll', onWindowScroll ); 1804 } else { 1805 elements.$window.on( 'scroll', onWindowScroll ); 1806 } 1807 }; 1808 1809 var unbindEvents = function() { 1810 elements.$window 1811 .off( 'scroll', onWindowScroll ) 1812 .off( 'resize', onWindowResize ); 1813 1814 elements.$body.off( 'scroll', onWindowScroll ); 1815 }; 1816 1817 var init = function() { 1818 initSettings(); 1819 1820 initElements(); 1821 1822 bindEvents(); 1823 1824 checkPosition(); 1825 }; 1826 1827 var backupCSS = function( $elementBackupCSS, backupState, properties ) { 1828 var css = {}, 1829 elementStyle = $elementBackupCSS[ 0 ].style; 1830 1831 properties.forEach( function( property ) { 1832 css[ property ] = undefined !== elementStyle[ property ] ? elementStyle[ property ] : ''; 1833 } ); 1834 1835 $elementBackupCSS.data( 'css-backup-' + backupState, css ); 1836 }; 1837 1838 var getCSSBackup = function( $elementCSSBackup, backupState ) { 1839 return $elementCSSBackup.data( 'css-backup-' + backupState ); 1840 }; 1841 1842 const updateElementSizesData = () => { 1843 elementWidth = getElementOuterSize( $element, 'width' ); 1844 elementOffsetValue = $element.offset().left; 1845 1846 if ( settings.isRTL ) { 1847 // `window.innerWidth` includes the scrollbar while `document.body.offsetWidth` doesn't. 1848 const documentWidth = settings.handleScrollbarWidth ? window.innerWidth : document.body.offsetWidth; 1849 1850 elementOffsetValue = Math.max( documentWidth - elementWidth - elementOffsetValue, 0 ); 1851 } 1852 } 1853 1854 var addSpacer = function() { 1855 elements.$spacer = $element.clone() 1856 .addClass( settings.classes.spacer ) 1857 .css( { 1858 visibility: 'hidden', 1859 transition: 'none', 1860 animation: 'none', 1861 } ); 1862 1863 $element.after( elements.$spacer ); 1864 }; 1865 1866 var removeSpacer = function() { 1867 elements.$spacer.remove(); 1868 }; 1869 1870 var stickElement = function() { 1871 backupCSS( $element, 'unsticky', [ 'position', 'width', 'margin-top', 'margin-bottom', 'top', 'bottom', 'inset-inline-start' ] ); 1872 1873 const css = { 1874 position: 'fixed', 1875 width: elementWidth, 1876 marginTop: 0, 1877 marginBottom: 0, 1878 }; 1879 1880 css[ settings.to ] = settings.offset; 1881 css[ 'top' === settings.to ? 'bottom' : 'top' ] = ''; 1882 1883 if ( elementOffsetValue ) { 1884 css[ 'inset-inline-start' ] = elementOffsetValue + 'px'; 1885 } 1886 1887 $element 1888 .css( css ) 1889 .addClass( settings.classes.stickyActive ); 1890 }; 1891 1892 var unstickElement = function() { 1893 $element 1894 .css( getCSSBackup( $element, 'unsticky' ) ) 1895 .removeClass( settings.classes.stickyActive ); 1896 }; 1897 1898 var followParent = function() { 1899 backupCSS( elements.$parent, 'childNotFollowing', [ 'position' ] ); 1900 1901 elements.$parent.css( 'position', 'relative' ); 1902
1903 backupCSS( $element, 'notFollowing', [ 'position', 'inset-inline-start', 'top', 'bottom' ] ); 1904 1905 const css = { 1906 position: 'absolute', 1907 }; 1908 1909 elementOffsetValue = elements.$spacer.position().left; 1910 1911 if ( settings.isRTL ) { 1912 const parentWidth = $element.parent().outerWidth(), 1913 elementOffsetValueLeft = elements.$spacer.position().left; 1914 1915 elementWidth = elements.$spacer.outerWidth(); 1916 elementOffsetValue = Math.max( parentWidth - elementWidth - elementOffsetValueLeft, 0 ); 1917 } 1918 1919 css[ 'inset-inline-start' ] = elementOffsetValue + 'px'; 1920 1921 css[ settings.to ] = ''; 1922 1923 css[ 'top' === settings.to ? 'bottom' : 'top' ] = 0; 1924 1925 $element.css( css ); 1926 1927 isFollowingParent = true; 1928 }; 1929 1930 var unfollowParent = function() { 1931 elements.$parent.css( getCSSBackup( elements.$parent, 'childNotFollowing' ) ); 1932 1933 $element.css( getCSSBackup( $element, 'notFollowing' ) ); 1934 1935 isFollowingParent = false; 1936 }; 1937 1938 var getElementOuterSize = function( $elementOuterSize, dimension, includeMargins ) { 1939 var computedStyle = getComputedStyle( $elementOuterSize[ 0 ] ), 1940 elementSize = parseFloat( computedStyle[ dimension ] ), 1941 sides = 'height' === dimension ? [ 'top', 'bottom' ] : [ 'left', 'right' ], 1942 propertiesToAdd = []; 1943 1944 if ( 'border-box' !== computedStyle.boxSizing ) { 1945 propertiesToAdd.push( 'border', 'padding' ); 1946 } 1947 1948 if ( includeMargins ) { 1949 propertiesToAdd.push( 'margin' ); 1950 } 1951 1952 propertiesToAdd.forEach( function( property ) { 1953 sides.forEach( function( side ) { 1954 elementSize += parseFloat( computedStyle[ property + '-' + side ] ); 1955 } ); 1956 } ); 1957 1958 return elementSize; 1959 }; 1960 1961 var getElementViewportOffset = function( $elementViewportOffset ) { 1962 var windowScrollTop = elements.$window.scrollTop(), 1963 elementHeight = getElementOuterSize( $elementViewportOffset, 'height' ), 1964 viewportHeight = innerHeight, 1965 elementOffsetFromTop = $elementViewportOffset.offset().top, 1966 distanceFromTop = elementOffsetFromTop - windowScrollTop, 1967 topFromBottom = distanceFromTop - viewportHeight; 1968 1969 return { 1970 top: { 1971 fromTop: distanceFromTop, 1972 fromBottom: topFromBottom, 1973 }, 1974 bottom: { 1975 fromTop: distanceFromTop + elementHeight, 1976 fromBottom: topFromBottom + elementHeight, 1977 }, 1978 }; 1979 }; 1980 1981 var stick = function() { 1982 updateElementSizesData(); 1983 1984 addSpacer(); 1985 1986 stickElement(); 1987 1988 isSticky = true; 1989 1990 $element.trigger( 'sticky:stick' ); 1991 }; 1992 1993 var unstick = function() { 1994 unstickElement(); 1995 1996 removeSpacer(); 1997 1998 isSticky = false; 1999 2000 $element.trigger( 'sticky:unstick' ); 2001 }; 2002 2003 var checkParent = function() { 2004 var elementOffset = getElementViewportOffset( $element ), 2005 isTop = 'top' === settings.to; 2006 2007 if ( isFollowingParent ) { 2008 var isNeedUnfollowing = isTop ? elementOffset.top.fromTop > settings.offset : elementOffset.bottom.fromBottom < -settings.offset; 2009 2010 if ( isNeedUnfollowing ) { 2011 unfollowParent(); 2012 } 2013 } else { 2014 var parentOffset = getElementViewportOffset( elements.$parent ), 2015 parentStyle = getComputedStyle( elements.$parent[ 0 ] ), 2016 borderWidthToDecrease = parseFloat( parentStyle[ isTop ? 'borderBottomWidth' : 'borderTopWidth' ] ), 2017 parentViewportDistance = isTop ? parentOffset.bottom.fromTop - borderWidthToDecrease : parentOffset.top.fromBottom + borderWidthToDecrease, 2018 isNeedFollowing = isTop ? parentViewportDistance <= elementOffset.bottom.fromTop : parentViewportDistance >= elementOffset.top.fromBottom; 2019 2020 if ( isNeedFollowing ) { 2021 followParent(); 2022 } 2023 } 2024 }; 2025 2026 var checkEffectsPoint = function( distanceFromTriggerPoint ) { 2027 if ( isReachedEffectsPoint && -distanceFromTriggerPoint < settings.effectsOffset ) { 2028 $element.removeClass( settings.classes.stickyEffects ); 2029 2030 isReachedEffectsPoint = false; 2031 } else if ( ! isReachedEffectsPoint && -distanceFromTriggerPoint >= settings.effectsOffset ) { 2032 $element.addClass( settings.classes.stickyEffects ); 2033 2034 isReachedEffectsPoint = true; 2035 } 2036 }; 2037 2038 var checkPosition = function() { 2039 var offset = settings.offset, 2040 distanceFromTriggerPoint; 2041 2042 if ( isSticky ) { 2043 var spacerViewportOffset = getElementViewportOffset( elements.$spacer ); 2044 2045 distanceFromTriggerPoint = 'top' === settings.to ? spacerViewportOffset.top.fromTop - offset : -spacerViewportOffset.bottom.fromBottom - offset; 2046 2047 if ( settings.parent ) { 2048 checkParent(); 2049 } 2050 2051 if ( distanceFromTriggerPoint > 0 ) { 2052 unstick(); 2053 } 2054 } else { 2055 var elementViewportOffset = getElementViewportOffset( $element ); 2056 2057 distanceFromTriggerPoint = 'top' === settings.to ? elementViewportOffset.top.fromTop - offset : -elementViewportOffset.bottom.fromBottom - offset; 2058 2059 if ( distanceFromTriggerPoint <= 0 ) { 2060 stick(); 2061 2062 if ( settings.parent ) { 2063 checkParent(); 2064 } 2065 } 2066 } 2067 2068 checkEffectsPoint( distanceFromTriggerPoint ); 2069 }; 2070 2071 var onWindowScroll = function() { 2072 checkPosition(); 2073 }; 2074 2075 var onWindowResize = function() { 2076 if ( ! isSticky ) { 2077 return; 2078 } 2079 2080 unstickElement(); 2081 2082 removeSpacer(); 2083 2084 updateElementSizesData(); 2085 2086 addSpacer(); 2087 2088 stickElement(); 2089 2090 if ( settings.parent ) { 2091 // Force recalculation of the relation between the element and its parent. 2092 isFollowingParent = false;
2093 2094 checkParent(); 2095 } 2096 }; 2097 2098 this.destroy = function() { 2099 if ( isSticky ) { 2100 unstick(); 2101 } 2102 2103 unbindEvents(); 2104 2105 $element.removeClass( settings.classes.sticky ); 2106 }; 2107 2108 init(); 2109 }; 2110 2111 $.fn.sticky = function( settings ) { 2112 var isCommand = 'string' === typeof settings; 2113 2114 this.each( function() { 2115 var $this = $( this ); 2116 2117 if ( ! isCommand ) { 2118 $this.data( 'sticky', new Sticky( this, settings ) ); 2119 2120 return; 2121 } 2122 2123 var instance = $this.data( 'sticky' ); 2124 2125 if ( ! instance ) { 2126 throw Error( 'Trying to perform the `' + settings + '` method prior to initialization' ); 2127 } 2128 2129 if ( ! instance[ settings ] ) { 2130 throw ReferenceError( 'Method `' + settings + '` not found in sticky instance' ); 2131 } 2132 2133 instance[ settings ].apply( instance, Array.prototype.slice.call( arguments, 1 ) ); 2134 2135 if ( 'destroy' === settings ) { 2136 $this.removeData( 'sticky' ); 2137 } 2138 } ); 2139 2140 return this; 2141 }; 2142 2143 window.Sticky = Sticky; 2144} )( jQuery ); 2145; 2146;(function($) { 2147 2148 PPOffcanvasContent = function( $scope ) { 2149 2150 this.node = $scope; 2151 this.wrap = $scope.find('.pp-offcanvas-content-wrap'); 2152 this.cart_wrap = $scope.find('.pp-offcanvas-cart-container'); 2153 this.content = $scope.find('.pp-offcanvas-content'); 2154 this.button = $scope.find('.pp-offcanvas-toggle'); 2155 this.settings = this.wrap.data('settings'); 2156 this.scopeUniqueId = this.getOffcanvasUniqueScopeId( $scope ), 2157 this.toggle_source = this.settings.toggle_source; 2158 this.id = this.scopeUniqueId; 2159 this.toggle_id = this.settings.toggle_id; 2160 this.toggle_class = this.settings.toggle_class; 2161 this.transition = this.settings.transition; 2162 this.esc_close = this.settings.esc_close; 2163 this.body_click_close = this.settings.body_click_close; 2164 this.links_click_close = this.settings.links_click_close; 2165 this.direction = this.settings.direction; 2166 this.buttons_position = this.settings.buttons_position; 2167 this.open_panel_add_to_cart = this.settings.open_panel_add_to_cart; 2168 this.add_to_cart_button = $( '.add_to_cart_button, .single_add_to_cart_button' ); 2169 this.duration = 500; 2170 2171 this.destroy(); 2172 this.init(); 2173 }; 2174 2175 PPOffcanvasContent.prototype = { 2176 id: '', 2177 node: '', 2178 wrap: '', 2179 content: '', 2180 button: '', 2181 settings: {}, 2182 transition: '', 2183 duration: 400, 2184 initialized: false, 2185 animations: [ 2186 'slide', 2187 'slide-along', 2188 'reveal', 2189 'push', 2190 ], 2191 2192 init: function () { 2193 if ( ! this.wrap.length ) { 2194 return; 2195 } 2196 2197 $('html').addClass('pp-offcanvas-content-widget'); 2198 2199 if ( $('.pp-offcanvas-container').length === 0 ) { 2200 var faProJs = $('#font-awesome-pro-js').length > 0 ? $('#font-awesome-pro-js').attr('src') : false; 2201 if ( faProJs ) { 2202 $('#font-awesome-pro-js').remove(); 2203 } 2204 $('body').wrapInner( '<div class="pp-offcanvas-container" />' ); 2205 this.content.insertBefore('.pp-offcanvas-container'); 2206 if ( faProJs ) { 2207 $('body').append( '<script type="text/javascript" id="font-awesome-pro-js" src="' + faProJs + '"></script>' ); 2208 } 2209 } 2210 2211 if ( this.wrap.find('.pp-offcanvas-content').length > 0 ) { 2212 if ( $('.pp-offcanvas-container > .pp-offcanvas-' + this.id).length > 0 ) { 2213 $('.pp-offcanvas-container > .pp-offcanvas-' + this.id).remove(); 2214 } 2215 if ( $('body > .pp-offcanvas-' + this.id ).length > 0 ) { 2216 $('body > .pp-offcanvas-' + this.id ).remove(); 2217 } 2218 $('body').prepend( this.wrap.find('.pp-offcanvas-content') ); 2219 } 2220 2221 this.bindEvents(); 2222 }, 2223 2224 getOffcanvasUniqueScopeId: function( $scope ) { 2225 var scopeId = $scope.data('id'), 2226 $clones = $( '[data-id="' + scopeId + '"]' ); 2227 2228 if ( ! this.hasMultipleScopeId( scopeId ) ) { 2229 return scopeId; 2230 } 2231 scopeIdCloned = scopeId; 2232 2233 $clones.each( function( index ) { 2234 $(this).attr( 'data-pp-offcanvas-index', index ); 2235 }); 2236
2237 scopeId = scopeId + '_' + $scope.data('pp-offcanvas-index'); 2238 2239 $( '#pp-offcanvas-' + scopeIdCloned ).each( function() { 2240 $( this ).attr( 'id', 'pp-offcanvas-' + scopeId ); 2241 2242 if ( $( this ).hasClass( 'pp-offcanvas-' + scopeIdCloned ) ) { 2243 //$( this ).removeClass( 'pp-offcanvas-' + scopeIdCloned ); 2244 $( this ).addClass( 'pp-offcanvas-' + scopeId ); 2245 } 2246 } ); 2247 2248 return scopeId; 2249 }, 2250 2251 hasMultipleScopeId : function( scopeId ) { 2252 var $clones = $( '[data-id="' + scopeId + '"]' ); 2253 2254 if ( 1 === $clones.length ) { 2255 return false; 2256 } 2257 2258 return true; 2259 }, 2260 2261 destroy: function() { 2262 this.close(); 2263 2264 this.animations.forEach(function( animation ) { 2265 if ( $('html').hasClass( 'pp-offcanvas-content-' + animation ) ) { 2266 $('html').removeClass( 'pp-offcanvas-content-' + animation ) 2267 } 2268 }); 2269 2270 if ( $('body > .pp-offcanvas-' + this.id ).length > 0 ) { 2271 //$('body > .pp-offcanvas-' + this.id ).remove(); 2272 } 2273 }, 2274 2275 setTrigger: function() { 2276 var $trigger = false; 2277 2278 if ( this.toggle_source == 'element-id' && this.toggle_id != '' ) { 2279 $trigger = $( '#' + this.toggle_id ); 2280 } else if ( this.toggle_source == 'element-class' && this.toggle_class != '' ) { 2281 $trigger = $( '.' + this.toggle_class ); 2282 } else { 2283 $trigger = this.node.find( '.pp-offcanvas-toggle' ); 2284 } 2285 2286 return $trigger; 2287 }, 2288 2289 bindEvents: function () { 2290 var self = this; 2291 $trigger = this.setTrigger(); 2292 2293 if ( $trigger ) { 2294 $trigger.on('click', $.proxy( this.toggleContent, this )); 2295 } 2296 2297 if( 'yes' === this.open_panel_add_to_cart ) { 2298 this.add_to_cart_button.on('click', function(e) { 2299 setTimeout(function() { 2300 self.toggleContent(e); 2301 }, 1000 ); 2302 }); 2303 } 2304 2305 $('body').delegate( '.pp-offcanvas-content .pp-offcanvas-close', 'click', $.proxy( this.close, this ) ); 2306 2307 if ( this.links_click_close === 'yes' ) { 2308 $('body').delegate( '.pp-offcanvas-content .pp-offcanvas-body a', 'click', $.proxy( this.close, this ) ); 2309 } 2310 2311 if ( this.esc_close === 'yes' ) { 2312 this.closeESC(); 2313 } 2314 if ( this.body_click_close === 'yes' ) { 2315 this.closeClick(); 2316 } 2317 $(window).resize( $.proxy( this._resize, this ) ); 2318 }, 2319 2320 toggleContent: function(e) { 2321 e.preventDefault(); 2322 2323 if ( ! $('html').hasClass('pp-offcanvas-open') ) { 2324 this.show(); 2325 } else { 2326 this.close(); 2327 } 2328 this._resize(); 2329 }, 2330 2331 show: function() { 2332 $('.pp-offcanvas-' + this.id).addClass('pp-offcanvas-visible'); 2333 // init animation class. 2334 $('html').addClass( 'pp-offcanvas-content-' + this.transition ); 2335 $('html').addClass( 'pp-offcanvas-' + this.direction ); 2336 $('html').addClass('pp-offcanvas-open'); 2337 $('html').addClass('pp-offcanvas-' + this.id + '-open'); 2338 $('html').addClass('pp-offcanvas-reset'); 2339 2340 this.button.addClass('pp-is-active'); 2341 this._resize(); 2342 }, 2343 2344 close: function() { 2345 $('html').removeClass('pp-offcanvas-open'); 2346 $('html').removeClass('pp-offcanvas-' + this.id + '-open'); 2347 setTimeout($.proxy(function () { 2348 $('html').removeClass('pp-offcanvas-reset'); 2349 $('html').removeClass( 'pp-offcanvas-content-' + this.transition ); 2350 $('html').removeClass( 'pp-offcanvas-' + this.direction ); 2351 $('.pp-offcanvas-' + this.id).removeClass('pp-offcanvas-visible'); 2352 }, this), 500); 2353 2354 this.button.removeClass('pp-is-active'); 2355 }, 2356 2357 closeESC: function() { 2358 var self = this; 2359 2360 if ( '' === self.settings.esc_close ) { 2361 return; 2362 } 2363 2364 // menu close on ESC key 2365 $(document).on('keydown', function (e) { 2366 if (e.keyCode === 27) { // ESC 2367 self.close(); 2368 } 2369 }); 2370 }, 2371 2372 closeClick: function() { 2373 var self = this; 2374 2375 if ( this.toggle_source == 'element-id' && this.toggle_id != '' ) { 2376 $trigger = '#' + this.toggle_id; 2377 } else if ( this.toggle_source == 'element-class' && this.toggle_class != '' ) { 2378 $trigger = '.' + this.toggle_class; 2379 } else { 2380 $trigger = '.pp-offcanvas-toggle'; 2381 } 2382 2383 $(document).on('click', function (e) { 2384 if ( $(e.target).is('.pp-offcanvas-content') || 2385 $(e.target).parents('.pp-offcanvas-content').length > 0 || 2386 $(e.target).is('.pp-offcanvas-toggle') || 2387 $(e.target).parents('.pp-offcanvas-toggle').length > 0 || 2388 $(e.target).is($trigger) || 2389 $(e.target).parents($trigger).length > 0 || 2390 ! $(e.target).is('.pp-offcanvas-container') ) { 2391 return; 2392 } else { 2393 self.close(); 2394 } 2395 }); 2396 }, 2397 2398 _resize: function() { 2399 if ( ! this.cart_wrap.length ) { 2400 return; 2401 } 2402 2403 var off_canvas = $('.pp-offcanvas-' + this.id); 2404 2405 if ( off_canvas && off_canvas.length > 0 ) { 2406 if ( this.buttons_position === 'bottom' ) { 2407 var winHeight = window.innerHeight; 2408 var offset = 0; 2409 2410 // if ( $('body').hasClass('admin-bar') ) { 2411 // offset = 32; 2412 // } 2413 2414 winHeight = winHeight - offset; 2415 off_canvas.find('.pp-offcanvas-inner').css({ 2416 'height': winHeight + 'px', 2417 'top': offset 2418 }); 2419 2420 headerHeight = off_canvas.find('.pp-offcanvas-cart-header').outerHeight(true); 2421 wrapHeight = off_canvas.find('.pp-offcanvas-wrap').outerHeight(); 2422 cartTotalHeight = off_canvas.find('.woocommerce-mini-cart__total').outerHeight(); 2423 cartButtonsHeight = off_canvas.find('.woocommerce-mini-cart__buttons').outerHeight(); 2424 cartMessageHeight = off_canvas.find('.pp-woo-menu-cart-message').outerHeight(); 2425 if ( undefined === cartMessageHeight ) { 2426 cartMessageHeight = 0; 2427 } 2428 itemsHeight = winHeight - (headerHeight + cartTotalHeight + cartButtonsHeight + cartMessageHeight); 2429 2430 finalItemsHeight = itemsHeight - ( winHeight - wrapHeight ); 2431 finalItemsHeight += 'px'; 2432 } else { 2433 finalItemsHeight = 'auto'; 2434 } 2435 2436 var style = '<style id="pp-woo-style-' + this.id + '">'; 2437 style += '#' + off_canvas.attr('id') + ' .woocommerce-mini-cart.cart_list {' 2438 style += 'height: ' + finalItemsHeight; 2439 style += '}'; 2440 style += '</style>'; 2441 2442 if ( $('#pp-woo-style-' + this.id).length > 0 ) { 2443 $('#pp-woo-style-' + this.id).remove(); 2444 } 2445 2446 $('head').append(style); 2447 } 2448 } 2449 }; 2450 2451 var OffCanvasContentHandler = function ($scope, $) { 2452 var content_wrap = $scope.find('.pp-offcanvas-content-wrap'); 2453 2454 if ( $(content_wrap).length > 0 ) { 2455 new PPOffcanvasContent( $scope ); 2456 } 2457 }; 2458 2459 $(window).on('elementor/frontend/init', function () { 2460 if ( elementorFrontend.isEditMode() ) { 2461 isEditMode = true; 2462 } 2463 2464 elementorFrontend.hooks.addAction( 'frontend/element_ready/pp-offcanvas-content.default', OffCanvasContentHandler ); 2465 }); 2466 2467})(jQuery);; 2468/*! This file is auto-generated */ 2469/*! 2470 * imagesLoaded PACKAGED v5.0.0 2471 * JavaScript is all like "You images are done yet or what?" 2472 * MIT License 2473 */ 2474!function(t,e){"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,(function(){function t(){}let e=t.prototype;return e.on=function(t,e){if(!t||!e)return this;let i=this._events=this._events||{},s=i[t]=i[t]||[];return s.includes(e)||s.push(e),this},e.once=function(t,e){if(!t||!e)return this;this.on(t,e);let i=this._onceEvents=this._onceEvents||{};return(i[t]=i[t]||{})[e]=!0,this},e.off=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;let s=i.indexOf(e);return-1!=s&&i.splice(s,1),this},e.emitEvent=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;i=i.slice(0),e=e||[];let s=this._onceEvents&&this._onceEvents[t];for(let n of i){s&&s[n]&&(this.off(t,n),delete s[n]),n.apply(this,e)}return this},e.allOff=function(){return delete this._events,delete this._onceEvents,this},t})), 2475/*! 2476 * imagesLoaded v5.0.0 2477 * JavaScript is all like "You images are done yet or what?" 2478 * MIT License 2479 */ 2480function(t,e){"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}("undefined"!=typeof window?window:this,(function(t,e){let i=t.jQuery,s=t.console;
vendor: 5,180 bytes, lines 2480-2515
2480function n(t,e,o){if(!(this instanceof n))return new n(t,e,o);let r=t;var h;("string"==typeof t&&(r=document.querySelectorAll(t)),r)?(this.elements=(h=r,Array.isArray(h)?h:"object"==typeof h&&"number"==typeof h.length?[...h]:[h]),this.options={},"function"==typeof e?o=e:Object.assign(this.options,e),o&&this.on("always",o),this.getImages(),i&&(this.jqDeferred=new i.Deferred),setTimeout(this.check.bind(this))):s.error(`Bad element for imagesLoaded ${r||t}`)}n.prototype=Object.create(e.prototype),n.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)};const o=[1,9,11];n.prototype.addElementImages=function(t){"IMG"===t.nodeName&&this.addImage(t),!0===this.options.background&&this.addElementBackgroundImages(t);let{nodeType:e}=t;if(!e||!o.includes(e))return;let i=t.querySelectorAll("img");for(let t of i)this.addImage(t);if("string"==typeof this.options.background){let e=t.querySelectorAll(this.options.background);for(let t of e)this.addElementBackgroundImages(t)}};const r=/url\((['"])?(.*?)\1\)/gi;function h(t){this.img=t}function d(t,e){this.url=t,this.element=e,this.img=new Image}return n.prototype.addElementBackgroundImages=function(t){let e=getComputedStyle(t);if(!e)return;let i=r.exec(e.backgroundImage);for(;null!==i;){let s=i&&i[2];s&&this.addBackground(s,t),i=r.exec(e.backgroundImage)}},n.prototype.addImage=function(t){let e=new h(t);this.images.push(e)},n.prototype.addBackground=function(t,e){let i=new d(t,e);this.images.push(i)},n.prototype.check=function(){if(this.progressedCount=0,this.hasAnyBroken=!1,!this.images.length)return void this.complete();let t=(t,e,i)=>{setTimeout((()=>{this.progress(t,e,i)}))};this.images.forEach((function(e){e.once("progress",t),e.check()}))},n.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount===this.images.length&&this.complete(),this.options.debug&&s&&s.log(`progress: ${i}`,t,e)},n.prototype.complete=function(){let t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){let t=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[t](this)}},h.prototype=Object.create(e.prototype),h.prototype.check=function(){this.getIsImageComplete()?this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.img.crossOrigin&&(this.proxyImage.crossOrigin=this.img.crossOrigin),this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.proxyImage.src=this.img.currentSrc||this.img.src)},h.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},h.prototype.confirm=function(t,e){this.isLoaded=t;let{parentNode:i}=this.img,s="PICTURE"===i.nodeName?i:this.img;this.emitEvent("progress",[this,s,e])},h.prototype.handleEvent=function(t){let e="on"+t.type;this[e]&&this[e](t)},h.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},h.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},h.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype=Object.create(h.prototype),d.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url,this.getIsImageComplete()&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},d.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},n.makeJQueryPlugin=function(e){(e=e||t.jQuery)&&(i=e,i.fn.imagesLoaded=function(t,e){return new n(this,t,e).jqDeferred.promise(i(this))})},n.makeJQueryPlugin(),n}));; 2481/** 2482 * Swiper 8.4.5 2483 * Most modern mobile touch slider and framework with hardware accelerated transitions 2484 * https://swiperjs.com 2485 * 2486 * Copyright 2014-2022 Vladimir Kharlampidi 2487 * 2488 * Released under the MIT License 2489 * 2490 * Released on: November 21, 2022 2491 */ 2492 2493 (function (global, factory) { 2494 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 2495 typeof define === 'function' && define.amd ? define(factory) : 2496 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Swiper = factory()); 2497})(this, (function () { 'use strict'; 2498 2499 /** 2500 * SSR Window 4.0.2 2501 * Better handling for window object in SSR environment 2502 * https://github.com/nolimits4web/ssr-window 2503 * 2504 * Copyright 2021, Vladimir Kharlampidi 2505 * 2506 * Licensed under MIT 2507 * 2508 * Released on: December 13, 2021 2509 */ 2510 2511 /* eslint-disable no-param-reassign */ 2512 function isObject$1(obj) { 2513 return obj !== null && typeof obj === 'object' && 'constructor' in obj && obj.constructor === Object; 2514 } 2515
vendor: 6,581 bytes, lines 2516-2846
2516 function extend$1(target, src) { 2517 if (target === void 0) { 2518 target = {}; 2519 } 2520 2521 if (src === void 0) { 2522 src = {}; 2523 } 2524 2525 Object.keys(src).forEach(key => { 2526 if (typeof target[key] === 'undefined') target[key] = src[key];else if (isObject$1(src[key]) && isObject$1(target[key]) && Object.keys(src[key]).length > 0) { 2527 extend$1(target[key], src[key]); 2528 } 2529 }); 2530 } 2531 2532 const ssrDocument = { 2533 body: {}, 2534 2535 addEventListener() {}, 2536 2537 removeEventListener() {}, 2538 2539 activeElement: { 2540 blur() {}, 2541 2542 nodeName: '' 2543 }, 2544 2545 querySelector() { 2546 return null; 2547 }, 2548 2549 querySelectorAll() { 2550 return []; 2551 }, 2552 2553 getElementById() { 2554 return null; 2555 }, 2556 2557 createEvent() { 2558 return { 2559 initEvent() {} 2560 2561 }; 2562 }, 2563 2564 createElement() { 2565 return { 2566 children: [], 2567 childNodes: [], 2568 style: {}, 2569 2570 setAttribute() {}, 2571 2572 getElementsByTagName() { 2573 return []; 2574 } 2575 2576 }; 2577 }, 2578 2579 createElementNS() { 2580 return {}; 2581 }, 2582 2583 importNode() { 2584 return null; 2585 }, 2586 2587 location: { 2588 hash: '', 2589 host: '', 2590 hostname: '', 2591 href: '', 2592 origin: '', 2593 pathname: '', 2594 protocol: '', 2595 search: '' 2596 } 2597 }; 2598 2599 function getDocument() { 2600 const doc = typeof document !== 'undefined' ? document : {}; 2601 extend$1(doc, ssrDocument); 2602 return doc; 2603 } 2604 2605 const ssrWindow = { 2606 document: ssrDocument, 2607 navigator: { 2608 userAgent: '' 2609 }, 2610 location: { 2611 hash: '', 2612 host: '', 2613 hostname: '', 2614 href: '', 2615 origin: '', 2616 pathname: '', 2617 protocol: '', 2618 search: '' 2619 }, 2620 history: { 2621 replaceState() {}, 2622 2623 pushState() {}, 2624 2625 go() {}, 2626 2627 back() {} 2628 2629 }, 2630 CustomEvent: function CustomEvent() { 2631 return this; 2632 }, 2633 2634 addEventListener() {}, 2635 2636 removeEventListener() {}, 2637 2638 getComputedStyle() { 2639 return { 2640 getPropertyValue() { 2641 return ''; 2642 } 2643 2644 }; 2645 }, 2646 2647 Image() {}, 2648 2649 Date() {}, 2650 2651 screen: {}, 2652 2653 setTimeout() {}, 2654 2655 clearTimeout() {}, 2656 2657 matchMedia() { 2658 return {}; 2659 }, 2660 2661 requestAnimationFrame(callback) { 2662 if (typeof setTimeout === 'undefined') { 2663 callback(); 2664 return null; 2665 } 2666 2667 return setTimeout(callback, 0); 2668 }, 2669 2670 cancelAnimationFrame(id) { 2671 if (typeof setTimeout === 'undefined') { 2672 return; 2673 } 2674 2675 clearTimeout(id); 2676 } 2677 2678 }; 2679 2680 function getWindow() { 2681 const win = typeof window !== 'undefined' ? window : {}; 2682 extend$1(win, ssrWindow); 2683 return win; 2684 } 2685 2686 /** 2687 * Dom7 4.0.4 2688 * Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API 2689 * https://framework7.io/docs/dom7.html 2690 * 2691 * Copyright 2022, Vladimir Kharlampidi 2692 * 2693 * Licensed under MIT 2694 * 2695 * Released on: January 11, 2022 2696 */ 2697 /* eslint-disable no-proto */ 2698 2699 function makeReactive(obj) { 2700 const proto = obj.__proto__; 2701 Object.defineProperty(obj, '__proto__', { 2702 get() { 2703 return proto; 2704 }, 2705 2706 set(value) { 2707 proto.__proto__ = value; 2708 } 2709 2710 }); 2711 } 2712 2713 class Dom7 extends Array { 2714 constructor(items) { 2715 if (typeof items === 'number') { 2716 super(items); 2717 } else { 2718 super(...(items || [])); 2719 makeReactive(this); 2720 } 2721 } 2722 2723 } 2724 2725 function arrayFlat(arr) { 2726 if (arr === void 0) { 2727 arr = []; 2728 } 2729 2730 const res = []; 2731 arr.forEach(el => { 2732 if (Array.isArray(el)) { 2733 res.push(...arrayFlat(el)); 2734 } else { 2735 res.push(el); 2736 } 2737 }); 2738 return res; 2739 } 2740 2741 function arrayFilter(arr, callback) { 2742 return Array.prototype.filter.call(arr, callback); 2743 } 2744 2745 function arrayUnique(arr) { 2746 const uniqueArray = []; 2747 2748 for (let i = 0; i < arr.length; i += 1) { 2749 if (uniqueArray.indexOf(arr[i]) === -1) uniqueArray.push(arr[i]); 2750 } 2751 2752 return uniqueArray; 2753 } 2754 2755 2756 function qsa(selector, context) { 2757 if (typeof selector !== 'string') { 2758 return [selector]; 2759 } 2760 2761 const a = []; 2762 const res = context.querySelectorAll(selector); 2763 2764 for (let i = 0; i < res.length; i += 1) { 2765 a.push(res[i]); 2766 } 2767 2768 return a; 2769 } 2770 2771 function $(selector, context) { 2772 const window = getWindow(); 2773 const document = getDocument(); 2774 let arr = []; 2775 2776 if (!context && selector instanceof Dom7) { 2777 return selector; 2778 } 2779 2780 if (!selector) { 2781 return new Dom7(arr); 2782 } 2783 2784 if (typeof selector === 'string') { 2785 const html = selector.trim(); 2786 2787 if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) { 2788 let toCreate = 'div'; 2789 if (html.indexOf('<li') === 0) toCreate = 'ul'; 2790 if (html.indexOf('<tr') === 0) toCreate = 'tbody'; 2791 if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr'; 2792 if (html.indexOf('<tbody') === 0) toCreate = 'table'; 2793 if (html.indexOf('<option') === 0) toCreate = 'select'; 2794 const tempParent = document.createElement(toCreate); 2795 tempParent.innerHTML = html; 2796 2797 for (let i = 0; i < tempParent.childNodes.length; i += 1) { 2798 arr.push(tempParent.childNodes[i]); 2799 } 2800 } else { 2801 arr = qsa(selector.trim(), context || document); 2802 } // arr = qsa(selector, document); 2803 2804 } else if (selector.nodeType || selector === window || selector === document) { 2805 arr.push(selector); 2806 } else if (Array.isArray(selector)) { 2807 if (selector instanceof Dom7) return selector; 2808 arr = selector; 2809 } 2810 2811 return new Dom7(arrayUnique(arr)); 2812 } 2813 2814 $.fn = Dom7.prototype; // eslint-disable-next-line 2815 2816 function addClass() { 2817 for (var _len = arguments.length, classes = new Array(_len), _key = 0; _key < _len; _key++) { 2818 classes[_key] = arguments[_key]; 2819 } 2820 2821 const classNames = arrayFlat(classes.map(c => c.split(' '))); 2822 this.forEach(el => { 2823 el.classList.add(...classNames); 2824 }); 2825 return this; 2826 } 2827 2828 function removeClass() { 2829 for (var _len2 = arguments.length, classes = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 2830 classes[_key2] = arguments[_key2]; 2831 } 2832 2833 const classNames = arrayFlat(classes.map(c => c.split(' '))); 2834 this.forEach(el => { 2835 el.classList.remove(...classNames); 2836 }); 2837 return this; 2838 } 2839 2840 function toggleClass() { 2841 for (var _len3 = arguments.length, classes = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { 2842 classes[_key3] = arguments[_key3]; 2843 } 2844 2845 const classNames = arrayFlat(classes.map(c => c.split(' '))); 2846 this.forEach(el => {
vendor: 9,647 bytes, lines 2847-3212
2847 classNames.forEach(className => { 2848 el.classList.toggle(className); 2849 }); 2850 }); 2851 } 2852 2853 function hasClass() { 2854 for (var _len4 = arguments.length, classes = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { 2855 classes[_key4] = arguments[_key4]; 2856 } 2857 2858 const classNames = arrayFlat(classes.map(c => c.split(' '))); 2859 return arrayFilter(this, el => { 2860 return classNames.filter(className => el.classList.contains(className)).length > 0; 2861 }).length > 0; 2862 } 2863 2864 function attr(attrs, value) { 2865 if (arguments.length === 1 && typeof attrs === 'string') { 2866 // Get attr 2867 if (this[0]) return this[0].getAttribute(attrs); 2868 return undefined; 2869 } // Set attrs 2870 2871 2872 for (let i = 0; i < this.length; i += 1) { 2873 if (arguments.length === 2) { 2874 // String 2875 this[i].setAttribute(attrs, value); 2876 } else { 2877 // Object 2878 for (const attrName in attrs) { 2879 this[i][attrName] = attrs[attrName]; 2880 this[i].setAttribute(attrName, attrs[attrName]); 2881 } 2882 } 2883 } 2884 2885 return this; 2886 } 2887 2888 function removeAttr(attr) { 2889 for (let i = 0; i < this.length; i += 1) { 2890 this[i].removeAttribute(attr); 2891 } 2892 2893 return this; 2894 } 2895 2896 function transform(transform) { 2897 for (let i = 0; i < this.length; i += 1) { 2898 this[i].style.transform = transform; 2899 } 2900 2901 return this; 2902 } 2903 2904 function transition$1(duration) { 2905 for (let i = 0; i < this.length; i += 1) { 2906 this[i].style.transitionDuration = typeof duration !== 'string' ? `${duration}ms` : duration; 2907 } 2908 2909 return this; 2910 } 2911 2912 function on() { 2913 for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { 2914 args[_key5] = arguments[_key5]; 2915 } 2916 2917 let [eventType, targetSelector, listener, capture] = args; 2918 2919 if (typeof args[1] === 'function') { 2920 [eventType, listener, capture] = args; 2921 targetSelector = undefined; 2922 } 2923 2924 if (!capture) capture = false; 2925 2926 function handleLiveEvent(e) { 2927 const target = e.target; 2928 if (!target) return; 2929 const eventData = e.target.dom7EventData || []; 2930 2931 if (eventData.indexOf(e) < 0) { 2932 eventData.unshift(e); 2933 } 2934 2935 if ($(target).is(targetSelector)) listener.apply(target, eventData);else { 2936 const parents = $(target).parents(); // eslint-disable-line 2937 2938 for (let k = 0; k < parents.length; k += 1) { 2939 if ($(parents[k]).is(targetSelector)) listener.apply(parents[k], eventData); 2940 } 2941 } 2942 } 2943 2944 function handleEvent(e) { 2945 const eventData = e && e.target ? e.target.dom7EventData || [] : []; 2946 2947 if (eventData.indexOf(e) < 0) { 2948 eventData.unshift(e); 2949 } 2950 2951 listener.apply(this, eventData); 2952 } 2953 2954 const events = eventType.split(' '); 2955 let j; 2956 2957 for (let i = 0; i < this.length; i += 1) { 2958 const el = this[i]; 2959 2960 if (!targetSelector) { 2961 for (j = 0; j < events.length; j += 1) { 2962 const event = events[j]; 2963 if (!el.dom7Listeners) el.dom7Listeners = {}; 2964 if (!el.dom7Listeners[event]) el.dom7Listeners[event] = []; 2965 el.dom7Listeners[event].push({ 2966 listener, 2967 proxyListener: handleEvent 2968 }); 2969 el.addEventListener(event, handleEvent, capture); 2970 } 2971 } else { 2972 // Live events 2973 for (j = 0; j < events.length; j += 1) { 2974 const event = events[j]; 2975 if (!el.dom7LiveListeners) el.dom7LiveListeners = {}; 2976 if (!el.dom7LiveListeners[event]) el.dom7LiveListeners[event] = []; 2977 el.dom7LiveListeners[event].push({ 2978 listener, 2979 proxyListener: handleLiveEvent 2980 }); 2981 el.addEventListener(event, handleLiveEvent, capture); 2982 } 2983 } 2984 } 2985 2986 return this; 2987 } 2988 2989 function off() { 2990 for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) { 2991 args[_key6] = arguments[_key6]; 2992 } 2993 2994 let [eventType, targetSelector, listener, capture] = args; 2995 2996 if (typeof args[1] === 'function') { 2997 [eventType, listener, capture] = args; 2998 targetSelector = undefined; 2999 } 3000 3001 if (!capture) capture = false; 3002 const events = eventType.split(' '); 3003 3004 for (let i = 0; i < events.length; i += 1) { 3005 const event = events[i]; 3006 3007 for (let j = 0; j < this.length; j += 1) { 3008 const el = this[j]; 3009 let handlers; 3010 3011 if (!targetSelector && el.dom7Listeners) { 3012 handlers = el.dom7Listeners[event]; 3013 } else if (targetSelector && el.dom7LiveListeners) { 3014 handlers = el.dom7LiveListeners[event]; 3015 } 3016 3017 if (handlers && handlers.length) { 3018 for (let k = handlers.length - 1; k >= 0; k -= 1) { 3019 const handler = handlers[k]; 3020 3021 if (listener && handler.listener === listener) { 3022 el.removeEventListener(event, handler.proxyListener, capture); 3023 handlers.splice(k, 1); 3024 } else if (listener && handler.listener && handler.listener.dom7proxy && handler.listener.dom7proxy === listener) { 3025 el.removeEventListener(event, handler.proxyListener, capture); 3026 handlers.splice(k, 1); 3027 } else if (!listener) { 3028 el.removeEventListener(event, handler.proxyListener, capture); 3029 handlers.splice(k, 1); 3030 } 3031 } 3032 } 3033 } 3034 } 3035 3036 return this; 3037 } 3038 3039 function trigger() { 3040 const window = getWindow(); 3041 3042 for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) { 3043 args[_key9] = arguments[_key9]; 3044 } 3045 3046 const events = args[0].split(' '); 3047 const eventData = args[1]; 3048 3049 for (let i = 0; i < events.length; i += 1) { 3050 const event = events[i]; 3051 3052 for (let j = 0; j < this.length; j += 1) { 3053 const el = this[j]; 3054 3055 if (window.CustomEvent) { 3056 const evt = new window.CustomEvent(event, { 3057 detail: eventData, 3058 bubbles: true, 3059 cancelable: true 3060 }); 3061 el.dom7EventData = args.filter((data, dataIndex) => dataIndex > 0); 3062 el.dispatchEvent(evt); 3063 el.dom7EventData = []; 3064 delete el.dom7EventData; 3065 } 3066 } 3067 } 3068 3069 return this; 3070 } 3071 3072 function transitionEnd$1(callback) { 3073 const dom = this; 3074 3075 function fireCallBack(e) { 3076 if (e.target !== this) return; 3077 callback.call(this, e); 3078 dom.off('transitionend', fireCallBack); 3079 } 3080 3081 if (callback) { 3082 dom.on('transitionend', fireCallBack); 3083 } 3084 3085 return this; 3086 } 3087 3088 function outerWidth(includeMargins) { 3089 if (this.length > 0) { 3090 if (includeMargins) { 3091 const styles = this.styles(); 3092 return this[0].offsetWidth + parseFloat(styles.getPropertyValue('margin-right')) + parseFloat(styles.getPropertyValue('margin-left')); 3093 } 3094 3095 return this[0].offsetWidth; 3096 } 3097 3098 return null; 3099 } 3100 3101 function outerHeight(includeMargins) { 3102 if (this.length > 0) { 3103 if (includeMargins) { 3104 const styles = this.styles(); 3105 return this[0].offsetHeight + parseFloat(styles.getPropertyValue('margin-top')) + parseFloat(styles.getPropertyValue('margin-bottom')); 3106 } 3107 3108 return this[0].offsetHeight; 3109 } 3110 3111 return null; 3112 } 3113 3114 function offset() { 3115 if (this.length > 0) { 3116 const window = getWindow(); 3117 const document = getDocument(); 3118 const el = this[0]; 3119 const box = el.getBoundingClientRect(); 3120 const body = document.body; 3121 const clientTop = el.clientTop || body.clientTop || 0; 3122 const clientLeft = el.clientLeft || body.clientLeft || 0; 3123 const scrollTop = el === window ? window.scrollY : el.scrollTop; 3124 const scrollLeft = el === window ? window.scrollX : el.scrollLeft; 3125 return { 3126 top: box.top + scrollTop - clientTop, 3127 left: box.left + scrollLeft - clientLeft 3128 }; 3129 } 3130 3131 return null; 3132 } 3133 3134 function styles() { 3135 const window = getWindow(); 3136 if (this[0]) return window.getComputedStyle(this[0], null); 3137 return {}; 3138 } 3139 3140 function css(props, value) { 3141 const window = getWindow(); 3142 let i; 3143 3144 if (arguments.length === 1) { 3145 if (typeof props === 'string') { 3146 // .css('width') 3147 if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props); 3148 } else { 3149 // .css({ width: '100px' }) 3150 for (i = 0; i < this.length; i += 1) { 3151 for (const prop in props) { 3152 this[i].style[prop] = props[prop]; 3153 } 3154 } 3155 3156 return this; 3157 } 3158 } 3159 3160 if (arguments.length === 2 && typeof props === 'string') { 3161 // .css('width', '100px') 3162 for (i = 0; i < this.length; i += 1) { 3163 this[i].style[props] = value; 3164 } 3165 3166 return this; 3167 } 3168 3169 return this; 3170 } 3171 3172 function each(callback) { 3173 if (!callback) return this; 3174 this.forEach((el, index) => { 3175 callback.apply(el, [el, index]); 3176 }); 3177 return this; 3178 } 3179 3180 function filter(callback) { 3181 const result = arrayFilter(this, callback); 3182 return $(result); 3183 } 3184 3185 function html(html) { 3186 if (typeof html === 'undefined') { 3187 return this[0] ? this[0].innerHTML : null; 3188 } 3189 3190 for (let i = 0; i < this.length; i += 1) { 3191 this[i].innerHTML = html; 3192 } 3193 3194 return this; 3195 } 3196 3197 function text(text) { 3198 if (typeof text === 'undefined') { 3199 return this[0] ? this[0].textContent.trim() : null; 3200 } 3201 3202 for (let i = 0; i < this.length; i += 1) { 3203 this[i].textContent = text; 3204 } 3205 3206 return this; 3207 } 3208 3209 function is(selector) { 3210 const window = getWindow(); 3211 const document = getDocument(); 3212 const el = this[0];
vendor: 5,415 bytes, lines 3213-3446
3213 let compareWith; 3214 let i; 3215 if (!el || typeof selector === 'undefined') return false; 3216 3217 if (typeof selector === 'string') { 3218 if (el.matches) return el.matches(selector); 3219 if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector); 3220 if (el.msMatchesSelector) return el.msMatchesSelector(selector); 3221 compareWith = $(selector); 3222 3223 for (i = 0; i < compareWith.length; i += 1) { 3224 if (compareWith[i] === el) return true; 3225 } 3226 3227 return false; 3228 } 3229 3230 if (selector === document) { 3231 return el === document; 3232 } 3233 3234 if (selector === window) { 3235 return el === window; 3236 } 3237 3238 if (selector.nodeType || selector instanceof Dom7) { 3239 compareWith = selector.nodeType ? [selector] : selector; 3240 3241 for (i = 0; i < compareWith.length; i += 1) { 3242 if (compareWith[i] === el) return true; 3243 } 3244 3245 return false; 3246 } 3247 3248 return false; 3249 } 3250 3251 function index() { 3252 let child = this[0]; 3253 let i; 3254 3255 if (child) { 3256 i = 0; // eslint-disable-next-line 3257 3258 while ((child = child.previousSibling) !== null) { 3259 if (child.nodeType === 1) i += 1; 3260 } 3261 3262 return i; 3263 } 3264 3265 return undefined; 3266 } 3267 3268 function eq(index) { 3269 if (typeof index === 'undefined') return this; 3270 const length = this.length; 3271 3272 if (index > length - 1) { 3273 return $([]); 3274 } 3275 3276 if (index < 0) { 3277 const returnIndex = length + index; 3278 if (returnIndex < 0) return $([]); 3279 return $([this[returnIndex]]); 3280 } 3281 3282 return $([this[index]]); 3283 } 3284 3285 function append() { 3286 let newChild; 3287 const document = getDocument(); 3288 3289 for (let k = 0; k < arguments.length; k += 1) { 3290 newChild = k < 0 || arguments.length <= k ? undefined : arguments[k]; 3291 3292 for (let i = 0; i < this.length; i += 1) { 3293 if (typeof newChild === 'string') { 3294 const tempDiv = document.createElement('div'); 3295 tempDiv.innerHTML = newChild; 3296 3297 while (tempDiv.firstChild) { 3298 this[i].appendChild(tempDiv.firstChild); 3299 } 3300 } else if (newChild instanceof Dom7) { 3301 for (let j = 0; j < newChild.length; j += 1) { 3302 this[i].appendChild(newChild[j]); 3303 } 3304 } else { 3305 this[i].appendChild(newChild); 3306 } 3307 } 3308 } 3309 3310 return this; 3311 } 3312 3313 function prepend(newChild) { 3314 const document = getDocument(); 3315 let i; 3316 let j; 3317 3318 for (i = 0; i < this.length; i += 1) { 3319 if (typeof newChild === 'string') { 3320 const tempDiv = document.createElement('div'); 3321 tempDiv.innerHTML = newChild; 3322 3323 for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) { 3324 this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]); 3325 } 3326 } else if (newChild instanceof Dom7) { 3327 for (j = 0; j < newChild.length; j += 1) { 3328 this[i].insertBefore(newChild[j], this[i].childNodes[0]); 3329 } 3330 } else { 3331 this[i].insertBefore(newChild, this[i].childNodes[0]); 3332 } 3333 } 3334 3335 return this; 3336 } 3337 3338 function next(selector) { 3339 if (this.length > 0) { 3340 if (selector) { 3341 if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) { 3342 return $([this[0].nextElementSibling]); 3343 } 3344 3345 return $([]); 3346 } 3347 3348 if (this[0].nextElementSibling) return $([this[0].nextElementSibling]); 3349 return $([]); 3350 } 3351 3352 return $([]); 3353 } 3354 3355 function nextAll(selector) { 3356 const nextEls = []; 3357 let el = this[0]; 3358 if (!el) return $([]); 3359 3360 while (el.nextElementSibling) { 3361 const next = el.nextElementSibling; // eslint-disable-line 3362 3363 if (selector) { 3364 if ($(next).is(selector)) nextEls.push(next); 3365 } else nextEls.push(next); 3366 3367 el = next; 3368 } 3369 3370 return $(nextEls); 3371 } 3372 3373 function prev(selector) { 3374 if (this.length > 0) { 3375 const el = this[0]; 3376 3377 if (selector) { 3378 if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) { 3379 return $([el.previousElementSibling]); 3380 } 3381 3382 return $([]); 3383 } 3384 3385 if (el.previousElementSibling) return $([el.previousElementSibling]); 3386 return $([]); 3387 } 3388 3389 return $([]); 3390 } 3391 3392 function prevAll(selector) { 3393 const prevEls = []; 3394 let el = this[0]; 3395 if (!el) return $([]); 3396 3397 while (el.previousElementSibling) { 3398 const prev = el.previousElementSibling; // eslint-disable-line 3399 3400 if (selector) { 3401 if ($(prev).is(selector)) prevEls.push(prev); 3402 } else prevEls.push(prev); 3403 3404 el = prev; 3405 } 3406 3407 return $(prevEls); 3408 } 3409 3410 function parent(selector) { 3411 const parents = []; // eslint-disable-line 3412 3413 for (let i = 0; i < this.length; i += 1) { 3414 if (this[i].parentNode !== null) { 3415 if (selector) { 3416 if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode); 3417 } else { 3418 parents.push(this[i].parentNode); 3419 } 3420 } 3421 } 3422 3423 return $(parents); 3424 } 3425 3426 function parents(selector) { 3427 const parents = []; // eslint-disable-line 3428 3429 for (let i = 0; i < this.length; i += 1) { 3430 let parent = this[i].parentNode; // eslint-disable-line 3431 3432 while (parent) { 3433 if (selector) { 3434 if ($(parent).is(selector)) parents.push(parent); 3435 } else { 3436 parents.push(parent); 3437 } 3438 3439 parent = parent.parentNode; 3440 } 3441 } 3442 3443 return $(parents); 3444 } 3445 3446 function closest(selector) {
vendor: 8,748 bytes, lines 3447-3776
3447 let closest = this; // eslint-disable-line 3448 3449 if (typeof selector === 'undefined') { 3450 return $([]); 3451 } 3452 3453 if (!closest.is(selector)) { 3454 closest = closest.parents(selector).eq(0); 3455 } 3456 3457 return closest; 3458 } 3459 3460 function find(selector) { 3461 const foundElements = []; 3462 3463 for (let i = 0; i < this.length; i += 1) { 3464 const found = this[i].querySelectorAll(selector); 3465 3466 for (let j = 0; j < found.length; j += 1) { 3467 foundElements.push(found[j]); 3468 } 3469 } 3470 3471 return $(foundElements); 3472 } 3473 3474 function children(selector) { 3475 const children = []; // eslint-disable-line 3476 3477 for (let i = 0; i < this.length; i += 1) { 3478 const childNodes = this[i].children; 3479 3480 for (let j = 0; j < childNodes.length; j += 1) { 3481 if (!selector || $(childNodes[j]).is(selector)) { 3482 children.push(childNodes[j]); 3483 } 3484 } 3485 } 3486 3487 return $(children); 3488 } 3489 3490 function remove() { 3491 for (let i = 0; i < this.length; i += 1) { 3492 if (this[i].parentNode) this[i].parentNode.removeChild(this[i]); 3493 } 3494 3495 return this; 3496 } 3497 3498 const Methods = { 3499 addClass, 3500 removeClass, 3501 hasClass, 3502 toggleClass, 3503 attr, 3504 removeAttr, 3505 transform, 3506 transition: transition$1, 3507 on, 3508 off, 3509 trigger, 3510 transitionEnd: transitionEnd$1, 3511 outerWidth, 3512 outerHeight, 3513 styles, 3514 offset, 3515 css, 3516 each, 3517 html, 3518 text, 3519 is, 3520 index, 3521 eq, 3522 append, 3523 prepend, 3524 next, 3525 nextAll, 3526 prev, 3527 prevAll, 3528 parent, 3529 parents, 3530 closest, 3531 find, 3532 children, 3533 filter, 3534 remove 3535 }; 3536 Object.keys(Methods).forEach(methodName => { 3537 Object.defineProperty($.fn, methodName, { 3538 value: Methods[methodName], 3539 writable: true 3540 }); 3541 }); 3542 3543 function deleteProps(obj) { 3544 const object = obj; 3545 Object.keys(object).forEach(key => { 3546 try { 3547 object[key] = null; 3548 } catch (e) {// no getter for object 3549 } 3550 3551 try { 3552 delete object[key]; 3553 } catch (e) {// something got wrong 3554 } 3555 }); 3556 } 3557 3558 function nextTick(callback, delay) { 3559 if (delay === void 0) { 3560 delay = 0; 3561 } 3562 3563 return setTimeout(callback, delay); 3564 } 3565 3566 function now() { 3567 return Date.now(); 3568 } 3569 3570 function getComputedStyle$1(el) { 3571 const window = getWindow(); 3572 let style; 3573 3574 if (window.getComputedStyle) { 3575 style = window.getComputedStyle(el, null); 3576 } 3577 3578 if (!style && el.currentStyle) { 3579 style = el.currentStyle; 3580 } 3581 3582 if (!style) { 3583 style = el.style; 3584 } 3585 3586 return style; 3587 } 3588 3589 function getTranslate(el, axis) { 3590 if (axis === void 0) { 3591 axis = 'x'; 3592 } 3593 3594 const window = getWindow(); 3595 let matrix; 3596 let curTransform; 3597 let transformMatrix; 3598 const curStyle = getComputedStyle$1(el); 3599 3600 if (window.WebKitCSSMatrix) { 3601 curTransform = curStyle.transform || curStyle.webkitTransform; 3602 3603 if (curTransform.split(',').length > 6) { 3604 curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', '); 3605 } // Some old versions of Webkit choke when 'none' is passed; pass 3606 // empty string instead in this case 3607 3608 3609 transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform); 3610 } else { 3611 transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,'); 3612 matrix = transformMatrix.toString().split(','); 3613 } 3614 3615 if (axis === 'x') { 3616 // Latest Chrome and webkits Fix 3617 if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41; // Crazy IE10 Matrix 3618 else if (matrix.length === 16) curTransform = parseFloat(matrix[12]); // Normal Browsers 3619 else curTransform = parseFloat(matrix[4]); 3620 } 3621 3622 if (axis === 'y') { 3623 // Latest Chrome and webkits Fix 3624 if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42; // Crazy IE10 Matrix 3625 else if (matrix.length === 16) curTransform = parseFloat(matrix[13]); // Normal Browsers 3626 else curTransform = parseFloat(matrix[5]); 3627 } 3628 3629 return curTransform || 0; 3630 } 3631 3632 function isObject(o) { 3633 return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object'; 3634 } 3635 3636 function isNode(node) { 3637 // eslint-disable-next-line 3638 if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') { 3639 return node instanceof HTMLElement; 3640 } 3641 3642 return node && (node.nodeType === 1 || node.nodeType === 11); 3643 } 3644 3645 function extend() { 3646 const to = Object(arguments.length <= 0 ? undefined : arguments[0]); 3647 const noExtend = ['__proto__', 'constructor', 'prototype']; 3648 3649 for (let i = 1; i < arguments.length; i += 1) { 3650 const nextSource = i < 0 || arguments.length <= i ? undefined : arguments[i]; 3651 3652 if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) { 3653 const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0); 3654 3655 for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) { 3656 const nextKey = keysArray[nextIndex]; 3657 const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey); 3658 3659 if (desc !== undefined && desc.enumerable) { 3660 if (isObject(to[nextKey]) && isObject(nextSource[nextKey])) { 3661 if (nextSource[nextKey].__swiper__) { 3662 to[nextKey] = nextSource[nextKey]; 3663 } else { 3664 extend(to[nextKey], nextSource[nextKey]); 3665 } 3666 } else if (!isObject(to[nextKey]) && isObject(nextSource[nextKey])) { 3667 to[nextKey] = {}; 3668 3669 if (nextSource[nextKey].__swiper__) { 3670 to[nextKey] = nextSource[nextKey]; 3671 } else { 3672 extend(to[nextKey], nextSource[nextKey]); 3673 } 3674 } else { 3675 to[nextKey] = nextSource[nextKey]; 3676 } 3677 } 3678 } 3679 } 3680 } 3681 3682 return to; 3683 } 3684 3685 function setCSSProperty(el, varName, varValue) { 3686 el.style.setProperty(varName, varValue); 3687 } 3688 3689 function animateCSSModeScroll(_ref) { 3690 let { 3691 swiper, 3692 targetPosition, 3693 side 3694 } = _ref; 3695 const window = getWindow(); 3696 const startPosition = -swiper.translate; 3697 let startTime = null; 3698 let time; 3699 const duration = swiper.params.speed; 3700 swiper.wrapperEl.style.scrollSnapType = 'none'; 3701 window.cancelAnimationFrame(swiper.cssModeFrameID); 3702 const dir = targetPosition > startPosition ? 'next' : 'prev'; 3703 3704 const isOutOfBound = (current, target) => { 3705 return dir === 'next' && current >= target || dir === 'prev' && current <= target; 3706 }; 3707 3708 const animate = () => { 3709 time = new Date().getTime(); 3710 3711 if (startTime === null) { 3712 startTime = time; 3713 } 3714 3715 const progress = Math.max(Math.min((time - startTime) / duration, 1), 0); 3716 const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2; 3717 let currentPosition = startPosition + easeProgress * (targetPosition - startPosition); 3718 3719 if (isOutOfBound(currentPosition, targetPosition)) { 3720 currentPosition = targetPosition; 3721 } 3722 3723 swiper.wrapperEl.scrollTo({ 3724 [side]: currentPosition 3725 }); 3726 3727 if (isOutOfBound(currentPosition, targetPosition)) { 3728 swiper.wrapperEl.style.overflow = 'hidden'; 3729 swiper.wrapperEl.style.scrollSnapType = ''; 3730 setTimeout(() => { 3731 swiper.wrapperEl.style.overflow = ''; 3732 swiper.wrapperEl.scrollTo({ 3733 [side]: currentPosition 3734 }); 3735 }); 3736 window.cancelAnimationFrame(swiper.cssModeFrameID); 3737 return; 3738 } 3739 3740 swiper.cssModeFrameID = window.requestAnimationFrame(animate); 3741 }; 3742 3743 animate(); 3744 } 3745 3746 let support; 3747 3748 function calcSupport() { 3749 const window = getWindow(); 3750 const document = getDocument(); 3751 return { 3752 smoothScroll: document.documentElement && 'scrollBehavior' in document.documentElement.style, 3753 touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch), 3754 passiveListener: function checkPassiveListener() { 3755 let supportsPassive = false; 3756 3757 try { 3758 const opts = Object.defineProperty({}, 'passive', { 3759 // eslint-disable-next-line 3760 get() { 3761 supportsPassive = true; 3762 } 3763 3764 }); 3765 window.addEventListener('testPassiveListener', null, opts); 3766 } catch (e) {// No support 3767 } 3768 3769 return supportsPassive; 3770 }(), 3771 gestures: function checkGestures() { 3772 return 'ongesturestart' in window; 3773 }() 3774 }; 3775 } 3776
3777 function getSupport() { 3778 if (!support) { 3779 support = calcSupport(); 3780 } 3781 3782 return support; 3783 } 3784 3785 let deviceCached; 3786 3787 function calcDevice(_temp) { 3788 let { 3789 userAgent 3790 } = _temp === void 0 ? {} : _temp; 3791 const support = getSupport(); 3792 const window = getWindow(); 3793 const platform = window.navigator.platform; 3794 const ua = userAgent || window.navigator.userAgent; 3795 const device = { 3796 ios: false, 3797 android: false 3798 }; 3799 const screenWidth = window.screen.width; 3800 const screenHeight = window.screen.height; 3801 const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line 3802 3803 let ipad = ua.match(/(iPad).*OS\s([\d_]+)/); 3804 const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/); 3805 const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/); 3806 const windows = platform === 'Win32'; 3807 let macos = platform === 'MacIntel'; // iPadOs 13 fix 3808 3809 const iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768', '820x1180', '1180x820', '810x1080', '1080x810']; 3810 3811 if (!ipad && macos && support.touch && iPadScreens.indexOf(`${screenWidth}x${screenHeight}`) >= 0) { 3812 ipad = ua.match(/(Version)\/([\d.]+)/); 3813 if (!ipad) ipad = [0, 1, '13_0_0']; 3814 macos = false; 3815 } // Android 3816 3817 3818 if (android && !windows) { 3819 device.os = 'android'; 3820 device.android = true; 3821 } 3822 3823 if (ipad || iphone || ipod) { 3824 device.os = 'ios'; 3825 device.ios = true; 3826 } // Export object 3827 3828 3829 return device; 3830 } 3831 3832 function getDevice(overrides) { 3833 if (overrides === void 0) { 3834 overrides = {}; 3835 } 3836 3837 if (!deviceCached) { 3838 deviceCached = calcDevice(overrides); 3839 } 3840 3841 return deviceCached; 3842 } 3843 3844 let browser; 3845 3846 function calcBrowser() { 3847 const window = getWindow(); 3848 3849 function isSafari() { 3850 const ua = window.navigator.userAgent.toLowerCase(); 3851 return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0; 3852 } 3853 3854 return { 3855 isSafari: isSafari(), 3856 isWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent) 3857 }; 3858 } 3859 3860 function getBrowser() { 3861 if (!browser) { 3862 browser = calcBrowser(); 3863 } 3864 3865 return browser; 3866 } 3867 3868 function Resize(_ref) { 3869 let { 3870 swiper, 3871 on, 3872 emit 3873 } = _ref; 3874 const window = getWindow(); 3875 let observer = null; 3876 let animationFrame = null; 3877 3878 const resizeHandler = () => { 3879 if (!swiper || swiper.destroyed || !swiper.initialized) return; 3880 emit('beforeResize'); 3881 emit('resize'); 3882 }; 3883 3884 const createObserver = () => { 3885 if (!swiper || swiper.destroyed || !swiper.initialized) return; 3886 observer = new ResizeObserver(entries => { 3887 animationFrame = window.requestAnimationFrame(() => { 3888 const { 3889 width, 3890 height 3891 } = swiper; 3892 let newWidth = width; 3893 let newHeight = height; 3894 entries.forEach(_ref2 => { 3895 let { 3896 contentBoxSize, 3897 contentRect, 3898 target 3899 } = _ref2; 3900 if (target && target !== swiper.el) return; 3901 newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize; 3902 newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize; 3903 }); 3904 3905 if (newWidth !== width || newHeight !== height) { 3906 resizeHandler(); 3907 } 3908 }); 3909 }); 3910 observer.observe(swiper.el); 3911 }; 3912 3913 const removeObserver = () => { 3914 if (animationFrame) { 3915 window.cancelAnimationFrame(animationFrame); 3916 } 3917 3918 if (observer && observer.unobserve && swiper.el) { 3919 observer.unobserve(swiper.el); 3920 observer = null; 3921 } 3922 }; 3923 3924 const orientationChangeHandler = () => { 3925 if (!swiper || swiper.destroyed || !swiper.initialized) return; 3926 emit('orientationchange'); 3927 }; 3928 3929 on('init', () => { 3930 if (swiper.params.resizeObserver && typeof window.ResizeObserver !== 'undefined') { 3931 createObserver(); 3932 return; 3933 } 3934 3935 window.addEventListener('resize', resizeHandler); 3936 window.addEventListener('orientationchange', orientationChangeHandler); 3937 }); 3938 on('destroy', () => { 3939 removeObserver(); 3940 window.removeEventListener('resize', resizeHandler); 3941 window.removeEventListener('orientationchange', orientationChangeHandler); 3942 }); 3943 } 3944 3945 function Observer(_ref) { 3946 let { 3947 swiper, 3948 extendParams, 3949 on, 3950 emit 3951 } = _ref; 3952 const observers = []; 3953 const window = getWindow(); 3954 3955 const attach = function (target, options) { 3956 if (options === void 0) { 3957 options = {}; 3958 } 3959 3960 const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver; 3961 const observer = new ObserverFunc(mutations => { 3962 // The observerUpdate event should only be triggered 3963 // once despite the number of mutations. Additional 3964 // triggers are redundant and are very costly 3965 if (mutations.length === 1) { 3966 emit('observerUpdate', mutations[0]); 3967 return; 3968 } 3969 3970 const observerUpdate = function observerUpdate() { 3971 emit('observerUpdate', mutations[0]); 3972 }; 3973 3974 if (window.requestAnimationFrame) { 3975 window.requestAnimationFrame(observerUpdate); 3976 } else { 3977 window.setTimeout(observerUpdate, 0); 3978 } 3979 }); 3980 observer.observe(target, { 3981 attributes: typeof options.attributes === 'undefined' ? true : options.attributes, 3982 childList: typeof options.childList === 'undefined' ? true : options.childList, 3983 characterData: typeof options.characterData === 'undefined' ? true : options.characterData 3984 }); 3985 observers.push(observer); 3986 }; 3987 3988 const init = () => { 3989 if (!swiper.params.observer) return; 3990 3991 if (swiper.params.observeParents) { 3992 const containerParents = swiper.$el.parents(); 3993 3994 for (let i = 0; i < containerParents.length; i += 1) { 3995 attach(containerParents[i]); 3996 } 3997 } // Observe container 3998 3999 4000 attach(swiper.$el[0], { 4001 childList: swiper.params.observeSlideChildren 4002 }); // Observe wrapper 4003 4004 attach(swiper.$wrapperEl[0], { 4005 attributes: false 4006 }); 4007 }; 4008 4009 const destroy = () => {
4010 observers.forEach(observer => { 4011 observer.disconnect(); 4012 }); 4013 observers.splice(0, observers.length); 4014 }; 4015 4016 extendParams({ 4017 observer: false, 4018 observeParents: false, 4019 observeSlideChildren: false 4020 }); 4021 on('init', init); 4022 on('destroy', destroy); 4023 } 4024 4025 /* eslint-disable no-underscore-dangle */ 4026 var eventsEmitter = { 4027 on(events, handler, priority) { 4028 const self = this; 4029 if (!self.eventsListeners || self.destroyed) return self; 4030 if (typeof handler !== 'function') return self; 4031 const method = priority ? 'unshift' : 'push'; 4032 events.split(' ').forEach(event => { 4033 if (!self.eventsListeners[event]) self.eventsListeners[event] = []; 4034 self.eventsListeners[event][method](handler); 4035 }); 4036 return self; 4037 }, 4038 4039 once(events, handler, priority) { 4040 const self = this; 4041 if (!self.eventsListeners || self.destroyed) return self; 4042 if (typeof handler !== 'function') return self; 4043 4044 function onceHandler() { 4045 self.off(events, onceHandler); 4046 4047 if (onceHandler.__emitterProxy) { 4048 delete onceHandler.__emitterProxy; 4049 } 4050 4051 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 4052 args[_key] = arguments[_key]; 4053 } 4054 4055 handler.apply(self, args); 4056 } 4057 4058 onceHandler.__emitterProxy = handler; 4059 return self.on(events, onceHandler, priority); 4060 }, 4061 4062 onAny(handler, priority) { 4063 const self = this; 4064 if (!self.eventsListeners || self.destroyed) return self; 4065 if (typeof handler !== 'function') return self; 4066 const method = priority ? 'unshift' : 'push'; 4067 4068 if (self.eventsAnyListeners.indexOf(handler) < 0) { 4069 self.eventsAnyListeners[method](handler); 4070 } 4071 4072 return self; 4073 }, 4074 4075 offAny(handler) { 4076 const self = this; 4077 if (!self.eventsListeners || self.destroyed) return self; 4078 if (!self.eventsAnyListeners) return self; 4079 const index = self.eventsAnyListeners.indexOf(handler); 4080 4081 if (index >= 0) { 4082 self.eventsAnyListeners.splice(index, 1); 4083 } 4084 4085 return self; 4086 }, 4087 4088 off(events, handler) { 4089 const self = this; 4090 if (!self.eventsListeners || self.destroyed) return self; 4091 if (!self.eventsListeners) return self; 4092 events.split(' ').forEach(event => { 4093 if (typeof handler === 'undefined') { 4094 self.eventsListeners[event] = []; 4095 } else if (self.eventsListeners[event]) { 4096 self.eventsListeners[event].forEach((eventHandler, index) => { 4097 if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) { 4098 self.eventsListeners[event].splice(index, 1); 4099 } 4100 }); 4101 } 4102 }); 4103 return self; 4104 }, 4105 4106 emit() { 4107 const self = this; 4108 if (!self.eventsListeners || self.destroyed) return self; 4109 if (!self.eventsListeners) return self; 4110 let events; 4111 let data; 4112 let context; 4113 4114 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 4115 args[_key2] = arguments[_key2]; 4116 } 4117 4118 if (typeof args[0] === 'string' || Array.isArray(args[0])) { 4119 events = args[0]; 4120 data = args.slice(1, args.length); 4121 context = self; 4122 } else { 4123 events = args[0].events; 4124 data = args[0].data; 4125 context = args[0].context || self; 4126 } 4127 4128 data.unshift(context); 4129 const eventsArray = Array.isArray(events) ? events : events.split(' '); 4130 eventsArray.forEach(event => { 4131 if (self.eventsAnyListeners && self.eventsAnyListeners.length) { 4132 self.eventsAnyListeners.forEach(eventHandler => { 4133 eventHandler.apply(context, [event, ...data]); 4134 }); 4135 } 4136 4137 if (self.eventsListeners && self.eventsListeners[event]) { 4138 self.eventsListeners[event].forEach(eventHandler => { 4139 eventHandler.apply(context, data); 4140 }); 4141 } 4142 }); 4143 return self; 4144 } 4145 4146 }; 4147 4148 function updateSize() { 4149 const swiper = this; 4150 let width; 4151 let height; 4152 const $el = swiper.$el; 4153 4154 if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) { 4155 width = swiper.params.width; 4156 } else { 4157 width = $el[0].clientWidth; 4158 } 4159 4160 if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) { 4161 height = swiper.params.height; 4162 } else { 4163 height = $el[0].clientHeight; 4164 } 4165 4166 if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) { 4167 return; 4168 } // Subtract paddings 4169 4170 4171 width = width - parseInt($el.css('padding-left') || 0, 10) - parseInt($el.css('padding-right') || 0, 10); 4172 height = height - parseInt($el.css('padding-top') || 0, 10) - parseInt($el.css('padding-bottom') || 0, 10); 4173 if (Number.isNaN(width)) width = 0; 4174 if (Number.isNaN(height)) height = 0;
vendor: 19,069 bytes, lines 4175-4727
4175 Object.assign(swiper, { 4176 width, 4177 height, 4178 size: swiper.isHorizontal() ? width : height 4179 }); 4180 } 4181 4182 function updateSlides() { 4183 const swiper = this; 4184 4185 function getDirectionLabel(property) { 4186 if (swiper.isHorizontal()) { 4187 return property; 4188 } // prettier-ignore 4189 4190 4191 return { 4192 'width': 'height', 4193 'margin-top': 'margin-left', 4194 'margin-bottom ': 'margin-right', 4195 'margin-left': 'margin-top', 4196 'margin-right': 'margin-bottom', 4197 'padding-left': 'padding-top', 4198 'padding-right': 'padding-bottom', 4199 'marginRight': 'marginBottom' 4200 }[property]; 4201 } 4202 4203 function getDirectionPropertyValue(node, label) { 4204 return parseFloat(node.getPropertyValue(getDirectionLabel(label)) || 0); 4205 } 4206 4207 const params = swiper.params; 4208 const { 4209 $wrapperEl, 4210 size: swiperSize, 4211 rtlTranslate: rtl, 4212 wrongRTL 4213 } = swiper; 4214 const isVirtual = swiper.virtual && params.virtual.enabled; 4215 const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length; 4216 const slides = $wrapperEl.children(`.${swiper.params.slideClass}`); 4217 const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length; 4218 let snapGrid = []; 4219 const slidesGrid = []; 4220 const slidesSizesGrid = []; 4221 let offsetBefore = params.slidesOffsetBefore; 4222 4223 if (typeof offsetBefore === 'function') { 4224 offsetBefore = params.slidesOffsetBefore.call(swiper); 4225 } 4226 4227 let offsetAfter = params.slidesOffsetAfter; 4228 4229 if (typeof offsetAfter === 'function') { 4230 offsetAfter = params.slidesOffsetAfter.call(swiper); 4231 } 4232 4233 const previousSnapGridLength = swiper.snapGrid.length; 4234 const previousSlidesGridLength = swiper.slidesGrid.length; 4235 let spaceBetween = params.spaceBetween; 4236 let slidePosition = -offsetBefore; 4237 let prevSlideSize = 0; 4238 let index = 0; 4239 4240 if (typeof swiperSize === 'undefined') { 4241 return; 4242 } 4243 4244 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) { 4245 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize; 4246 } 4247 4248 swiper.virtualSize = -spaceBetween; // reset margins 4249 4250 if (rtl) slides.css({ 4251 marginLeft: '', 4252 marginBottom: '', 4253 marginTop: '' 4254 });else slides.css({ 4255 marginRight: '', 4256 marginBottom: '', 4257 marginTop: '' 4258 }); // reset cssMode offsets 4259 4260 if (params.centeredSlides && params.cssMode) { 4261 setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-before', ''); 4262 setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-after', ''); 4263 } 4264 4265 const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid; 4266 4267 if (gridEnabled) { 4268 swiper.grid.initSlides(slidesLength); 4269 } // Calc slides 4270 4271 4272 let slideSize; 4273 const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => { 4274 return typeof params.breakpoints[key].slidesPerView !== 'undefined'; 4275 }).length > 0; 4276 4277 for (let i = 0; i < slidesLength; i += 1) { 4278 slideSize = 0; 4279 const slide = slides.eq(i); 4280 4281 if (gridEnabled) { 4282 swiper.grid.updateSlide(i, slide, slidesLength, getDirectionLabel); 4283 } 4284 4285 if (slide.css('display') === 'none') continue; // eslint-disable-line 4286 4287 if (params.slidesPerView === 'auto') { 4288 if (shouldResetSlideSize) { 4289 slides[i].style[getDirectionLabel('width')] = ``; 4290 } 4291 4292 const slideStyles = getComputedStyle(slide[0]); 4293 const currentTransform = slide[0].style.transform; 4294 const currentWebKitTransform = slide[0].style.webkitTransform; 4295 4296 if (currentTransform) { 4297 slide[0].style.transform = 'none'; 4298 } 4299 4300 if (currentWebKitTransform) { 4301 slide[0].style.webkitTransform = 'none'; 4302 } 4303 4304 if (params.roundLengths) { 4305 slideSize = swiper.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true); 4306 } else { 4307 // eslint-disable-next-line 4308 const width = getDirectionPropertyValue(slideStyles, 'width'); 4309 const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left'); 4310 const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right'); 4311 const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left'); 4312 const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right'); 4313 const boxSizing = slideStyles.getPropertyValue('box-sizing'); 4314 4315 if (boxSizing && boxSizing === 'border-box') { 4316 slideSize = width + marginLeft + marginRight; 4317 } else { 4318 const { 4319 clientWidth, 4320 offsetWidth 4321 } = slide[0]; 4322 slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth); 4323 } 4324 } 4325 4326 if (currentTransform) { 4327 slide[0].style.transform = currentTransform; 4328 } 4329 4330 if (currentWebKitTransform) { 4331 slide[0].style.webkitTransform = currentWebKitTransform; 4332 } 4333 4334 if (params.roundLengths) slideSize = Math.floor(slideSize); 4335 } else { 4336 slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView; 4337 if (params.roundLengths) slideSize = Math.floor(slideSize); 4338 4339 if (slides[i]) { 4340 slides[i].style[getDirectionLabel('width')] = `${slideSize}px`; 4341 } 4342 } 4343 4344 if (slides[i]) { 4345 slides[i].swiperSlideSize = slideSize; 4346 } 4347 4348 slidesSizesGrid.push(slideSize); 4349 4350 if (params.centeredSlides) { 4351 slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween; 4352 if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween; 4353 if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween; 4354 if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0; 4355 if (params.roundLengths) slidePosition = Math.floor(slidePosition); 4356 if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition); 4357 slidesGrid.push(slidePosition); 4358 } else { 4359 if (params.roundLengths) slidePosition = Math.floor(slidePosition); 4360 if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition); 4361 slidesGrid.push(slidePosition); 4362 slidePosition = slidePosition + slideSize + spaceBetween; 4363 } 4364 4365 swiper.virtualSize += slideSize + spaceBetween; 4366 prevSlideSize = slideSize; 4367 index += 1; 4368 } 4369 4370 swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter; 4371 4372 if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) { 4373 $wrapperEl.css({ 4374 width: `${swiper.virtualSize + params.spaceBetween}px` 4375 }); 4376 } 4377 4378 if (params.setWrapperSize) { 4379 $wrapperEl.css({ 4380 [getDirectionLabel('width')]: `${swiper.virtualSize + params.spaceBetween}px` 4381 }); 4382 } 4383 4384 if (gridEnabled) { 4385 swiper.grid.updateWrapperSize(slideSize, snapGrid, getDirectionLabel); 4386 } // Remove last grid elements depending on width 4387 4388 4389 if (!params.centeredSlides) { 4390 const newSlidesGrid = []; 4391 4392 for (let i = 0; i < snapGrid.length; i += 1) { 4393 let slidesGridItem = snapGrid[i]; 4394 if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem); 4395 4396 if (snapGrid[i] <= swiper.virtualSize - swiperSize) { 4397 newSlidesGrid.push(slidesGridItem); 4398 } 4399 } 4400 4401 snapGrid = newSlidesGrid; 4402 4403 if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) { 4404 snapGrid.push(swiper.virtualSize - swiperSize); 4405 } 4406 } 4407 4408 if (snapGrid.length === 0) snapGrid = [0]; 4409 4410 if (params.spaceBetween !== 0) { 4411 const key = swiper.isHorizontal() && rtl ? 'marginLeft' : getDirectionLabel('marginRight'); 4412 slides.filter((_, slideIndex) => { 4413 if (!params.cssMode) return true; 4414 4415 if (slideIndex === slides.length - 1) { 4416 return false; 4417 } 4418 4419 return true; 4420 }).css({ 4421 [key]: `${spaceBetween}px` 4422 }); 4423 } 4424 4425 if (params.centeredSlides && params.centeredSlidesBounds) { 4426 let allSlidesSize = 0; 4427 slidesSizesGrid.forEach(slideSizeValue => { 4428 allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0); 4429 }); 4430 allSlidesSize -= params.spaceBetween; 4431 const maxSnap = allSlidesSize - swiperSize; 4432 snapGrid = snapGrid.map(snap => { 4433 if (snap < 0) return -offsetBefore; 4434 if (snap > maxSnap) return maxSnap + offsetAfter; 4435 return snap; 4436 }); 4437 } 4438 4439 if (params.centerInsufficientSlides) { 4440 let allSlidesSize = 0; 4441 slidesSizesGrid.forEach(slideSizeValue => { 4442 allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0); 4443 }); 4444 allSlidesSize -= params.spaceBetween; 4445 4446 if (allSlidesSize < swiperSize) { 4447 const allSlidesOffset = (swiperSize - allSlidesSize) / 2; 4448 snapGrid.forEach((snap, snapIndex) => { 4449 snapGrid[snapIndex] = snap - allSlidesOffset; 4450 }); 4451 slidesGrid.forEach((snap, snapIndex) => { 4452 slidesGrid[snapIndex] = snap + allSlidesOffset; 4453 }); 4454 } 4455 } 4456 4457 Object.assign(swiper, { 4458 slides, 4459 snapGrid, 4460 slidesGrid, 4461 slidesSizesGrid 4462 }); 4463 4464 if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) { 4465 setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`); 4466 setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-after', `${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`); 4467 const addToSnapGrid = -swiper.snapGrid[0]; 4468 const addToSlidesGrid = -swiper.slidesGrid[0]; 4469 swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid); 4470 swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid); 4471 } 4472 4473 if (slidesLength !== previousSlidesLength) { 4474 swiper.emit('slidesLengthChange'); 4475 } 4476 4477 if (snapGrid.length !== previousSnapGridLength) { 4478 if (swiper.params.watchOverflow) swiper.checkOverflow(); 4479 swiper.emit('snapGridLengthChange'); 4480 } 4481 4482 if (slidesGrid.length !== previousSlidesGridLength) { 4483 swiper.emit('slidesGridLengthChange'); 4484 } 4485 4486 if (params.watchSlidesProgress) { 4487 swiper.updateSlidesOffset(); 4488 } 4489 4490 if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) { 4491 const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`; 4492 const hasClassBackfaceClassAdded = swiper.$el.hasClass(backFaceHiddenClass); 4493 4494 if (slidesLength <= params.maxBackfaceHiddenSlides) { 4495 if (!hasClassBackfaceClassAdded) swiper.$el.addClass(backFaceHiddenClass); 4496 } else if (hasClassBackfaceClassAdded) { 4497 swiper.$el.removeClass(backFaceHiddenClass); 4498 } 4499 } 4500 } 4501 4502 function updateAutoHeight(speed) { 4503 const swiper = this; 4504 const activeSlides = []; 4505 const isVirtual = swiper.virtual && swiper.params.virtual.enabled; 4506 let newHeight = 0; 4507 let i; 4508 4509 if (typeof speed === 'number') { 4510 swiper.setTransition(speed); 4511 } else if (speed === true) { 4512 swiper.setTransition(swiper.params.speed); 4513 } 4514 4515 const getSlideByIndex = index => { 4516 if (isVirtual) { 4517 return swiper.slides.filter(el => parseInt(el.getAttribute('data-swiper-slide-index'), 10) === index)[0]; 4518 } 4519 4520 return swiper.slides.eq(index)[0]; 4521 }; // Find slides currently in view 4522 4523 4524 if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) { 4525 if (swiper.params.centeredSlides) { 4526 (swiper.visibleSlides || $([])).each(slide => { 4527 activeSlides.push(slide); 4528 }); 4529 } else { 4530 for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) { 4531 const index = swiper.activeIndex + i; 4532 if (index > swiper.slides.length && !isVirtual) break; 4533 activeSlides.push(getSlideByIndex(index)); 4534 } 4535 } 4536 } else { 4537 activeSlides.push(getSlideByIndex(swiper.activeIndex)); 4538 } // Find new height from highest slide in view 4539 4540 4541 for (i = 0; i < activeSlides.length; i += 1) { 4542 if (typeof activeSlides[i] !== 'undefined') { 4543 const height = activeSlides[i].offsetHeight; 4544 newHeight = height > newHeight ? height : newHeight; 4545 } 4546 } // Update Height 4547 4548 4549 if (newHeight || newHeight === 0) swiper.$wrapperEl.css('height', `${newHeight}px`); 4550 } 4551 4552 function updateSlidesOffset() { 4553 const swiper = this; 4554 const slides = swiper.slides; 4555 4556 for (let i = 0; i < slides.length; i += 1) { 4557 slides[i].swiperSlideOffset = swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop; 4558 } 4559 } 4560 4561 function updateSlidesProgress(translate) { 4562 if (translate === void 0) { 4563 translate = this && this.translate || 0; 4564 } 4565 4566 const swiper = this; 4567 const params = swiper.params; 4568 const { 4569 slides, 4570 rtlTranslate: rtl, 4571 snapGrid 4572 } = swiper; 4573 if (slides.length === 0) return; 4574 if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset(); 4575 let offsetCenter = -translate; 4576 if (rtl) offsetCenter = translate; // Visible Slides 4577 4578 slides.removeClass(params.slideVisibleClass); 4579 swiper.visibleSlidesIndexes = []; 4580 swiper.visibleSlides = []; 4581 4582 for (let i = 0; i < slides.length; i += 1) { 4583 const slide = slides[i]; 4584 let slideOffset = slide.swiperSlideOffset; 4585 4586 if (params.cssMode && params.centeredSlides) { 4587 slideOffset -= slides[0].swiperSlideOffset; 4588 } 4589 4590 const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + params.spaceBetween); 4591 const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + params.spaceBetween); 4592 const slideBefore = -(offsetCenter - slideOffset); 4593 const slideAfter = slideBefore + swiper.slidesSizesGrid[i]; 4594 const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size; 4595 4596 if (isVisible) { 4597 swiper.visibleSlides.push(slide); 4598 swiper.visibleSlidesIndexes.push(i); 4599 slides.eq(i).addClass(params.slideVisibleClass); 4600 } 4601 4602 slide.progress = rtl ? -slideProgress : slideProgress; 4603 slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress; 4604 } 4605 4606 swiper.visibleSlides = $(swiper.visibleSlides); 4607 } 4608 4609 function updateProgress(translate) { 4610 const swiper = this; 4611 4612 if (typeof translate === 'undefined') { 4613 const multiplier = swiper.rtlTranslate ? -1 : 1; // eslint-disable-next-line 4614 4615 translate = swiper && swiper.translate && swiper.translate * multiplier || 0; 4616 } 4617 4618 const params = swiper.params; 4619 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); 4620 let { 4621 progress, 4622 isBeginning, 4623 isEnd 4624 } = swiper; 4625 const wasBeginning = isBeginning; 4626 const wasEnd = isEnd; 4627 4628 if (translatesDiff === 0) { 4629 progress = 0; 4630 isBeginning = true; 4631 isEnd = true; 4632 } else { 4633 progress = (translate - swiper.minTranslate()) / translatesDiff; 4634 isBeginning = progress <= 0; 4635 isEnd = progress >= 1; 4636 } 4637 4638 Object.assign(swiper, { 4639 progress, 4640 isBeginning, 4641 isEnd 4642 }); 4643 if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate); 4644 4645 if (isBeginning && !wasBeginning) { 4646 swiper.emit('reachBeginning toEdge'); 4647 } 4648 4649 if (isEnd && !wasEnd) { 4650 swiper.emit('reachEnd toEdge'); 4651 } 4652 4653 if (wasBeginning && !isBeginning || wasEnd && !isEnd) { 4654 swiper.emit('fromEdge'); 4655 } 4656 4657 swiper.emit('progress', progress); 4658 } 4659 4660 function updateSlidesClasses() { 4661 const swiper = this; 4662 const { 4663 slides, 4664 params, 4665 $wrapperEl, 4666 activeIndex, 4667 realIndex 4668 } = swiper; 4669 const isVirtual = swiper.virtual && params.virtual.enabled; 4670 slides.removeClass(`${params.slideActiveClass} ${params.slideNextClass} ${params.slidePrevClass} ${params.slideDuplicateActiveClass} ${params.slideDuplicateNextClass} ${params.slideDuplicatePrevClass}`); 4671 let activeSlide; 4672 4673 if (isVirtual) { 4674 activeSlide = swiper.$wrapperEl.find(`.${params.slideClass}[data-swiper-slide-index="${activeIndex}"]`); 4675 } else { 4676 activeSlide = slides.eq(activeIndex); 4677 } // Active classes 4678 4679 4680 activeSlide.addClass(params.slideActiveClass); 4681 4682 if (params.loop) { 4683 // Duplicate to all looped slides 4684 if (activeSlide.hasClass(params.slideDuplicateClass)) { 4685 $wrapperEl.children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${realIndex}"]`).addClass(params.slideDuplicateActiveClass); 4686 } else { 4687 $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${realIndex}"]`).addClass(params.slideDuplicateActiveClass); 4688 } 4689 } // Next Slide 4690 4691 4692 let nextSlide = activeSlide.nextAll(`.${params.slideClass}`).eq(0).addClass(params.slideNextClass); 4693 4694 if (params.loop && nextSlide.length === 0) { 4695 nextSlide = slides.eq(0); 4696 nextSlide.addClass(params.slideNextClass); 4697 } // Prev Slide 4698 4699 4700 let prevSlide = activeSlide.prevAll(`.${params.slideClass}`).eq(0).addClass(params.slidePrevClass); 4701 4702 if (params.loop && prevSlide.length === 0) { 4703 prevSlide = slides.eq(-1); 4704 prevSlide.addClass(params.slidePrevClass); 4705 } 4706 4707 if (params.loop) { 4708 // Duplicate to all looped slides 4709 if (nextSlide.hasClass(params.slideDuplicateClass)) { 4710 $wrapperEl.children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${nextSlide.attr('data-swiper-slide-index')}"]`).addClass(params.slideDuplicateNextClass); 4711 } else { 4712 $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${nextSlide.attr('data-swiper-slide-index')}"]`).addClass(params.slideDuplicateNextClass); 4713 } 4714 4715 if (prevSlide.hasClass(params.slideDuplicateClass)) { 4716 $wrapperEl.children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${prevSlide.attr('data-swiper-slide-index')}"]`).addClass(params.slideDuplicatePrevClass); 4717 } else { 4718 $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${prevSlide.attr('data-swiper-slide-index')}"]`).addClass(params.slideDuplicatePrevClass); 4719 } 4720 } 4721 4722 swiper.emitSlidesClasses(); 4723 } 4724 4725 function updateActiveIndex(newActiveIndex) { 4726 const swiper = this; 4727 const translate = swiper.rtlTranslate ? swiper.translate : -swi
4727per.translate; 4728 const { 4729 slidesGrid, 4730 snapGrid, 4731 params, 4732 activeIndex: previousIndex, 4733 realIndex: previousRealIndex, 4734 snapIndex: previousSnapIndex 4735 } = swiper; 4736 let activeIndex = newActiveIndex; 4737 let snapIndex; 4738 4739 if (typeof activeIndex === 'undefined') { 4740 for (let i = 0; i < slidesGrid.length; i += 1) { 4741 if (typeof slidesGrid[i + 1] !== 'undefined') { 4742 if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) { 4743 activeIndex = i; 4744 } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) { 4745 activeIndex = i + 1; 4746 } 4747 } else if (translate >= slidesGrid[i]) { 4748 activeIndex = i; 4749 } 4750 } // Normalize slideIndex 4751 4752 4753 if (params.normalizeSlideIndex) { 4754 if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0; 4755 } 4756 } 4757 4758 if (snapGrid.indexOf(translate) >= 0) { 4759 snapIndex = snapGrid.indexOf(translate); 4760 } else { 4761 const skip = Math.min(params.slidesPerGroupSkip, activeIndex); 4762 snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup); 4763 } 4764 4765 if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1; 4766 4767 if (activeIndex === previousIndex) { 4768 if (snapIndex !== previousSnapIndex) { 4769 swiper.snapIndex = snapIndex; 4770 swiper.emit('snapIndexChange'); 4771 } 4772 4773 return; 4774 } // Get real index 4775 4776 4777 const realIndex = parseInt(swiper.slides.eq(activeIndex).attr('data-swiper-slide-index') || activeIndex, 10); 4778 Object.assign(swiper, { 4779 snapIndex, 4780 realIndex, 4781 previousIndex, 4782 activeIndex 4783 }); 4784 swiper.emit('activeIndexChange'); 4785 swiper.emit('snapIndexChange'); 4786 4787 if (previousRealIndex !== realIndex) { 4788 swiper.emit('realIndexChange'); 4789 } 4790 4791 if (swiper.initialized || swiper.params.runCallbacksOnInit) { 4792 swiper.emit('slideChange'); 4793 } 4794 } 4795 4796 function updateClickedSlide(e) { 4797 const swiper = this; 4798 const params = swiper.params; 4799 const slide = $(e).closest(`.${params.slideClass}`)[0]; 4800 let slideFound = false; 4801 let slideIndex; 4802 4803 if (slide) { 4804 for (let i = 0; i < swiper.slides.length; i += 1) { 4805 if (swiper.slides[i] === slide) { 4806 slideFound = true; 4807 slideIndex = i; 4808 break; 4809 } 4810 } 4811 } 4812 4813 if (slide && slideFound) { 4814 swiper.clickedSlide = slide; 4815 4816 if (swiper.virtual && swiper.params.virtual.enabled) { 4817 swiper.clickedIndex = parseInt($(slide).attr('data-swiper-slide-index'), 10); 4818 } else { 4819 swiper.clickedIndex = slideIndex; 4820 } 4821 } else { 4822 swiper.clickedSlide = undefined; 4823 swiper.clickedIndex = undefined; 4824 return; 4825 } 4826 4827 if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) { 4828 swiper.slideToClickedSlide(); 4829 } 4830 } 4831 4832 var update = { 4833 updateSize, 4834 updateSlides, 4835 updateAutoHeight, 4836 updateSlidesOffset, 4837 updateSlidesProgress, 4838 updateProgress, 4839 updateSlidesClasses, 4840 updateActiveIndex, 4841 updateClickedSlide 4842 }; 4843 4844 function getSwiperTranslate(axis) { 4845 if (axis === void 0) { 4846 axis = this.isHorizontal() ? 'x' : 'y'; 4847 } 4848 4849 const swiper = this; 4850 const { 4851 params, 4852 rtlTranslate: rtl, 4853 translate, 4854 $wrapperEl 4855 } = swiper; 4856 4857 if (params.virtualTranslate) { 4858 return rtl ? -translate : translate; 4859 } 4860 4861 if (params.cssMode) { 4862 return translate; 4863 } 4864 4865 let currentTranslate = getTranslate($wrapperEl[0], axis); 4866 if (rtl) currentTranslate = -currentTranslate; 4867 return currentTranslate || 0; 4868 } 4869 4870 function setTranslate(translate, byController) { 4871 const swiper = this; 4872 const { 4873 rtlTranslate: rtl, 4874 params, 4875 $wrapperEl, 4876 wrapperEl, 4877 progress 4878 } = swiper; 4879 let x = 0; 4880 let y = 0; 4881 const z = 0; 4882 4883 if (swiper.isHorizontal()) { 4884 x = rtl ? -translate : translate; 4885 } else { 4886 y = translate; 4887 } 4888 4889 if (params.roundLengths) { 4890 x = Math.floor(x); 4891 y = Math.floor(y); 4892 } 4893 4894 if (params.cssMode) { 4895 wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y; 4896 } else if (!params.virtualTranslate) { 4897 $wrapperEl.transform(`translate3d(${x}px, ${y}px, ${z}px)`); 4898 } 4899 4900 swiper.previousTranslate = swiper.translate; 4901 swiper.translate = swiper.isHorizontal() ? x : y; // Check if we need to update progress 4902 4903 let newProgress; 4904 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); 4905 4906 if (translatesDiff === 0) { 4907 newProgress = 0; 4908 } else { 4909 newProgress = (translate - swiper.minTranslate()) / translatesDiff; 4910 } 4911 4912 if (newProgress !== progress) { 4913 swiper.updateProgress(translate); 4914 } 4915 4916 swiper.emit('setTranslate', swiper.translate, byController); 4917 } 4918 4919 function minTranslate() { 4920 return -this.snapGrid[0]; 4921 } 4922 4923 function maxTranslate() { 4924 return -this.snapGrid[this.snapGrid.length - 1]; 4925 } 4926 4927 function translateTo(translate, speed, runCallbacks, translateBounds, internal) { 4928 if (translate === void 0) { 4929 translate = 0; 4930 } 4931 4932 if (speed === void 0) { 4933 speed = this.params.speed; 4934 } 4935 4936 if (runCallbacks === void 0) { 4937 runCallbacks = true; 4938 } 4939 4940 if (translateBounds === void 0) { 4941 translateBounds = true; 4942 } 4943 4944 const swiper = this; 4945 const { 4946 params, 4947 wrapperEl 4948 } = swiper; 4949 4950 if (swiper.animating && params.preventInteractionOnTransition) { 4951 return false;
vendor: 4,172 bytes, lines 4952-5113
4952 } 4953 4954 const minTranslate = swiper.minTranslate(); 4955 const maxTranslate = swiper.maxTranslate(); 4956 let newTranslate; 4957 if (translateBounds && translate > minTranslate) newTranslate = minTranslate;else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;else newTranslate = translate; // Update progress 4958 4959 swiper.updateProgress(newTranslate); 4960 4961 if (params.cssMode) { 4962 const isH = swiper.isHorizontal(); 4963 4964 if (speed === 0) { 4965 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate; 4966 } else { 4967 if (!swiper.support.smoothScroll) { 4968 animateCSSModeScroll({ 4969 swiper, 4970 targetPosition: -newTranslate, 4971 side: isH ? 'left' : 'top' 4972 }); 4973 return true; 4974 } 4975 4976 wrapperEl.scrollTo({ 4977 [isH ? 'left' : 'top']: -newTranslate, 4978 behavior: 'smooth' 4979 }); 4980 } 4981 4982 return true; 4983 } 4984 4985 if (speed === 0) { 4986 swiper.setTransition(0); 4987 swiper.setTranslate(newTranslate); 4988 4989 if (runCallbacks) { 4990 swiper.emit('beforeTransitionStart', speed, internal); 4991 swiper.emit('transitionEnd'); 4992 } 4993 } else { 4994 swiper.setTransition(speed); 4995 swiper.setTranslate(newTranslate); 4996 4997 if (runCallbacks) { 4998 swiper.emit('beforeTransitionStart', speed, internal); 4999 swiper.emit('transitionStart'); 5000 } 5001 5002 if (!swiper.animating) { 5003 swiper.animating = true; 5004 5005 if (!swiper.onTranslateToWrapperTransitionEnd) { 5006 swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) { 5007 if (!swiper || swiper.destroyed) return; 5008 if (e.target !== this) return; 5009 swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd); 5010 swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onTranslateToWrapperTransitionEnd); 5011 swiper.onTranslateToWrapperTransitionEnd = null; 5012 delete swiper.onTranslateToWrapperTransitionEnd; 5013 5014 if (runCallbacks) { 5015 swiper.emit('transitionEnd'); 5016 } 5017 }; 5018 } 5019 5020 swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd); 5021 swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onTranslateToWrapperTransitionEnd); 5022 } 5023 } 5024 5025 return true; 5026 } 5027 5028 var translate = { 5029 getTranslate: getSwiperTranslate, 5030 setTranslate, 5031 minTranslate, 5032 maxTranslate, 5033 translateTo 5034 }; 5035 5036 function setTransition(duration, byController) { 5037 const swiper = this; 5038 5039 if (!swiper.params.cssMode) { 5040 swiper.$wrapperEl.transition(duration); 5041 } 5042 5043 swiper.emit('setTransition', duration, byController); 5044 } 5045 5046 function transitionEmit(_ref) { 5047 let { 5048 swiper, 5049 runCallbacks, 5050 direction, 5051 step 5052 } = _ref; 5053 const { 5054 activeIndex, 5055 previousIndex 5056 } = swiper; 5057 let dir = direction; 5058 5059 if (!dir) { 5060 if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset'; 5061 } 5062 5063 swiper.emit(`transition${step}`); 5064 5065 if (runCallbacks && activeIndex !== previousIndex) { 5066 if (dir === 'reset') { 5067 swiper.emit(`slideResetTransition${step}`); 5068 return; 5069 } 5070 5071 swiper.emit(`slideChangeTransition${step}`); 5072 5073 if (dir === 'next') { 5074 swiper.emit(`slideNextTransition${step}`); 5075 } else { 5076 swiper.emit(`slidePrevTransition${step}`); 5077 } 5078 } 5079 } 5080 5081 function transitionStart(runCallbacks, direction) { 5082 if (runCallbacks === void 0) { 5083 runCallbacks = true; 5084 } 5085 5086 const swiper = this; 5087 const { 5088 params 5089 } = swiper; 5090 if (params.cssMode) return; 5091 5092 if (params.autoHeight) { 5093 swiper.updateAutoHeight(); 5094 } 5095 5096 transitionEmit({ 5097 swiper, 5098 runCallbacks, 5099 direction, 5100 step: 'Start' 5101 }); 5102 } 5103 5104 function transitionEnd(runCallbacks, direction) { 5105 if (runCallbacks === void 0) { 5106 runCallbacks = true; 5107 } 5108 5109 const swiper = this; 5110 const { 5111 params 5112 } = swiper; 5113 swiper.animating = false;
5114 if (params.cssMode) return; 5115 swiper.setTransition(0); 5116 transitionEmit({ 5117 swiper, 5118 runCallbacks, 5119 direction, 5120 step: 'End' 5121 }); 5122 } 5123 5124 var transition = { 5125 setTransition, 5126 transitionStart, 5127 transitionEnd 5128 }; 5129 5130 function slideTo(index, speed, runCallbacks, internal, initial) { 5131 if (index === void 0) { 5132 index = 0; 5133 } 5134 5135 if (speed === void 0) { 5136 speed = this.params.speed; 5137 } 5138 5139 if (runCallbacks === void 0) { 5140 runCallbacks = true; 5141 } 5142 5143 if (typeof index !== 'number' && typeof index !== 'string') { 5144 throw new Error(`The 'index' argument cannot have type other than 'number' or 'string'. [${typeof index}] given.`); 5145 } 5146 5147 if (typeof index === 'string') { 5148 /** 5149 * The `index` argument converted from `string` to `number`. 5150 * @type {number} 5151 */ 5152 const indexAsNumber = parseInt(index, 10); 5153 /** 5154 * Determines whether the `index` argument is a valid `number` 5155 * after being converted from the `string` type. 5156 * @type {boolean} 5157 */ 5158 5159 const isValidNumber = isFinite(indexAsNumber); 5160 5161 if (!isValidNumber) { 5162 throw new Error(`The passed-in 'index' (string) couldn't be converted to 'number'. [${index}] given.`); 5163 } // Knowing that the converted `index` is a valid number, 5164 // we can update the original argument's value. 5165 5166 5167 index = indexAsNumber; 5168 } 5169 5170 const swiper = this; 5171 let slideIndex = index; 5172 if (slideIndex < 0) slideIndex = 0; 5173 const { 5174 params, 5175 snapGrid, 5176 slidesGrid, 5177 previousIndex, 5178 activeIndex, 5179 rtlTranslate: rtl, 5180 wrapperEl, 5181 enabled 5182 } = swiper; 5183 5184 if (swiper.animating && params.preventInteractionOnTransition || !enabled && !internal && !initial) { 5185 return false; 5186 } 5187 5188 const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex); 5189 let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup); 5190 if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1; 5191 const translate = -snapGrid[snapIndex]; // Normalize slideIndex 5192 5193 if (params.normalizeSlideIndex) { 5194 for (let i = 0; i < slidesGrid.length; i += 1) { 5195 const normalizedTranslate = -Math.floor(translate * 100); 5196 const normalizedGrid = Math.floor(slidesGrid[i] * 100); 5197 const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100); 5198 5199 if (typeof slidesGrid[i + 1] !== 'undefined') { 5200 if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) { 5201 slideIndex = i; 5202 } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) { 5203 slideIndex = i + 1; 5204 } 5205 } else if (normalizedTranslate >= normalizedGrid) { 5206 slideIndex = i; 5207 } 5208 } 5209 } // Directions locks 5210 5211 5212 if (swiper.initialized && slideIndex !== activeIndex) { 5213 if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) { 5214 return false; 5215 } 5216 5217 if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) { 5218 if ((activeIndex || 0) !== slideIndex) return false; 5219 } 5220 } 5221 5222 if (slideIndex !== (previousIndex || 0) && runCallbacks) { 5223 swiper.emit('beforeSlideChangeStart'); 5224 } // Update progress 5225 5226 5227 swiper.updateProgress(translate); 5228 let direction; 5229 if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset'; // Update Index 5230 5231 if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) { 5232 swiper.updateActiveIndex(slideIndex); // Update Height 5233 5234 if (params.autoHeight) { 5235 swiper.updateAutoHeight(); 5236 } 5237 5238 swiper.updateSlidesClasses(); 5239 5240 if (params.effect !== 'slide') { 5241 swiper.setTranslate(translate); 5242 } 5243 5244 if (direction !== 'reset') { 5245 swiper.transitionStart(runCallbacks, direction); 5246 swiper.transitionEnd(runCallbacks, direction); 5247 } 5248 5249 return false;
5250 } 5251 5252 if (params.cssMode) { 5253 const isH = swiper.isHorizontal(); 5254 const t = rtl ? translate : -translate; 5255 5256 if (speed === 0) { 5257 const isVirtual = swiper.virtual && swiper.params.virtual.enabled; 5258 5259 if (isVirtual) { 5260 swiper.wrapperEl.style.scrollSnapType = 'none'; 5261 swiper._immediateVirtual = true; 5262 } 5263 5264 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t; 5265 5266 if (isVirtual) { 5267 requestAnimationFrame(() => { 5268 swiper.wrapperEl.style.scrollSnapType = ''; 5269 swiper._swiperImmediateVirtual = false; 5270 }); 5271 } 5272 } else { 5273 if (!swiper.support.smoothScroll) { 5274 animateCSSModeScroll({ 5275 swiper, 5276 targetPosition: t, 5277 side: isH ? 'left' : 'top' 5278 }); 5279 return true; 5280 } 5281 5282 wrapperEl.scrollTo({ 5283 [isH ? 'left' : 'top']: t, 5284 behavior: 'smooth' 5285 }); 5286 } 5287 5288 return true; 5289 } 5290 5291 swiper.setTransition(speed); 5292 swiper.setTranslate(translate); 5293 swiper.updateActiveIndex(slideIndex); 5294 swiper.updateSlidesClasses(); 5295 swiper.emit('beforeTransitionStart', speed, internal); 5296 swiper.transitionStart(runCallbacks, direction); 5297 5298 if (speed === 0) { 5299 swiper.transitionEnd(runCallbacks, direction); 5300 } else if (!swiper.animating) { 5301 swiper.animating = true; 5302 5303 if (!swiper.onSlideToWrapperTransitionEnd) { 5304 swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) { 5305 if (!swiper || swiper.destroyed) return; 5306 if (e.target !== this) return; 5307 swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd); 5308 swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd); 5309 swiper.onSlideToWrapperTransitionEnd = null; 5310 delete swiper.onSlideToWrapperTransitionEnd; 5311 swiper.transitionEnd(runCallbacks, direction); 5312 }; 5313 } 5314 5315 swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd); 5316 swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd); 5317 } 5318 5319 return true; 5320 } 5321 5322 function slideToLoop(index, speed, runCallbacks, internal) { 5323 if (index === void 0) { 5324 index = 0; 5325 } 5326 5327 if (speed === void 0) { 5328 speed = this.params.speed; 5329 } 5330 5331 if (runCallbacks === void 0) { 5332 runCallbacks = true; 5333 } 5334 5335 if (typeof index === 'string') { 5336 /** 5337 * The `index` argument converted from `string` to `number`. 5338 * @type {number} 5339 */ 5340 const indexAsNumber = parseInt(index, 10); 5341 /** 5342 * Determines whether the `index` argument is a valid `number` 5343 * after being converted from the `string` type. 5344 * @type {boolean} 5345 */ 5346 5347 const isValidNumber = isFinite(indexAsNumber); 5348 5349 if (!isValidNumber) { 5350 throw new Error(`The passed-in 'index' (string) couldn't be converted to 'number'. [${index}] given.`); 5351 } // Knowing that the converted `index` is a valid number, 5352 // we can update the original argument's value. 5353 5354 5355 index = indexAsNumber; 5356 } 5357 5358 const swiper = this; 5359 let newIndex = index; 5360 5361 if (swiper.params.loop) { 5362 newIndex += swiper.loopedSlides; 5363 } 5364 5365 return swiper.slideTo(newIndex, speed, runCallbacks, internal); 5366 } 5367 5368 /* eslint no-unused-vars: "off" */ 5369 function slideNext(speed, runCallbacks, internal) { 5370 if (speed === void 0) { 5371 speed = this.params.speed; 5372 } 5373 5374 if (runCallbacks === void 0) { 5375 runCallbacks = true; 5376 } 5377 5378 const swiper = this; 5379 const { 5380 animating, 5381 enabled, 5382 params 5383 } = swiper; 5384 if (!enabled) return swiper; 5385 let perGroup = params.slidesPerGroup; 5386 5387 if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) { 5388 perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1); 5389 } 5390 5391 const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup; 5392 5393 if (params.loop) { 5394 if (animating && params.loopPreventsSlide) return false;
5395 swiper.loopFix(); // eslint-disable-next-line 5396 5397 swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; 5398 } 5399 5400 if (params.rewind && swiper.isEnd) { 5401 return swiper.slideTo(0, speed, runCallbacks, internal); 5402 } 5403 5404 return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal); 5405 } 5406 5407 /* eslint no-unused-vars: "off" */ 5408 function slidePrev(speed, runCallbacks, internal) { 5409 if (speed === void 0) { 5410 speed = this.params.speed; 5411 } 5412 5413 if (runCallbacks === void 0) { 5414 runCallbacks = true; 5415 } 5416 5417 const swiper = this; 5418 const { 5419 params, 5420 animating, 5421 snapGrid, 5422 slidesGrid, 5423 rtlTranslate, 5424 enabled 5425 } = swiper; 5426 if (!enabled) return swiper; 5427 5428 if (params.loop) { 5429 if (animating && params.loopPreventsSlide) return false; 5430 swiper.loopFix(); // eslint-disable-next-line 5431 5432 swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; 5433 } 5434 5435 const translate = rtlTranslate ? swiper.translate : -swiper.translate; 5436 5437 function normalize(val) { 5438 if (val < 0) return -Math.floor(Math.abs(val)); 5439 return Math.floor(val); 5440 } 5441 5442 const normalizedTranslate = normalize(translate); 5443 const normalizedSnapGrid = snapGrid.map(val => normalize(val)); 5444 let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1]; 5445 5446 if (typeof prevSnap === 'undefined' && params.cssMode) { 5447 let prevSnapIndex; 5448 snapGrid.forEach((snap, snapIndex) => { 5449 if (normalizedTranslate >= snap) { 5450 // prevSnap = snap; 5451 prevSnapIndex = snapIndex; 5452 } 5453 }); 5454 5455 if (typeof prevSnapIndex !== 'undefined') { 5456 prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex]; 5457 } 5458 } 5459 5460 let prevIndex = 0; 5461 5462 if (typeof prevSnap !== 'undefined') { 5463 prevIndex = slidesGrid.indexOf(prevSnap); 5464 if (prevIndex < 0) prevIndex = swiper.activeIndex - 1; 5465 5466 if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) { 5467 prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1; 5468 prevIndex = Math.max(prevIndex, 0); 5469 } 5470 } 5471 5472 if (params.rewind && swiper.isBeginning) { 5473 const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1; 5474 return swiper.slideTo(lastIndex, speed, runCallbacks, internal); 5475 } 5476 5477 return swiper.slideTo(prevIndex, speed, runCallbacks, internal); 5478 } 5479 5480 /* eslint no-unused-vars: "off" */ 5481 function slideReset(speed, runCallbacks, internal) { 5482 if (speed === void 0) { 5483 speed = this.params.speed; 5484 } 5485 5486 if (runCallbacks === void 0) { 5487 runCallbacks = true; 5488 } 5489 5490 const swiper = this; 5491 return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal); 5492 } 5493 5494 /* eslint no-unused-vars: "off" */ 5495 function slideToClosest(speed, runCallbacks, internal, threshold) { 5496 if (speed === void 0) { 5497 speed = this.params.speed; 5498 } 5499 5500 if (runCallbacks === void 0) { 5501 runCallbacks = true; 5502 } 5503 5504 if (threshold === void 0) { 5505 threshold = 0.5; 5506 } 5507 5508 const swiper = this; 5509 let index = swiper.activeIndex; 5510 const skip = Math.min(swiper.params.slidesPerGroupSkip, index); 5511 const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup); 5512 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate; 5513 5514 if (translate >= swiper.snapGrid[snapIndex]) { 5515 // The current translate is on or after the current snap index, so the choice 5516 // is between the current index and the one after it. 5517 const currentSnap = swiper.snapGrid[snapIndex]; 5518 const nextSnap = swiper.snapGrid[snapIndex + 1]; 5519 5520 if (translate - currentSnap > (nextSnap - currentSnap) * threshold) { 5521 index += swiper.params.slidesPerGroup; 5522 } 5523 } else { 5524 // The current translate is before the current snap index, so the choice 5525 // is between the current index and the one before it. 5526 const prevSnap = swiper.snapGrid[snapIndex - 1]; 5527 const currentSnap = swiper.snapGrid[snapIndex]; 5528 5529 if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) { 5530 index -= swiper.params.slidesPerGroup; 5531 } 5532 } 5533 5534 index = Math.max(index, 0); 5535 index = Math.min(index, swiper.slidesGrid.length - 1); 5536 return swiper.slideTo(index, speed, runCallbacks, internal); 5537 } 5538 5539 function slideToClickedSlide() { 5540 const swiper = this; 5541 const { 5542 params, 5543 $wrapperEl 5544 } = swiper; 5545 const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView; 5546 let slideToIndex = swiper.clickedIndex; 5547 let realIndex; 5548 5549 if (params.loop) { 5550 if (swiper.animating) return; 5551 realIndex = parseInt($(swiper.clickedSlide).attr('data-swiper-slide-index'), 10); 5552 5553 if (params.centeredSlides) { 5554 if (slideToIndex < swiper.loopedSlides - slidesPerView / 2 || slideToIndex > swiper.slides.length - swiper.loopedSlides + slidesPerView / 2) { 5555 swiper.loopFix(); 5556 slideToIndex = $wrapperEl.children(`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`).eq(0).index(); 5557 nextTick(() => { 5558 swiper.slideTo(slideToIndex); 5559 }); 5560 } else { 5561 swiper.slideTo(slideToIndex); 5562 } 5563 } else if (slideToIndex > swiper.slides.length - slidesPerView) { 5564 swiper.loopFix(); 5565 slideToIndex = $wrapperEl.children(`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`).eq(0).index(); 5566 nextTick(() => { 5567 swiper.slideTo(slideToIndex); 5568 }); 5569 } else { 5570 swiper.slideTo(slideToIndex); 5571 } 5572 } else { 5573 swiper.slideTo(slideToIndex); 5574 } 5575 } 5576 5577 var slide = { 5578 slideTo, 5579 slideToLoop, 5580 slideNext, 5581 slidePrev, 5582 slideReset, 5583 slideToClosest, 5584 slideToClickedSlide 5585 }; 5586 5587 function loopCreate() { 5588 const swiper = this; 5589 const document = getDocument(); 5590 const { 5591 params, 5592 $wrapperEl 5593 } = swiper; // Remove duplicated slides 5594 5595 const $selector = $wrapperEl.children().length > 0 ? $($wrapperEl.children()[0].parentNode) : $wrapperEl; 5596 $selector.children(`.${params.slideClass}.${params.slideDuplicateClass}`).remove(); 5597 let slides = $selector.children(`.${params.slideClass}`); 5598 5599 if (params.loopFillGroupWithBlank) { 5600 const blankSlidesNum = params.slidesPerGroup - slides.length % params.slidesPerGroup; 5601 5602 if (blankSlidesNum !== params.slidesPerGroup) { 5603 for (let i = 0; i < blankSlidesNum; i += 1) { 5604 const blankNode = $(document.createElement('div')).addClass(`${params.slideClass} ${params.slideBlankClass}`); 5605 $selector.append(blankNode); 5606 } 5607 5608 slides = $selector.children(`.${params.slideClass}`); 5609 } 5610 } 5611 5612 if (params.slidesPerView === 'auto' && !params.loopedSlides) params.loopedSlides = slides.length; 5613 swiper.loopedSlides = Math.ceil(parseFloat(params.loopedSlides || params.slidesPerView, 10)); 5614 swiper.loopedSlides += params.loopAdditionalSlides; 5615 5616 if (swiper.loopedSlides > slides.length && swiper.params.loopedSlidesLimit) { 5617 swiper.loopedSlides = slides.length; 5618 } 5619 5620 const prependSlides = []; 5621 const appendSlides = []; 5622 slides.each((el, index) => { 5623 const slide = $(el); 5624 slide.attr('data-swiper-slide-index', index); 5625 }); 5626 5627 for (let i = 0; i < swiper.loopedSlides; i += 1) { 5628 const index = i - Math.floor(i / slides.length) * slides.length; 5629 appendSlides.push(slides.eq(index)[0]); 5630 prependSlides.unshift(slides.eq(slides.length - index - 1)[0]); 5631 } 5632 5633 for (let i = 0; i < appendSlides.length; i += 1) { 5634 $selector.append($(appendSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass)); 5635 } 5636 5637 for (let i = prependSlides.length - 1; i >= 0; i -= 1) {
5638 $selector.prepend($(prependSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass)); 5639 } 5640 } 5641 5642 function loopFix() { 5643 const swiper = this; 5644 swiper.emit('beforeLoopFix'); 5645 const { 5646 activeIndex, 5647 slides, 5648 loopedSlides, 5649 allowSlidePrev, 5650 allowSlideNext, 5651 snapGrid, 5652 rtlTranslate: rtl 5653 } = swiper; 5654 let newIndex; 5655 swiper.allowSlidePrev = true; 5656 swiper.allowSlideNext = true; 5657 const snapTranslate = -snapGrid[activeIndex]; 5658 const diff = snapTranslate - swiper.getTranslate(); // Fix For Negative Oversliding 5659 5660 if (activeIndex < loopedSlides) { 5661 newIndex = slides.length - loopedSlides * 3 + activeIndex; 5662 newIndex += loopedSlides; 5663 const slideChanged = swiper.slideTo(newIndex, 0, false, true); 5664 5665 if (slideChanged && diff !== 0) { 5666 swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff); 5667 } 5668 } else if (activeIndex >= slides.length - loopedSlides) { 5669 // Fix For Positive Oversliding 5670 newIndex = -slides.length + activeIndex + loopedSlides; 5671 newIndex += loopedSlides; 5672 const slideChanged = swiper.slideTo(newIndex, 0, false, true); 5673 5674 if (slideChanged && diff !== 0) { 5675 swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff); 5676 } 5677 } 5678 5679 swiper.allowSlidePrev = allowSlidePrev; 5680 swiper.allowSlideNext = allowSlideNext; 5681 swiper.emit('loopFix'); 5682 } 5683 5684 function loopDestroy() { 5685 const swiper = this; 5686 const { 5687 $wrapperEl, 5688 params, 5689 slides 5690 } = swiper; 5691 $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass},.${params.slideClass}.${params.slideBlankClass}`).remove(); 5692 slides.removeAttr('data-swiper-slide-index'); 5693 } 5694 5695 var loop = { 5696 loopCreate, 5697 loopFix, 5698 loopDestroy 5699 }; 5700 5701 function setGrabCursor(moving) { 5702 const swiper = this; 5703 if (swiper.support.touch || !swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return; 5704 const el = swiper.params.touchEventsTarget === 'container' ? swiper.el : swiper.wrapperEl; 5705 el.style.cursor = 'move'; 5706 el.style.cursor = moving ? 'grabbing' : 'grab'; 5707 } 5708 5709 function unsetGrabCursor() { 5710 const swiper = this; 5711 5712 if (swiper.support.touch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) { 5713 return; 5714 } 5715 5716 swiper[swiper.params.touchEventsTarget === 'container' ? 'el' : 'wrapperEl'].style.cursor = ''; 5717 } 5718 5719 var grabCursor = { 5720 setGrabCursor, 5721 unsetGrabCursor 5722 }; 5723 5724 function closestElement(selector, base) { 5725 if (base === void 0) { 5726 base = this; 5727 } 5728 5729 function __closestFrom(el) { 5730 if (!el || el === getDocument() || el === getWindow()) return null; 5731 if (el.assignedSlot) el = el.assignedSlot; 5732 const found = el.closest(selector); 5733 5734 if (!found && !el.getRootNode) { 5735 return null; 5736 } 5737 5738 return found || __closestFrom(el.getRootNode().host); 5739 } 5740 5741 return __closestFrom(base); 5742 } 5743 5744 function onTouchStart(event) { 5745 const swiper = this; 5746 const document = getDocument(); 5747 const window = getWindow(); 5748 const data = swiper.touchEventsData; 5749 const { 5750 params, 5751 touches, 5752 enabled 5753 } = swiper; 5754 if (!enabled) return; 5755 5756 if (swiper.animating && params.preventInteractionOnTransition) { 5757 return; 5758 } 5759 5760 if (!swiper.animating && params.cssMode && params.loop) { 5761 swiper.loopFix(); 5762 } 5763 5764 let e = event; 5765 if (e.originalEvent) e = e.originalEvent; 5766 let $targetEl = $(e.target); 5767 5768 if (params.touchEventsTarget === 'wrapper') { 5769 if (!$targetEl.closest(swiper.wrapperEl).length) return; 5770 } 5771 5772 data.isTouchEvent = e.type === 'touchstart'; 5773 if (!data.isTouchEvent && 'which' in e && e.which === 3) return; 5774 if (!data.isTouchEvent && 'button' in e && e.button > 0) return; 5775 if (data.isTouched && data.isMoved) return; // change target el for shadow root component 5776 5777 const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== ''; // eslint-disable-next-line 5778 5779 const eventPath = event.composedPath ? event.composedPath() : event.path; 5780 5781 if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) { 5782 $targetEl = $(eventPath[0]); 5783 } 5784 5785 const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`; 5786 const isTargetShadow = !!(e.target && e.target.shadowRoot); // use closestElement for shadow root element to get the actual closest for nested shadow root element 5787 5788 if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, $targetEl[0]) : $targetEl.closest(noSwipingSelector)[0])) { 5789 swiper.allowClick = true; 5790 return; 5791 } 5792 5793 if (params.swipeHandler) { 5794 if (!$targetEl.closest(params.swipeHandler)[0]) return; 5795 } 5796 5797 touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX; 5798 touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY; 5799 const startX = touches.currentX; 5800 const startY = touches.currentY; // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore 5801 5802 const edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection; 5803 const edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold; 5804 5805 if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) { 5806 if (edgeSwipeDetection === 'prevent') { 5807 event.preventDefault(); 5808 } else { 5809 return; 5810 } 5811 } 5812 5813 Object.assign(data, { 5814 isTouched: true, 5815 isMoved: false, 5816 allowTouchCallbacks: true, 5817 isScrolling: undefined, 5818 startMoving: undefined 5819 }); 5820 touches.startX = startX; 5821 touches.startY = startY;
vendor: 5,906 bytes, lines 5822-6020
5822 data.touchStartTime = now(); 5823 swiper.allowClick = true; 5824 swiper.updateSize(); 5825 swiper.swipeDirection = undefined; 5826 if (params.threshold > 0) data.allowThresholdMove = false; 5827 5828 if (e.type !== 'touchstart') { 5829 let preventDefault = true; 5830 5831 if ($targetEl.is(data.focusableElements)) { 5832 preventDefault = false; 5833 5834 if ($targetEl[0].nodeName === 'SELECT') { 5835 data.isTouched = false; 5836 } 5837 } 5838 5839 if (document.activeElement && $(document.activeElement).is(data.focusableElements) && document.activeElement !== $targetEl[0]) { 5840 document.activeElement.blur(); 5841 } 5842 5843 const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault; 5844 5845 if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !$targetEl[0].isContentEditable) { 5846 e.preventDefault(); 5847 } 5848 } 5849 5850 if (swiper.params.freeMode && swiper.params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) { 5851 swiper.freeMode.onTouchStart(); 5852 } 5853 5854 swiper.emit('touchStart', e); 5855 } 5856 5857 function onTouchMove(event) { 5858 const document = getDocument(); 5859 const swiper = this; 5860 const data = swiper.touchEventsData; 5861 const { 5862 params, 5863 touches, 5864 rtlTranslate: rtl, 5865 enabled 5866 } = swiper; 5867 if (!enabled) return; 5868 let e = event; 5869 if (e.originalEvent) e = e.originalEvent; 5870 5871 if (!data.isTouched) { 5872 if (data.startMoving && data.isScrolling) { 5873 swiper.emit('touchMoveOpposite', e); 5874 } 5875 5876 return; 5877 } 5878 5879 if (data.isTouchEvent && e.type !== 'touchmove') return; 5880 const targetTouch = e.type === 'touchmove' && e.targetTouches && (e.targetTouches[0] || e.changedTouches[0]); 5881 const pageX = e.type === 'touchmove' ? targetTouch.pageX : e.pageX; 5882 const pageY = e.type === 'touchmove' ? targetTouch.pageY : e.pageY; 5883 5884 if (e.preventedByNestedSwiper) { 5885 touches.startX = pageX; 5886 touches.startY = pageY; 5887 return; 5888 } 5889 5890 if (!swiper.allowTouchMove) { 5891 if (!$(e.target).is(data.focusableElements)) { 5892 swiper.allowClick = false; 5893 } 5894 5895 if (data.isTouched) { 5896 Object.assign(touches, { 5897 startX: pageX, 5898 startY: pageY, 5899 currentX: pageX, 5900 currentY: pageY 5901 }); 5902 data.touchStartTime = now(); 5903 } 5904 5905 return; 5906 } 5907 5908 if (data.isTouchEvent && params.touchReleaseOnEdges && !params.loop) { 5909 if (swiper.isVertical()) { 5910 // Vertical 5911 if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) { 5912 data.isTouched = false; 5913 data.isMoved = false; 5914 return; 5915 } 5916 } else if (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate()) { 5917 return; 5918 } 5919 } 5920 5921 if (data.isTouchEvent && document.activeElement) { 5922 if (e.target === document.activeElement && $(e.target).is(data.focusableElements)) { 5923 data.isMoved = true; 5924 swiper.allowClick = false; 5925 return; 5926 } 5927 } 5928 5929 if (data.allowTouchCallbacks) { 5930 swiper.emit('touchMove', e); 5931 } 5932 5933 if (e.targetTouches && e.targetTouches.length > 1) return; 5934 touches.currentX = pageX; 5935 touches.currentY = pageY; 5936 const diffX = touches.currentX - touches.startX; 5937 const diffY = touches.currentY - touches.startY; 5938 if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return; 5939 5940 if (typeof data.isScrolling === 'undefined') { 5941 let touchAngle; 5942 5943 if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) { 5944 data.isScrolling = false; 5945 } else { 5946 // eslint-disable-next-line 5947 if (diffX * diffX + diffY * diffY >= 25) { 5948 touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI; 5949 data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle; 5950 } 5951 } 5952 } 5953 5954 if (data.isScrolling) { 5955 swiper.emit('touchMoveOpposite', e); 5956 } 5957 5958 if (typeof data.startMoving === 'undefined') { 5959 if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) { 5960 data.startMoving = true; 5961 } 5962 } 5963 5964 if (data.isScrolling) { 5965 data.isTouched = false; 5966 return; 5967 } 5968 5969 if (!data.startMoving) { 5970 return; 5971 } 5972 5973 swiper.allowClick = false; 5974 5975 if (!params.cssMode && e.cancelable) { 5976 e.preventDefault(); 5977 } 5978 5979 if (params.touchMoveStopPropagation && !params.nested) { 5980 e.stopPropagation(); 5981 } 5982 5983 if (!data.isMoved) { 5984 if (params.loop && !params.cssMode) { 5985 swiper.loopFix(); 5986 } 5987 5988 data.startTranslate = swiper.getTranslate(); 5989 swiper.setTransition(0); 5990 5991 if (swiper.animating) { 5992 swiper.$wrapperEl.trigger('webkitTransitionEnd transitionend'); 5993 } 5994 5995 data.allowMomentumBounce = false; // Grab Cursor 5996 5997 if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) { 5998 swiper.setGrabCursor(true); 5999 } 6000 6001 swiper.emit('sliderFirstMove', e); 6002 } 6003 6004 swiper.emit('sliderMove', e); 6005 data.isMoved = true; 6006 let diff = swiper.isHorizontal() ? diffX : diffY; 6007 touches.diff = diff; 6008 diff *= params.touchRatio; 6009 if (rtl) diff = -diff; 6010 swiper.swipeDirection = diff > 0 ? 'prev' : 'next'; 6011 data.currentTranslate = diff + data.startTranslate; 6012 let disableParentSwiper = true; 6013 let resistanceRatio = params.resistanceRatio; 6014 6015 if (params.touchReleaseOnEdges) { 6016 resistanceRatio = 0; 6017 } 6018 6019 if (diff > 0 && data.currentTranslate > swiper.minTranslate()) { 6020 disableParentSwiper = false;
vendor: 7,174 bytes, lines 6021-6245
6021 if (params.resistance) data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio; 6022 } else if (diff < 0 && data.currentTranslate < swiper.maxTranslate()) { 6023 disableParentSwiper = false; 6024 if (params.resistance) data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio; 6025 } 6026 6027 if (disableParentSwiper) { 6028 e.preventedByNestedSwiper = true; 6029 } // Directions locks 6030 6031 6032 if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) { 6033 data.currentTranslate = data.startTranslate; 6034 } 6035 6036 if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) { 6037 data.currentTranslate = data.startTranslate; 6038 } 6039 6040 if (!swiper.allowSlidePrev && !swiper.allowSlideNext) { 6041 data.currentTranslate = data.startTranslate; 6042 } // Threshold 6043 6044 6045 if (params.threshold > 0) { 6046 if (Math.abs(diff) > params.threshold || data.allowThresholdMove) { 6047 if (!data.allowThresholdMove) { 6048 data.allowThresholdMove = true; 6049 touches.startX = touches.currentX; 6050 touches.startY = touches.currentY; 6051 data.currentTranslate = data.startTranslate; 6052 touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY; 6053 return; 6054 } 6055 } else { 6056 data.currentTranslate = data.startTranslate; 6057 return; 6058 } 6059 } 6060 6061 if (!params.followFinger || params.cssMode) return; // Update active index in free mode 6062 6063 if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) { 6064 swiper.updateActiveIndex(); 6065 swiper.updateSlidesClasses(); 6066 } 6067 6068 if (swiper.params.freeMode && params.freeMode.enabled && swiper.freeMode) { 6069 swiper.freeMode.onTouchMove(); 6070 } // Update progress 6071 6072 6073 swiper.updateProgress(data.currentTranslate); // Update translate 6074 6075 swiper.setTranslate(data.currentTranslate); 6076 } 6077 6078 function onTouchEnd(event) { 6079 const swiper = this; 6080 const data = swiper.touchEventsData; 6081 const { 6082 params, 6083 touches, 6084 rtlTranslate: rtl, 6085 slidesGrid, 6086 enabled 6087 } = swiper; 6088 if (!enabled) return; 6089 let e = event; 6090 if (e.originalEvent) e = e.originalEvent; 6091 6092 if (data.allowTouchCallbacks) { 6093 swiper.emit('touchEnd', e); 6094 } 6095 6096 data.allowTouchCallbacks = false; 6097 6098 if (!data.isTouched) { 6099 if (data.isMoved && params.grabCursor) { 6100 swiper.setGrabCursor(false); 6101 } 6102 6103 data.isMoved = false; 6104 data.startMoving = false; 6105 return; 6106 } // Return Grab Cursor 6107 6108 6109 if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) { 6110 swiper.setGrabCursor(false); 6111 } // Time diff 6112 6113 6114 const touchEndTime = now(); 6115 const timeDiff = touchEndTime - data.touchStartTime; // Tap, doubleTap, Click 6116 6117 if (swiper.allowClick) { 6118 const pathTree = e.path || e.composedPath && e.composedPath(); 6119 swiper.updateClickedSlide(pathTree && pathTree[0] || e.target); 6120 swiper.emit('tap click', e); 6121 6122 if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) { 6123 swiper.emit('doubleTap doubleClick', e); 6124 } 6125 } 6126 6127 data.lastClickTime = now(); 6128 nextTick(() => { 6129 if (!swiper.destroyed) swiper.allowClick = true; 6130 }); 6131 6132 if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate === data.startTranslate) { 6133 data.isTouched = false; 6134 data.isMoved = false; 6135 data.startMoving = false; 6136 return; 6137 } 6138 6139 data.isTouched = false; 6140 data.isMoved = false; 6141 data.startMoving = false; 6142 let currentPos; 6143 6144 if (params.followFinger) { 6145 currentPos = rtl ? swiper.translate : -swiper.translate; 6146 } else { 6147 currentPos = -data.currentTranslate; 6148 } 6149 6150 if (params.cssMode) { 6151 return; 6152 } 6153 6154 if (swiper.params.freeMode && params.freeMode.enabled) { 6155 swiper.freeMode.onTouchEnd({ 6156 currentPos 6157 }); 6158 return; 6159 } // Find current slide 6160 6161 6162 let stopIndex = 0; 6163 let groupSize = swiper.slidesSizesGrid[0]; 6164 6165 for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) { 6166 const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup; 6167 6168 if (typeof slidesGrid[i + increment] !== 'undefined') { 6169 if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) { 6170 stopIndex = i; 6171 groupSize = slidesGrid[i + increment] - slidesGrid[i]; 6172 } 6173 } else if (currentPos >= slidesGrid[i]) { 6174 stopIndex = i; 6175 groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2]; 6176 } 6177 } 6178 6179 let rewindFirstIndex = null; 6180 let rewindLastIndex = null; 6181 6182 if (params.rewind) { 6183 if (swiper.isBeginning) { 6184 rewindLastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1; 6185 } else if (swiper.isEnd) { 6186 rewindFirstIndex = 0; 6187 } 6188 } // Find current slide size 6189 6190 6191 const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize; 6192 const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup; 6193 6194 if (timeDiff > params.longSwipesMs) { 6195 // Long touches 6196 if (!params.longSwipes) { 6197 swiper.slideTo(swiper.activeIndex); 6198 return; 6199 } 6200 6201 if (swiper.swipeDirection === 'next') { 6202 if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);else swiper.slideTo(stopIndex); 6203 } 6204 6205 if (swiper.swipeDirection === 'prev') { 6206 if (ratio > 1 - params.longSwipesRatio) { 6207 swiper.slideTo(stopIndex + increment); 6208 } else if (rewindLastIndex !== null && ratio < 0 && Math.abs(ratio) > params.longSwipesRatio) { 6209 swiper.slideTo(rewindLastIndex); 6210 } else { 6211 swiper.slideTo(stopIndex); 6212 } 6213 } 6214 } else { 6215 // Short swipes 6216 if (!params.shortSwipes) { 6217 swiper.slideTo(swiper.activeIndex); 6218 return; 6219 } 6220 6221 const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl); 6222 6223 if (!isNavButtonTarget) { 6224 if (swiper.swipeDirection === 'next') { 6225 swiper.slideTo(rewindFirstIndex !== null ? rewindFirstIndex : stopIndex + increment); 6226 } 6227 6228 if (swiper.swipeDirection === 'prev') { 6229 swiper.slideTo(rewindLastIndex !== null ? rewindLastIndex : stopIndex); 6230 } 6231 } else if (e.target === swiper.navigation.nextEl) { 6232 swiper.slideTo(stopIndex + increment); 6233 } else { 6234 swiper.slideTo(stopIndex); 6235 } 6236 } 6237 } 6238 6239 function onResize() { 6240 const swiper = this; 6241 const { 6242 params, 6243 el 6244 } = swiper; 6245 if (el && el.offsetWidth === 0) return;
vendor: 5,330 bytes, lines 6245-6439
6245 // Breakpoints 6246 6247 if (params.breakpoints) { 6248 swiper.setBreakpoint(); 6249 } // Save locks 6250 6251 6252 const { 6253 allowSlideNext, 6254 allowSlidePrev, 6255 snapGrid 6256 } = swiper; // Disable locks on resize 6257 6258 swiper.allowSlideNext = true; 6259 swiper.allowSlidePrev = true; 6260 swiper.updateSize(); 6261 swiper.updateSlides(); 6262 swiper.updateSlidesClasses(); 6263 6264 if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides) { 6265 swiper.slideTo(swiper.slides.length - 1, 0, false, true); 6266 } else { 6267 swiper.slideTo(swiper.activeIndex, 0, false, true); 6268 } 6269 6270 if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) { 6271 swiper.autoplay.run(); 6272 } // Return locks after resize 6273 6274 6275 swiper.allowSlidePrev = allowSlidePrev; 6276 swiper.allowSlideNext = allowSlideNext; 6277 6278 if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) { 6279 swiper.checkOverflow(); 6280 } 6281 } 6282 6283 function onClick(e) { 6284 const swiper = this; 6285 if (!swiper.enabled) return; 6286 6287 if (!swiper.allowClick) { 6288 if (swiper.params.preventClicks) e.preventDefault(); 6289 6290 if (swiper.params.preventClicksPropagation && swiper.animating) { 6291 e.stopPropagation(); 6292 e.stopImmediatePropagation(); 6293 } 6294 } 6295 } 6296 6297 function onScroll() { 6298 const swiper = this; 6299 const { 6300 wrapperEl, 6301 rtlTranslate, 6302 enabled 6303 } = swiper; 6304 if (!enabled) return; 6305 swiper.previousTranslate = swiper.translate; 6306 6307 if (swiper.isHorizontal()) { 6308 swiper.translate = -wrapperEl.scrollLeft; 6309 } else { 6310 swiper.translate = -wrapperEl.scrollTop; 6311 } // eslint-disable-next-line 6312 6313 6314 if (swiper.translate === 0) swiper.translate = 0; 6315 swiper.updateActiveIndex(); 6316 swiper.updateSlidesClasses(); 6317 let newProgress; 6318 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); 6319 6320 if (translatesDiff === 0) { 6321 newProgress = 0; 6322 } else { 6323 newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff; 6324 } 6325 6326 if (newProgress !== swiper.progress) { 6327 swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate); 6328 } 6329 6330 swiper.emit('setTranslate', swiper.translate, false); 6331 } 6332 6333 let dummyEventAttached = false; 6334 6335 function dummyEventListener() {} 6336 6337 const events = (swiper, method) => { 6338 const document = getDocument(); 6339 const { 6340 params, 6341 touchEvents, 6342 el, 6343 wrapperEl, 6344 device, 6345 support 6346 } = swiper; 6347 const capture = !!params.nested; 6348 const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener'; 6349 const swiperMethod = method; // Touch Events 6350 6351 if (!support.touch) { 6352 el[domMethod](touchEvents.start, swiper.onTouchStart, false); 6353 document[domMethod](touchEvents.move, swiper.onTouchMove, capture); 6354 document[domMethod](touchEvents.end, swiper.onTouchEnd, false); 6355 } else { 6356 const passiveListener = touchEvents.start === 'touchstart' && support.passiveListener && params.passiveListeners ? { 6357 passive: true, 6358 capture: false 6359 } : false; 6360 el[domMethod](touchEvents.start, swiper.onTouchStart, passiveListener); 6361 el[domMethod](touchEvents.move, swiper.onTouchMove, support.passiveListener ? { 6362 passive: false, 6363 capture 6364 } : capture); 6365 el[domMethod](touchEvents.end, swiper.onTouchEnd, passiveListener); 6366 6367 if (touchEvents.cancel) { 6368 el[domMethod](touchEvents.cancel, swiper.onTouchEnd, passiveListener); 6369 } 6370 } // Prevent Links Clicks 6371 6372 6373 if (params.preventClicks || params.preventClicksPropagation) { 6374 el[domMethod]('click', swiper.onClick, true); 6375 } 6376 6377 if (params.cssMode) { 6378 wrapperEl[domMethod]('scroll', swiper.onScroll); 6379 } // Resize handler 6380 6381 6382 if (params.updateOnWindowResize) { 6383 swiper[swiperMethod](device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize, true); 6384 } else { 6385 swiper[swiperMethod]('observerUpdate', onResize, true); 6386 } 6387 }; 6388 6389 function attachEvents() { 6390 const swiper = this; 6391 const document = getDocument(); 6392 const { 6393 params, 6394 support 6395 } = swiper; 6396 swiper.onTouchStart = onTouchStart.bind(swiper); 6397 swiper.onTouchMove = onTouchMove.bind(swiper); 6398 swiper.onTouchEnd = onTouchEnd.bind(swiper); 6399 6400 if (params.cssMode) { 6401 swiper.onScroll = onScroll.bind(swiper); 6402 } 6403 6404 swiper.onClick = onClick.bind(swiper); 6405 6406 if (support.touch && !dummyEventAttached) { 6407 document.addEventListener('touchstart', dummyEventListener); 6408 dummyEventAttached = true; 6409 } 6410 6411 events(swiper, 'on'); 6412 } 6413 6414 function detachEvents() { 6415 const swiper = this; 6416 events(swiper, 'off'); 6417 } 6418 6419 var events$1 = { 6420 attachEvents, 6421 detachEvents 6422 }; 6423 6424 const isGridEnabled = (swiper, params) => { 6425 return swiper.grid && params.grid && params.grid.rows > 1; 6426 }; 6427 6428 function setBreakpoint() { 6429 const swiper = this; 6430 const { 6431 activeIndex, 6432 initialized, 6433 loopedSlides = 0, 6434 params, 6435 $el 6436 } = swiper; 6437 const breakpoints = params.breakpoints; 6438 if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return; // Get breakpoint for window width and update parameters 6439
6440 const breakpoint = swiper.getBreakpoint(breakpoints, swiper.params.breakpointsBase, swiper.el); 6441 if (!breakpoint || swiper.currentBreakpoint === breakpoint) return; 6442 const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined; 6443 const breakpointParams = breakpointOnlyParams || swiper.originalParams; 6444 const wasMultiRow = isGridEnabled(swiper, params); 6445 const isMultiRow = isGridEnabled(swiper, breakpointParams); 6446 const wasEnabled = params.enabled; 6447 6448 if (wasMultiRow && !isMultiRow) { 6449 $el.removeClass(`${params.containerModifierClass}grid ${params.containerModifierClass}grid-column`); 6450 swiper.emitContainerClasses(); 6451 } else if (!wasMultiRow && isMultiRow) { 6452 $el.addClass(`${params.containerModifierClass}grid`); 6453 6454 if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') { 6455 $el.addClass(`${params.containerModifierClass}grid-column`); 6456 } 6457 6458 swiper.emitContainerClasses(); 6459 } // Toggle navigation, pagination, scrollbar 6460 6461 6462 ['navigation', 'pagination', 'scrollbar'].forEach(prop => { 6463 const wasModuleEnabled = params[prop] && params[prop].enabled; 6464 const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled; 6465 6466 if (wasModuleEnabled && !isModuleEnabled) { 6467 swiper[prop].disable(); 6468 } 6469 6470 if (!wasModuleEnabled && isModuleEnabled) { 6471 swiper[prop].enable(); 6472 } 6473 }); 6474 const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction; 6475 const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged); 6476 6477 if (directionChanged && initialized) { 6478 swiper.changeDirection(); 6479 } 6480 6481 extend(swiper.params, breakpointParams); 6482 const isEnabled = swiper.params.enabled; 6483 Object.assign(swiper, { 6484 allowTouchMove: swiper.params.allowTouchMove, 6485 allowSlideNext: swiper.params.allowSlideNext, 6486 allowSlidePrev: swiper.params.allowSlidePrev 6487 }); 6488 6489 if (wasEnabled && !isEnabled) { 6490 swiper.disable(); 6491 } else if (!wasEnabled && isEnabled) { 6492 swiper.enable(); 6493 } 6494 6495 swiper.currentBreakpoint = breakpoint; 6496 swiper.emit('_beforeBreakpoint', breakpointParams); 6497 6498 if (needsReLoop && initialized) { 6499 swiper.loopDestroy(); 6500 swiper.loopCreate(); 6501 swiper.updateSlides(); 6502 swiper.slideTo(activeIndex - loopedSlides + swiper.loopedSlides, 0, false); 6503 } 6504 6505 swiper.emit('breakpoint', breakpointParams); 6506 } 6507 6508 function getBreakpoint(breakpoints, base, containerEl) { 6509 if (base === void 0) { 6510 base = 'window'; 6511 } 6512 6513 if (!breakpoints || base === 'container' && !containerEl) return undefined; 6514 let breakpoint = false; 6515 const window = getWindow(); 6516 const currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight; 6517 const points = Object.keys(breakpoints).map(point => { 6518 if (typeof point === 'string' && point.indexOf('@') === 0) { 6519 const minRatio = parseFloat(point.substr(1)); 6520 const value = currentHeight * minRatio; 6521 return { 6522 value, 6523 point 6524 }; 6525 } 6526 6527 return { 6528 value: point, 6529 point 6530 }; 6531 }); 6532 points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10)); 6533 6534 for (let i = 0; i < points.length; i += 1) { 6535 const { 6536 point, 6537 value 6538 } = points[i]; 6539 6540 if (base === 'window') { 6541 if (window.matchMedia(`(min-width: ${value}px)`).matches) { 6542 breakpoint = point; 6543 } 6544 } else if (value <= containerEl.clientWidth) { 6545 breakpoint = point; 6546 } 6547 } 6548 6549 return breakpoint || 'max'; 6550 } 6551 6552 var breakpoints = { 6553 setBreakpoint, 6554 getBreakpoint 6555 }; 6556 6557 function prepareClasses(entries, prefix) { 6558 const resultClasses = []; 6559 entries.forEach(item => { 6560 if (typeof item === 'object') { 6561 Object.keys(item).forEach(classNames => { 6562 if (item[classNames]) { 6563 resultClasses.push(prefix + classNames); 6564 } 6565 }); 6566 } else if (typeof item === 'string') { 6567 resultClasses.push(prefix + item); 6568 } 6569 }); 6570 return resultClasses; 6571 } 6572 6573 function addClasses() { 6574 const swiper = this; 6575 const { 6576 classNames, 6577 params, 6578 rtl, 6579 $el, 6580 device, 6581 support 6582 } = swiper; // prettier-ignore 6583 6584 const suffixes = prepareClasses(['initialized', params.direction, { 6585 'pointer-events': !support.touch 6586 }, {
6587 'free-mode': swiper.params.freeMode && params.freeMode.enabled 6588 }, { 6589 'autoheight': params.autoHeight 6590 }, { 6591 'rtl': rtl 6592 }, { 6593 'grid': params.grid && params.grid.rows > 1 6594 }, { 6595 'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column' 6596 }, { 6597 'android': device.android 6598 }, { 6599 'ios': device.ios 6600 }, { 6601 'css-mode': params.cssMode 6602 }, { 6603 'centered': params.cssMode && params.centeredSlides 6604 }, { 6605 'watch-progress': params.watchSlidesProgress 6606 }], params.containerModifierClass); 6607 classNames.push(...suffixes); 6608 $el.addClass([...classNames].join(' ')); 6609 swiper.emitContainerClasses(); 6610 } 6611 6612 function removeClasses() { 6613 const swiper = this; 6614 const { 6615 $el, 6616 classNames 6617 } = swiper; 6618 $el.removeClass(classNames.join(' ')); 6619 swiper.emitContainerClasses(); 6620 } 6621 6622 var classes = { 6623 addClasses, 6624 removeClasses 6625 }; 6626 6627 function loadImage(imageEl, src, srcset, sizes, checkForComplete, callback) { 6628 const window = getWindow(); 6629 let image; 6630 6631 function onReady() { 6632 if (callback) callback(); 6633 } 6634 6635 const isPicture = $(imageEl).parent('picture')[0]; 6636 6637 if (!isPicture && (!imageEl.complete || !checkForComplete)) { 6638 if (src) { 6639 image = new window.Image(); 6640 image.onload = onReady; 6641 image.onerror = onReady; 6642 6643 if (sizes) { 6644 image.sizes = sizes; 6645 } 6646 6647 if (srcset) { 6648 image.srcset = srcset; 6649 } 6650 6651 if (src) { 6652 image.src = src; 6653 } 6654 } else { 6655 onReady(); 6656 } 6657 } else { 6658 // image already loaded... 6659 onReady(); 6660 } 6661 } 6662 6663 function preloadImages() { 6664 const swiper = this; 6665 swiper.imagesToLoad = swiper.$el.find('img'); 6666 6667 function onReady() { 6668 if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper.destroyed) return; 6669 if (swiper.imagesLoaded !== undefined) swiper.imagesLoaded += 1; 6670 6671 if (swiper.imagesLoaded === swiper.imagesToLoad.length) { 6672 if (swiper.params.updateOnImagesReady) swiper.update(); 6673 swiper.emit('imagesReady'); 6674 } 6675 } 6676 6677 for (let i = 0; i < swiper.imagesToLoad.length; i += 1) { 6678 const imageEl = swiper.imagesToLoad[i]; 6679 swiper.loadImage(imageEl, imageEl.currentSrc || imageEl.getAttribute('src'), imageEl.srcset || imageEl.getAttribute('srcset'), imageEl.sizes || imageEl.getAttribute('sizes'), true, onReady); 6680 } 6681 } 6682 6683 var images = { 6684 loadImage, 6685 preloadImages 6686 }; 6687 6688 function checkOverflow() { 6689 const swiper = this; 6690 const { 6691 isLocked: wasLocked, 6692 params 6693 } = swiper; 6694 const { 6695 slidesOffsetBefore 6696 } = params; 6697 6698 if (slidesOffsetBefore) { 6699 const lastSlideIndex = swiper.slides.length - 1; 6700 const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] + slidesOffsetBefore * 2; 6701 swiper.isLocked = swiper.size > lastSlideRightEdge; 6702 } else { 6703 swiper.isLocked = swiper.snapGrid.length === 1; 6704 } 6705 6706 if (params.allowSlideNext === true) { 6707 swiper.allowSlideNext = !swiper.isLocked; 6708 } 6709 6710 if (params.allowSlidePrev === true) { 6711 swiper.allowSlidePrev = !swiper.isLocked; 6712 } 6713 6714 if (wasLocked && wasLocked !== swiper.isLocked) { 6715 swiper.isEnd = false; 6716 } 6717 6718 if (wasLocked !== swiper.isLocked) { 6719 swiper.emit(swiper.isLocked ? 'lock' : 'unlock'); 6720 } 6721 } 6722 6723 var checkOverflow$1 = { 6724 checkOverflow 6725 }; 6726 6727 var defaults = { 6728 init: true, 6729 direction: 'horizontal', 6730 touchEventsTarget: 'wrapper', 6731 initialSlide: 0, 6732 speed: 300, 6733 cssMode: false, 6734 updateOnWindowResize: true, 6735 resizeObserver: true, 6736 nested: false, 6737 createElements: false, 6738 enabled: true, 6739 focusableElements: 'input, select, option, textarea, button, video, label', 6740 // Overrides 6741 width: null, 6742 height: null, 6743 // 6744 preventInteractionOnTransition: false, 6745 // ssr 6746 userAgent: null, 6747 url: null, 6748 // To support iOS's swipe-to-go-back gesture (when being used in-app). 6749 edgeSwipeDetection: false, 6750 edgeSwipeThreshold: 20, 6751 // Autoheight 6752 autoHeight: false, 6753 // Set wrapper width 6754 setWrapperSize: false, 6755 // Virtual Translate 6756 virtualTranslate: false, 6757 // Effects 6758 effect: 'slide', 6759 // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
6760 // Breakpoints 6761 breakpoints: undefined, 6762 breakpointsBase: 'window', 6763 // Slides grid 6764 spaceBetween: 0, 6765 slidesPerView: 1, 6766 slidesPerGroup: 1, 6767 slidesPerGroupSkip: 0, 6768 slidesPerGroupAuto: false, 6769 centeredSlides: false, 6770 centeredSlidesBounds: false, 6771 slidesOffsetBefore: 0, 6772 // in px 6773 slidesOffsetAfter: 0, 6774 // in px 6775 normalizeSlideIndex: true, 6776 centerInsufficientSlides: false, 6777 // Disable swiper and hide navigation when container not overflow 6778 watchOverflow: true, 6779 // Round length 6780 roundLengths: false, 6781 // Touches 6782 touchRatio: 1, 6783 touchAngle: 45, 6784 simulateTouch: true, 6785 shortSwipes: true, 6786 longSwipes: true, 6787 longSwipesRatio: 0.5, 6788 longSwipesMs: 300, 6789 followFinger: true, 6790 allowTouchMove: true, 6791 threshold: 0, 6792 touchMoveStopPropagation: false, 6793 touchStartPreventDefault: true, 6794 touchStartForcePreventDefault: false, 6795 touchReleaseOnEdges: false, 6796 // Unique Navigation Elements 6797 uniqueNavElements: true, 6798 // Resistance 6799 resistance: true, 6800 resistanceRatio: 0.85, 6801 // Progress 6802 watchSlidesProgress: false, 6803 // Cursor 6804 grabCursor: false, 6805 // Clicks 6806 preventClicks: true, 6807 preventClicksPropagation: true, 6808 slideToClickedSlide: false, 6809 // Images 6810 preloadImages: true, 6811 updateOnImagesReady: true, 6812 // loop 6813 loop: false, 6814 loopAdditionalSlides: 0, 6815 loopedSlides: null, 6816 loopedSlidesLimit: true, 6817 loopFillGroupWithBlank: false, 6818 loopPreventsSlide: true, 6819 // rewind 6820 rewind: false, 6821 // Swiping/no swiping 6822 allowSlidePrev: true, 6823 allowSlideNext: true, 6824 swipeHandler: null, 6825 // '.swipe-handler', 6826 noSwiping: true, 6827 noSwipingClass: 'swiper-no-swiping', 6828 noSwipingSelector: null, 6829 // Passive Listeners 6830 passiveListeners: true, 6831 maxBackfaceHiddenSlides: 10, 6832 // NS 6833 containerModifierClass: 'swiper-', 6834 // NEW 6835 slideClass: 'swiper-slide', 6836 slideBlankClass: 'swiper-slide-invisible-blank', 6837 slideActiveClass: 'swiper-slide-active', 6838 slideDuplicateActiveClass: 'swiper-slide-duplicate-active', 6839 slideVisibleClass: 'swiper-slide-visible', 6840 slideDuplicateClass: 'swiper-slide-duplicate', 6841 slideNextClass: 'swiper-slide-next', 6842 slideDuplicateNextClass: 'swiper-slide-duplicate-next', 6843 slidePrevClass: 'swiper-slide-prev', 6844 slideDuplicatePrevClass: 'swiper-slide-duplicate-prev', 6845 wrapperClass: 'swiper-wrapper', 6846 // Callbacks 6847 runCallbacksOnInit: true, 6848 // Internals 6849 _emitClasses: false 6850 }; 6851 6852 function moduleExtendParams(params, allModulesParams) { 6853 return function extendParams(obj) { 6854 if (obj === void 0) { 6855 obj = {}; 6856 } 6857 6858 const moduleParamName = Object.keys(obj)[0]; 6859 const moduleParams = obj[moduleParamName]; 6860 6861 if (typeof moduleParams !== 'object' || moduleParams === null) { 6862 extend(allModulesParams, obj); 6863 return; 6864 } 6865 6866 if (['navigation', 'pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] === true) { 6867 params[moduleParamName] = { 6868 auto: true 6869 }; 6870 } 6871 6872 if (!(moduleParamName in params && 'enabled' in moduleParams)) { 6873 extend(allModulesParams, obj); 6874 return; 6875 } 6876 6877 if (params[moduleParamName] === true) { 6878 params[moduleParamName] = { 6879 enabled: true 6880 }; 6881 } 6882 6883 if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) { 6884 params[moduleParamName].enabled = true; 6885 } 6886 6887 if (!params[moduleParamName]) params[moduleParamName] = { 6888 enabled: false 6889 }; 6890 extend(allModulesParams, obj); 6891 }; 6892 } 6893 6894 /* eslint no-param-reassign: "off" */ 6895 const prototypes = { 6896 eventsEmitter, 6897 update, 6898 translate, 6899 transition, 6900 slide, 6901 loop, 6902 grabCursor, 6903 events: events$1, 6904 breakpoints, 6905 checkOverflow: checkOverflow$1, 6906 classes, 6907 images 6908 }; 6909 const extendedDefaults = {}; 6910 6911 class Swiper { 6912 constructor() { 6913 let el; 6914 let params; 6915 6916 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 6917 args[_key] = arguments[_key]; 6918 } 6919
vendor: 11,062 bytes, lines 6920-7297
6920 if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') { 6921 params = args[0]; 6922 } else { 6923 [el, params] = args; 6924 } 6925 6926 if (!params) params = {}; 6927 params = extend({}, params); 6928 if (el && !params.el) params.el = el; 6929 6930 if (params.el && $(params.el).length > 1) { 6931 const swipers = []; 6932 $(params.el).each(containerEl => { 6933 const newParams = extend({}, params, { 6934 el: containerEl 6935 }); 6936 swipers.push(new Swiper(newParams)); 6937 }); // eslint-disable-next-line no-constructor-return 6938 6939 return swipers; 6940 } // Swiper Instance 6941 6942 6943 const swiper = this; 6944 swiper.__swiper__ = true; 6945 swiper.support = getSupport(); 6946 swiper.device = getDevice({ 6947 userAgent: params.userAgent 6948 }); 6949 swiper.browser = getBrowser(); 6950 swiper.eventsListeners = {}; 6951 swiper.eventsAnyListeners = []; 6952 swiper.modules = [...swiper.__modules__]; 6953 6954 if (params.modules && Array.isArray(params.modules)) { 6955 swiper.modules.push(...params.modules); 6956 } 6957 6958 const allModulesParams = {}; 6959 swiper.modules.forEach(mod => { 6960 mod({ 6961 swiper, 6962 extendParams: moduleExtendParams(params, allModulesParams), 6963 on: swiper.on.bind(swiper), 6964 once: swiper.once.bind(swiper), 6965 off: swiper.off.bind(swiper), 6966 emit: swiper.emit.bind(swiper) 6967 }); 6968 }); // Extend defaults with modules params 6969 6970 const swiperParams = extend({}, defaults, allModulesParams); // Extend defaults with passed params 6971 6972 swiper.params = extend({}, swiperParams, extendedDefaults, params); 6973 swiper.originalParams = extend({}, swiper.params); 6974 swiper.passedParams = extend({}, params); // add event listeners 6975 6976 if (swiper.params && swiper.params.on) { 6977 Object.keys(swiper.params.on).forEach(eventName => { 6978 swiper.on(eventName, swiper.params.on[eventName]); 6979 }); 6980 } 6981 6982 if (swiper.params && swiper.params.onAny) { 6983 swiper.onAny(swiper.params.onAny); 6984 } // Save Dom lib 6985 6986 6987 swiper.$ = $; // Extend Swiper 6988 6989 Object.assign(swiper, { 6990 enabled: swiper.params.enabled, 6991 el, 6992 // Classes 6993 classNames: [], 6994 // Slides 6995 slides: $(), 6996 slidesGrid: [], 6997 snapGrid: [], 6998 slidesSizesGrid: [], 6999 7000 // isDirection 7001 isHorizontal() { 7002 return swiper.params.direction === 'horizontal'; 7003 }, 7004 7005 isVertical() { 7006 return swiper.params.direction === 'vertical'; 7007 }, 7008 7009 // Indexes 7010 activeIndex: 0, 7011 realIndex: 0, 7012 // 7013 isBeginning: true, 7014 isEnd: false, 7015 // Props 7016 translate: 0, 7017 previousTranslate: 0, 7018 progress: 0, 7019 velocity: 0, 7020 animating: false, 7021 // Locks 7022 allowSlideNext: swiper.params.allowSlideNext, 7023 allowSlidePrev: swiper.params.allowSlidePrev, 7024 // Touch Events 7025 touchEvents: function touchEvents() { 7026 const touch = ['touchstart', 'touchmove', 'touchend', 'touchcancel']; 7027 const desktop = ['pointerdown', 'pointermove', 'pointerup']; 7028 swiper.touchEventsTouch = { 7029 start: touch[0], 7030 move: touch[1], 7031 end: touch[2], 7032 cancel: touch[3] 7033 }; 7034 swiper.touchEventsDesktop = { 7035 start: desktop[0], 7036 move: desktop[1], 7037 end: desktop[2] 7038 }; 7039 return swiper.support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch : swiper.touchEventsDesktop; 7040 }(), 7041 touchEventsData: { 7042 isTouched: undefined, 7043 isMoved: undefined, 7044 allowTouchCallbacks: undefined, 7045 touchStartTime: undefined, 7046 isScrolling: undefined, 7047 currentTranslate: undefined, 7048 startTranslate: undefined, 7049 allowThresholdMove: undefined, 7050 // Form elements to match 7051 focusableElements: swiper.params.focusableElements, 7052 // Last click time 7053 lastClickTime: now(), 7054 clickTimeout: undefined, 7055 // Velocities 7056 velocities: [], 7057 allowMomentumBounce: undefined, 7058 isTouchEvent: undefined, 7059 startMoving: undefined 7060 }, 7061 // Clicks 7062 allowClick: true, 7063 // Touches 7064 allowTouchMove: swiper.params.allowTouchMove, 7065 touches: { 7066 startX: 0, 7067 startY: 0, 7068 currentX: 0, 7069 currentY: 0, 7070 diff: 0 7071 }, 7072 // Images 7073 imagesToLoad: [], 7074 imagesLoaded: 0 7075 }); 7076 swiper.emit('_swiper'); // Init 7077 7078 if (swiper.params.init) { 7079 swiper.init(); 7080 } // Return app instance 7081 // eslint-disable-next-line no-constructor-return 7082 7083 7084 return swiper; 7085 } 7086 7087 enable() { 7088 const swiper = this; 7089 if (swiper.enabled) return; 7090 swiper.enabled = true; 7091 7092 if (swiper.params.grabCursor) { 7093 swiper.setGrabCursor(); 7094 } 7095 7096 swiper.emit('enable'); 7097 } 7098 7099 disable() { 7100 const swiper = this; 7101 if (!swiper.enabled) return; 7102 swiper.enabled = false; 7103 7104 if (swiper.params.grabCursor) { 7105 swiper.unsetGrabCursor(); 7106 } 7107 7108 swiper.emit('disable'); 7109 } 7110 7111 setProgress(progress, speed) { 7112 const swiper = this; 7113 progress = Math.min(Math.max(progress, 0), 1); 7114 const min = swiper.minTranslate(); 7115 const max = swiper.maxTranslate(); 7116 const current = (max - min) * progress + min; 7117 swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed); 7118 swiper.updateActiveIndex(); 7119 swiper.updateSlidesClasses(); 7120 } 7121 7122 emitContainerClasses() { 7123 const swiper = this; 7124 if (!swiper.params._emitClasses || !swiper.el) return; 7125 const cls = swiper.el.className.split(' ').filter(className => { 7126 return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0; 7127 }); 7128 swiper.emit('_containerClasses', cls.join(' ')); 7129 } 7130 7131 getSlideClasses(slideEl) { 7132 const swiper = this; 7133 if (swiper.destroyed) return ''; 7134 return slideEl.className.split(' ').filter(className => { 7135 return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0; 7136 }).join(' '); 7137 } 7138 7139 emitSlidesClasses() { 7140 const swiper = this; 7141 if (!swiper.params._emitClasses || !swiper.el) return; 7142 const updates = []; 7143 swiper.slides.each(slideEl => { 7144 const classNames = swiper.getSlideClasses(slideEl); 7145 updates.push({ 7146 slideEl, 7147 classNames 7148 }); 7149 swiper.emit('_slideClass', slideEl, classNames); 7150 }); 7151 swiper.emit('_slideClasses', updates); 7152 } 7153 7154 slidesPerViewDynamic(view, exact) { 7155 if (view === void 0) { 7156 view = 'current'; 7157 } 7158 7159 if (exact === void 0) { 7160 exact = false; 7161 } 7162 7163 const swiper = this; 7164 const { 7165 params, 7166 slides, 7167 slidesGrid, 7168 slidesSizesGrid, 7169 size: swiperSize, 7170 activeIndex 7171 } = swiper; 7172 let spv = 1; 7173 7174 if (params.centeredSlides) { 7175 let slideSize = slides[activeIndex].swiperSlideSize; 7176 let breakLoop; 7177 7178 for (let i = activeIndex + 1; i < slides.length; i += 1) { 7179 if (slides[i] && !breakLoop) { 7180 slideSize += slides[i].swiperSlideSize; 7181 spv += 1; 7182 if (slideSize > swiperSize) breakLoop = true; 7183 } 7184 } 7185 7186 for (let i = activeIndex - 1; i >= 0; i -= 1) { 7187 if (slides[i] && !breakLoop) { 7188 slideSize += slides[i].swiperSlideSize; 7189 spv += 1; 7190 if (slideSize > swiperSize) breakLoop = true; 7191 } 7192 } 7193 } else { 7194 // eslint-disable-next-line 7195 if (view === 'current') { 7196 for (let i = activeIndex + 1; i < slides.length; i += 1) { 7197 const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize; 7198 7199 if (slideInView) { 7200 spv += 1; 7201 } 7202 } 7203 } else { 7204 // previous 7205 for (let i = activeIndex - 1; i >= 0; i -= 1) { 7206 const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize; 7207 7208 if (slideInView) { 7209 spv += 1; 7210 } 7211 } 7212 } 7213 } 7214 7215 return spv; 7216 } 7217 7218 update() { 7219 const swiper = this; 7220 if (!swiper || swiper.destroyed) return; 7221 const { 7222 snapGrid, 7223 params 7224 } = swiper; // Breakpoints 7225 7226 if (params.breakpoints) { 7227 swiper.setBreakpoint(); 7228 } 7229 7230 swiper.updateSize(); 7231 swiper.updateSlides(); 7232 swiper.updateProgress(); 7233 swiper.updateSlidesClasses(); 7234 7235 function setTranslate() { 7236 const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate; 7237 const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate()); 7238 swiper.setTranslate(newTranslate); 7239 swiper.updateActiveIndex(); 7240 swiper.updateSlidesClasses(); 7241 } 7242 7243 let translated; 7244 7245 if (swiper.params.freeMode && swiper.params.freeMode.enabled) { 7246 setTranslate(); 7247 7248 if (swiper.params.autoHeight) { 7249 swiper.updateAutoHeight(); 7250 } 7251 } else { 7252 if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) { 7253 translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true); 7254 } else { 7255 translated = swiper.slideTo(swiper.activeIndex, 0, false, true); 7256 } 7257 7258 if (!translated) { 7259 setTranslate(); 7260 } 7261 } 7262 7263 if (params.watchOverflow && snapGrid !== swiper.snapGrid) { 7264 swiper.checkOverflow(); 7265 } 7266 7267 swiper.emit('update'); 7268 } 7269 7270 changeDirection(newDirection, needUpdate) { 7271 if (needUpdate === void 0) { 7272 needUpdate = true; 7273 } 7274 7275 const swiper = this; 7276 const currentDirection = swiper.params.direction; 7277 7278 if (!newDirection) { 7279 // eslint-disable-next-line 7280 newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal'; 7281 } 7282 7283 if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') { 7284 return swiper; 7285 } 7286 7287 swiper.$el.removeClass(`${swiper.params.containerModifierClass}${currentDirection}`).addClass(`${swiper.params.containerModifierClass}${newDirection}`); 7288 swiper.emitContainerClasses(); 7289 swiper.params.direction = newDirection; 7290 swiper.slides.each(slideEl => { 7291 if (newDirection === 'vertical') { 7292 slideEl.style.width = ''; 7293 } else { 7294 slideEl.style.height = ''; 7295 } 7296 }); 7297 swiper.emit('changeDirection');
7298 if (needUpdate) swiper.update(); 7299 return swiper; 7300 } 7301 7302 changeLanguageDirection(direction) { 7303 const swiper = this; 7304 if (swiper.rtl && direction === 'rtl' || !swiper.rtl && direction === 'ltr') return; 7305 swiper.rtl = direction === 'rtl'; 7306 swiper.rtlTranslate = swiper.params.direction === 'horizontal' && swiper.rtl; 7307 7308 if (swiper.rtl) { 7309 swiper.$el.addClass(`${swiper.params.containerModifierClass}rtl`); 7310 swiper.el.dir = 'rtl'; 7311 } else { 7312 swiper.$el.removeClass(`${swiper.params.containerModifierClass}rtl`); 7313 swiper.el.dir = 'ltr'; 7314 } 7315 7316 swiper.update(); 7317 } 7318 7319 mount(el) { 7320 const swiper = this; 7321 if (swiper.mounted) return true; // Find el 7322 7323 const $el = $(el || swiper.params.el); 7324 el = $el[0]; 7325 7326 if (!el) { 7327 return false; 7328 } 7329 7330 el.swiper = swiper; 7331 7332 const getWrapperSelector = () => { 7333 return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`; 7334 }; 7335 7336 const getWrapper = () => { 7337 if (el && el.shadowRoot && el.shadowRoot.querySelector) { 7338 const res = $(el.shadowRoot.querySelector(getWrapperSelector())); // Children needs to return slot items 7339 7340 res.children = options => $el.children(options); 7341 7342 return res; 7343 } 7344 7345 if (!$el.children) { 7346 return $($el).children(getWrapperSelector()); 7347 } 7348 7349 return $el.children(getWrapperSelector()); 7350 }; // Find Wrapper 7351 7352 7353 let $wrapperEl = getWrapper(); 7354 7355 if ($wrapperEl.length === 0 && swiper.params.createElements) { 7356 const document = getDocument(); 7357 const wrapper = document.createElement('div'); 7358 $wrapperEl = $(wrapper); 7359 wrapper.className = swiper.params.wrapperClass; 7360 $el.append(wrapper); 7361 $el.children(`.${swiper.params.slideClass}`).each(slideEl => { 7362 $wrapperEl.append(slideEl); 7363 }); 7364 } 7365 7366 Object.assign(swiper, { 7367 $el, 7368 el, 7369 $wrapperEl, 7370 wrapperEl: $wrapperEl[0], 7371 mounted: true, 7372 // RTL 7373 rtl: el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl', 7374 rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'), 7375 wrongRTL: $wrapperEl.css('display') === '-webkit-box' 7376 }); 7377 return true; 7378 } 7379 7380 init(el) { 7381 const swiper = this; 7382 if (swiper.initialized) return swiper; 7383 const mounted = swiper.mount(el); 7384 if (mounted === false) return swiper; 7385 swiper.emit('beforeInit'); // Set breakpoint 7386 7387 if (swiper.params.breakpoints) { 7388 swiper.setBreakpoint(); 7389 } // Add Classes 7390 7391 7392 swiper.addClasses(); // Create loop 7393 7394 if (swiper.params.loop) { 7395 swiper.loopCreate(); 7396 } // Update size 7397 7398 7399 swiper.updateSize(); // Update slides 7400 7401 swiper.updateSlides(); 7402 7403 if (swiper.params.watchOverflow) { 7404 swiper.checkOverflow(); 7405 } // Set Grab Cursor 7406 7407 7408 if (swiper.params.grabCursor && swiper.enabled) { 7409 swiper.setGrabCursor(); 7410 } 7411 7412 if (swiper.params.preloadImages) { 7413 swiper.preloadImages(); 7414 } // Slide To Initial Slide 7415 7416 7417 if (swiper.params.loop) { 7418 swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params.runCallbacksOnInit, false, true); 7419 } else { 7420 swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true); 7421 } // Attach events 7422 7423 7424 swiper.attachEvents(); // Init Flag 7425 7426 swiper.initialized = true; // Emit 7427 7428 swiper.emit('init'); 7429 swiper.emit('afterInit'); 7430 return swiper; 7431 } 7432 7433 destroy(deleteInstance, cleanStyles) { 7434 if (deleteInstance === void 0) { 7435 deleteInstance = true; 7436 } 7437 7438 if (cleanStyles === void 0) { 7439 cleanStyles = true; 7440 } 7441 7442 const swiper = this; 7443 const { 7444 params, 7445 $el, 7446 $wrapperEl, 7447 slides 7448 } = swiper; 7449 7450 if (typeof swiper.params === 'undefined' || swiper.destroyed) { 7451 return null; 7452 } 7453 7454 swiper.emit('beforeDestroy'); // Init Flag 7455 7456 swiper.initialized = false; // Detach events 7457 7458 swiper.detachEvents(); // Destroy loop 7459 7460 if (params.loop) { 7461 swiper.loopDestroy(); 7462 } // Cleanup styles 7463 7464 7465 if (cleanStyles) { 7466 swiper.removeClasses(); 7467 $el.removeAttr('style'); 7468 $wrapperEl.removeAttr('style'); 7469 7470 if (slides && slides.length) { 7471 slides.removeClass([params.slideVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass].join(' ')).removeAttr('style').removeAttr('data-swiper-slide-index'); 7472 } 7473 } 7474 7475 swiper.emit('destroy'); // Detach emitter events 7476
7477 Object.keys(swiper.eventsListeners).forEach(eventName => { 7478 swiper.off(eventName); 7479 }); 7480 7481 if (deleteInstance !== false) { 7482 swiper.$el[0].swiper = null; 7483 deleteProps(swiper); 7484 } 7485 7486 swiper.destroyed = true; 7487 return null; 7488 } 7489 7490 static extendDefaults(newDefaults) { 7491 extend(extendedDefaults, newDefaults); 7492 } 7493 7494 static get extendedDefaults() { 7495 return extendedDefaults; 7496 } 7497 7498 static get defaults() { 7499 return defaults; 7500 } 7501 7502 static installModule(mod) { 7503 if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = []; 7504 const modules = Swiper.prototype.__modules__; 7505 7506 if (typeof mod === 'function' && modules.indexOf(mod) < 0) { 7507 modules.push(mod); 7508 } 7509 } 7510 7511 static use(module) { 7512 if (Array.isArray(module)) { 7513 module.forEach(m => Swiper.installModule(m)); 7514 return Swiper; 7515 } 7516 7517 Swiper.installModule(module); 7518 return Swiper; 7519 } 7520 7521 } 7522 7523 Object.keys(prototypes).forEach(prototypeGroup => { 7524 Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => { 7525 Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod]; 7526 }); 7527 }); 7528 Swiper.use([Resize, Observer]); 7529 7530 function Virtual(_ref) { 7531 let { 7532 swiper, 7533 extendParams, 7534 on, 7535 emit 7536 } = _ref; 7537 extendParams({ 7538 virtual: { 7539 enabled: false, 7540 slides: [], 7541 cache: true, 7542 renderSlide: null, 7543 renderExternal: null, 7544 renderExternalUpdate: true, 7545 addSlidesBefore: 0, 7546 addSlidesAfter: 0 7547 } 7548 }); 7549 let cssModeTimeout; 7550 swiper.virtual = { 7551 cache: {}, 7552 from: undefined, 7553 to: undefined, 7554 slides: [], 7555 offset: 0, 7556 slidesGrid: [] 7557 }; 7558
7559 function renderSlide(slide, index) { 7560 const params = swiper.params.virtual; 7561 7562 if (params.cache && swiper.virtual.cache[index]) { 7563 return swiper.virtual.cache[index]; 7564 } 7565 7566 const $slideEl = params.renderSlide ? $(params.renderSlide.call(swiper, slide, index)) : $(`<div class="${swiper.params.slideClass}" data-swiper-slide-index="${index}">${slide}</div>`); 7567 if (!$slideEl.attr('data-swiper-slide-index')) $slideEl.attr('data-swiper-slide-index', index); 7568 if (params.cache) swiper.virtual.cache[index] = $slideEl; 7569 return $slideEl; 7570 } 7571 7572 function update(force) { 7573 const { 7574 slidesPerView, 7575 slidesPerGroup, 7576 centeredSlides 7577 } = swiper.params; 7578 const { 7579 addSlidesBefore, 7580 addSlidesAfter 7581 } = swiper.params.virtual; 7582 const { 7583 from: previousFrom, 7584 to: previousTo, 7585 slides, 7586 slidesGrid: previousSlidesGrid, 7587 offset: previousOffset 7588 } = swiper.virtual; 7589 7590 if (!swiper.params.cssMode) { 7591 swiper.updateActiveIndex(); 7592 } 7593 7594 const activeIndex = swiper.activeIndex || 0; 7595 let offsetProp; 7596 if (swiper.rtlTranslate) offsetProp = 'right';else offsetProp = swiper.isHorizontal() ? 'left' : 'top'; 7597 let slidesAfter; 7598 let slidesBefore; 7599 7600 if (centeredSlides) { 7601 slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter; 7602 slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore; 7603 } else { 7604 slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter; 7605 slidesBefore = slidesPerGroup + addSlidesBefore; 7606 } 7607 7608 const from = Math.max((activeIndex || 0) - slidesBefore, 0); 7609 const to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1); 7610 const offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0); 7611 Object.assign(swiper.virtual, { 7612 from, 7613 to, 7614 offset, 7615 slidesGrid: swiper.slidesGrid 7616 }); 7617 7618 function onRendered() { 7619 swiper.updateSlides(); 7620 swiper.updateProgress(); 7621 swiper.updateSlidesClasses(); 7622 7623 if (swiper.lazy && swiper.params.lazy.enabled) { 7624 swiper.lazy.load(); 7625 } 7626 7627 emit('virtualUpdate'); 7628 } 7629 7630 if (previousFrom === from && previousTo === to && !force) { 7631 if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) { 7632 swiper.slides.css(offsetProp, `${offset}px`); 7633 } 7634 7635 swiper.updateProgress(); 7636 emit('virtualUpdate'); 7637 return; 7638 } 7639 7640 if (swiper.params.virtual.renderExternal) { 7641 swiper.params.virtual.renderExternal.call(swiper, { 7642 offset, 7643 from, 7644 to, 7645 slides: function getSlides() { 7646 const slidesToRender = []; 7647 7648 for (let i = from; i <= to; i += 1) { 7649 slidesToRender.push(slides[i]); 7650 } 7651 7652 return slidesToRender; 7653 }() 7654 }); 7655 7656 if (swiper.params.virtual.renderExternalUpdate) { 7657 onRendered(); 7658 } else { 7659 emit('virtualUpdate'); 7660 } 7661 7662 return; 7663 } 7664 7665 const prependIndexes = []; 7666 const appendIndexes = []; 7667 7668 if (force) { 7669 swiper.$wrapperEl.find(`.${swiper.params.slideClass}`).remove(); 7670 } else { 7671 for (let i = previousFrom; i <= previousTo; i += 1) { 7672 if (i < from || i > to) { 7673 swiper.$wrapperEl.find(`.${swiper.params.slideClass}[data-swiper-slide-index="${i}"]`).remove(); 7674 } 7675 } 7676 } 7677 7678 for (let i = 0; i < slides.length; i += 1) { 7679 if (i >= from && i <= to) { 7680 if (typeof previousTo === 'undefined' || force) { 7681 appendIndexes.push(i); 7682 } else { 7683 if (i > previousTo) appendIndexes.push(i); 7684 if (i < previousFrom) prependIndexes.push(i); 7685 } 7686 } 7687 } 7688 7689 appendIndexes.forEach(index => { 7690 swiper.$wrapperEl.append(renderSlide(slides[index], index)); 7691 }); 7692 prependIndexes.sort((a, b) =>
7692 b - a).forEach(index => { 7693 swiper.$wrapperEl.prepend(renderSlide(slides[index], index)); 7694 }); 7695 swiper.$wrapperEl.children('.swiper-slide').css(offsetProp, `${offset}px`); 7696 onRendered(); 7697 } 7698 7699 function appendSlide(slides) { 7700 if (typeof slides === 'object' && 'length' in slides) { 7701 for (let i = 0; i < slides.length; i += 1) { 7702 if (slides[i]) swiper.virtual.slides.push(slides[i]); 7703 } 7704 } else { 7705 swiper.virtual.slides.push(slides); 7706 } 7707 7708 update(true); 7709 } 7710 7711 function prependSlide(slides) { 7712 const activeIndex = swiper.activeIndex; 7713 let newActiveIndex = activeIndex + 1; 7714 let numberOfNewSlides = 1; 7715 7716 if (Array.isArray(slides)) { 7717 for (let i = 0; i < slides.length; i += 1) { 7718 if (slides[i]) swiper.virtual.slides.unshift(slides[i]); 7719 } 7720 7721 newActiveIndex = activeIndex + slides.length; 7722 numberOfNewSlides = slides.length; 7723 } else { 7724 swiper.virtual.slides.unshift(slides); 7725 } 7726 7727 if (swiper.params.virtual.cache) { 7728 const cache = swiper.virtual.cache; 7729 const newCache = {}; 7730 Object.keys(cache).forEach(cachedIndex => { 7731 const $cachedEl = cache[cachedIndex]; 7732 const cachedElIndex = $cachedEl.attr('data-swiper-slide-index'); 7733 7734 if (cachedElIndex) { 7735 $cachedEl.attr('data-swiper-slide-index', parseInt(cachedElIndex, 10) + numberOfNewSlides); 7736 } 7737 7738 newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = $cachedEl; 7739 }); 7740 swiper.virtual.cache = newCache; 7741 } 7742 7743 update(true); 7744 swiper.slideTo(newActiveIndex, 0); 7745 } 7746 7747 function removeSlide(slidesIndexes) { 7748 if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return; 7749 let activeIndex = swiper.activeIndex; 7750 7751 if (Array.isArray(slidesIndexes)) { 7752 for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) { 7753 swiper.virtual.slides.splice(slidesIndexes[i], 1); 7754 7755 if (swiper.params.virtual.cache) { 7756 delete swiper.virtual.cache[slidesIndexes[i]]; 7757 } 7758 7759 if (slidesIndexes[i] < activeIndex) activeIndex -= 1; 7760 activeIndex = Math.max(activeIndex, 0); 7761 } 7762 } else { 7763 swiper.virtual.slides.splice(slidesIndexes, 1); 7764 7765 if (swiper.params.virtual.cache) { 7766 delete swiper.virtual.cache[slidesIndexes]; 7767 } 7768 7769 if (slidesIndexes < activeIndex) activeIndex -= 1; 7770 activeIndex = Math.max(activeIndex, 0); 7771 } 7772 7773 update(true); 7774 swiper.slideTo(activeIndex, 0); 7775 } 7776 7777 function removeAllSlides() { 7778 swiper.virtual.slides = []; 7779 7780 if (swiper.params.virtual.cache) { 7781 swiper.virtual.cache = {}; 7782 } 7783 7784 update(true); 7785 swiper.slideTo(0, 0); 7786 } 7787 7788 on('beforeInit', () => { 7789 if (!swiper.params.virtual.enabled) return; 7790 swiper.virtual.slides = swiper.params.virtual.slides; 7791 swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`); 7792 swiper.params.watchSlidesProgress = true; 7793 swiper.originalParams.watchSlidesProgress = true; 7794 7795 if (!swiper.params.initialSlide) { 7796 update(); 7797 } 7798 }); 7799 on('setTranslate', () => { 7800 if (!swiper.params.virtual.enabled) return; 7801 7802 if (swiper.params.cssMode && !swiper._immediateVirtual) { 7803 clearTimeout(cssModeTimeout); 7804 cssModeTimeout = setTimeout(() => { 7805 update(); 7806 }, 100); 7807 } else { 7808 update(); 7809 } 7810 }); 7811 on('init update resize', () => { 7812 if (!swiper.params.virtual.enabled) return; 7813 7814 if (swiper.params.cssMode) { 7815 setCSSProperty(swiper.wrapperEl, '--swiper-virtual-size', `${swiper.virtualSize}px`); 7816 } 7817 }); 7818 Object.assign(swiper.virtual, { 7819 appendSlide, 7820 prependSlide, 7821 removeSlide, 7822 removeAllSlides, 7823 update 7824 }); 7825 } 7826 7827 /* eslint-disable consistent-return */ 7828 function Keyboard(_ref) { 7829 let { 7830 swiper, 7831 extendParams, 7832 on, 7833 emit 7834 } = _ref; 7835 const document = getDocument(); 7836 const window = getWindow(); 7837 swiper.keyboard = { 7838 enabled: false 7839 }; 7840 extendParams({ 7841 keyboard: { 7842 enabled: false, 7843 onlyInViewport: true, 7844 pageUpDown: true 7845 } 7846 }); 7847 7848 function handle(event) { 7849 if (!swiper.enabled) return; 7850 const { 7851 rtlTranslate: rtl 7852 } = swiper; 7853 let e = event; 7854 if (e.originalEvent) e = e.originalEvent; // jquery fix 7855
vendor: 4,051 bytes, lines 7856-7971
7856 const kc = e.keyCode || e.charCode; 7857 const pageUpDown = swiper.params.keyboard.pageUpDown; 7858 const isPageUp = pageUpDown && kc === 33; 7859 const isPageDown = pageUpDown && kc === 34; 7860 const isArrowLeft = kc === 37; 7861 const isArrowRight = kc === 39; 7862 const isArrowUp = kc === 38; 7863 const isArrowDown = kc === 40; // Directions locks 7864 7865 if (!swiper.allowSlideNext && (swiper.isHorizontal() && isArrowRight || swiper.isVertical() && isArrowDown || isPageDown)) { 7866 return false; 7867 } 7868 7869 if (!swiper.allowSlidePrev && (swiper.isHorizontal() && isArrowLeft || swiper.isVertical() && isArrowUp || isPageUp)) { 7870 return false; 7871 } 7872 7873 if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { 7874 return undefined; 7875 } 7876 7877 if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) { 7878 return undefined; 7879 } 7880 7881 if (swiper.params.keyboard.onlyInViewport && (isPageUp || isPageDown || isArrowLeft || isArrowRight || isArrowUp || isArrowDown)) { 7882 let inView = false; // Check that swiper should be inside of visible area of window 7883 7884 if (swiper.$el.parents(`.${swiper.params.slideClass}`).length > 0 && swiper.$el.parents(`.${swiper.params.slideActiveClass}`).length === 0) { 7885 return undefined; 7886 } 7887 7888 const $el = swiper.$el; 7889 const swiperWidth = $el[0].clientWidth; 7890 const swiperHeight = $el[0].clientHeight; 7891 const windowWidth = window.innerWidth; 7892 const windowHeight = window.innerHeight; 7893 const swiperOffset = swiper.$el.offset(); 7894 if (rtl) swiperOffset.left -= swiper.$el[0].scrollLeft; 7895 const swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiperWidth, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiperHeight], [swiperOffset.left + swiperWidth, swiperOffset.top + swiperHeight]]; 7896 7897 for (let i = 0; i < swiperCoord.length; i += 1) { 7898 const point = swiperCoord[i]; 7899 7900 if (point[0] >= 0 && point[0] <= windowWidth && point[1] >= 0 && point[1] <= windowHeight) { 7901 if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line 7902 7903 inView = true; 7904 } 7905 } 7906 7907 if (!inView) return undefined; 7908 } 7909 7910 if (swiper.isHorizontal()) { 7911 if (isPageUp || isPageDown || isArrowLeft || isArrowRight) { 7912 if (e.preventDefault) e.preventDefault();else e.returnValue = false; 7913 } 7914 7915 if ((isPageDown || isArrowRight) && !rtl || (isPageUp || isArrowLeft) && rtl) swiper.slideNext(); 7916 if ((isPageUp || isArrowLeft) && !rtl || (isPageDown || isArrowRight) && rtl) swiper.slidePrev(); 7917 } else { 7918 if (isPageUp || isPageDown || isArrowUp || isArrowDown) { 7919 if (e.preventDefault) e.preventDefault();else e.returnValue = false; 7920 } 7921 7922 if (isPageDown || isArrowDown) swiper.slideNext(); 7923 if (isPageUp || isArrowUp) swiper.slidePrev(); 7924 } 7925 7926 emit('keyPress', kc); 7927 return undefined; 7928 } 7929 7930 function enable() { 7931 if (swiper.keyboard.enabled) return; 7932 $(document).on('keydown', handle); 7933 swiper.keyboard.enabled = true; 7934 } 7935 7936 function disable() { 7937 if (!swiper.keyboard.enabled) return; 7938 $(document).off('keydown', handle); 7939 swiper.keyboard.enabled = false; 7940 } 7941 7942 on('init', () => { 7943 if (swiper.params.keyboard.enabled) { 7944 enable(); 7945 } 7946 }); 7947 on('destroy', () => { 7948 if (swiper.keyboard.enabled) { 7949 disable(); 7950 } 7951 }); 7952 Object.assign(swiper.keyboard, { 7953 enable, 7954 disable 7955 }); 7956 } 7957 7958 /* eslint-disable consistent-return */ 7959 function Mousewheel(_ref) { 7960 let { 7961 swiper, 7962 extendParams, 7963 on, 7964 emit 7965 } = _ref; 7966 const window = getWindow(); 7967 extendParams({ 7968 mousewheel: { 7969 enabled: false, 7970 releaseOnEdges: false, 7971 invert: false,
vendor: 9,568 bytes, lines 7972-8258
7972 forceToAxis: false, 7973 sensitivity: 1, 7974 eventsTarget: 'container', 7975 thresholdDelta: null, 7976 thresholdTime: null 7977 } 7978 }); 7979 swiper.mousewheel = { 7980 enabled: false 7981 }; 7982 let timeout; 7983 let lastScrollTime = now(); 7984 let lastEventBeforeSnap; 7985 const recentWheelEvents = []; 7986 7987 function normalize(e) { 7988 // Reasonable defaults 7989 const PIXEL_STEP = 10; 7990 const LINE_HEIGHT = 40; 7991 const PAGE_HEIGHT = 800; 7992 let sX = 0; 7993 let sY = 0; // spinX, spinY 7994 7995 let pX = 0; 7996 let pY = 0; // pixelX, pixelY 7997 // Legacy 7998 7999 if ('detail' in e) { 8000 sY = e.detail; 8001 } 8002 8003 if ('wheelDelta' in e) { 8004 sY = -e.wheelDelta / 120; 8005 } 8006 8007 if ('wheelDeltaY' in e) { 8008 sY = -e.wheelDeltaY / 120; 8009 } 8010 8011 if ('wheelDeltaX' in e) { 8012 sX = -e.wheelDeltaX / 120; 8013 } // side scrolling on FF with DOMMouseScroll 8014 8015 8016 if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) { 8017 sX = sY; 8018 sY = 0; 8019 } 8020 8021 pX = sX * PIXEL_STEP; 8022 pY = sY * PIXEL_STEP; 8023 8024 if ('deltaY' in e) { 8025 pY = e.deltaY; 8026 } 8027 8028 if ('deltaX' in e) { 8029 pX = e.deltaX; 8030 } 8031 8032 if (e.shiftKey && !pX) { 8033 // if user scrolls with shift he wants horizontal scroll 8034 pX = pY; 8035 pY = 0; 8036 } 8037 8038 if ((pX || pY) && e.deltaMode) { 8039 if (e.deltaMode === 1) { 8040 // delta in LINE units 8041 pX *= LINE_HEIGHT; 8042 pY *= LINE_HEIGHT; 8043 } else { 8044 // delta in PAGE units 8045 pX *= PAGE_HEIGHT; 8046 pY *= PAGE_HEIGHT; 8047 } 8048 } // Fall-back if spin cannot be determined 8049 8050 8051 if (pX && !sX) { 8052 sX = pX < 1 ? -1 : 1; 8053 } 8054 8055 if (pY && !sY) { 8056 sY = pY < 1 ? -1 : 1; 8057 } 8058 8059 return { 8060 spinX: sX, 8061 spinY: sY, 8062 pixelX: pX, 8063 pixelY: pY 8064 }; 8065 } 8066 8067 function handleMouseEnter() { 8068 if (!swiper.enabled) return; 8069 swiper.mouseEntered = true; 8070 } 8071 8072 function handleMouseLeave() { 8073 if (!swiper.enabled) return; 8074 swiper.mouseEntered = false; 8075 } 8076 8077 function animateSlider(newEvent) { 8078 if (swiper.params.mousewheel.thresholdDelta && newEvent.delta < swiper.params.mousewheel.thresholdDelta) { 8079 // Prevent if delta of wheel scroll delta is below configured threshold 8080 return false; 8081 } 8082 8083 if (swiper.params.mousewheel.thresholdTime && now() - lastScrollTime < swiper.params.mousewheel.thresholdTime) { 8084 // Prevent if time between scrolls is below configured threshold 8085 return false; 8086 } // If the movement is NOT big enough and 8087 // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider): 8088 // Don't go any further (avoid insignificant scroll movement). 8089 8090 8091 if (newEvent.delta >= 6 && now() - lastScrollTime < 60) { 8092 // Return false as a default 8093 return true; 8094 } // If user is scrolling towards the end: 8095 // If the slider hasn't hit the latest slide or 8096 // if the slider is a loop and 8097 // if the slider isn't moving right now: 8098 // Go to next slide and 8099 // emit a scroll event. 8100 // Else (the user is scrolling towards the beginning) and 8101 // if the slider hasn't hit the first slide or 8102 // if the slider is a loop and 8103 // if the slider isn't moving right now: 8104 // Go to prev slide and 8105 // emit a scroll event. 8106 8107 8108 if (newEvent.direction < 0) { 8109 if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) { 8110 swiper.slideNext(); 8111 emit('scroll', newEvent.raw); 8112 } 8113 } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) { 8114 swiper.slidePrev(); 8115 emit('scroll', newEvent.raw); 8116 } // If you got here is because an animation has been triggered so store the current time 8117 8118 8119 lastScrollTime = new window.Date().getTime(); // Return false as a default 8120 8121 return false; 8122 } 8123 8124 function releaseScroll(newEvent) { 8125 const params = swiper.params.mousewheel; 8126 8127 if (newEvent.direction < 0) { 8128 if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) { 8129 // Return true to animate scroll on edges 8130 return true; 8131 } 8132 } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) { 8133 // Return true to animate scroll on edges 8134 return true; 8135 } 8136 8137 return false; 8138 } 8139 8140 function handle(event) { 8141 let e = event; 8142 let disableParentSwiper = true; 8143 if (!swiper.enabled) return; 8144 const params = swiper.params.mousewheel; 8145 8146 if (swiper.params.cssMode) { 8147 e.preventDefault(); 8148 } 8149 8150 let target = swiper.$el; 8151 8152 if (swiper.params.mousewheel.eventsTarget !== 'container') { 8153 target = $(swiper.params.mousewheel.eventsTarget); 8154 } 8155 8156 if (!swiper.mouseEntered && !target[0].contains(e.target) && !params.releaseOnEdges) return true; 8157 if (e.originalEvent) e = e.originalEvent; // jquery fix 8158 8159 let delta = 0; 8160 const rtlFactor = swiper.rtlTranslate ? -1 : 1; 8161 const data = normalize(e); 8162 8163 if (params.forceToAxis) { 8164 if (swiper.isHorizontal()) { 8165 if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = -data.pixelX * rtlFactor;else return true; 8166 } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = -data.pixelY;else return true; 8167 } else { 8168 delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY; 8169 } 8170 8171 if (delta === 0) return true; 8172 if (params.invert) delta = -delta; // Get the scroll positions 8173 8174 let positions = swiper.getTranslate() + delta * params.sensitivity; 8175 if (positions >= swiper.minTranslate()) positions = swiper.minTranslate(); 8176 if (positions <= swiper.maxTranslate()) positions = swiper.maxTranslate(); // When loop is true: 8177 // the disableParentSwiper will be true. 8178 // When loop is false: 8179 // if the scroll positions is not on edge, 8180 // then the disableParentSwiper will be true. 8181 // if the scroll on edge positions, 8182 // then the disableParentSwiper will be false. 8183 8184 disableParentSwiper = swiper.params.loop ? true : !(positions === swiper.minTranslate() || positions === swiper.maxTranslate()); 8185 if (disableParentSwiper && swiper.params.nested) e.stopPropagation(); 8186 8187 if (!swiper.params.freeMode || !swiper.params.freeMode.enabled) { 8188 // Register the new event in a variable which stores the relevant data 8189 const newEvent = { 8190 time: now(), 8191 delta: Math.abs(delta), 8192 direction: Math.sign(delta), 8193 raw: event 8194 }; // Keep the most recent events 8195 8196 if (recentWheelEvents.length >= 2) { 8197 recentWheelEvents.shift(); // only store the last N events 8198 } 8199 8200 const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined; 8201 recentWheelEvents.push(newEvent); // If there is at least one previous recorded event: 8202 // If direction has changed or 8203 // if the scroll is quicker than the previous one: 8204 // Animate the slider. 8205 // Else (this is the first time the wheel is moved): 8206 // Animate the slider. 8207 8208 if (prevEvent) { 8209 if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) { 8210 animateSlider(newEvent); 8211 } 8212 } else { 8213 animateSlider(newEvent); 8214 } // If it's time to release the scroll: 8215 // Return now so you don't hit the preventDefault. 8216 8217 8218 if (releaseScroll(newEvent)) { 8219 return true; 8220 } 8221 } else { 8222 // Freemode or scrollContainer: 8223 // If we recently snapped after a momentum scroll, then ignore wheel events 8224 // to give time for the deceleration to finish. Stop ignoring after 500 msecs 8225 // or if it's a new scroll (larger delta or inverse sign as last event before 8226 // an end-of-momentum snap). 8227 const newEvent = { 8228 time: now(), 8229 delta: Math.abs(delta), 8230 direction: Math.sign(delta) 8231 }; 8232 const ignoreWheelEvents = lastEventBeforeSnap && newEvent.time < lastEventBeforeSnap.time + 500 && newEvent.delta <= lastEventBeforeSnap.delta && newEvent.direction === lastEventBeforeSnap.direction; 8233 8234 if (!ignoreWheelEvents) { 8235 lastEventBeforeSnap = undefined; 8236 8237 if (swiper.params.loop) { 8238 swiper.loopFix(); 8239 } 8240 8241 let position = swiper.getTranslate() + delta * params.sensitivity; 8242 const wasBeginning = swiper.isBeginning; 8243 const wasEnd = swiper.isEnd; 8244 if (position >= swiper.minTranslate()) position = swiper.minTranslate(); 8245 if (position <= swiper.maxTranslate()) position = swiper.maxTranslate(); 8246 swiper.setTransition(0); 8247 swiper.setTranslate(position); 8248 swiper.updateProgress(); 8249 swiper.updateActiveIndex(); 8250 swiper.updateSlidesClasses(); 8251 8252 if (!wasBeginning && swiper.isBeginning || !wasEnd && swiper.isEnd) { 8253 swiper.updateSlidesClasses(); 8254 } 8255 8256 if (swiper.params.freeMode.sticky) { 8257 // When wheel scrolling starts with sticky (aka snap) enabled, then detect 8258 // the end of a momentum scroll by storing recent (N=15?) wheel events.
8259 // 1. do all N events have decreasing or same (absolute value) delta? 8260 // 2. did all N events arrive in the last M (M=500?) msecs? 8261 // 3. does the earliest event have an (absolute value) delta that's 8262 // at least P (P=1?) larger than the most recent event's delta? 8263 // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels? 8264 // If 1-4 are "yes" then we're near the end of a momentum scroll deceleration. 8265 // Snap immediately and ignore remaining wheel events in this scroll. 8266 // See comment above for "remaining wheel events in this scroll" determination. 8267 // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event. 8268 clearTimeout(timeout); 8269 timeout = undefined; 8270 8271 if (recentWheelEvents.length >= 15) { 8272 recentWheelEvents.shift(); // only store the last N events 8273 } 8274 8275 const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined; 8276 const firstEvent = recentWheelEvents[0]; 8277 recentWheelEvents.push(newEvent); 8278 8279 if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) { 8280 // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log. 8281 recentWheelEvents.splice(0); 8282 } else if (recentWheelEvents.length >= 15 && newEvent.time - firstEvent.time < 500 && firstEvent.delta - newEvent.delta >= 1 && newEvent.delta <= 6) { 8283 // We're at the end of the deceleration of a momentum scroll, so there's no need 8284 // to wait for more events. Snap ASAP on the next tick. 8285 // Also, because there's some remaining momentum we'll bias the snap in the 8286 // direction of the ongoing scroll because it's better UX for the scroll to snap 8287 // in the same direction as the scroll instead of reversing to snap. Therefore, 8288 // if it's already scrolled more than 20% in the current direction, keep going. 8289 const snapToThreshold = delta > 0 ? 0.8 : 0.2; 8290 lastEventBeforeSnap = newEvent; 8291 recentWheelEvents.splice(0); 8292 timeout = nextTick(() => { 8293 swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold); 8294 }, 0); // no delay; move on next tick 8295 } 8296 8297 if (!timeout) { 8298 // if we get here, then we haven't detected the end of a momentum scroll, so 8299 // we'll consider a scroll "complete" when there haven't been any wheel events 8300 // for 500ms. 8301 timeout = nextTick(() => { 8302 const snapToThreshold = 0.5; 8303 lastEventBeforeSnap = newEvent; 8304 recentWheelEvents.splice(0); 8305 swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold); 8306 }, 500); 8307 } 8308 } // Emit event 8309 8310 8311 if (!ignoreWheelEvents) emit('scroll', e); // Stop autoplay 8312 8313 if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop(); // Return page scroll on edge positions 8314 8315 if (position === swiper.minTranslate() || position === swiper.maxTranslate()) return true; 8316 } 8317 } 8318 8319 if (e.preventDefault) e.preventDefault();else e.returnValue = false; 8320 return false; 8321 } 8322 8323 function events(method) { 8324 let target = swiper.$el; 8325 8326 if (swiper.params.mousewheel.eventsTarget !== 'container') { 8327 target = $(swiper.params.mousewheel.eventsTarget); 8328 } 8329 8330 target[method]('mouseenter', handleMouseEnter); 8331 target[method]('mouseleave', handleMouseLeave); 8332 target[method]('wheel', handle); 8333 } 8334 8335 function enable() { 8336 if (swiper.params.cssMode) { 8337 swiper.wrapperEl.removeEventListener('wheel', handle); 8338 return true; 8339 } 8340 8341 if (swiper.mousewheel.enabled) return false; 8342 events('on'); 8343 swiper.mousewheel.enabled = true; 8344 return true; 8345 } 8346 8347 function disable() { 8348 if (swiper.params.cssMode) { 8349 swiper.wrapperEl.addEventListener(event, handle); 8350 return true; 8351 } 8352 8353 if (!swiper.mousewheel.enabled) return false;
8354 events('off'); 8355 swiper.mousewheel.enabled = false; 8356 return true; 8357 } 8358 8359 on('init', () => { 8360 if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) { 8361 disable(); 8362 } 8363 8364 if (swiper.params.mousewheel.enabled) enable(); 8365 }); 8366 on('destroy', () => { 8367 if (swiper.params.cssMode) { 8368 enable(); 8369 } 8370 8371 if (swiper.mousewheel.enabled) disable(); 8372 }); 8373 Object.assign(swiper.mousewheel, { 8374 enable, 8375 disable 8376 }); 8377 } 8378 8379 function createElementIfNotDefined(swiper, originalParams, params, checkProps) { 8380 const document = getDocument(); 8381 8382 if (swiper.params.createElements) { 8383 Object.keys(checkProps).forEach(key => { 8384 if (!params[key] && params.auto === true) { 8385 let element = swiper.$el.children(`.${checkProps[key]}`)[0]; 8386 8387 if (!element) { 8388 element = document.createElement('div'); 8389 element.className = checkProps[key]; 8390 swiper.$el.append(element); 8391 } 8392 8393 params[key] = element; 8394 originalParams[key] = element; 8395 } 8396 }); 8397 } 8398 8399 return params; 8400 } 8401 8402 function Navigation(_ref) { 8403 let { 8404 swiper, 8405 extendParams, 8406 on, 8407 emit 8408 } = _ref; 8409 extendParams({ 8410 navigation: { 8411 nextEl: null, 8412 prevEl: null, 8413 hideOnClick: false, 8414 disabledClass: 'swiper-button-disabled', 8415 hiddenClass: 'swiper-button-hidden', 8416 lockClass: 'swiper-button-lock', 8417 navigationDisabledClass: 'swiper-navigation-disabled' 8418 } 8419 }); 8420 swiper.navigation = { 8421 nextEl: null, 8422 $nextEl: null, 8423 prevEl: null, 8424 $prevEl: null 8425 }; 8426 8427 function getEl(el) { 8428 let $el; 8429 8430 if (el) { 8431 $el = $(el); 8432 8433 if (swiper.params.uniqueNavElements && typeof el === 'string' && $el.length > 1 && swiper.$el.find(el).length === 1) { 8434 $el = swiper.$el.find(el); 8435 } 8436 } 8437 8438 return $el; 8439 } 8440 8441 function toggleEl($el, disabled) { 8442 const params = swiper.params.navigation; 8443 8444 if ($el && $el.length > 0) { 8445 $el[disabled ? 'addClass' : 'removeClass'](params.disabledClass); 8446 if ($el[0] && $el[0].tagName === 'BUTTON') $el[0].disabled = disabled; 8447 8448 if (swiper.params.watchOverflow && swiper.enabled) { 8449 $el[swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass); 8450 } 8451 } 8452 } 8453 8454 function update() { 8455 // Update Navigation Buttons 8456 if (swiper.params.loop) return; 8457 const { 8458 $nextEl, 8459 $prevEl 8460 } = swiper.navigation; 8461 toggleEl($prevEl, swiper.isBeginning && !swiper.params.rewind); 8462 toggleEl($nextEl, swiper.isEnd && !swiper.params.rewind); 8463 } 8464 8465 function onPrevClick(e) { 8466 e.preventDefault(); 8467 if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return; 8468 swiper.slidePrev(); 8469 emit('navigationPrev'); 8470 } 8471 8472 function onNextClick(e) { 8473 e.preventDefault(); 8474 if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return; 8475 swiper.slideNext(); 8476 emit('navigationNext'); 8477 } 8478 8479 function init() { 8480 const params = swiper.params.navigation; 8481 swiper.params.navigation = createElementIfNotDefined(swiper, swiper.originalParams.navigation, swiper.params.navigation, { 8482 nextEl: 'swiper-button-next', 8483 prevEl: 'swiper-button-prev' 8484 }); 8485 if (!(params.nextEl || params.prevEl)) return; 8486 const $nextEl = getEl(params.nextEl); 8487 const $prevEl = getEl(params.prevEl); 8488 8489 if ($nextEl && $nextEl.length > 0) { 8490 $nextEl.on('click', onNextClick); 8491 } 8492 8493 if ($prevEl && $prevEl.length > 0) { 8494 $prevEl.on('click', onPrevClick); 8495 } 8496 8497 Object.assign(swiper.navigation, { 8498 $nextEl, 8499 nextEl: $nextEl && $nextEl[0], 8500 $prevEl, 8501 prevEl: $prevEl && $prevEl[0] 8502 }); 8503 8504 if (!swiper.enabled) { 8505 if ($nextEl) $nextEl.addClass(params.lockClass); 8506 if ($prevEl) $prevEl.addClass(params.lockClass); 8507 } 8508 } 8509 8510 function destroy() { 8511 const { 8512 $nextEl, 8513 $prevEl 8514 } = swiper.navigation; 8515 8516 if ($nextEl && $nextEl.length) { 8517 $nextEl.off('click', onNextClick); 8518 $nextEl.removeClass(swiper.params.navigation.disabledClass); 8519 } 8520 8521 if ($prevEl && $prevEl.length) { 8522 $prevEl.off('click', onPrevClick); 8523 $prevEl.removeClass(swiper.params.navigation.disabledClass); 8524 } 8525 } 8526 8527 on('init', () => { 8528 if (swiper.params.navigation.enabled === false) { 8529 // eslint-disable-next-line 8530 disable(); 8531 } else { 8532 init(); 8533 update(); 8534 } 8535 }); 8536 on('toEdge fromEdge lock unlock', () => { 8537 update(); 8538 }); 8539 on('destroy', () => { 8540 destroy(); 8541 }); 8542 on('enable disable', () => { 8543 const { 8544 $nextEl, 8545 $prevEl 8546 } = swiper.navigation; 8547 8548 if ($nextEl) { 8549 $nextEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass); 8550 } 8551 8552 if ($prevEl) { 8553 $prevEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass); 8554 } 8555 }); 8556 on('click', (_s, e) => { 8557 const { 8558 $nextEl, 8559 $prevEl 8560 } = swiper.navigation; 8561 const targetEl = e.target; 8562 8563 if (swiper.params.navigation.hideOnClick && !$(targetEl).is($prevEl) && !$(targetEl).is($nextEl)) { 8564 if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return; 8565 let isHidden; 8566 8567 if ($nextEl) { 8568 isHidden = $nextEl.hasClass(swiper.params.navigation.hiddenClass); 8569 } else if ($prevEl) { 8570 isHidden = $prevEl.hasClass(swiper.params.navigation.hiddenClass); 8571 } 8572 8573 if (isHidden === true) { 8574 emit('navigationShow'); 8575 } else { 8576 emit('navigationHide'); 8577 } 8578 8579 if ($nextEl) { 8580 $nextEl.toggleClass(swiper.params.navigation.hiddenClass); 8581 } 8582 8583 if ($prevEl) { 8584 $prevEl.toggleClass(swiper.params.navigation.hiddenClass); 8585 } 8586 } 8587 }); 8588 8589 const enable = () => { 8590 swiper.$el.removeClass(swiper.params.navigation.navigationDisabledClass); 8591 init(); 8592 update(); 8593 }; 8594 8595 const disable = () => { 8596 swiper.$el.addClass(swiper.params.navigation.navigationDisabledClass); 8597 destroy(); 8598 }; 8599 8600 Object.assign(swiper.navigation, { 8601 enable, 8602 disable, 8603 update, 8604 init, 8605 destroy 8606 }); 8607 } 8608 8609 function classesToSelector(classes) { 8610 if (classes === void 0) { 8611 classes = ''; 8612 } 8613 8614 return `.${classes.trim().replace(/([\.:!\/])/g, '\\$1') // eslint-disable-line 8615.replace(/ /g, '.')}`; 8616 } 8617 8618 function Pagination(_ref) { 8619 let { 8620 swiper, 8621 extendParams, 8622 on, 8623 emit 8624 } = _ref; 8625 const pfx = 'swiper-pagination'; 8626 extendParams({ 8627 pagination: { 8628 el: null, 8629 bulletElement: 'span', 8630 clickable: false, 8631 hideOnClick: false, 8632 renderBullet: null, 8633 renderProgressbar: null, 8634 renderFraction: null, 8635 renderCustom: null, 8636 progressbarOpposite: false, 8637 type: 'bullets', 8638 // 'bullets' or 'progressbar' or 'fraction' or 'custom' 8639 dynamicBullets: false, 8640 dynamicMainBullets: 1, 8641 formatFractionCurrent: number => number, 8642 formatFractionTotal: number => number, 8643 bulletClass: `${pfx}-bullet`, 8644 bulletActiveClass: `${pfx}-bullet-active`, 8645 modifierClass: `${pfx}-`, 8646 currentClass: `${pfx}-current`, 8647 totalClass: `${pfx}-total`, 8648 hiddenClass: `${pfx}-hidden`, 8649 progressbarFillClass: `${pfx}-progressbar-fill`, 8650 progressbarOppositeClass: `${pfx}-progressbar-opposite`, 8651 clickableClass: `${pfx}-clickable`, 8652 lockClass: `${pfx}-lock`, 8653 horizontalClass: `${pfx}-horizontal`, 8654 verticalClass: `${pfx}-vertical`, 8655 paginationDisabledClass: `${pfx}-disabled` 8656 } 8657 }); 8658 swiper.pagination = { 8659 el: null, 8660 $el: null, 8661 bullets: [] 8662 }; 8663 let bulletSize; 8664 let dynamicBulletIndex = 0; 8665 8666 function isPaginationDisabled() { 8667 return !swiper.params.pagination.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0; 8668 } 8669 8670 function setSideBullets($bulletEl, position) { 8671 const { 8672 bulletActiveClass 8673 } = swiper.params.pagination; 8674 $bulletEl[position]().addClass(`${bulletActiveClass}-${position}`)[position]().addClass(`${bulletActiveClass}-${position}-${position}`); 8675 } 8676
vendor: 5,685 bytes, lines 8677-8817
8677 function update() { 8678 // Render || Update Pagination bullets/items 8679 const rtl = swiper.rtl; 8680 const params = swiper.params.pagination; 8681 if (isPaginationDisabled()) return; 8682 const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length; 8683 const $el = swiper.pagination.$el; // Current/Total 8684 8685 let current; 8686 const total = swiper.params.loop ? Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) : swiper.snapGrid.length; 8687 8688 if (swiper.params.loop) { 8689 current = Math.ceil((swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup); 8690 8691 if (current > slidesLength - 1 - swiper.loopedSlides * 2) { 8692 current -= slidesLength - swiper.loopedSlides * 2; 8693 } 8694 8695 if (current > total - 1) current -= total; 8696 if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current; 8697 } else if (typeof swiper.snapIndex !== 'undefined') { 8698 current = swiper.snapIndex; 8699 } else { 8700 current = swiper.activeIndex || 0; 8701 } // Types 8702 8703 8704 if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) { 8705 const bullets = swiper.pagination.bullets; 8706 let firstIndex; 8707 let lastIndex; 8708 let midIndex; 8709 8710 if (params.dynamicBullets) { 8711 bulletSize = bullets.eq(0)[swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'](true); 8712 $el.css(swiper.isHorizontal() ? 'width' : 'height', `${bulletSize * (params.dynamicMainBullets + 4)}px`); 8713 8714 if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) { 8715 dynamicBulletIndex += current - (swiper.previousIndex - swiper.loopedSlides || 0); 8716 8717 if (dynamicBulletIndex > params.dynamicMainBullets - 1) { 8718 dynamicBulletIndex = params.dynamicMainBullets - 1; 8719 } else if (dynamicBulletIndex < 0) { 8720 dynamicBulletIndex = 0; 8721 } 8722 } 8723 8724 firstIndex = Math.max(current - dynamicBulletIndex, 0); 8725 lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1); 8726 midIndex = (lastIndex + firstIndex) / 2; 8727 } 8728 8729 bullets.removeClass(['', '-next', '-next-next', '-prev', '-prev-prev', '-main'].map(suffix => `${params.bulletActiveClass}${suffix}`).join(' ')); 8730 8731 if ($el.length > 1) { 8732 bullets.each(bullet => { 8733 const $bullet = $(bullet); 8734 const bulletIndex = $bullet.index(); 8735 8736 if (bulletIndex === current) { 8737 $bullet.addClass(params.bulletActiveClass); 8738 } 8739 8740 if (params.dynamicBullets) { 8741 if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) { 8742 $bullet.addClass(`${params.bulletActiveClass}-main`); 8743 } 8744 8745 if (bulletIndex === firstIndex) { 8746 setSideBullets($bullet, 'prev'); 8747 } 8748 8749 if (bulletIndex === lastIndex) { 8750 setSideBullets($bullet, 'next'); 8751 } 8752 } 8753 }); 8754 } else { 8755 const $bullet = bullets.eq(current); 8756 const bulletIndex = $bullet.index(); 8757 $bullet.addClass(params.bulletActiveClass); 8758 8759 if (params.dynamicBullets) { 8760 const $firstDisplayedBullet = bullets.eq(firstIndex); 8761 const $lastDisplayedBullet = bullets.eq(lastIndex); 8762 8763 for (let i = firstIndex; i <= lastIndex; i += 1) { 8764 bullets.eq(i).addClass(`${params.bulletActiveClass}-main`); 8765 } 8766 8767 if (swiper.params.loop) { 8768 if (bulletIndex >= bullets.length) { 8769 for (let i = params.dynamicMainBullets; i >= 0; i -= 1) { 8770 bullets.eq(bullets.length - i).addClass(`${params.bulletActiveClass}-main`); 8771 } 8772 8773 bullets.eq(bullets.length - params.dynamicMainBullets - 1).addClass(`${params.bulletActiveClass}-prev`); 8774 } else { 8775 setSideBullets($firstDisplayedBullet, 'prev'); 8776 setSideBullets($lastDisplayedBullet, 'next'); 8777 } 8778 } else { 8779 setSideBullets($firstDisplayedBullet, 'prev'); 8780 setSideBullets($lastDisplayedBullet, 'next'); 8781 } 8782 } 8783 } 8784 8785 if (params.dynamicBullets) { 8786 const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4); 8787 const bulletsOffset = (bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize; 8788 const offsetProp = rtl ? 'right' : 'left'; 8789 bullets.css(swiper.isHorizontal() ? offsetProp : 'top', `${bulletsOffset}px`); 8790 } 8791 } 8792 8793 if (params.type === 'fraction') { 8794 $el.find(classesToSelector(params.currentClass)).text(params.formatFractionCurrent(current + 1)); 8795 $el.find(classesToSelector(params.totalClass)).text(params.formatFractionTotal(total)); 8796 } 8797 8798 if (params.type === 'progressbar') { 8799 let progressbarDirection; 8800 8801 if (params.progressbarOpposite) { 8802 progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal'; 8803 } else { 8804 progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical'; 8805 } 8806 8807 const scale = (current + 1) / total; 8808 let scaleX = 1; 8809 let scaleY = 1; 8810 8811 if (progressbarDirection === 'horizontal') { 8812 scaleX = scale; 8813 } else { 8814 scaleY = scale; 8815 } 8816 8817 $el.find(classesToSelector(params.progressbarFillClass)).transform(`translate3d(0,
88170,0) scaleX(${scaleX}) scaleY(${scaleY})`).transition(swiper.params.speed); 8818 } 8819 8820 if (params.type === 'custom' && params.renderCustom) { 8821 $el.html(params.renderCustom(swiper, current + 1, total)); 8822 emit('paginationRender', $el[0]); 8823 } else { 8824 emit('paginationUpdate', $el[0]); 8825 } 8826 8827 if (swiper.params.watchOverflow && swiper.enabled) { 8828 $el[swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass); 8829 } 8830 } 8831 8832 function render() { 8833 // Render Container 8834 const params = swiper.params.pagination; 8835 if (isPaginationDisabled()) return; 8836 const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length; 8837 const $el = swiper.pagination.$el; 8838 let paginationHTML = ''; 8839 8840 if (params.type === 'bullets') { 8841 let numberOfBullets = swiper.params.loop ? Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) : swiper.snapGrid.length; 8842 8843 if (swiper.params.freeMode && swiper.params.freeMode.enabled && !swiper.params.loop && numberOfBullets > slidesLength) { 8844 numberOfBullets = slidesLength; 8845 } 8846 8847 for (let i = 0; i < numberOfBullets; i += 1) { 8848 if (params.renderBullet) { 8849 paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass); 8850 } else { 8851 paginationHTML += `<${params.bulletElement} class="${params.bulletClass}"></${params.bulletElement}>`; 8852 } 8853 } 8854 8855 $el.html(paginationHTML); 8856 swiper.pagination.bullets = $el.find(classesToSelector(params.bulletClass)); 8857 } 8858 8859 if (params.type === 'fraction') { 8860 if (params.renderFraction) { 8861 paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass); 8862 } else { 8863 paginationHTML = `<span class="${params.currentClass}"></span>` + ' / ' + `<span class="${params.totalClass}"></span>`; 8864 } 8865 8866 $el.html(paginationHTML); 8867 } 8868 8869 if (params.type === 'progressbar') { 8870 if (params.renderProgressbar) { 8871 paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass); 8872 } else { 8873 paginationHTML = `<span class="${params.progressbarFillClass}"></span>`; 8874 } 8875 8876 $el.html(paginationHTML); 8877 } 8878 8879 if (params.type !== 'custom') { 8880 emit('paginationRender', swiper.pagination.$el[0]); 8881 } 8882 } 8883 8884 function init() { 8885 swiper.params.pagination = createElementIfNotDefined(swiper, swiper.originalParams.pagination, swiper.params.pagination, { 8886 el: 'swiper-pagination' 8887 }); 8888 const params = swiper.params.pagination; 8889 if (!params.el) return; 8890 let $el = $(params.el); 8891 if ($el.length === 0) return; 8892 8893 if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1) { 8894 $el = swiper.$el.find(params.el); // check if it belongs to another nested Swiper 8895 8896 if ($el.length > 1) { 8897 $el = $el.filter(el => { 8898 if ($(el).parents('.swiper')[0] !== swiper.el) return false; 8899 return true; 8900 }); 8901 } 8902 } 8903 8904 if (params.type === 'bullets' && params.clickable) { 8905 $el.addClass(params.clickableClass); 8906 } 8907 8908 $el.addClass(params.modifierClass + params.type); 8909 $el.addClass(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass); 8910 8911 if (params.type === 'bullets' && params.dynamicBullets) { 8912 $el.addClass(`${params.modifierClass}${params.type}-dynamic`); 8913 dynamicBulletIndex = 0; 8914 8915 if (params.dynamicMainBullets < 1) { 8916 params.dynamicMainBullets = 1; 8917 } 8918 } 8919 8920 if (params.type === 'progressbar' && params.progressbarOpposite) { 8921 $el.addClass(params.progressbarOppositeClass); 8922 } 8923 8924 if (params.clickable) { 8925 $el.on('click', classesToSelector(params.bulletClass), function onClick(e) { 8926 e.preventDefault(); 8927 let index = $(this).index() * swiper.params.slidesPerGroup; 8928 if (swiper.params.loop) index += swiper.loopedSlides; 8929 swiper.slideTo(index); 8930 }); 8931 } 8932 8933 Object.assign(swiper.pagination, { 8934 $el, 8935 el: $el[0] 8936 }); 8937 8938 if (!swiper.enabled) { 8939 $el.addClass(params.lockClass); 8940 } 8941 } 8942 8943 function destroy() { 8944 const params = swiper.params.pagination; 8945 if (isPaginationDisabled()) return; 8946 const $el = swiper.pagination.$el; 8947 $el.removeClass(params.hiddenClass); 8948 $el.removeClass(params.modifierClass + params.type); 8949 $el.removeClass(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass); 8950 if (swiper.pagination.bullets && swiper.pagination.bullets.removeClass) swiper.pagination.bullets.removeClass(params.bulletActiveClass); 8951 8952 if (params.clickable) { 8953 $el.off('click', classesToSelector(params.bulletClass)); 8954 } 8955 } 8956 8957 on('init', () => { 8958 if (swiper.params.pagination.enabled === false) { 8959 // eslint-disable-next-line 8960 disable(); 8961 } else { 8962 init(); 8963 render(); 8964 update(); 8965 } 8966 }); 8967 on('activeIndexChange', () => { 8968 if (swiper.params.loop) { 8969 update(); 8970 } else if (typeof swiper.snapIndex === 'undefined') { 8971 update(); 8972 } 8973 }); 8974 on('snapIndexChange', () => { 8975 if (!swiper.params.loop) { 8976 update(); 8977 } 8978 }); 8979 on('slidesLengthChange', () => { 8980 if (swiper.params.loop) { 8981 render(); 8982 update(); 8983 } 8984 }); 8985 on('snapGridLengthChange', () => { 8986 if (!swiper.params.loop) { 8987 render(); 8988 update(); 8989 } 8990 }); 8991 on('destroy', () => { 8992 destroy(); 8993 }); 8994 on('enable disable', () => { 8995 const { 8996 $el 8997 } = swiper.pagination; 8998 8999 if ($el) { 9000 $el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.pagination.lockClass); 9001 } 9002 }); 9003 on('lock unlock', () => { 9004 update(); 9005 }); 9006 on('click', (_s, e) => { 9007 const targetEl = e.target; 9008 const { 9009 $el 9010 } = swiper.pagination; 9011 9012 if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && $el && $el.length > 0 && !$(targetEl).hasClass(swiper.params.pagination.bulletClass)) { 9013 if (swiper.navigation && (swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl || swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl)) return; 9014 const isHidden = $el.hasClass(swiper.params.pagination.hiddenClass); 9015 9016 if (isHidden === true) { 9017 emit('paginationShow'); 9018 } else { 9019 emit('paginationHide'); 9020 } 9021 9022 $el.toggleClass(swiper.params.pagination.hiddenClass); 9023 } 9024 }); 9025 9026 const enable = () => { 9027 swiper.$el.removeClass(swiper.params.pagination.paginationDisabledClass); 9028 9029 if (swiper.pagination.$el) { 9030 swiper.pagination.$el.removeClass(swiper.params.pagination.paginationDisabledClass); 9031 } 9032 9033 init(); 9034 render(); 9035 update(); 9036 }; 9037 9038 const disable = () => { 9039 swiper.$el.addClass(swiper.params.pagination.paginationDisabledClass); 9040 9041 if (swiper.pagination.$el) { 9042 swiper.pagination.$el.addClass(swiper.params.pagination.paginationDisabledClass); 9043 } 9044 9045 destroy(); 9046 }; 9047 9048 Object.assign(swiper.pagination, { 9049 enable, 9050 disable, 9051 render, 9052 update, 9053 init, 9054 destroy 9055 }); 9056 } 9057 9058 function Scrollbar(_ref) { 9059 let { 9060 swiper, 9061 extendParams, 9062 on, 9063 emit 9064 } = _ref; 9065 const document = getDocument(); 9066 let isTouched = false;
vendor: 5,559 bytes, lines 9067-9261
9067 let timeout = null; 9068 let dragTimeout = null; 9069 let dragStartPos; 9070 let dragSize; 9071 let trackSize; 9072 let divider; 9073 extendParams({ 9074 scrollbar: { 9075 el: null, 9076 dragSize: 'auto', 9077 hide: false, 9078 draggable: false, 9079 snapOnRelease: true, 9080 lockClass: 'swiper-scrollbar-lock', 9081 dragClass: 'swiper-scrollbar-drag', 9082 scrollbarDisabledClass: 'swiper-scrollbar-disabled', 9083 horizontalClass: `swiper-scrollbar-horizontal`, 9084 verticalClass: `swiper-scrollbar-vertical` 9085 } 9086 }); 9087 swiper.scrollbar = { 9088 el: null, 9089 dragEl: null, 9090 $el: null, 9091 $dragEl: null 9092 }; 9093 9094 function setTranslate() { 9095 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; 9096 const { 9097 scrollbar, 9098 rtlTranslate: rtl, 9099 progress 9100 } = swiper; 9101 const { 9102 $dragEl, 9103 $el 9104 } = scrollbar; 9105 const params = swiper.params.scrollbar; 9106 let newSize = dragSize; 9107 let newPos = (trackSize - dragSize) * progress; 9108 9109 if (rtl) { 9110 newPos = -newPos; 9111 9112 if (newPos > 0) { 9113 newSize = dragSize - newPos; 9114 newPos = 0; 9115 } else if (-newPos + dragSize > trackSize) { 9116 newSize = trackSize + newPos; 9117 } 9118 } else if (newPos < 0) { 9119 newSize = dragSize + newPos; 9120 newPos = 0; 9121 } else if (newPos + dragSize > trackSize) { 9122 newSize = trackSize - newPos; 9123 } 9124 9125 if (swiper.isHorizontal()) { 9126 $dragEl.transform(`translate3d(${newPos}px, 0, 0)`); 9127 $dragEl[0].style.width = `${newSize}px`; 9128 } else { 9129 $dragEl.transform(`translate3d(0px, ${newPos}px, 0)`); 9130 $dragEl[0].style.height = `${newSize}px`; 9131 } 9132 9133 if (params.hide) { 9134 clearTimeout(timeout); 9135 $el[0].style.opacity = 1; 9136 timeout = setTimeout(() => { 9137 $el[0].style.opacity = 0; 9138 $el.transition(400); 9139 }, 1000); 9140 } 9141 } 9142 9143 function setTransition(duration) { 9144 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; 9145 swiper.scrollbar.$dragEl.transition(duration); 9146 } 9147 9148 function updateSize() { 9149 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; 9150 const { 9151 scrollbar 9152 } = swiper; 9153 const { 9154 $dragEl, 9155 $el 9156 } = scrollbar; 9157 $dragEl[0].style.width = ''; 9158 $dragEl[0].style.height = ''; 9159 trackSize = swiper.isHorizontal() ? $el[0].offsetWidth : $el[0].offsetHeight; 9160 divider = swiper.size / (swiper.virtualSize + swiper.params.slidesOffsetBefore - (swiper.params.centeredSlides ? swiper.snapGrid[0] : 0)); 9161 9162 if (swiper.params.scrollbar.dragSize === 'auto') { 9163 dragSize = trackSize * divider; 9164 } else { 9165 dragSize = parseInt(swiper.params.scrollbar.dragSize, 10); 9166 } 9167 9168 if (swiper.isHorizontal()) { 9169 $dragEl[0].style.width = `${dragSize}px`; 9170 } else { 9171 $dragEl[0].style.height = `${dragSize}px`; 9172 } 9173 9174 if (divider >= 1) { 9175 $el[0].style.display = 'none'; 9176 } else { 9177 $el[0].style.display = ''; 9178 } 9179 9180 if (swiper.params.scrollbar.hide) { 9181 $el[0].style.opacity = 0; 9182 } 9183 9184 if (swiper.params.watchOverflow && swiper.enabled) { 9185 scrollbar.$el[swiper.isLocked ? 'addClass' : 'removeClass'](swiper.params.scrollbar.lockClass); 9186 } 9187 } 9188 9189 function getPointerPosition(e) { 9190 if (swiper.isHorizontal()) { 9191 return e.type === 'touchstart' || e.type === 'touchmove' ? e.targetTouches[0].clientX : e.clientX; 9192 } 9193 9194 return e.type === 'touchstart' || e.type === 'touchmove' ? e.targetTouches[0].clientY : e.clientY; 9195 } 9196 9197 function setDragPosition(e) { 9198 const { 9199 scrollbar, 9200 rtlTranslate: rtl 9201 } = swiper; 9202 const { 9203 $el 9204 } = scrollbar; 9205 let positionRatio; 9206 positionRatio = (getPointerPosition(e) - $el.offset()[swiper.isHorizontal() ? 'left' : 'top'] - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize); 9207 positionRatio = Math.max(Math.min(positionRatio, 1), 0); 9208 9209 if (rtl) { 9210 positionRatio = 1 - positionRatio; 9211 } 9212 9213 const position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio; 9214 swiper.updateProgress(position); 9215 swiper.setTranslate(position); 9216 swiper.updateActiveIndex(); 9217 swiper.updateSlidesClasses(); 9218 } 9219 9220 function onDragStart(e) { 9221 const params = swiper.params.scrollbar; 9222 const { 9223 scrollbar, 9224 $wrapperEl 9225 } = swiper; 9226 const { 9227 $el, 9228 $dragEl 9229 } = scrollbar; 9230 isTouched = true; 9231 dragStartPos = e.target === $dragEl[0] || e.target === $dragEl ? getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null; 9232 e.preventDefault(); 9233 e.stopPropagation(); 9234 $wrapperEl.transition(100); 9235 $dragEl.transition(100); 9236 setDragPosition(e); 9237 clearTimeout(dragTimeout); 9238 $el.transition(0); 9239 9240 if (params.hide) { 9241 $el.css('opacity', 1); 9242 } 9243 9244 if (swiper.params.cssMode) { 9245 swiper.$wrapperEl.css('scroll-snap-type', 'none'); 9246 } 9247 9248 emit('scrollbarDragStart', e); 9249 } 9250 9251 function onDragMove(e) { 9252 const { 9253 scrollbar, 9254 $wrapperEl 9255 } = swiper; 9256 const { 9257 $el, 9258 $dragEl 9259 } = scrollbar; 9260 if (!isTouched) return; 9261 if (e.preventDefault) e.preventDefault();else e.returnValue = false;
9262 setDragPosition(e); 9263 $wrapperEl.transition(0); 9264 $el.transition(0); 9265 $dragEl.transition(0); 9266 emit('scrollbarDragMove', e); 9267 } 9268 9269 function onDragEnd(e) { 9270 const params = swiper.params.scrollbar; 9271 const { 9272 scrollbar, 9273 $wrapperEl 9274 } = swiper; 9275 const { 9276 $el 9277 } = scrollbar; 9278 if (!isTouched) return; 9279 isTouched = false; 9280 9281 if (swiper.params.cssMode) { 9282 swiper.$wrapperEl.css('scroll-snap-type', ''); 9283 $wrapperEl.transition(''); 9284 } 9285 9286 if (params.hide) { 9287 clearTimeout(dragTimeout); 9288 dragTimeout = nextTick(() => { 9289 $el.css('opacity', 0); 9290 $el.transition(400); 9291 }, 1000); 9292 } 9293 9294 emit('scrollbarDragEnd', e); 9295 9296 if (params.snapOnRelease) { 9297 swiper.slideToClosest(); 9298 } 9299 } 9300 9301 function events(method) { 9302 const { 9303 scrollbar, 9304 touchEventsTouch, 9305 touchEventsDesktop, 9306 params, 9307 support 9308 } = swiper; 9309 const $el = scrollbar.$el; 9310 if (!$el) return; 9311 const target = $el[0]; 9312 const activeListener = support.passiveListener && params.passiveListeners ? { 9313 passive: false, 9314 capture: false 9315 } : false; 9316 const passiveListener = support.passiveListener && params.passiveListeners ? { 9317 passive: true, 9318 capture: false 9319 } : false; 9320 if (!target) return; 9321 const eventMethod = method === 'on' ? 'addEventListener' : 'removeEventListener'; 9322 9323 if (!support.touch) { 9324 target[eventMethod](touchEventsDesktop.start, onDragStart, activeListener); 9325 document[eventMethod](touchEventsDesktop.move, onDragMove, activeListener); 9326 document[eventMethod](touchEventsDesktop.end, onDragEnd, passiveListener); 9327 } else { 9328 target[eventMethod](touchEventsTouch.start, onDragStart, activeListener); 9329 target[eventMethod](touchEventsTouch.move, onDragMove, activeListener); 9330 target[eventMethod](touchEventsTouch.end, onDragEnd, passiveListener); 9331 } 9332 } 9333 9334 function enableDraggable() { 9335 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; 9336 events('on'); 9337 } 9338 9339 function disableDraggable() { 9340 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; 9341 events('off'); 9342 } 9343 9344 function init() { 9345 const { 9346 scrollbar, 9347 $el: $swiperEl 9348 } = swiper; 9349 swiper.params.scrollbar = createElementIfNotDefined(swiper, swiper.originalParams.scrollbar, swiper.params.scrollbar, { 9350 el: 'swiper-scrollbar' 9351 }); 9352 const params = swiper.params.scrollbar; 9353 if (!params.el) return; 9354 let $el = $(params.el); 9355 9356 if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1 && $swiperEl.find(params.el).length === 1) { 9357 $el = $swiperEl.find(params.el); 9358 } 9359 9360 $el.addClass(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass); 9361 let $dragEl = $el.find(`.${swiper.params.scrollbar.dragClass}`); 9362 9363 if ($dragEl.length === 0) { 9364 $dragEl = $(`<div class="${swiper.params.scrollbar.dragClass}"></div>`); 9365 $el.append($dragEl); 9366 } 9367 9368 Object.assign(scrollbar, { 9369 $el, 9370 el: $el[0], 9371 $dragEl, 9372 dragEl: $dragEl[0] 9373 }); 9374 9375 if (params.draggable) { 9376 enableDraggable(); 9377 } 9378 9379 if ($el) { 9380 $el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.scrollbar.lockClass); 9381 } 9382 } 9383 9384 function destroy() { 9385 const params = swiper.params.scrollbar; 9386 const $el = swiper.scrollbar.$el; 9387 9388 if ($el) { 9389 $el.removeClass(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass); 9390 } 9391 9392 disableDraggable(); 9393 } 9394 9395 on('init', () => { 9396 if (swiper.params.scrollbar.enabled === false) { 9397 // eslint-disable-next-line 9398 disable(); 9399 } else { 9400 init(); 9401 updateSize(); 9402 setTranslate(); 9403 } 9404 }); 9405 on('update resize observerUpdate lock unlock', () => { 9406 updateSize(); 9407 }); 9408 on('setTranslate', () => { 9409 setTranslate(); 9410 }); 9411 on('setTransition', (_s, duration) => { 9412 setTransition(duration); 9413 }); 9414 on('enable disable', () => { 9415 const { 9416 $el 9417 } = swiper.scrollbar; 9418 9419 if ($el) { 9420 $el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.scrollbar.lockClass); 9421 } 9422 }); 9423 on('destroy', () => { 9424 destroy(); 9425 }); 9426 9427 const enable = () => { 9428 swiper.$el.removeClass(swiper.params.scrollbar.scrollbarDisabledClass); 9429 9430 if (swiper.scrollbar.$el) { 9431 swiper.scrollbar.$el.removeClass(swiper.params.scrollbar.scrollbarDisabledClass); 9432 } 9433 9434 init(); 9435 updateSize(); 9436 setTranslate(); 9437 }; 9438 9439 const disable = () => { 9440 swiper.$el.addClass(swiper.params.scrollbar.scrollbarDisabledClass); 9441 9442 if (swiper.scrollbar.$el) { 9443 swiper.scrollbar.$el.addClass(swiper.params.scrollbar.scrollbarDisabledClass); 9444 } 9445 9446 destroy(); 9447 }; 9448 9449 Object.assign(swiper.scrollbar, { 9450 enable, 9451 disable, 9452 updateSize, 9453 setTranslate, 9454 init, 9455 destroy 9456 }); 9457 } 9458 9459 function Parallax(_ref) { 9460 let { 9461 swiper, 9462 extendParams, 9463 on 9464 } = _ref; 9465 extendParams({ 9466 parallax: { 9467 enabled: false 9468 } 9469 }); 9470 9471 const setTransform = (el, progress) => { 9472 const { 9473 rtl 9474 } = swiper; 9475 const $el = $(el); 9476 const rtlFactor = rtl ? -1 : 1; 9477 const p = $el.attr('data-swiper-parallax') || '0'; 9478 let x = $el.attr('data-swiper-parallax-x'); 9479 let y = $el.attr('data-swiper-parallax-y'); 9480 const scale = $el.attr('data-swiper-parallax-scale'); 9481 const opacity = $el.attr('data-swiper-parallax-opacity'); 9482 9483 if (x || y) { 9484 x = x || '0'; 9485 y = y || '0'; 9486 } else if (swiper.isHorizontal()) { 9487 x = p; 9488 y = '0'; 9489 } else { 9490 y = p; 9491 x = '0'; 9492 } 9493 9494 if (x.indexOf('%') >= 0) { 9495 x = `${parseInt(x, 10) * progress * rtlFactor}%`; 9496 } else { 9497 x = `${x * progress * rtlFactor}px`;
9498 } 9499 9500 if (y.indexOf('%') >= 0) { 9501 y = `${parseInt(y, 10) * progress}%`; 9502 } else { 9503 y = `${y * progress}px`; 9504 } 9505 9506 if (typeof opacity !== 'undefined' && opacity !== null) { 9507 const currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress)); 9508 $el[0].style.opacity = currentOpacity; 9509 } 9510 9511 if (typeof scale === 'undefined' || scale === null) { 9512 $el.transform(`translate3d(${x}, ${y}, 0px)`); 9513 } else { 9514 const currentScale = scale - (scale - 1) * (1 - Math.abs(progress)); 9515 $el.transform(`translate3d(${x}, ${y}, 0px) scale(${currentScale})`); 9516 } 9517 }; 9518 9519 const setTranslate = () => { 9520 const { 9521 $el, 9522 slides, 9523 progress, 9524 snapGrid 9525 } = swiper; 9526 $el.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(el => { 9527 setTransform(el, progress); 9528 }); 9529 slides.each((slideEl, slideIndex) => { 9530 let slideProgress = slideEl.progress; 9531 9532 if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') { 9533 slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1); 9534 } 9535 9536 slideProgress = Math.min(Math.max(slideProgress, -1), 1); 9537 $(slideEl).find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(el => { 9538 setTransform(el, slideProgress); 9539 }); 9540 }); 9541 }; 9542 9543 const setTransition = function (duration) { 9544 if (duration === void 0) { 9545 duration = swiper.params.speed; 9546 } 9547 9548 const { 9549 $el 9550 } = swiper; 9551 $el.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(parallaxEl => { 9552 const $parallaxEl = $(parallaxEl); 9553 let parallaxDuration = parseInt($parallaxEl.attr('data-swiper-parallax-duration'), 10) || duration; 9554 if (duration === 0) parallaxDuration = 0; 9555 $parallaxEl.transition(parallaxDuration); 9556 }); 9557 }; 9558 9559 on('beforeInit', () => { 9560 if (!swiper.params.parallax.enabled) return; 9561 swiper.params.watchSlidesProgress = true; 9562 swiper.originalParams.watchSlidesProgress = true; 9563 }); 9564 on('init', () => { 9565 if (!swiper.params.parallax.enabled) return; 9566 setTranslate(); 9567 }); 9568 on('setTranslate', () => { 9569 if (!swiper.params.parallax.enabled) return; 9570 setTranslate(); 9571 }); 9572 on('setTransition', (_swiper, duration) => { 9573 if (!swiper.params.parallax.enabled) return; 9574 setTransition(duration); 9575 }); 9576 } 9577 9578 function Zoom(_ref) { 9579 let { 9580 swiper, 9581 extendParams, 9582 on, 9583 emit 9584 } = _ref; 9585 const window = getWindow(); 9586 extendParams({ 9587 zoom: { 9588 enabled: false, 9589 maxRatio: 3, 9590 minRatio: 1, 9591 toggle: true, 9592 containerClass: 'swiper-zoom-container', 9593 zoomedSlideClass: 'swiper-slide-zoomed' 9594 } 9595 }); 9596 swiper.zoom = { 9597 enabled: false 9598 }; 9599 let currentScale = 1; 9600 let isScaling = false; 9601 let gesturesEnabled; 9602 let fakeGestureTouched; 9603 let fakeGestureMoved; 9604 const gesture = { 9605 $slideEl: undefined, 9606 slideWidth: undefined, 9607 slideHeight: undefined, 9608 $imageEl: undefined, 9609 $imageWrapEl: undefined, 9610 maxRatio: 3 9611 }; 9612 const image = { 9613 isTouched: undefined, 9614 isMoved: undefined, 9615 currentX: undefined, 9616 currentY: undefined, 9617 minX: undefined, 9618 minY: undefined, 9619 maxX: undefined, 9620 maxY: undefined, 9621 width: undefined, 9622 height: undefined, 9623 startX: undefined, 9624 startY: undefined, 9625 touchesStart: {}, 9626 touchesCurrent: {} 9627 }; 9628 const velocity = { 9629 x: undefined, 9630 y: undefined, 9631 prevPositionX: undefined, 9632 prevPositionY: undefined, 9633 prevTime: undefined 9634 }; 9635 let scale = 1; 9636 Object.defineProperty(swiper.zoom, 'scale', { 9637 get() { 9638 return scale; 9639 }, 9640 9641 set(value) { 9642 if (scale !== value) { 9643 const imageEl = gesture.$imageEl ? gesture.$imageEl[0] : undefined; 9644 const slideEl = gesture.$slideEl ? gesture.$slideEl[0] : undefined; 9645 emit('zoomChange', value, imageEl, slideEl); 9646 } 9647 9648 scale = value; 9649 } 9650 9651 }); 9652 9653 function getDistanceBetweenTouches(e) { 9654 if (e.targetTouches.length < 2) return 1; 9655 const x1 = e.targetTouches[0].pageX; 9656 const y1 = e.targetTouches[0].pageY; 9657 const x2 = e.targetTouches[1].pageX; 9658 const y2 = e.targetTouches[1].pageY; 9659 const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); 9660 return distance; 9661 } // Events 9662 9663 9664 function onGestureStart(e) { 9665 const support = swiper.support; 9666 const params = swiper.params.zoom; 9667 fakeGestureTouched = false;
vendor: 19,102 bytes, lines 9668-10179
9668 fakeGestureMoved = false; 9669 9670 if (!support.gestures) { 9671 if (e.type !== 'touchstart' || e.type === 'touchstart' && e.targetTouches.length < 2) { 9672 return; 9673 } 9674 9675 fakeGestureTouched = true; 9676 gesture.scaleStart = getDistanceBetweenTouches(e); 9677 } 9678 9679 if (!gesture.$slideEl || !gesture.$slideEl.length) { 9680 gesture.$slideEl = $(e.target).closest(`.${swiper.params.slideClass}`); 9681 if (gesture.$slideEl.length === 0) gesture.$slideEl = swiper.slides.eq(swiper.activeIndex); 9682 gesture.$imageEl = gesture.$slideEl.find(`.${params.containerClass}`).eq(0).find('picture, img, svg, canvas, .swiper-zoom-target').eq(0); 9683 gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`); 9684 gesture.maxRatio = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; 9685 9686 if (gesture.$imageWrapEl.length === 0) { 9687 gesture.$imageEl = undefined; 9688 return; 9689 } 9690 } 9691 9692 if (gesture.$imageEl) { 9693 gesture.$imageEl.transition(0); 9694 } 9695 9696 isScaling = true; 9697 } 9698 9699 function onGestureChange(e) { 9700 const support = swiper.support; 9701 const params = swiper.params.zoom; 9702 const zoom = swiper.zoom; 9703 9704 if (!support.gestures) { 9705 if (e.type !== 'touchmove' || e.type === 'touchmove' && e.targetTouches.length < 2) { 9706 return; 9707 } 9708 9709 fakeGestureMoved = true; 9710 gesture.scaleMove = getDistanceBetweenTouches(e); 9711 } 9712 9713 if (!gesture.$imageEl || gesture.$imageEl.length === 0) { 9714 if (e.type === 'gesturechange') onGestureStart(e); 9715 return; 9716 } 9717 9718 if (support.gestures) { 9719 zoom.scale = e.scale * currentScale; 9720 } else { 9721 zoom.scale = gesture.scaleMove / gesture.scaleStart * currentScale; 9722 } 9723 9724 if (zoom.scale > gesture.maxRatio) { 9725 zoom.scale = gesture.maxRatio - 1 + (zoom.scale - gesture.maxRatio + 1) ** 0.5; 9726 } 9727 9728 if (zoom.scale < params.minRatio) { 9729 zoom.scale = params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5; 9730 } 9731 9732 gesture.$imageEl.transform(`translate3d(0,0,0) scale(${zoom.scale})`); 9733 } 9734 9735 function onGestureEnd(e) { 9736 const device = swiper.device; 9737 const support = swiper.support; 9738 const params = swiper.params.zoom; 9739 const zoom = swiper.zoom; 9740 9741 if (!support.gestures) { 9742 if (!fakeGestureTouched || !fakeGestureMoved) { 9743 return; 9744 } 9745 9746 if (e.type !== 'touchend' || e.type === 'touchend' && e.changedTouches.length < 2 && !device.android) { 9747 return; 9748 } 9749 9750 fakeGestureTouched = false; 9751 fakeGestureMoved = false; 9752 } 9753 9754 if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; 9755 zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio); 9756 gesture.$imageEl.transition(swiper.params.speed).transform(`translate3d(0,0,0) scale(${zoom.scale})`); 9757 currentScale = zoom.scale; 9758 isScaling = false; 9759 if (zoom.scale === 1) gesture.$slideEl = undefined; 9760 } 9761 9762 function onTouchStart(e) { 9763 const device = swiper.device; 9764 if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; 9765 if (image.isTouched) return; 9766 if (device.android && e.cancelable) e.preventDefault(); 9767 image.isTouched = true; 9768 image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX; 9769 image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY; 9770 } 9771 9772 function onTouchMove(e) { 9773 const zoom = swiper.zoom; 9774 if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; 9775 swiper.allowClick = false; 9776 if (!image.isTouched || !gesture.$slideEl) return; 9777 9778 if (!image.isMoved) { 9779 image.width = gesture.$imageEl[0].offsetWidth; 9780 image.height = gesture.$imageEl[0].offsetHeight; 9781 image.startX = getTranslate(gesture.$imageWrapEl[0], 'x') || 0; 9782 image.startY = getTranslate(gesture.$imageWrapEl[0], 'y') || 0; 9783 gesture.slideWidth = gesture.$slideEl[0].offsetWidth; 9784 gesture.slideHeight = gesture.$slideEl[0].offsetHeight; 9785 gesture.$imageWrapEl.transition(0); 9786 } // Define if we need image drag 9787 9788 9789 const scaledWidth = image.width * zoom.scale; 9790 const scaledHeight = image.height * zoom.scale; 9791 if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) return; 9792 image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0); 9793 image.maxX = -image.minX; 9794 image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0); 9795 image.maxY = -image.minY; 9796 image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX; 9797 image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY; 9798 9799 if (!image.isMoved && !isScaling) { 9800 if (swiper.isHorizontal() && (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x || Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x)) { 9801 image.isTouched = false; 9802 return; 9803 } 9804 9805 if (!swiper.isHorizontal() && (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y || Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y)) { 9806 image.isTouched = false; 9807 return; 9808 } 9809 } 9810 9811 if (e.cancelable) { 9812 e.preventDefault(); 9813 } 9814 9815 e.stopPropagation(); 9816 image.isMoved = true; 9817 image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX; 9818 image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY; 9819 9820 if (image.currentX < image.minX) { 9821 image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8; 9822 } 9823 9824 if (image.currentX > image.maxX) { 9825 image.currentX = image.maxX - 1 + (image.currentX - image.maxX + 1) ** 0.8; 9826 } 9827 9828 if (image.currentY < image.minY) { 9829 image.currentY = image.minY + 1 - (image.minY - image.currentY + 1) ** 0.8; 9830 } 9831 9832 if (image.currentY > image.maxY) { 9833 image.currentY = image.maxY - 1 + (image.currentY - image.maxY + 1) ** 0.8; 9834 } // Velocity 9835 9836 9837 if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x; 9838 if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y; 9839 if (!velocity.prevTime) velocity.prevTime = Date.now(); 9840 velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2; 9841 velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2; 9842 if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0; 9843 if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0; 9844 velocity.prevPositionX = image.touchesCurrent.x; 9845 velocity.prevPositionY = image.touchesCurrent.y; 9846 velocity.prevTime = Date.now(); 9847 gesture.$imageWrapEl.transform(`translate3d(${image.currentX}px, ${image.currentY}px,0)`); 9848 } 9849 9850 function onTouchEnd() { 9851 const zoom = swiper.zoom; 9852 if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; 9853 9854 if (!image.isTouched || !image.isMoved) { 9855 image.isTouched = false; 9856 image.isMoved = false; 9857 return; 9858 } 9859 9860 image.isTouched = false; 9861 image.isMoved = false; 9862 let momentumDurationX = 300; 9863 let momentumDurationY = 300; 9864 const momentumDistanceX = velocity.x * momentumDurationX; 9865 const newPositionX = image.currentX + momentumDistanceX; 9866 const momentumDistanceY = velocity.y * momentumDurationY; 9867 const newPositionY = image.currentY + momentumDistanceY; // Fix duration 9868 9869 if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x); 9870 if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y); 9871 const momentumDuration = Math.max(momentumDurationX, momentumDurationY); 9872 image.currentX = newPositionX; 9873 image.currentY = newPositionY; // Define if we need image drag 9874 9875 const scaledWidth = image.width * zoom.scale; 9876 const scaledHeight = image.height * zoom.scale; 9877 image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0); 9878 image.maxX = -image.minX; 9879 image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0); 9880 image.maxY = -image.minY; 9881 image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX); 9882 image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY); 9883 gesture.$imageWrapEl.transition(momentumDuration).transform(`translate3d(${image.currentX}px, ${image.currentY}px,0)`); 9884 } 9885 9886 function onTransitionEnd() { 9887 const zoom = swiper.zoom; 9888 9889 if (gesture.$slideEl && swiper.previousIndex !== swiper.activeIndex) { 9890 if (gesture.$imageEl) { 9891 gesture.$imageEl.transform('translate3d(0,0,0) scale(1)'); 9892 } 9893 9894 if (gesture.$imageWrapEl) { 9895 gesture.$imageWrapEl.transform('translate3d(0,0,0)'); 9896 } 9897 9898 zoom.scale = 1; 9899 currentScale = 1; 9900 gesture.$slideEl = undefined; 9901 gesture.$imageEl = undefined; 9902 gesture.$imageWrapEl = undefined; 9903 } 9904 } 9905 9906 function zoomIn(e) { 9907 const zoom = swiper.zoom; 9908 const params = swiper.params.zoom; 9909 9910 if (!gesture.$slideEl) { 9911 if (e && e.target) { 9912 gesture.$slideEl = $(e.target).closest(`.${swiper.params.slideClass}`); 9913 } 9914 9915 if (!gesture.$slideEl) { 9916 if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) { 9917 gesture.$slideEl = swiper.$wrapperEl.children(`.${swiper.params.slideActiveClass}`); 9918 } else { 9919 gesture.$slideEl = swiper.slides.eq(swiper.activeIndex); 9920 } 9921 } 9922 9923 gesture.$imageEl = gesture.$slideEl.find(`.${params.containerClass}`).eq(0).find('picture, img, svg, canvas, .swiper-zoom-target').eq(0); 9924 gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`); 9925 } 9926 9927 if (!gesture.$imageEl || gesture.$imageEl.length === 0 || !gesture.$imageWrapEl || gesture.$imageWrapEl.length === 0) return; 9928 9929 if (swiper.params.cssMode) { 9930 swiper.wrapperEl.style.overflow = 'hidden'; 9931 swiper.wrapperEl.style.touchAction = 'none'; 9932 } 9933 9934 gesture.$slideEl.addClass(`${params.zoomedSlideClass}`); 9935 let touchX; 9936 let touchY; 9937 let offsetX; 9938 let offsetY; 9939 let diffX; 9940 let diffY; 9941 let translateX; 9942 let translateY; 9943 let imageWidth; 9944 let imageHeight; 9945 let scaledWidth; 9946 let scaledHeight; 9947 let translateMinX; 9948 let translateMinY; 9949 let translateMaxX; 9950 let translateMaxY; 9951 let slideWidth; 9952 let slideHeight; 9953 9954 if (typeof image.touchesStart.x === 'undefined' && e) { 9955 touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX; 9956 touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY; 9957 } else { 9958 touchX = image.touchesStart.x; 9959 touchY = image.touchesStart.y; 9960 } 9961 9962 zoom.scale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; 9963 currentScale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; 9964 9965 if (e) { 9966 slideWidth = gesture.$slideEl[0].offsetWidth; 9967 slideHeight = gesture.$slideEl[0].offsetHeight; 9968 offsetX = gesture.$slideEl.offset().left + window.scrollX; 9969 offsetY = gesture.$slideEl.offset().top + window.scrollY; 9970 diffX = offsetX + slideWidth / 2 - touchX; 9971 diffY = offsetY + slideHeight / 2 - touchY; 9972 imageWidth = gesture.$imageEl[0].offsetWidth; 9973 imageHeight = gesture.$imageEl[0].offsetHeight; 9974 scaledWidth = imageWidth * zoom.scale; 9975 scaledHeight = imageHeight * zoom.scale; 9976 translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0); 9977 translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0); 9978 translateMaxX = -translateMinX; 9979 translateMaxY = -translateMinY; 9980 translateX = diffX * zoom.scale; 9981 translateY = diffY * zoom.scale; 9982 9983 if (translateX < translateMinX) { 9984 translateX = translateMinX; 9985 } 9986 9987 if (translateX > translateMaxX) { 9988 translateX = translateMaxX; 9989 } 9990 9991 if (translateY < translateMinY) { 9992 translateY = translateMinY; 9993 } 9994 9995 if (translateY > translateMaxY) { 9996 translateY = translateMaxY; 9997 } 9998 } else { 9999 translateX = 0; 10000 translateY = 0; 10001 } 10002 10003 gesture.$imageWrapEl.transition(300).transform(`translate3d(${translateX}px, ${translateY}px,0)`); 10004 gesture.$imageEl.transition(300).transform(`translate3d(0,0,0) scale(${zoom.scale})`); 10005 } 10006 10007 function zoomOut() { 10008 const zoom = swiper.zoom; 10009 const params = swiper.params.zoom; 10010 10011 if (!gesture.$slideEl) { 10012 if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) { 10013 gesture.$slideEl = swiper.$wrapperEl.children(`.${swiper.params.slideActiveClass}`); 10014 } else { 10015 gesture.$slideEl = swiper.slides.eq(swiper.activeIndex); 10016 } 10017 10018 gesture.$imageEl = gesture.$slideEl.find(`.${params.containerClass}`).eq(0).find('picture, img, svg, canvas, .swiper-zoom-target').eq(0); 10019 gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`); 10020 } 10021 10022 if (!gesture.$imageEl || gesture.$imageEl.length === 0 || !gesture.$imageWrapEl || gesture.$imageWrapEl.length === 0) return; 10023 10024 if (swiper.params.cssMode) { 10025 swiper.wrapperEl.style.overflow = ''; 10026 swiper.wrapperEl.style.touchAction = ''; 10027 } 10028 10029 zoom.scale = 1; 10030 currentScale = 1; 10031 gesture.$imageWrapEl.transition(300).transform('translate3d(0,0,0)'); 10032 gesture.$imageEl.transition(300).transform('translate3d(0,0,0) scale(1)'); 10033 gesture.$slideEl.removeClass(`${params.zoomedSlideClass}`); 10034 gesture.$slideEl = undefined; 10035 } // Toggle Zoom 10036 10037 10038 function zoomToggle(e) { 10039 const zoom = swiper.zoom; 10040 10041 if (zoom.scale && zoom.scale !== 1) { 10042 // Zoom Out 10043 zoomOut(); 10044 } else { 10045 // Zoom In 10046 zoomIn(e); 10047 } 10048 } 10049 10050 function getListeners() { 10051 const support = swiper.support; 10052 const passiveListener = swiper.touchEvents.start === 'touchstart' && support.passiveListener && swiper.params.passiveListeners ? { 10053 passive: true, 10054 capture: false 10055 } : false; 10056 const activeListenerWithCapture = support.passiveListener ? { 10057 passive: false, 10058 capture: true 10059 } : true; 10060 return { 10061 passiveListener, 10062 activeListenerWithCapture 10063 }; 10064 } 10065 10066 function getSlideSelector() { 10067 return `.${swiper.params.slideClass}`; 10068 } 10069 10070 function toggleGestures(method) { 10071 const { 10072 passiveListener 10073 } = getListeners(); 10074 const slideSelector = getSlideSelector(); 10075 swiper.$wrapperEl[method]('gesturestart', slideSelector, onGestureStart, passiveListener); 10076 swiper.$wrapperEl[method]('gesturechange', slideSelector, onGestureChange, passiveListener); 10077 swiper.$wrapperEl[method]('gestureend', slideSelector, onGestureEnd, passiveListener); 10078 } 10079 10080 function enableGestures() { 10081 if (gesturesEnabled) return; 10082 gesturesEnabled = true; 10083 toggleGestures('on'); 10084 } 10085 10086 function disableGestures() { 10087 if (!gesturesEnabled) return; 10088 gesturesEnabled = false; 10089 toggleGestures('off'); 10090 } // Attach/Detach Events 10091 10092 10093 function enable() { 10094 const zoom = swiper.zoom; 10095 if (zoom.enabled) return; 10096 zoom.enabled = true; 10097 const support = swiper.support; 10098 const { 10099 passiveListener, 10100 activeListenerWithCapture 10101 } = getListeners(); 10102 const slideSelector = getSlideSelector(); // Scale image 10103 10104 if (support.gestures) { 10105 swiper.$wrapperEl.on(swiper.touchEvents.start, enableGestures, passiveListener); 10106 swiper.$wrapperEl.on(swiper.touchEvents.end, disableGestures, passiveListener); 10107 } else if (swiper.touchEvents.start === 'touchstart') { 10108 swiper.$wrapperEl.on(swiper.touchEvents.start, slideSelector, onGestureStart, passiveListener); 10109 swiper.$wrapperEl.on(swiper.touchEvents.move, slideSelector, onGestureChange, activeListenerWithCapture); 10110 swiper.$wrapperEl.on(swiper.touchEvents.end, slideSelector, onGestureEnd, passiveListener); 10111 10112 if (swiper.touchEvents.cancel) { 10113 swiper.$wrapperEl.on(swiper.touchEvents.cancel, slideSelector, onGestureEnd, passiveListener); 10114 } 10115 } // Move image 10116 10117 10118 swiper.$wrapperEl.on(swiper.touchEvents.move, `.${swiper.params.zoom.containerClass}`, onTouchMove, activeListenerWithCapture); 10119 } 10120 10121 function disable() { 10122 const zoom = swiper.zoom; 10123 if (!zoom.enabled) return; 10124 const support = swiper.support; 10125 zoom.enabled = false; 10126 const { 10127 passiveListener, 10128 activeListenerWithCapture 10129 } = getListeners(); 10130 const slideSelector = getSlideSelector(); // Scale image 10131 10132 if (support.gestures) { 10133 swiper.$wrapperEl.off(swiper.touchEvents.start, enableGestures, passiveListener); 10134 swiper.$wrapperEl.off(swiper.touchEvents.end, disableGestures, passiveListener); 10135 } else if (swiper.touchEvents.start === 'touchstart') { 10136 swiper.$wrapperEl.off(swiper.touchEvents.start, slideSelector, onGestureStart, passiveListener); 10137 swiper.$wrapperEl.off(swiper.touchEvents.move, slideSelector, onGestureChange, activeListenerWithCapture); 10138 swiper.$wrapperEl.off(swiper.touchEvents.end, slideSelector, onGestureEnd, passiveListener); 10139 10140 if (swiper.touchEvents.cancel) { 10141 swiper.$wrapperEl.off(swiper.touchEvents.cancel, slideSelector, onGestureEnd, passiveListener); 10142 } 10143 } // Move image 10144 10145 10146 swiper.$wrapperEl.off(swiper.touchEvents.move, `.${swiper.params.zoom.containerClass}`, onTouchMove, activeListenerWithCapture); 10147 } 10148 10149 on('init', () => { 10150 if (swiper.params.zoom.enabled) { 10151 enable(); 10152 } 10153 }); 10154 on('destroy', () => { 10155 disable(); 10156 }); 10157 on('touchStart', (_s, e) => { 10158 if (!swiper.zoom.enabled) return; 10159 onTouchStart(e); 10160 }); 10161 on('touchEnd', (_s, e) => { 10162 if (!swiper.zoom.enabled) return; 10163 onTouchEnd(); 10164 }); 10165 on('doubleTap', (_s, e) => { 10166 if (!swiper.animating && swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) { 10167 zoomToggle(e); 10168 } 10169 }); 10170 on('transitionEnd', () => { 10171 if (swiper.zoom.enabled && swiper.params.zoom.enabled) { 10172 onTransitionEnd(); 10173 } 10174 }); 10175 on('slideChange', () => { 10176 if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) { 10177 onTransitionEnd(); 10178 } 10179 });
10180 Object.assign(swiper.zoom, { 10181 enable, 10182 disable, 10183 in: zoomIn, 10184 out: zoomOut, 10185 toggle: zoomToggle 10186 }); 10187 } 10188 10189 function Lazy(_ref) { 10190 let { 10191 swiper, 10192 extendParams, 10193 on, 10194 emit 10195 } = _ref; 10196 extendParams({ 10197 lazy: { 10198 checkInView: false, 10199 enabled: false, 10200 loadPrevNext: false, 10201 loadPrevNextAmount: 1, 10202 loadOnTransitionStart: false, 10203 scrollingElement: '', 10204 elementClass: 'swiper-lazy', 10205 loadingClass: 'swiper-lazy-loading', 10206 loadedClass: 'swiper-lazy-loaded', 10207 preloaderClass: 'swiper-lazy-preloader' 10208 } 10209 }); 10210 swiper.lazy = {}; 10211 let scrollHandlerAttached = false; 10212 let initialImageLoaded = false; 10213 10214 function loadInSlide(index, loadInDuplicate) { 10215 if (loadInDuplicate === void 0) { 10216 loadInDuplicate = true; 10217 } 10218 10219 const params = swiper.params.lazy; 10220 if (typeof index === 'undefined') return; 10221 if (swiper.slides.length === 0) return; 10222 const isVirtual = swiper.virtual && swiper.params.virtual.enabled; 10223 const $slideEl = isVirtual ? swiper.$wrapperEl.children(`.${swiper.params.slideClass}[data-swiper-slide-index="${index}"]`) : swiper.slides.eq(index); 10224 const $images = $slideEl.find(`.${params.elementClass}:not(.${params.loadedClass}):not(.${params.loadingClass})`); 10225 10226 if ($slideEl.hasClass(params.elementClass) && !$slideEl.hasClass(params.loadedClass) && !$slideEl.hasClass(params.loadingClass)) { 10227 $images.push($slideEl[0]); 10228 } 10229 10230 if ($images.length === 0) return; 10231 $images.each(imageEl => { 10232 const $imageEl = $(imageEl); 10233 $imageEl.addClass(params.loadingClass); 10234 const background = $imageEl.attr('data-background'); 10235 const src = $imageEl.attr('data-src'); 10236 const srcset = $imageEl.attr('data-srcset'); 10237 const sizes = $imageEl.attr('data-sizes'); 10238 const $pictureEl = $imageEl.parent('picture'); 10239 swiper.loadImage($imageEl[0], src || background, srcset, sizes, false, () => { 10240 if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper && !swiper.params || swiper.destroyed) return; 10241 10242 if (background) { 10243 $imageEl.css('background-image', `url("${background}")`); 10244 $imageEl.removeAttr('data-background'); 10245 } else { 10246 if (srcset) { 10247 $imageEl.attr('srcset', srcset); 10248 $imageEl.removeAttr('data-srcset'); 10249 } 10250 10251 if (sizes) { 10252 $imageEl.attr('sizes', sizes); 10253 $imageEl.removeAttr('data-sizes'); 10254 } 10255 10256 if ($pictureEl.length) { 10257 $pictureEl.children('source').each(sourceEl => { 10258 const $source = $(sourceEl); 10259 10260 if ($source.attr('data-srcset')) { 10261 $source.attr('srcset', $source.attr('data-srcset')); 10262 $source.removeAttr('data-srcset'); 10263 } 10264 }); 10265 } 10266 10267 if (src) { 10268 $imageEl.attr('src', src); 10269 $imageEl.removeAttr('data-src'); 10270 } 10271 } 10272 10273 $imageEl.addClass(params.loadedClass).removeClass(params.loadingClass); 10274 $slideEl.find(`.${params.preloaderClass}`).remove(); 10275 10276 if (swiper.params.loop && loadInDuplicate) { 10277 const slideOriginalIndex = $slideEl.attr('data-swiper-slide-index'); 10278 10279 if ($slideEl.hasClass(swiper.params.slideDuplicateClass)) { 10280 const originalSlide = swiper.$wrapperEl.children(`[data-swiper-slide-index="${slideOriginalIndex}"]:not(.${swiper.params.slideDuplicateClass})`); 10281 loadInSlide(originalSlide.index(), false); 10282 } else { 10283 const duplicatedSlide = swiper.$wrapperEl.children(`.${swiper.params.slideDuplicateClass}[data-swiper-slide-index="${slideOriginalIndex}"]`); 10284 loadInSlide(duplicatedSlide.index(), false); 10285 } 10286 } 10287 10288 emit('lazyImageReady', $slideEl[0], $imageEl[0]); 10289 10290 if (swiper.params.autoHeight) { 10291 swiper.updateAutoHeight(); 10292 } 10293 }); 10294 emit('lazyImageLoad', $slideEl[0], $imageEl[0]); 10295 }); 10296 } 10297 10298 function load() { 10299 const { 10300 $wrapperEl, 10301 params: swiperParams, 10302 slides, 10303 activeIndex 10304 } = swiper; 10305 const isVirtual = swiper.virtual && swiperParams.virtual.enabled; 10306 const params = swiperParams.lazy; 10307 let slidesPerView = swiperParams.slidesPerView; 10308 10309 if (slidesPerView === 'auto') { 10310 slidesPerView = 0; 10311 } 10312 10313 function slideExist(index) { 10314 if (isVirtual) { 10315 if ($wrapperEl.children(`.${swiperParams.slideClass}[data-swiper-slide-index="${index}"]`).length) { 10316 return true; 10317 } 10318 } else if (slides[index]) return true; 10319 10320 return false;
10321 } 10322 10323 function slideIndex(slideEl) { 10324 if (isVirtual) { 10325 return $(slideEl).attr('data-swiper-slide-index'); 10326 } 10327 10328 return $(slideEl).index(); 10329 } 10330 10331 if (!initialImageLoaded) initialImageLoaded = true; 10332 10333 if (swiper.params.watchSlidesProgress) { 10334 $wrapperEl.children(`.${swiperParams.slideVisibleClass}`).each(slideEl => { 10335 const index = isVirtual ? $(slideEl).attr('data-swiper-slide-index') : $(slideEl).index(); 10336 loadInSlide(index); 10337 }); 10338 } else if (slidesPerView > 1) { 10339 for (let i = activeIndex; i < activeIndex + slidesPerView; i += 1) { 10340 if (slideExist(i)) loadInSlide(i); 10341 } 10342 } else { 10343 loadInSlide(activeIndex); 10344 } 10345 10346 if (params.loadPrevNext) { 10347 if (slidesPerView > 1 || params.loadPrevNextAmount && params.loadPrevNextAmount > 1) { 10348 const amount = params.loadPrevNextAmount; 10349 const spv = Math.ceil(slidesPerView); 10350 const maxIndex = Math.min(activeIndex + spv + Math.max(amount, spv), slides.length); 10351 const minIndex = Math.max(activeIndex - Math.max(spv, amount), 0); // Next Slides 10352 10353 for (let i = activeIndex + spv; i < maxIndex; i += 1) { 10354 if (slideExist(i)) loadInSlide(i); 10355 } // Prev Slides 10356 10357 10358 for (let i = minIndex; i < activeIndex; i += 1) { 10359 if (slideExist(i)) loadInSlide(i); 10360 } 10361 } else { 10362 const nextSlide = $wrapperEl.children(`.${swiperParams.slideNextClass}`); 10363 if (nextSlide.length > 0) loadInSlide(slideIndex(nextSlide)); 10364 const prevSlide = $wrapperEl.children(`.${swiperParams.slidePrevClass}`); 10365 if (prevSlide.length > 0) loadInSlide(slideIndex(prevSlide)); 10366 } 10367 } 10368 } 10369 10370 function checkInViewOnLoad() { 10371 const window = getWindow(); 10372 if (!swiper || swiper.destroyed) return; 10373 const $scrollElement = swiper.params.lazy.scrollingElement ? $(swiper.params.lazy.scrollingElement) : $(window); 10374 const isWindow = $scrollElement[0] === window; 10375 const scrollElementWidth = isWindow ? window.innerWidth : $scrollElement[0].offsetWidth; 10376 const scrollElementHeight = isWindow ? window.innerHeight : $scrollElement[0].offsetHeight; 10377 const swiperOffset = swiper.$el.offset(); 10378 const { 10379 rtlTranslate: rtl 10380 } = swiper; 10381 let inView = false; 10382 if (rtl) swiperOffset.left -= swiper.$el[0].scrollLeft; 10383 const swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiper.width, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiper.height], [swiperOffset.left + swiper.width, swiperOffset.top + swiper.height]]; 10384 10385 for (let i = 0; i < swiperCoord.length; i += 1) { 10386 const point = swiperCoord[i]; 10387 10388 if (point[0] >= 0 && point[0] <= scrollElementWidth && point[1] >= 0 && point[1] <= scrollElementHeight) { 10389 if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line 10390 10391 inView = true; 10392 } 10393 } 10394 10395 const passiveListener = swiper.touchEvents.start === 'touchstart' && swiper.support.passiveListener && swiper.params.passiveListeners ? { 10396 passive: true, 10397 capture: false 10398 } : false; 10399 10400 if (inView) { 10401 load(); 10402 $scrollElement.off('scroll', checkInViewOnLoad, passiveListener); 10403 } else if (!scrollHandlerAttached) { 10404 scrollHandlerAttached = true; 10405 $scrollElement.on('scroll', checkInViewOnLoad, passiveListener); 10406 } 10407 } 10408 10409 on('beforeInit', () => { 10410 if (swiper.params.lazy.enabled && swiper.params.preloadImages) { 10411 swiper.params.preloadImages = false; 10412 } 10413 }); 10414 on('init', () => { 10415 if (swiper.params.lazy.enabled) { 10416 if (swiper.params.lazy.checkInView) { 10417 checkInViewOnLoad(); 10418 } else { 10419 load(); 10420 } 10421 } 10422 }); 10423 on('scroll', () => { 10424 if (swiper.params.freeMode && swiper.params.freeMode.enabled && !swiper.params.freeMode.sticky) { 10425 load(); 10426 } 10427 }); 10428 on('scrollbarDragMove resize _freeModeNoMomentumRelease', () => { 10429 if (swiper.params.lazy.enabled) { 10430 if (swiper.params.lazy.checkInView) { 10431 checkInViewOnLoad(); 10432 } else { 10433 load(); 10434 } 10435 } 10436 }); 10437 on('transitionStart', () => { 10438 if (swiper.params.lazy.enabled) { 10439 if (swiper.params.lazy.loadOnTransitionStart || !swiper.params.lazy.loadOnTransitionStart && !initialImageLoaded) { 10440 if (swiper.params.lazy.checkInView) { 10441 checkInViewOnLoad(); 10442 } else { 10443 load(); 10444 } 10445 } 10446 } 10447 }); 10448 on('transitionEnd', () => { 10449 if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) { 10450 if (swiper.params.lazy.checkInView) { 10451 checkInViewOnLoad(); 10452 } else { 10453 load(); 10454 } 10455 } 10456 }); 10457 on('slideChange', () => { 10458 const { 10459 lazy, 10460 cssMode, 10461 watchSlidesProgress, 10462 touchReleaseOnEdges, 10463 resistanceRatio 10464 } = swiper.params; 10465 10466 if (lazy.enabled && (cssMode || watchSlidesProgress && (touchReleaseOnEdges || resistanceRatio === 0))) { 10467 load(); 10468 } 10469 }); 10470 on('destroy', () => { 10471 if (!swiper.$el) return; 10472 swiper.$el.find(`.${swiper.params.lazy.loadingClass}`).removeClass(swiper.params.lazy.loadingClass); 10473 });
10474 Object.assign(swiper.lazy, { 10475 load, 10476 loadInSlide 10477 }); 10478 } 10479 10480 /* eslint no-bitwise: ["error", { "allow": [">>"] }] */ 10481 function Controller(_ref) { 10482 let { 10483 swiper, 10484 extendParams, 10485 on 10486 } = _ref; 10487 extendParams({ 10488 controller: { 10489 control: undefined, 10490 inverse: false, 10491 by: 'slide' // or 'container' 10492 10493 } 10494 }); 10495 swiper.controller = { 10496 control: undefined 10497 }; 10498 10499 function LinearSpline(x, y) { 10500 const binarySearch = function search() { 10501 let maxIndex; 10502 let minIndex; 10503 let guess; 10504 return (array, val) => { 10505 minIndex = -1; 10506 maxIndex = array.length; 10507 10508 while (maxIndex - minIndex > 1) { 10509 guess = maxIndex + minIndex >> 1; 10510 10511 if (array[guess] <= val) { 10512 minIndex = guess; 10513 } else { 10514 maxIndex = guess; 10515 } 10516 } 10517 10518 return maxIndex; 10519 }; 10520 }(); 10521 10522 this.x = x; 10523 this.y = y; 10524 this.lastIndex = x.length - 1; // Given an x value (x2), return the expected y2 value: 10525 // (x1,y1) is the known point before given value, 10526 // (x3,y3) is the known point after given value. 10527 10528 let i1; 10529 let i3; 10530 10531 this.interpolate = function interpolate(x2) { 10532 if (!x2) return 0; // Get the indexes of x1 and x3 (the array indexes before and after given x2): 10533 10534 i3 = binarySearch(this.x, x2); 10535 i1 = i3 - 1; // We have our indexes i1 & i3, so we can calculate already: 10536 // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1 10537 10538 return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1]; 10539 }; 10540 10541 return this; 10542 } // xxx: for now i will just save one spline function to to 10543 10544 10545 function getInterpolateFunction(c) { 10546 if (!swiper.controller.spline) { 10547 swiper.controller.spline = swiper.params.loop ? new LinearSpline(swiper.slidesGrid, c.slidesGrid) : new LinearSpline(swiper.snapGrid, c.snapGrid); 10548 } 10549 } 10550 10551 function setTranslate(_t, byController) { 10552 const controlled = swiper.controller.control; 10553 let multiplier; 10554 let controlledTranslate; 10555 const Swiper = swiper.constructor; 10556 10557 function setControlledTranslate(c) { 10558 // this will create an Interpolate function based on the snapGrids 10559 // x is the Grid of the scrolled scroller and y will be the controlled scroller 10560 // it makes sense to create this only once and recall it for the interpolation 10561 // the function does a lot of value caching for performance 10562 const translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate; 10563 10564 if (swiper.params.controller.by === 'slide') { 10565 getInterpolateFunction(c); // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid 10566 // but it did not work out 10567 10568 controlledTranslate = -swiper.controller.spline.interpolate(-translate); 10569 } 10570 10571 if (!controlledTranslate || swiper.params.controller.by === 'container') { 10572 multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate()); 10573 controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate(); 10574 } 10575 10576 if (swiper.params.controller.inverse) { 10577 controlledTranslate = c.maxTranslate() - controlledTranslate; 10578 } 10579 10580 c.updateProgress(controlledTranslate); 10581 c.setTranslate(controlledTranslate, swiper); 10582 c.updateActiveIndex(); 10583 c.updateSlidesClasses(); 10584 } 10585 10586 if (Array.isArray(controlled)) { 10587 for (let i = 0; i < controlled.length; i += 1) { 10588 if (controlled[i] !== byController && controlled[i] instanceof Swiper) { 10589 setControlledTranslate(controlled[i]); 10590 } 10591 } 10592 } else if (controlled instanceof Swiper && byController !== controlled) { 10593 setControlledTranslate(controlled); 10594 } 10595 } 10596 10597 function setTransition(duration, byController) { 10598 const Swiper = swiper.constructor; 10599 const controlled = swiper.controller.control; 10600 let i; 10601 10602 function setControlledTransition(c) { 10603 c.setTransition(duration, swiper); 10604 10605 if (duration !== 0) { 10606 c.transitionStart(); 10607 10608 if (c.params.autoHeight) { 10609 nextTick(() => { 10610 c.updateAutoHeight(); 10611 }); 10612 } 10613 10614 c.$wrapperEl.transitionEnd(() => { 10615 if (!controlled) return; 10616 10617 if (c.params.loop && swiper.params.controller.by === 'slide') { 10618 c.loopFix(); 10619 } 10620 10621 c.transitionEnd(); 10622 }); 10623 } 10624 } 10625 10626 if (Array.isArray(controlled)) { 10627 for (i = 0; i < controlled.length; i += 1) { 10628 if (controlled[i] !== byController && controlled[i] instanceof Swiper) { 10629 setControlledTransition(controlled[i]); 10630 } 10631 } 10632 } else if (controlled instanceof Swiper && byController !== controlled) { 10633 setControlledTransition(controlled); 10634 } 10635 } 10636 10637 function removeSpline() { 10638 if (!swiper.controller.control) return; 10639 10640 if (swiper.controller.spline) { 10641 swiper.controller.spline = undefined; 10642 delete swiper.controller.spline; 10643 } 10644 } 10645 10646 on('beforeInit', () => { 10647 swiper.controller.control = swiper.params.controller.control; 10648 }); 10649 on('update', () => { 10650 removeSpline(); 10651 }); 10652 on('resize', () => { 10653 removeSpline(); 10654 }); 10655 on('observerUpdate', () => { 10656 removeSpline(); 10657 }); 10658 on('setTranslate', (_s, translate, byController) => { 10659 if (!swiper.controller.control) return; 10660 swiper.controller.setTranslate(translate, byController); 10661 }); 10662 on('setTransition', (_s, duration, byController) => { 10663 if (!swiper.controller.control) return; 10664 swiper.controller.setTransition(duration, byController); 10665 });
10666 Object.assign(swiper.controller, { 10667 setTranslate, 10668 setTransition 10669 }); 10670 } 10671 10672 function A11y(_ref) { 10673 let { 10674 swiper, 10675 extendParams, 10676 on 10677 } = _ref; 10678 extendParams({ 10679 a11y: { 10680 enabled: true, 10681 notificationClass: 'swiper-notification', 10682 prevSlideMessage: 'Previous slide', 10683 nextSlideMessage: 'Next slide', 10684 firstSlideMessage: 'This is the first slide', 10685 lastSlideMessage: 'This is the last slide', 10686 paginationBulletMessage: 'Go to slide {{index}}', 10687 slideLabelMessage: '{{index}} / {{slidesLength}}', 10688 containerMessage: null, 10689 containerRoleDescriptionMessage: null, 10690 itemRoleDescriptionMessage: null, 10691 slideRole: 'group', 10692 id: null 10693 } 10694 }); 10695 swiper.a11y = { 10696 clicked: false 10697 }; 10698 let liveRegion = null; 10699 10700 function notify(message) { 10701 const notification = liveRegion; 10702 if (notification.length === 0) return; 10703 notification.html(''); 10704 notification.html(message); 10705 } 10706 10707 function getRandomNumber(size) { 10708 if (size === void 0) { 10709 size = 16; 10710 } 10711 10712 const randomChar = () => Math.round(16 * Math.random()).toString(16); 10713 10714 return 'x'.repeat(size).replace(/x/g, randomChar); 10715 } 10716 10717 function makeElFocusable($el) { 10718 $el.attr('tabIndex', '0'); 10719 } 10720 10721 function makeElNotFocusable($el) { 10722 $el.attr('tabIndex', '-1'); 10723 } 10724 10725 function addElRole($el, role) { 10726 $el.attr('role', role); 10727 } 10728 10729 function addElRoleDescription($el, description) { 10730 $el.attr('aria-roledescription', description); 10731 } 10732 10733 function addElControls($el, controls) { 10734 $el.attr('aria-controls', controls); 10735 } 10736 10737 function addElLabel($el, label) { 10738 $el.attr('aria-label', label); 10739 } 10740 10741 function addElId($el, id) { 10742 $el.attr('id', id); 10743 } 10744 10745 function addElLive($el, live) { 10746 $el.attr('aria-live', live); 10747 } 10748 10749 function disableEl($el) { 10750 $el.attr('aria-disabled', true); 10751 } 10752 10753 function enableEl($el) { 10754 $el.attr('aria-disabled', false); 10755 } 10756 10757 function onEnterOrSpaceKey(e) { 10758 if (e.keyCode !== 13 && e.keyCode !== 32) return; 10759 const params = swiper.params.a11y; 10760 const $targetEl = $(e.target); 10761 10762 if (swiper.navigation && swiper.navigation.$nextEl && $targetEl.is(swiper.navigation.$nextEl)) { 10763 if (!(swiper.isEnd && !swiper.params.loop)) { 10764 swiper.slideNext(); 10765 } 10766 10767 if (swiper.isEnd) { 10768 notify(params.lastSlideMessage); 10769 } else { 10770 notify(params.nextSlideMessage); 10771 } 10772 } 10773 10774 if (swiper.navigation && swiper.navigation.$prevEl && $targetEl.is(swiper.navigation.$prevEl)) { 10775 if (!(swiper.isBeginning && !swiper.params.loop)) { 10776 swiper.slidePrev(); 10777 } 10778 10779 if (swiper.isBeginning) { 10780 notify(params.firstSlideMessage); 10781 } else { 10782 notify(params.prevSlideMessage); 10783 } 10784 } 10785 10786 if (swiper.pagination && $targetEl.is(classesToSelector(swiper.params.pagination.bulletClass))) { 10787 $targetEl[0].click(); 10788 } 10789 } 10790 10791 function updateNavigation() { 10792 if (swiper.params.loop || swiper.params.rewind || !swiper.navigation) return; 10793 const { 10794 $nextEl, 10795 $prevEl 10796 } = swiper.navigation; 10797 10798 if ($prevEl && $prevEl.length > 0) { 10799 if (swiper.isBeginning) { 10800 disableEl($prevEl); 10801 makeElNotFocusable($prevEl); 10802 } else { 10803 enableEl($prevEl); 10804 makeElFocusable($prevEl); 10805 } 10806 } 10807 10808 if ($nextEl && $nextEl.length > 0) { 10809 if (swiper.isEnd) { 10810 disableEl($nextEl); 10811 makeElNotFocusable($nextEl); 10812 } else { 10813 enableEl($nextEl); 10814 makeElFocusable($nextEl); 10815 } 10816 } 10817 } 10818 10819 function hasPagination() { 10820 return swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length; 10821 } 10822 10823 function hasClickablePagination() { 10824 return hasPagination() && swiper.params.pagination.clickable; 10825 } 10826 10827 function updatePagination() { 10828 const params = swiper.params.a11y; 10829 if (!hasPagination()) return; 10830 swiper.pagination.bullets.each(bulletEl => { 10831 const $bulletEl = $(bulletEl); 10832 10833 if (swiper.params.pagination.clickable) { 10834 makeElFocusable($bulletEl); 10835 10836 if (!swiper.params.pagination.renderBullet) { 10837 addElRole($bulletEl, 'button'); 10838 addElLabel($bulletEl, params.paginationBulletMessage.replace(/\{\{index\}\}/, $bulletEl.index() + 1)); 10839 } 10840 } 10841 10842 if ($bulletEl.is(`.${swiper.params.pagination.bulletActiveClass}`)) { 10843 $bulletEl.attr('aria-current', 'true'); 10844 } else { 10845 $bulletEl.removeAttr('aria-current'); 10846 } 10847 }); 10848 } 10849 10850 const initNavEl = ($el, wrapperId, message) => { 10851 makeElFocusable($el); 10852 10853 if ($el[0].tagName !== 'BUTTON') { 10854 addElRole($el, 'button'); 10855 $el.on('keydown', onEnterOrSpaceKey); 10856 } 10857 10858 addElLabel($el, message); 10859 addElControls($el, wrapperId); 10860 }; 10861 10862 const handlePointerDown = () => { 10863 swiper.a11y.clicked = true; 10864 }; 10865 10866 const handlePointerUp = () => { 10867 requestAnimationFrame(() => { 10868 requestAnimationFrame(() => { 10869 if (!swiper.destroyed) { 10870 swiper.a11y.clicked = false;
10871 } 10872 }); 10873 }); 10874 }; 10875 10876 const handleFocus = e => { 10877 if (swiper.a11y.clicked) return; 10878 const slideEl = e.target.closest(`.${swiper.params.slideClass}`); 10879 if (!slideEl || !swiper.slides.includes(slideEl)) return; 10880 const isActive = swiper.slides.indexOf(slideEl) === swiper.activeIndex; 10881 const isVisible = swiper.params.watchSlidesProgress && swiper.visibleSlides && swiper.visibleSlides.includes(slideEl); 10882 if (isActive || isVisible) return; 10883 if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents) return; 10884 10885 if (swiper.isHorizontal()) { 10886 swiper.el.scrollLeft = 0; 10887 } else { 10888 swiper.el.scrollTop = 0; 10889 } 10890 10891 swiper.slideTo(swiper.slides.indexOf(slideEl), 0); 10892 }; 10893 10894 const initSlides = () => { 10895 const params = swiper.params.a11y; 10896 10897 if (params.itemRoleDescriptionMessage) { 10898 addElRoleDescription($(swiper.slides), params.itemRoleDescriptionMessage); 10899 } 10900 10901 if (params.slideRole) { 10902 addElRole($(swiper.slides), params.slideRole); 10903 } 10904 10905 const slidesLength = swiper.params.loop ? swiper.slides.filter(el => !el.classList.contains(swiper.params.slideDuplicateClass)).length : swiper.slides.length; 10906 10907 if (params.slideLabelMessage) { 10908 swiper.slides.each((slideEl, index) => { 10909 const $slideEl = $(slideEl); 10910 const slideIndex = swiper.params.loop ? parseInt($slideEl.attr('data-swiper-slide-index'), 10) : index; 10911 const ariaLabelMessage = params.slideLabelMessage.replace(/\{\{index\}\}/, slideIndex + 1).replace(/\{\{slidesLength\}\}/, slidesLength); 10912 addElLabel($slideEl, ariaLabelMessage); 10913 }); 10914 } 10915 }; 10916 10917 const init = () => { 10918 const params = swiper.params.a11y; 10919 swiper.$el.append(liveRegion); // Container 10920 10921 const $containerEl = swiper.$el; 10922 10923 if (params.containerRoleDescriptionMessage) { 10924 addElRoleDescription($containerEl, params.containerRoleDescriptionMessage); 10925 } 10926 10927 if (params.containerMessage) { 10928 addElLabel($containerEl, params.containerMessage); 10929 } // Wrapper 10930 10931 10932 const $wrapperEl = swiper.$wrapperEl; 10933 const wrapperId = params.id || $wrapperEl.attr('id') || `swiper-wrapper-${getRandomNumber(16)}`; 10934 const live = swiper.params.autoplay && swiper.params.autoplay.enabled ? 'off' : 'polite'; 10935 addElId($wrapperEl, wrapperId); 10936 addElLive($wrapperEl, live); // Slide 10937 10938 initSlides(); // Navigation 10939 10940 let $nextEl; 10941 let $prevEl; 10942 10943 if (swiper.navigation && swiper.navigation.$nextEl) { 10944 $nextEl = swiper.navigation.$nextEl; 10945 } 10946 10947 if (swiper.navigation && swiper.navigation.$prevEl) { 10948 $prevEl = swiper.navigation.$prevEl; 10949 } 10950 10951 if ($nextEl && $nextEl.length) { 10952 initNavEl($nextEl, wrapperId, params.nextSlideMessage); 10953 } 10954 10955 if ($prevEl && $prevEl.length) { 10956 initNavEl($prevEl, wrapperId, params.prevSlideMessage); 10957 } // Pagination 10958 10959 10960 if (hasClickablePagination()) { 10961 swiper.pagination.$el.on('keydown', classesToSelector(swiper.params.pagination.bulletClass), onEnterOrSpaceKey); 10962 } // Tab focus 10963 10964 10965 swiper.$el.on('focus', handleFocus, true); 10966 swiper.$el.on('pointerdown', handlePointerDown, true); 10967 swiper.$el.on('pointerup', handlePointerUp, true); 10968 }; 10969 10970 function destroy() { 10971 if (liveRegion && liveRegion.length > 0) liveRegion.remove(); 10972 let $nextEl; 10973 let $prevEl; 10974 10975 if (swiper.navigation && swiper.navigation.$nextEl) { 10976 $nextEl = swiper.navigation.$nextEl; 10977 } 10978 10979 if (swiper.navigation && swiper.navigation.$prevEl) { 10980 $prevEl = swiper.navigation.$prevEl; 10981 } 10982 10983 if ($nextEl) { 10984 $nextEl.off('keydown', onEnterOrSpaceKey); 10985 } 10986 10987 if ($prevEl) { 10988 $prevEl.off('keydown', onEnterOrSpaceKey); 10989 } // Pagination 10990 10991 10992 if (hasClickablePagination()) { 10993 swiper.pagination.$el.off('keydown', classesToSelector(swiper.params.pagination.bulletClass), onEnterOrSpaceKey); 10994 } // Tab focus 10995 10996 10997 swiper.$el.off('focus', handleFocus, true); 10998 swiper.$el.off('pointerdown', handlePointerDown, true); 10999 swiper.$el.off('pointerup', handlePointerUp, true); 11000 } 11001 11002 on('beforeInit', () => { 11003 liveRegion = $(`<span class="${swiper.params.a11y.notificationClass}
vendor: 5,029 bytes, lines 11003-11190
11003" aria-live="assertive" aria-atomic="true"></span>`); 11004 }); 11005 on('afterInit', () => { 11006 if (!swiper.params.a11y.enabled) return; 11007 init(); 11008 }); 11009 on('slidesLengthChange snapGridLengthChange slidesGridLengthChange', () => { 11010 if (!swiper.params.a11y.enabled) return; 11011 initSlides(); 11012 }); 11013 on('fromEdge toEdge afterInit lock unlock', () => { 11014 if (!swiper.params.a11y.enabled) return; 11015 updateNavigation(); 11016 }); 11017 on('paginationUpdate', () => { 11018 if (!swiper.params.a11y.enabled) return; 11019 updatePagination(); 11020 }); 11021 on('destroy', () => { 11022 if (!swiper.params.a11y.enabled) return; 11023 destroy(); 11024 }); 11025 } 11026 11027 function History(_ref) { 11028 let { 11029 swiper, 11030 extendParams, 11031 on 11032 } = _ref; 11033 extendParams({ 11034 history: { 11035 enabled: false, 11036 root: '', 11037 replaceState: false, 11038 key: 'slides', 11039 keepQuery: false 11040 } 11041 }); 11042 let initialized = false; 11043 let paths = {}; 11044 11045 const slugify = text => { 11046 return text.toString().replace(/\s+/g, '-').replace(/[^\w-]+/g, '').replace(/--+/g, '-').replace(/^-+/, '').replace(/-+$/, ''); 11047 }; 11048 11049 const getPathValues = urlOverride => { 11050 const window = getWindow(); 11051 let location; 11052 11053 if (urlOverride) { 11054 location = new URL(urlOverride); 11055 } else { 11056 location = window.location; 11057 } 11058 11059 const pathArray = location.pathname.slice(1).split('/').filter(part => part !== ''); 11060 const total = pathArray.length; 11061 const key = pathArray[total - 2]; 11062 const value = pathArray[total - 1]; 11063 return { 11064 key, 11065 value 11066 }; 11067 }; 11068 11069 const setHistory = (key, index) => { 11070 const window = getWindow(); 11071 if (!initialized || !swiper.params.history.enabled) return; 11072 let location; 11073 11074 if (swiper.params.url) { 11075 location = new URL(swiper.params.url); 11076 } else { 11077 location = window.location; 11078 } 11079 11080 const slide = swiper.slides.eq(index); 11081 let value = slugify(slide.attr('data-history')); 11082 11083 if (swiper.params.history.root.length > 0) { 11084 let root = swiper.params.history.root; 11085 if (root[root.length - 1] === '/') root = root.slice(0, root.length - 1); 11086 value = `${root}/${key}/${value}`; 11087 } else if (!location.pathname.includes(key)) { 11088 value = `${key}/${value}`; 11089 } 11090 11091 if (swiper.params.history.keepQuery) { 11092 value += location.search; 11093 } 11094 11095 const currentState = window.history.state; 11096 11097 if (currentState && currentState.value === value) { 11098 return; 11099 } 11100 11101 if (swiper.params.history.replaceState) { 11102 window.history.replaceState({ 11103 value 11104 }, null, value); 11105 } else { 11106 window.history.pushState({ 11107 value 11108 }, null, value); 11109 } 11110 }; 11111 11112 const scrollToSlide = (speed, value, runCallbacks) => { 11113 if (value) { 11114 for (let i = 0, length = swiper.slides.length; i < length; i += 1) { 11115 const slide = swiper.slides.eq(i); 11116 const slideHistory = slugify(slide.attr('data-history')); 11117 11118 if (slideHistory === value && !slide.hasClass(swiper.params.slideDuplicateClass)) { 11119 const index = slide.index(); 11120 swiper.slideTo(index, speed, runCallbacks); 11121 } 11122 } 11123 } else { 11124 swiper.slideTo(0, speed, runCallbacks); 11125 } 11126 }; 11127 11128 const setHistoryPopState = () => { 11129 paths = getPathValues(swiper.params.url); 11130 scrollToSlide(swiper.params.speed, paths.value, false); 11131 }; 11132 11133 const init = () => { 11134 const window = getWindow(); 11135 if (!swiper.params.history) return; 11136 11137 if (!window.history || !window.history.pushState) { 11138 swiper.params.history.enabled = false; 11139 swiper.params.hashNavigation.enabled = true; 11140 return; 11141 } 11142 11143 initialized = true; 11144 paths = getPathValues(swiper.params.url); 11145 if (!paths.key && !paths.value) return; 11146 scrollToSlide(0, paths.value, swiper.params.runCallbacksOnInit); 11147 11148 if (!swiper.params.history.replaceState) { 11149 window.addEventListener('popstate', setHistoryPopState); 11150 } 11151 }; 11152 11153 const destroy = () => { 11154 const window = getWindow(); 11155 11156 if (!swiper.params.history.replaceState) { 11157 window.removeEventListener('popstate', setHistoryPopState); 11158 } 11159 }; 11160 11161 on('init', () => { 11162 if (swiper.params.history.enabled) { 11163 init(); 11164 } 11165 }); 11166 on('destroy', () => { 11167 if (swiper.params.history.enabled) { 11168 destroy(); 11169 } 11170 }); 11171 on('transitionEnd _freeModeNoMomentumRelease', () => { 11172 if (initialized) { 11173 setHistory(swiper.params.history.key, swiper.activeIndex); 11174 } 11175 }); 11176 on('slideChange', () => { 11177 if (initialized && swiper.params.cssMode) { 11178 setHistory(swiper.params.history.key, swiper.activeIndex); 11179 } 11180 }); 11181 } 11182 11183 function HashNavigation(_ref) { 11184 let { 11185 swiper, 11186 extendParams, 11187 emit, 11188 on 11189 } = _ref; 11190 let initialized = false;
11191 const document = getDocument(); 11192 const window = getWindow(); 11193 extendParams({ 11194 hashNavigation: { 11195 enabled: false, 11196 replaceState: false, 11197 watchState: false 11198 } 11199 }); 11200 11201 const onHashChange = () => { 11202 emit('hashChange'); 11203 const newHash = document.location.hash.replace('#', ''); 11204 const activeSlideHash = swiper.slides.eq(swiper.activeIndex).attr('data-hash'); 11205 11206 if (newHash !== activeSlideHash) { 11207 const newIndex = swiper.$wrapperEl.children(`.${swiper.params.slideClass}[data-hash="${newHash}"]`).index(); 11208 if (typeof newIndex === 'undefined') return; 11209 swiper.slideTo(newIndex); 11210 } 11211 }; 11212 11213 const setHash = () => { 11214 if (!initialized || !swiper.params.hashNavigation.enabled) return; 11215 11216 if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) { 11217 window.history.replaceState(null, null, `#${swiper.slides.eq(swiper.activeIndex).attr('data-hash')}` || ''); 11218 emit('hashSet'); 11219 } else { 11220 const slide = swiper.slides.eq(swiper.activeIndex); 11221 const hash = slide.attr('data-hash') || slide.attr('data-history'); 11222 document.location.hash = hash || ''; 11223 emit('hashSet'); 11224 } 11225 }; 11226 11227 const init = () => { 11228 if (!swiper.params.hashNavigation.enabled || swiper.params.history && swiper.params.history.enabled) return; 11229 initialized = true; 11230 const hash = document.location.hash.replace('#', ''); 11231 11232 if (hash) { 11233 const speed = 0; 11234 11235 for (let i = 0, length = swiper.slides.length; i < length; i += 1) { 11236 const slide = swiper.slides.eq(i); 11237 const slideHash = slide.attr('data-hash') || slide.attr('data-history'); 11238 11239 if (slideHash === hash && !slide.hasClass(swiper.params.slideDuplicateClass)) { 11240 const index = slide.index(); 11241 swiper.slideTo(index, speed, swiper.params.runCallbacksOnInit, true); 11242 } 11243 } 11244 } 11245 11246 if (swiper.params.hashNavigation.watchState) { 11247 $(window).on('hashchange', onHashChange); 11248 } 11249 }; 11250 11251 const destroy = () => { 11252 if (swiper.params.hashNavigation.watchState) { 11253 $(window).off('hashchange', onHashChange); 11254 } 11255 }; 11256 11257 on('init', () => { 11258 if (swiper.params.hashNavigation.enabled) { 11259 init(); 11260 } 11261 }); 11262 on('destroy', () => { 11263 if (swiper.params.hashNavigation.enabled) { 11264 destroy(); 11265 } 11266 }); 11267 on('transitionEnd _freeModeNoMomentumRelease', () => { 11268 if (initialized) { 11269 setHash(); 11270 } 11271 }); 11272 on('slideChange', () => { 11273 if (initialized && swiper.params.cssMode) { 11274 setHash(); 11275 } 11276 }); 11277 } 11278 11279 /* eslint no-underscore-dangle: "off" */ 11280 function Autoplay(_ref) { 11281 let { 11282 swiper, 11283 extendParams, 11284 on, 11285 emit 11286 } = _ref; 11287 let timeout; 11288 swiper.autoplay = { 11289 running: false, 11290 paused: false 11291 }; 11292 extendParams({ 11293 autoplay: { 11294 enabled: false, 11295 delay: 3000, 11296 waitForTransition: true, 11297 disableOnInteraction: true, 11298 stopOnLastSlide: false, 11299 reverseDirection: false, 11300 pauseOnMouseEnter: false 11301 } 11302 }); 11303 11304 function run() { 11305 if (!swiper.size) { 11306 swiper.autoplay.running = false; 11307 swiper.autoplay.paused = false; 11308 return; 11309 } 11310 11311 const $activeSlideEl = swiper.slides.eq(swiper.activeIndex); 11312 let delay = swiper.params.autoplay.delay; 11313 11314 if ($activeSlideEl.attr('data-swiper-autoplay')) { 11315 delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay; 11316 } 11317 11318 clearTimeout(timeout); 11319 timeout = nextTick(() => { 11320 let autoplayResult; 11321 11322 if (swiper.params.autoplay.reverseDirection) { 11323 if (swiper.params.loop) { 11324 swiper.loopFix(); 11325 autoplayResult = swiper.slidePrev(swiper.params.speed, true, true); 11326 emit('autoplay'); 11327 } else if (!swiper.isBeginning) { 11328 autoplayResult = swiper.slidePrev(swiper.params.speed, true, true); 11329 emit('autoplay'); 11330 } else if (!swiper.params.autoplay.stopOnLastSlide) { 11331 autoplayResult = swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true); 11332 emit('autoplay'); 11333 } else { 11334 stop(); 11335 } 11336 } else if (swiper.params.loop) { 11337 swiper.loopFix(); 11338 autoplayResult = swiper.slideNext(swiper.params.speed, true, true); 11339 emit('autoplay'); 11340 } else if (!swiper.isEnd) { 11341 autoplayResult = swiper.slideNext(swiper.params.speed, true, true); 11342 emit('autoplay'); 11343 } else if (!swiper.params.autoplay.stopOnLastSlide) { 11344 autoplayResult = swiper.slideTo(0, swiper.params.speed, true, true); 11345 emit('autoplay'); 11346 } else { 11347 stop(); 11348 } 11349 11350 if (swiper.params.cssMode && swiper.autoplay.running) run();else if (autoplayResult === false) { 11351 run(); 11352 } 11353 }, delay); 11354 } 11355 11356 function start() { 11357 if (typeof timeout !== 'undefined') return false;
11358 if (swiper.autoplay.running) return false; 11359 swiper.autoplay.running = true; 11360 emit('autoplayStart'); 11361 run(); 11362 return true; 11363 } 11364 11365 function stop() { 11366 if (!swiper.autoplay.running) return false; 11367 if (typeof timeout === 'undefined') return false; 11368 11369 if (timeout) { 11370 clearTimeout(timeout); 11371 timeout = undefined; 11372 } 11373 11374 swiper.autoplay.running = false; 11375 emit('autoplayStop'); 11376 return true; 11377 } 11378 11379 function pause(speed) { 11380 if (!swiper.autoplay.running) return; 11381 if (swiper.autoplay.paused) return; 11382 if (timeout) clearTimeout(timeout); 11383 swiper.autoplay.paused = true; 11384 11385 if (speed === 0 || !swiper.params.autoplay.waitForTransition) { 11386 swiper.autoplay.paused = false; 11387 run(); 11388 } else { 11389 ['transitionend', 'webkitTransitionEnd'].forEach(event => { 11390 swiper.$wrapperEl[0].addEventListener(event, onTransitionEnd); 11391 }); 11392 } 11393 } 11394 11395 function onVisibilityChange() { 11396 const document = getDocument(); 11397 11398 if (document.visibilityState === 'hidden' && swiper.autoplay.running) { 11399 pause(); 11400 } 11401 11402 if (document.visibilityState === 'visible' && swiper.autoplay.paused) { 11403 run(); 11404 swiper.autoplay.paused = false; 11405 } 11406 } 11407 11408 function onTransitionEnd(e) { 11409 if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return; 11410 if (e.target !== swiper.$wrapperEl[0]) return; 11411 ['transitionend', 'webkitTransitionEnd'].forEach(event => { 11412 swiper.$wrapperEl[0].removeEventListener(event, onTransitionEnd); 11413 }); 11414 swiper.autoplay.paused = false; 11415 11416 if (!swiper.autoplay.running) { 11417 stop(); 11418 } else { 11419 run(); 11420 } 11421 } 11422 11423 function onMouseEnter() { 11424 if (swiper.params.autoplay.disableOnInteraction) { 11425 stop(); 11426 } else { 11427 emit('autoplayPause'); 11428 pause(); 11429 } 11430 11431 ['transitionend', 'webkitTransitionEnd'].forEach(event => { 11432 swiper.$wrapperEl[0].removeEventListener(event, onTransitionEnd); 11433 }); 11434 } 11435 11436 function onMouseLeave() { 11437 if (swiper.params.autoplay.disableOnInteraction) { 11438 return; 11439 } 11440 11441 swiper.autoplay.paused = false; 11442 emit('autoplayResume'); 11443 run(); 11444 } 11445 11446 function attachMouseEvents() { 11447 if (swiper.params.autoplay.pauseOnMouseEnter) { 11448 swiper.$el.on('mouseenter', onMouseEnter); 11449 swiper.$el.on('mouseleave', onMouseLeave); 11450 } 11451 } 11452 11453 function detachMouseEvents() { 11454 swiper.$el.off('mouseenter', onMouseEnter); 11455 swiper.$el.off('mouseleave', onMouseLeave); 11456 } 11457 11458 on('init', () => { 11459 if (swiper.params.autoplay.enabled) { 11460 start(); 11461 const document = getDocument(); 11462 document.addEventListener('visibilitychange', onVisibilityChange); 11463 attachMouseEvents(); 11464 } 11465 }); 11466 on('beforeTransitionStart', (_s, speed, internal) => { 11467 if (swiper.autoplay.running) { 11468 if (internal || !swiper.params.autoplay.disableOnInteraction) { 11469 swiper.autoplay.pause(speed); 11470 } else { 11471 stop(); 11472 } 11473 } 11474 }); 11475 on('sliderFirstMove', () => { 11476 if (swiper.autoplay.running) { 11477 if (swiper.params.autoplay.disableOnInteraction) { 11478 stop(); 11479 } else { 11480 pause(); 11481 } 11482 } 11483 }); 11484 on('touchEnd', () => { 11485 if (swiper.params.cssMode && swiper.autoplay.paused && !swiper.params.autoplay.disableOnInteraction) { 11486 run(); 11487 } 11488 }); 11489 on('destroy', () => { 11490 detachMouseEvents(); 11491 11492 if (swiper.autoplay.running) { 11493 stop(); 11494 } 11495 11496 const document = getDocument(); 11497 document.removeEventListener('visibilitychange', onVisibilityChange); 11498 }); 11499 Object.assign(swiper.autoplay, { 11500 pause, 11501 run, 11502 start, 11503 stop 11504 }); 11505 } 11506 11507 function Thumb(_ref) { 11508 let { 11509 swiper, 11510 extendParams, 11511 on 11512 } = _ref; 11513 extendParams({ 11514 thumbs: { 11515 swiper: null, 11516 multipleActiveThumbs: true, 11517 autoScrollOffset: 0, 11518 slideThumbActiveClass: 'swiper-slide-thumb-active', 11519 thumbsContainerClass: 'swiper-thumbs' 11520 } 11521 }); 11522 let initialized = false;
11523 let swiperCreated = false; 11524 swiper.thumbs = { 11525 swiper: null 11526 }; 11527 11528 function onThumbClick() { 11529 const thumbsSwiper = swiper.thumbs.swiper; 11530 if (!thumbsSwiper || thumbsSwiper.destroyed) return; 11531 const clickedIndex = thumbsSwiper.clickedIndex; 11532 const clickedSlide = thumbsSwiper.clickedSlide; 11533 if (clickedSlide && $(clickedSlide).hasClass(swiper.params.thumbs.slideThumbActiveClass)) return; 11534 if (typeof clickedIndex === 'undefined' || clickedIndex === null) return; 11535 let slideToIndex; 11536 11537 if (thumbsSwiper.params.loop) { 11538 slideToIndex = parseInt($(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10); 11539 } else { 11540 slideToIndex = clickedIndex; 11541 } 11542 11543 if (swiper.params.loop) { 11544 let currentIndex = swiper.activeIndex; 11545 11546 if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) { 11547 swiper.loopFix(); // eslint-disable-next-line 11548 11549 swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; 11550 currentIndex = swiper.activeIndex; 11551 } 11552 11553 const prevIndex = swiper.slides.eq(currentIndex).prevAll(`[data-swiper-slide-index="${slideToIndex}"]`).eq(0).index(); 11554 const nextIndex = swiper.slides.eq(currentIndex).nextAll(`[data-swiper-slide-index="${slideToIndex}"]`).eq(0).index(); 11555 if (typeof prevIndex === 'undefined') slideToIndex = nextIndex;else if (typeof nextIndex === 'undefined') slideToIndex = prevIndex;else if (nextIndex - currentIndex < currentIndex - prevIndex) slideToIndex = nextIndex;else slideToIndex = prevIndex; 11556 } 11557 11558 swiper.slideTo(slideToIndex); 11559 } 11560 11561 function init() { 11562 const { 11563 thumbs: thumbsParams 11564 } = swiper.params; 11565 if (initialized) return false; 11566 initialized = true; 11567 const SwiperClass = swiper.constructor; 11568 11569 if (thumbsParams.swiper instanceof SwiperClass) { 11570 swiper.thumbs.swiper = thumbsParams.swiper; 11571 Object.assign(swiper.thumbs.swiper.originalParams, { 11572 watchSlidesProgress: true, 11573 slideToClickedSlide: false 11574 }); 11575 Object.assign(swiper.thumbs.swiper.params, { 11576 watchSlidesProgress: true, 11577 slideToClickedSlide: false 11578 }); 11579 } else if (isObject(thumbsParams.swiper)) { 11580 const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper); 11581 Object.assign(thumbsSwiperParams, { 11582 watchSlidesProgress: true, 11583 slideToClickedSlide: false 11584 }); 11585 swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams); 11586 swiperCreated = true; 11587 } 11588 11589 swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass); 11590 swiper.thumbs.swiper.on('tap', onThumbClick); 11591 return true; 11592 } 11593 11594 function update(initial) { 11595 const thumbsSwiper = swiper.thumbs.swiper; 11596 if (!thumbsSwiper || thumbsSwiper.destroyed) return; 11597 const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView; // Activate thumbs 11598 11599 let thumbsToActivate = 1; 11600 const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass; 11601 11602 if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) { 11603 thumbsToActivate = swiper.params.slidesPerView; 11604 } 11605 11606 if (!swiper.params.thumbs.multipleActiveThumbs) { 11607 thumbsToActivate = 1; 11608 } 11609 11610 thumbsToActivate = Math.floor(thumbsToActivate); 11611 thumbsSwiper.slides.removeClass(thumbActiveClass); 11612 11613 if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) { 11614 for (let i = 0; i < thumbsToActivate; i += 1) { 11615 thumbsSwiper.$wrapperEl.children(`[data-swiper-slide-index="${swiper.realIndex + i}"]`).addClass(thumbActiveClass); 11616 } 11617 } else { 11618 for (let i = 0; i < thumbsToActivate; i += 1) { 11619 thumbsSwiper.slides.eq(swiper.realIndex + i).addClass(thumbActiveClass); 11620 } 11621 } 11622 11623 const autoScrollOffset = swiper.params.thumbs.autoScrollOffset; 11624 const useOffset = autoScrollOffset && !thumbsSwiper.params.loop; 11625 11626 if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) { 11627 let currentThumbsIndex = thumbsSwiper.activeIndex; 11628 let newThumbsIndex; 11629 let direction; 11630 11631 if (thumbsSwiper.params.loop) { 11632 if (thumbsSwiper.slides.eq(currentThumbsIndex).hasClass(thumbsSwiper.params.slideDuplicateClass)) { 11633 thumbsSwiper.loopFix(); // eslint-disable-next-line 11634 11635 thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft; 11636 currentThumbsIndex = thumbsSwiper.activeIndex; 11637 } // Find actual thumbs index to slide to 11638 11639 11640 const prevThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).prevAll(`[data-swiper-slide-index="${swiper.realIndex}"]`).eq(0).index(); 11641 const nextThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).nextAll(`[data-swiper-slide-index="${swiper.realIndex}"]`).eq(0).index(); 11642 11643 if (typeof prevThumbsIndex === 'undefined') { 11644 newThumbsIndex = nextThumbsIndex; 11645 } else if (typeof nextThumbsIndex === 'undefined') { 11646 newThumbsIndex = prevThumbsIndex; 11647 } else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) { 11648 newThumbsIndex = thumbsSwiper.params.slidesPerGroup > 1 ? nextThumbsIndex : currentThumbsIndex; 11649 } else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) { 11650 newThumbsIndex = nextThumbsIndex; 11651 } else { 11652 newThumbsIndex = prevThumbsIndex; 11653 } 11654 11655 direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev'; 11656 } else { 11657 newThumbsIndex = swiper.realIndex; 11658 direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev'; 11659 } 11660 11661 if (useOffset) { 11662 newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset; 11663 } 11664 11665 if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) { 11666 if (thumbsSwiper.params.centeredSlides) { 11667 if (newThumbsIndex > currentThumbsIndex) { 11668 newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1; 11669 } else { 11670 newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1; 11671 } 11672 } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1) ; 11673 11674 thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined); 11675 } 11676 } 11677 } 11678 11679 on('beforeInit', () => { 11680 const { 11681 thumbs 11682 } = swiper.params; 11683 if (!thumbs || !thumbs.swiper) return; 11684 init(); 11685 update(true); 11686 }); 11687 on('slideChange update resize observerUpdate', () => { 11688 update(); 11689 }); 11690 on('setTransition', (_s, duration) => { 11691 const thumbsSwiper = swiper.thumbs.swiper; 11692 if (!thumbsSwiper || thumbsSwiper.destroyed) return; 11693 thumbsSwiper.setTransition(duration); 11694 }); 11695 on('beforeDestroy', () => { 11696 const thumbsSwiper = swiper.thumbs.swiper; 11697 if (!thumbsSwiper || thumbsSwiper.destroyed) return; 11698 11699 if (swiperCreated) { 11700 thumbsSwiper.destroy(); 11701 } 11702 });
11703 Object.assign(swiper.thumbs, { 11704 init, 11705 update 11706 }); 11707 } 11708 11709 function freeMode(_ref) { 11710 let { 11711 swiper, 11712 extendParams, 11713 emit, 11714 once 11715 } = _ref; 11716 extendParams({ 11717 freeMode: { 11718 enabled: false, 11719 momentum: true, 11720 momentumRatio: 1, 11721 momentumBounce: true, 11722 momentumBounceRatio: 1, 11723 momentumVelocityRatio: 1, 11724 sticky: false, 11725 minimumVelocity: 0.02 11726 } 11727 }); 11728 11729 function onTouchStart() { 11730 const translate = swiper.getTranslate(); 11731 swiper.setTranslate(translate); 11732 swiper.setTransition(0); 11733 swiper.touchEventsData.velocities.length = 0; 11734 swiper.freeMode.onTouchEnd({ 11735 currentPos: swiper.rtl ? swiper.translate : -swiper.translate 11736 }); 11737 } 11738 11739 function onTouchMove() { 11740 const { 11741 touchEventsData: data, 11742 touches 11743 } = swiper; // Velocity 11744 11745 if (data.velocities.length === 0) { 11746 data.velocities.push({ 11747 position: touches[swiper.isHorizontal() ? 'startX' : 'startY'], 11748 time: data.touchStartTime 11749 }); 11750 } 11751 11752 data.velocities.push({ 11753 position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'], 11754 time: now() 11755 }); 11756 } 11757 11758 function onTouchEnd(_ref2) { 11759 let { 11760 currentPos 11761 } = _ref2; 11762 const { 11763 params, 11764 $wrapperEl, 11765 rtlTranslate: rtl, 11766 snapGrid, 11767 touchEventsData: data 11768 } = swiper; // Time diff 11769 11770 const touchEndTime = now(); 11771 const timeDiff = touchEndTime - data.touchStartTime; 11772
vendor: 7,238 bytes, lines 11773-11977
11773 if (currentPos < -swiper.minTranslate()) { 11774 swiper.slideTo(swiper.activeIndex); 11775 return; 11776 } 11777 11778 if (currentPos > -swiper.maxTranslate()) { 11779 if (swiper.slides.length < snapGrid.length) { 11780 swiper.slideTo(snapGrid.length - 1); 11781 } else { 11782 swiper.slideTo(swiper.slides.length - 1); 11783 } 11784 11785 return; 11786 } 11787 11788 if (params.freeMode.momentum) { 11789 if (data.velocities.length > 1) { 11790 const lastMoveEvent = data.velocities.pop(); 11791 const velocityEvent = data.velocities.pop(); 11792 const distance = lastMoveEvent.position - velocityEvent.position; 11793 const time = lastMoveEvent.time - velocityEvent.time; 11794 swiper.velocity = distance / time; 11795 swiper.velocity /= 2; 11796 11797 if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) { 11798 swiper.velocity = 0; 11799 } // this implies that the user stopped moving a finger then released. 11800 // There would be no events with distance zero, so the last event is stale. 11801 11802 11803 if (time > 150 || now() - lastMoveEvent.time > 300) { 11804 swiper.velocity = 0; 11805 } 11806 } else { 11807 swiper.velocity = 0; 11808 } 11809 11810 swiper.velocity *= params.freeMode.momentumVelocityRatio; 11811 data.velocities.length = 0; 11812 let momentumDuration = 1000 * params.freeMode.momentumRatio; 11813 const momentumDistance = swiper.velocity * momentumDuration; 11814 let newPosition = swiper.translate + momentumDistance; 11815 if (rtl) newPosition = -newPosition; 11816 let doBounce = false; 11817 let afterBouncePosition; 11818 const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio; 11819 let needsLoopFix; 11820 11821 if (newPosition < swiper.maxTranslate()) { 11822 if (params.freeMode.momentumBounce) { 11823 if (newPosition + swiper.maxTranslate() < -bounceAmount) { 11824 newPosition = swiper.maxTranslate() - bounceAmount; 11825 } 11826 11827 afterBouncePosition = swiper.maxTranslate(); 11828 doBounce = true; 11829 data.allowMomentumBounce = true; 11830 } else { 11831 newPosition = swiper.maxTranslate(); 11832 } 11833 11834 if (params.loop && params.centeredSlides) needsLoopFix = true; 11835 } else if (newPosition > swiper.minTranslate()) { 11836 if (params.freeMode.momentumBounce) { 11837 if (newPosition - swiper.minTranslate() > bounceAmount) { 11838 newPosition = swiper.minTranslate() + bounceAmount; 11839 } 11840 11841 afterBouncePosition = swiper.minTranslate(); 11842 doBounce = true; 11843 data.allowMomentumBounce = true; 11844 } else { 11845 newPosition = swiper.minTranslate(); 11846 } 11847 11848 if (params.loop && params.centeredSlides) needsLoopFix = true; 11849 } else if (params.freeMode.sticky) { 11850 let nextSlide; 11851 11852 for (let j = 0; j < snapGrid.length; j += 1) { 11853 if (snapGrid[j] > -newPosition) { 11854 nextSlide = j; 11855 break; 11856 } 11857 } 11858 11859 if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') { 11860 newPosition = snapGrid[nextSlide]; 11861 } else { 11862 newPosition = snapGrid[nextSlide - 1]; 11863 } 11864 11865 newPosition = -newPosition; 11866 } 11867 11868 if (needsLoopFix) { 11869 once('transitionEnd', () => { 11870 swiper.loopFix(); 11871 }); 11872 } // Fix duration 11873 11874 11875 if (swiper.velocity !== 0) { 11876 if (rtl) { 11877 momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity); 11878 } else { 11879 momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity); 11880 } 11881 11882 if (params.freeMode.sticky) { 11883 // If freeMode.sticky is active and the user ends a swipe with a slow-velocity 11884 // event, then durations can be 20+ seconds to slide one (or zero!) slides. 11885 // It's easy to see this when simulating touch with mouse events. To fix this, 11886 // limit single-slide swipes to the default slide duration. This also has the 11887 // nice side effect of matching slide speed if the user stopped moving before 11888 // lifting finger or mouse vs. moving slowly before lifting the finger/mouse. 11889 // For faster swipes, also apply limits (albeit higher ones). 11890 const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate); 11891 const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex]; 11892 11893 if (moveDistance < currentSlideSize) { 11894 momentumDuration = params.speed; 11895 } else if (moveDistance < 2 * currentSlideSize) { 11896 momentumDuration = params.speed * 1.5; 11897 } else { 11898 momentumDuration = params.speed * 2.5; 11899 } 11900 } 11901 } else if (params.freeMode.sticky) { 11902 swiper.slideToClosest(); 11903 return; 11904 } 11905 11906 if (params.freeMode.momentumBounce && doBounce) { 11907 swiper.updateProgress(afterBouncePosition); 11908 swiper.setTransition(momentumDuration); 11909 swiper.setTranslate(newPosition); 11910 swiper.transitionStart(true, swiper.swipeDirection); 11911 swiper.animating = true; 11912 $wrapperEl.transitionEnd(() => { 11913 if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return; 11914 emit('momentumBounce'); 11915 swiper.setTransition(params.speed); 11916 setTimeout(() => { 11917 swiper.setTranslate(afterBouncePosition); 11918 $wrapperEl.transitionEnd(() => { 11919 if (!swiper || swiper.destroyed) return; 11920 swiper.transitionEnd(); 11921 }); 11922 }, 0); 11923 }); 11924 } else if (swiper.velocity) { 11925 emit('_freeModeNoMomentumRelease'); 11926 swiper.updateProgress(newPosition); 11927 swiper.setTransition(momentumDuration); 11928 swiper.setTranslate(newPosition); 11929 swiper.transitionStart(true, swiper.swipeDirection); 11930 11931 if (!swiper.animating) { 11932 swiper.animating = true; 11933 $wrapperEl.transitionEnd(() => { 11934 if (!swiper || swiper.destroyed) return; 11935 swiper.transitionEnd(); 11936 }); 11937 } 11938 } else { 11939 swiper.updateProgress(newPosition); 11940 } 11941 11942 swiper.updateActiveIndex(); 11943 swiper.updateSlidesClasses(); 11944 } else if (params.freeMode.sticky) { 11945 swiper.slideToClosest(); 11946 return; 11947 } else if (params.freeMode) { 11948 emit('_freeModeNoMomentumRelease'); 11949 } 11950 11951 if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) { 11952 swiper.updateProgress(); 11953 swiper.updateActiveIndex(); 11954 swiper.updateSlidesClasses(); 11955 } 11956 } 11957 11958 Object.assign(swiper, { 11959 freeMode: { 11960 onTouchStart, 11961 onTouchMove, 11962 onTouchEnd 11963 } 11964 }); 11965 } 11966 11967 function Grid(_ref) { 11968 let { 11969 swiper, 11970 extendParams 11971 } = _ref; 11972 extendParams({ 11973 grid: { 11974 rows: 1, 11975 fill: 'column' 11976 } 11977 });
11978 let slidesNumberEvenToRows; 11979 let slidesPerRow; 11980 let numFullColumns; 11981 11982 const initSlides = slidesLength => { 11983 const { 11984 slidesPerView 11985 } = swiper.params; 11986 const { 11987 rows, 11988 fill 11989 } = swiper.params.grid; 11990 slidesPerRow = slidesNumberEvenToRows / rows; 11991 numFullColumns = Math.floor(slidesLength / rows); 11992 11993 if (Math.floor(slidesLength / rows) === slidesLength / rows) { 11994 slidesNumberEvenToRows = slidesLength; 11995 } else { 11996 slidesNumberEvenToRows = Math.ceil(slidesLength / rows) * rows; 11997 } 11998 11999 if (slidesPerView !== 'auto' && fill === 'row') { 12000 slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, slidesPerView * rows); 12001 } 12002 }; 12003 12004 const updateSlide = (i, slide, slidesLength, getDirectionLabel) => { 12005 const { 12006 slidesPerGroup, 12007 spaceBetween 12008 } = swiper.params; 12009 const { 12010 rows, 12011 fill 12012 } = swiper.params.grid; // Set slides order 12013 12014 let newSlideOrderIndex; 12015 let column; 12016 let row; 12017 12018 if (fill === 'row' && slidesPerGroup > 1) { 12019 const groupIndex = Math.floor(i / (slidesPerGroup * rows)); 12020 const slideIndexInGroup = i - rows * slidesPerGroup * groupIndex; 12021 const columnsInGroup = groupIndex === 0 ? slidesPerGroup : Math.min(Math.ceil((slidesLength - groupIndex * rows * slidesPerGroup) / rows), slidesPerGroup); 12022 row = Math.floor(slideIndexInGroup / columnsInGroup); 12023 column = slideIndexInGroup - row * columnsInGroup + groupIndex * slidesPerGroup; 12024 newSlideOrderIndex = column + row * slidesNumberEvenToRows / rows; 12025 slide.css({ 12026 '-webkit-order': newSlideOrderIndex, 12027 order: newSlideOrderIndex 12028 }); 12029 } else if (fill === 'column') { 12030 column = Math.floor(i / rows); 12031 row = i - column * rows; 12032 12033 if (column > numFullColumns || column === numFullColumns && row === rows - 1) { 12034 row += 1; 12035 12036 if (row >= rows) { 12037 row = 0; 12038 column += 1; 12039 } 12040 } 12041 } else { 12042 row = Math.floor(i / slidesPerRow); 12043 column = i - row * slidesPerRow; 12044 } 12045 12046 slide.css(getDirectionLabel('margin-top'), row !== 0 ? spaceBetween && `${spaceBetween}px` : ''); 12047 }; 12048 12049 const updateWrapperSize = (slideSize, snapGrid, getDirectionLabel) => { 12050 const { 12051 spaceBetween, 12052 centeredSlides, 12053 roundLengths 12054 } = swiper.params; 12055 const { 12056 rows 12057 } = swiper.params.grid; 12058 swiper.virtualSize = (slideSize + spaceBetween) * slidesNumberEvenToRows; 12059 swiper.virtualSize = Math.ceil(swiper.virtualSize / rows) - spaceBetween; 12060 swiper.$wrapperEl.css({ 12061 [getDirectionLabel('width')]: `${swiper.virtualSize + spaceBetween}px` 12062 }); 12063 12064 if (centeredSlides) { 12065 snapGrid.splice(0, snapGrid.length); 12066 const newSlidesGrid = []; 12067 12068 for (let i = 0; i < snapGrid.length; i += 1) { 12069 let slidesGridItem = snapGrid[i]; 12070 if (roundLengths) slidesGridItem = Math.floor(slidesGridItem); 12071 if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem); 12072 } 12073 12074 snapGrid.push(...newSlidesGrid); 12075 } 12076 }; 12077 12078 swiper.grid = { 12079 initSlides, 12080 updateSlide, 12081 updateWrapperSize 12082 }; 12083 } 12084 12085 function appendSlide(slides) { 12086 const swiper = this; 12087 const { 12088 $wrapperEl, 12089 params 12090 } = swiper; 12091 12092 if (params.loop) { 12093 swiper.loopDestroy(); 12094 } 12095 12096 if (typeof slides === 'object' && 'length' in slides) { 12097 for (let i = 0; i < slides.length; i += 1) { 12098 if (slides[i]) $wrapperEl.append(slides[i]); 12099 } 12100 } else { 12101 $wrapperEl.append(slides); 12102 } 12103 12104 if (params.loop) { 12105 swiper.loopCreate(); 12106 } 12107 12108 if (!params.observer) { 12109 swiper.update(); 12110 } 12111 } 12112 12113 function prependSlide(slides) { 12114 const swiper = this; 12115 const { 12116 params, 12117 $wrapperEl, 12118 activeIndex 12119 } = swiper; 12120 12121 if (params.loop) { 12122 swiper.loopDestroy(); 12123 } 12124 12125 let newActiveIndex = activeIndex + 1; 12126 12127 if (typeof slides === 'object' && 'length' in slides) { 12128 for (let i = 0; i < slides.length; i += 1) {
vendor: 5,698 bytes, lines 12129-12342
12129 if (slides[i]) $wrapperEl.prepend(slides[i]); 12130 } 12131 12132 newActiveIndex = activeIndex + slides.length; 12133 } else { 12134 $wrapperEl.prepend(slides); 12135 } 12136 12137 if (params.loop) { 12138 swiper.loopCreate(); 12139 } 12140 12141 if (!params.observer) { 12142 swiper.update(); 12143 } 12144 12145 swiper.slideTo(newActiveIndex, 0, false); 12146 } 12147 12148 function addSlide(index, slides) { 12149 const swiper = this; 12150 const { 12151 $wrapperEl, 12152 params, 12153 activeIndex 12154 } = swiper; 12155 let activeIndexBuffer = activeIndex; 12156 12157 if (params.loop) { 12158 activeIndexBuffer -= swiper.loopedSlides; 12159 swiper.loopDestroy(); 12160 swiper.slides = $wrapperEl.children(`.${params.slideClass}`); 12161 } 12162 12163 const baseLength = swiper.slides.length; 12164 12165 if (index <= 0) { 12166 swiper.prependSlide(slides); 12167 return; 12168 } 12169 12170 if (index >= baseLength) { 12171 swiper.appendSlide(slides); 12172 return; 12173 } 12174 12175 let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer; 12176 const slidesBuffer = []; 12177 12178 for (let i = baseLength - 1; i >= index; i -= 1) { 12179 const currentSlide = swiper.slides.eq(i); 12180 currentSlide.remove(); 12181 slidesBuffer.unshift(currentSlide); 12182 } 12183 12184 if (typeof slides === 'object' && 'length' in slides) { 12185 for (let i = 0; i < slides.length; i += 1) { 12186 if (slides[i]) $wrapperEl.append(slides[i]); 12187 } 12188 12189 newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer; 12190 } else { 12191 $wrapperEl.append(slides); 12192 } 12193 12194 for (let i = 0; i < slidesBuffer.length; i += 1) { 12195 $wrapperEl.append(slidesBuffer[i]); 12196 } 12197 12198 if (params.loop) { 12199 swiper.loopCreate(); 12200 } 12201 12202 if (!params.observer) { 12203 swiper.update(); 12204 } 12205 12206 if (params.loop) { 12207 swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false); 12208 } else { 12209 swiper.slideTo(newActiveIndex, 0, false); 12210 } 12211 } 12212 12213 function removeSlide(slidesIndexes) { 12214 const swiper = this; 12215 const { 12216 params, 12217 $wrapperEl, 12218 activeIndex 12219 } = swiper; 12220 let activeIndexBuffer = activeIndex; 12221 12222 if (params.loop) { 12223 activeIndexBuffer -= swiper.loopedSlides; 12224 swiper.loopDestroy(); 12225 swiper.slides = $wrapperEl.children(`.${params.slideClass}`); 12226 } 12227 12228 let newActiveIndex = activeIndexBuffer; 12229 let indexToRemove; 12230 12231 if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) { 12232 for (let i = 0; i < slidesIndexes.length; i += 1) { 12233 indexToRemove = slidesIndexes[i]; 12234 if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove(); 12235 if (indexToRemove < newActiveIndex) newActiveIndex -= 1; 12236 } 12237 12238 newActiveIndex = Math.max(newActiveIndex, 0); 12239 } else { 12240 indexToRemove = slidesIndexes; 12241 if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove(); 12242 if (indexToRemove < newActiveIndex) newActiveIndex -= 1; 12243 newActiveIndex = Math.max(newActiveIndex, 0); 12244 } 12245 12246 if (params.loop) { 12247 swiper.loopCreate(); 12248 } 12249 12250 if (!params.observer) { 12251 swiper.update(); 12252 } 12253 12254 if (params.loop) { 12255 swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false); 12256 } else { 12257 swiper.slideTo(newActiveIndex, 0, false); 12258 } 12259 } 12260 12261 function removeAllSlides() { 12262 const swiper = this; 12263 const slidesIndexes = []; 12264 12265 for (let i = 0; i < swiper.slides.length; i += 1) { 12266 slidesIndexes.push(i); 12267 } 12268 12269 swiper.removeSlide(slidesIndexes); 12270 } 12271 12272 function Manipulation(_ref) { 12273 let { 12274 swiper 12275 } = _ref; 12276 Object.assign(swiper, { 12277 appendSlide: appendSlide.bind(swiper), 12278 prependSlide: prependSlide.bind(swiper), 12279 addSlide: addSlide.bind(swiper), 12280 removeSlide: removeSlide.bind(swiper), 12281 removeAllSlides: removeAllSlides.bind(swiper) 12282 }); 12283 } 12284 12285 function effectInit(params) { 12286 const { 12287 effect, 12288 swiper, 12289 on, 12290 setTranslate, 12291 setTransition, 12292 overwriteParams, 12293 perspective, 12294 recreateShadows, 12295 getEffectParams 12296 } = params; 12297 on('beforeInit', () => { 12298 if (swiper.params.effect !== effect) return; 12299 swiper.classNames.push(`${swiper.params.containerModifierClass}${effect}`); 12300 12301 if (perspective && perspective()) { 12302 swiper.classNames.push(`${swiper.params.containerModifierClass}3d`); 12303 } 12304 12305 const overwriteParamsResult = overwriteParams ? overwriteParams() : {}; 12306 Object.assign(swiper.params, overwriteParamsResult); 12307 Object.assign(swiper.originalParams, overwriteParamsResult); 12308 }); 12309 on('setTranslate', () => { 12310 if (swiper.params.effect !== effect) return; 12311 setTranslate(); 12312 }); 12313 on('setTransition', (_s, duration) => { 12314 if (swiper.params.effect !== effect) return; 12315 setTransition(duration); 12316 }); 12317 on('transitionEnd', () => { 12318 if (swiper.params.effect !== effect) return; 12319 12320 if (recreateShadows) { 12321 if (!getEffectParams || !getEffectParams().slideShadows) return; // remove shadows 12322 12323 swiper.slides.each(slideEl => { 12324 const $slideEl = swiper.$(slideEl); 12325 $slideEl.find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').remove(); 12326 }); // create new one 12327 12328 recreateShadows(); 12329 } 12330 }); 12331 let requireUpdateOnVirtual; 12332 on('virtualUpdate', () => { 12333 if (swiper.params.effect !== effect) return; 12334 12335 if (!swiper.slides.length) { 12336 requireUpdateOnVirtual = true; 12337 } 12338 12339 requestAnimationFrame(() => { 12340 if (requireUpdateOnVirtual && swiper.slides && swiper.slides.length) { 12341 setTranslate(); 12342 requireUpdateOnVirtual = false;
12343 } 12344 }); 12345 }); 12346 } 12347 12348 function effectTarget(effectParams, $slideEl) { 12349 if (effectParams.transformEl) { 12350 return $slideEl.find(effectParams.transformEl).css({ 12351 'backface-visibility': 'hidden', 12352 '-webkit-backface-visibility': 'hidden' 12353 }); 12354 } 12355 12356 return $slideEl; 12357 } 12358 12359 function effectVirtualTransitionEnd(_ref) { 12360 let { 12361 swiper, 12362 duration, 12363 transformEl, 12364 allSlides 12365 } = _ref; 12366 const { 12367 slides, 12368 activeIndex, 12369 $wrapperEl 12370 } = swiper; 12371 12372 if (swiper.params.virtualTranslate && duration !== 0) { 12373 let eventTriggered = false; 12374 let $transitionEndTarget; 12375 12376 if (allSlides) { 12377 $transitionEndTarget = transformEl ? slides.find(transformEl) : slides; 12378 } else { 12379 $transitionEndTarget = transformEl ? slides.eq(activeIndex).find(transformEl) : slides.eq(activeIndex); 12380 } 12381 12382 $transitionEndTarget.transitionEnd(() => { 12383 if (eventTriggered) return; 12384 if (!swiper || swiper.destroyed) return; 12385 eventTriggered = true; 12386 swiper.animating = false; 12387 const triggerEvents = ['webkitTransitionEnd', 'transitionend']; 12388 12389 for (let i = 0; i < triggerEvents.length; i += 1) { 12390 $wrapperEl.trigger(triggerEvents[i]); 12391 } 12392 }); 12393 } 12394 } 12395 12396 function EffectFade(_ref) { 12397 let { 12398 swiper, 12399 extendParams, 12400 on 12401 } = _ref; 12402 extendParams({ 12403 fadeEffect: { 12404 crossFade: false, 12405 transformEl: null 12406 } 12407 }); 12408 12409 const setTranslate = () => { 12410 const { 12411 slides 12412 } = swiper; 12413 const params = swiper.params.fadeEffect; 12414 12415 for (let i = 0; i < slides.length; i += 1) { 12416 const $slideEl = swiper.slides.eq(i); 12417 const offset = $slideEl[0].swiperSlideOffset; 12418 let tx = -offset; 12419 if (!swiper.params.virtualTranslate) tx -= swiper.translate; 12420 let ty = 0; 12421 12422 if (!swiper.isHorizontal()) { 12423 ty = tx; 12424 tx = 0; 12425 } 12426 12427 const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs($slideEl[0].progress), 0) : 1 + Math.min(Math.max($slideEl[0].progress, -1), 0); 12428 const $targetEl = effectTarget(params, $slideEl); 12429 $targetEl.css({ 12430 opacity: slideOpacity 12431 }).transform(`translate3d(${tx}px, ${ty}px, 0px)`); 12432 } 12433 }; 12434 12435 const setTransition = duration => { 12436 const { 12437 transformEl 12438 } = swiper.params.fadeEffect; 12439 const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides; 12440 $transitionElements.transition(duration); 12441 effectVirtualTransitionEnd({ 12442 swiper, 12443 duration, 12444 transformEl, 12445 allSlides: true 12446 }); 12447 }; 12448 12449 effectInit({ 12450 effect: 'fade', 12451 swiper, 12452 on, 12453 setTranslate, 12454 setTransition, 12455 overwriteParams: () => ({ 12456 slidesPerView: 1, 12457 slidesPerGroup: 1, 12458 watchSlidesProgress: true, 12459 spaceBetween: 0, 12460 virtualTranslate: !swiper.params.cssMode 12461 }) 12462 }); 12463 } 12464 12465 function EffectCube(_ref) { 12466 let { 12467 swiper, 12468 extendParams, 12469 on 12470 } = _ref; 12471 extendParams({ 12472 cubeEffect: { 12473 slideShadows: true, 12474 shadow: true, 12475 shadowOffset: 20, 12476 shadowScale: 0.94 12477 } 12478 }); 12479 12480 const createSlideShadows = ($slideEl, progress, isHorizontal) => { 12481 let shadowBefore = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); 12482 let shadowAfter = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); 12483 12484 if (shadowBefore.length === 0) { 12485 shadowBefore = $(`<div class="swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}"></div>`); 12486 $slideEl.append(shadowBefore); 12487 } 12488 12489 if (shadowAfter.length === 0) { 12490 shadowAfter = $(`<div class="swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}"></div>`); 12491 $slideEl.append(shadowAfter); 12492 } 12493 12494 if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0); 12495 if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0); 12496 }; 12497 12498 const recreateShadows = () => { 12499 // create new ones 12500 const isHorizontal = swiper.isHorizontal(); 12501 swiper.slides.each(slideEl => { 12502 const progress = Math.max(Math.min(slideEl.progress, 1), -1); 12503 createSlideShadows($(slideEl), progress, isHorizontal); 12504 }); 12505 }; 12506 12507 const setTranslate = () => { 12508 const { 12509 $el, 12510 $wrapperEl, 12511 slides, 12512 width: swiperWidth, 12513 height: swiperHeight, 12514 rtlTranslate: rtl, 12515 size: swiperSize, 12516 browser 12517 } = swiper; 12518 const params = swiper.params.cubeEffect; 12519 const isHorizontal = swiper.isHorizontal(); 12520 const isVirtual = swiper.virtual && swiper.params.virtual.enabled; 12521 let wrapperRotate = 0; 12522 let $cubeShadowEl; 12523 12524 if (params.shadow) { 12525 if (isHorizontal) { 12526 $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow'); 12527 12528 if ($cubeShadowEl.length === 0) {
12529 $cubeShadowEl = $('<div class="swiper-cube-shadow"></div>'); 12530 $wrapperEl.append($cubeShadowEl); 12531 } 12532 12533 $cubeShadowEl.css({ 12534 height: `${swiperWidth}px` 12535 }); 12536 } else { 12537 $cubeShadowEl = $el.find('.swiper-cube-shadow'); 12538 12539 if ($cubeShadowEl.length === 0) { 12540 $cubeShadowEl = $('<div class="swiper-cube-shadow"></div>'); 12541 $el.append($cubeShadowEl); 12542 } 12543 } 12544 } 12545 12546 for (let i = 0; i < slides.length; i += 1) { 12547 const $slideEl = slides.eq(i); 12548 let slideIndex = i; 12549 12550 if (isVirtual) { 12551 slideIndex = parseInt($slideEl.attr('data-swiper-slide-index'), 10); 12552 } 12553 12554 let slideAngle = slideIndex * 90; 12555 let round = Math.floor(slideAngle / 360); 12556 12557 if (rtl) { 12558 slideAngle = -slideAngle; 12559 round = Math.floor(-slideAngle / 360); 12560 } 12561 12562 const progress = Math.max(Math.min($slideEl[0].progress, 1), -1); 12563 let tx = 0; 12564 let ty = 0; 12565 let tz = 0; 12566 12567 if (slideIndex % 4 === 0) { 12568 tx = -round * 4 * swiperSize; 12569 tz = 0; 12570 } else if ((slideIndex - 1) % 4 === 0) { 12571 tx = 0; 12572 tz = -round * 4 * swiperSize; 12573 } else if ((slideIndex - 2) % 4 === 0) { 12574 tx = swiperSize + round * 4 * swiperSize; 12575 tz = swiperSize; 12576 } else if ((slideIndex - 3) % 4 === 0) { 12577 tx = -swiperSize; 12578 tz = 3 * swiperSize + swiperSize * 4 * round; 12579 } 12580 12581 if (rtl) { 12582 tx = -tx; 12583 } 12584 12585 if (!isHorizontal) { 12586 ty = tx; 12587 tx = 0; 12588 } 12589 12590 const transform = `rotateX(${isHorizontal ? 0 : -slideAngle}deg) rotateY(${isHorizontal ? slideAngle : 0}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`; 12591 12592 if (progress <= 1 && progress > -1) { 12593 wrapperRotate = slideIndex * 90 + progress * 90; 12594 if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90; 12595 } 12596 12597 $slideEl.transform(transform); 12598 12599 if (params.slideShadows) { 12600 createSlideShadows($slideEl, progress, isHorizontal); 12601 } 12602 } 12603 12604 $wrapperEl.css({ 12605 '-webkit-transform-origin': `50% 50% -${swiperSize / 2}px`, 12606 'transform-origin': `50% 50% -${swiperSize / 2}px` 12607 }); 12608 12609 if (params.shadow) { 12610 if (isHorizontal) { 12611 $cubeShadowEl.transform(`translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${-swiperWidth / 2}px) rotateX(90deg) rotateZ(0deg) scale(${params.shadowScale})`); 12612 } else { 12613 const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90; 12614 const multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2); 12615 const scale1 = params.shadowScale; 12616 const scale2 = params.shadowScale / multiplier; 12617 const offset = params.shadowOffset; 12618 $cubeShadowEl.transform(`scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${-swiperHeight / 2 / scale2}px) rotateX(-90deg)`); 12619 } 12620 } 12621 12622 const zFactor = browser.isSafari || browser.isWebView ? -swiperSize / 2 : 0; 12623 $wrapperEl.transform(`translate3d(0px,0,${zFactor}px) rotateX(${swiper.isHorizontal() ? 0 : wrapperRotate}deg) rotateY(${swiper.isHorizontal() ? -wrapperRotate : 0}deg)`); 12624 $wrapperEl[0].style.setProperty('--swiper-cube-translate-z', `${zFactor}px`); 12625 }; 12626 12627 const setTransition = duration => { 12628 const { 12629 $el, 12630 slides 12631 } = swiper; 12632 slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration); 12633 12634 if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) { 12635 $el.find('.swiper-cube-shadow').transition(duration); 12636 } 12637 }; 12638 12639 effectInit({ 12640 effect: 'cube', 12641 swiper, 12642 on, 12643 setTranslate, 12644 setTransition, 12645 recreateShadows, 12646 getEffectParams: () => swiper.params.cubeEffect, 12647 perspective: () => true, 12648 overwriteParams: () => ({ 12649 slidesPerView: 1, 12650 slidesPerGroup: 1, 12651 watchSlidesProgress: true, 12652 resistanceRatio: 0, 12653 spaceBetween: 0, 12654 centeredSlides: false, 12655 virtualTranslate: true 12656 }) 12657 }); 12658 } 12659 12660 function createShadow(params, $slideEl, side) { 12661 const shadowClass = `swiper-slide-shadow${side ? `-${side}` : ''}`; 12662 const $shadowContainer = params.transformEl ? $slideEl.find(params.transformEl) : $slideEl; 12663 let $shadowEl = $shadowContainer.children(`.${shadowClass}`); 12664 12665 if (!$shadowEl.length) { 12666 $shadowEl = $(`<div class="swiper-slide-shadow${side ? `-${side}` : ''}"></div>`); 12667 $shadowContainer.append($shadowEl); 12668 } 12669 12670 return $shadowEl; 12671 } 12672 12673 function EffectFlip(_ref) { 12674 let { 12675 swiper, 12676 extendParams, 12677 on 12678 } = _ref; 12679 extendParams({ 12680 flipEffect: { 12681 slideShadows: true, 12682 limitRotation: true, 12683 transformEl: null 12684 } 12685 }); 12686 12687 const createSlideShadows = ($slideEl, progress, params) => { 12688 let shadowBefore = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); 12689 let shadowAfter = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); 12690 12691 if (shadowBefore.length === 0) { 12692 shadowBefore = createShadow(params, $slideEl, swiper.isHorizontal() ? 'left' : 'top'); 12693 } 12694 12695 if (shadowAfter.length === 0) { 12696 shadowAfter = createShadow(params, $slideEl, swiper.isHorizontal() ? 'right' : 'bottom'); 12697 } 12698 12699 if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0); 12700 if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0); 12701 }; 12702 12703 const recreateShadows = () => { 12704 // Set shadows 12705 const params = swiper.params.flipEffect; 12706 swiper.slides.each(slideEl => { 12707 const $slideEl = $(slideEl); 12708 let progress = $slideEl[0].progress; 12709 12710 if (swiper.params.flipEffect.limitRotation) { 12711 progress = Math.max(Math.min(slideEl.progress, 1), -1); 12712 } 12713 12714 createSlideShadows($slideEl, progress, params); 12715 }); 12716 }; 12717 12718 const setTranslate = () => { 12719 const { 12720 slides, 12721 rtlTranslate: rtl 12722 } = swiper; 12723 const params = swiper.params.flipEffect; 12724 12725 for (let i = 0; i < slides.length; i += 1) { 12726 const $slideEl = slides.eq(i); 12727 let progress = $slideEl[0].progress; 12728 12729 if (swiper.params.flipEffect.limitRotation) { 12730 progress = Math.max(Math.min($slideEl[0].progress, 1), -1); 12731 } 12732 12733 const offset = $slideEl[0].swiperSlideOffset; 12734 const rotate = -180 * progress; 12735 let rotateY = rotate; 12736 let rotateX = 0; 12737 let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset; 12738 let ty = 0; 12739 12740 if (!swiper.isHorizontal()) { 12741 ty = tx; 12742 tx = 0; 12743 rotateX = -rotateY; 12744 rotateY = 0; 12745 } else if (rtl) { 12746 rotateY = -rotateY; 12747 } 12748 12749 $slideEl[0].style.zIndex = -Math.abs(Math.round(progress)) + slides.length; 12750 12751 if (params.slideShadows) { 12752 createSlideShadows($slideEl, progress, params); 12753 } 12754 12755 const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; 12756 const $targetEl = effectTarget(params, $slideEl); 12757 $targetEl.transform(transform); 12758 } 12759 }; 12760 12761 const setTransition = duration => { 12762 const { 12763 transformEl 12764 } = swiper.params.flipEffect; 12765 const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides; 12766 $transitionElements.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration); 12767 effectVirtualTransitionEnd({ 12768 swiper, 12769 duration, 12770 transformEl 12771 }); 12772 }; 12773 12774 effectInit({ 12775 effect: 'flip', 12776 swiper, 12777 on, 12778 setTranslate, 12779 setTransition, 12780 recreateShadows, 12781 getEffectParams: () => swiper.params.flipEffect, 12782 perspective: () => true, 12783 overwriteParams: () => ({ 12784 slidesPerView: 1, 12785 slidesPerGroup: 1, 12786 watchSlidesProgress: true, 12787 spaceBetween: 0, 12788 virtualTranslate: !swiper.params.cssMode 12789 }) 12790 }); 12791 } 12792 12793 function EffectCoverflow(_ref) { 12794 let { 12795 swiper, 12796 extendParams, 12797 on 12798 } = _ref; 12799 extendParams({ 12800 coverflowEffect: { 12801 rotate: 50, 12802 stretch: 0, 12803 depth: 100, 12804 scale: 1, 12805 modifier: 1, 12806 slideShadows: true, 12807 transformEl: null 12808 } 12809 }); 12810 12811 const setTranslate = () => { 12812 const { 12813 width: swiperWidth, 12814 height: swiperHeight, 12815 slides, 12816 slidesSizesGrid 12817 } = swiper; 12818 const params = swiper.params.coverflowEffect; 12819 const isHorizontal = swiper.isHorizontal(); 12820 const transform = swiper.translate; 12821 const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2; 12822 const rotate = isHorizontal ? params.rotate : -params.rotate; 12823 const translate = params.depth; // Each slide offset from center 12824 12825 for (let i = 0, length = slides.length; i < length; i += 1) { 12826 const $slideEl = slides.eq(i); 12827 const slideSize = slidesSizesGrid[i]; 12828 const slideOffset = $slideEl[0].swiperSlideOffset; 12829 const centerOffset = (center - slideOffset - slideSize / 2) / slideSize; 12830 const offsetMultiplier = typeof params.modifier === 'function' ? params.modifier(centerOffset) : centerOffset * params.modifier; 12831 let rotateY = isHorizontal ? rotate * offsetMultiplier : 0; 12832 let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; // var rotateZ = 0 12833 12834 let translateZ = -translate * Math.abs(offsetMultiplier); 12835 let stretch = params.stretch; // Allow percentage to make a relative stretch for responsive sliders 12836 12837 if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) { 12838 stretch = parseFloat(params.stretch) / 100 * slideSize; 12839 } 12840 12841 let translateY = isHorizontal ? 0 : stretch * offsetMultiplier; 12842 let translateX = isHorizontal ? stretch * offsetMultiplier : 0; 12843 let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier); // Fix for ultra small values 12844 12845 if (Math.abs(translateX) < 0.001) translateX = 0; 12846 if (Math.abs(translateY) < 0.001) translateY = 0; 12847 if (Math.abs(translateZ) < 0.001) translateZ = 0; 12848 if (Math.abs(rotateY) < 0.001) rotateY = 0; 12849 if (Math.abs(rotateX) < 0.001) rotateX = 0; 12850 if (Math.abs(scale) < 0.001) scale = 0; 12851 const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(${scale})`; 12852 const $targetEl = effectTarget(params, $slideEl); 12853 $targetEl.transform(slideTransform); 12854 $slideEl[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1; 12855 12856 if (params.slideShadows) { 12857 // Set shadows 12858 let $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); 12859 let $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); 12860 12861 if ($shadowBeforeEl.length === 0) { 12862 $shadowBeforeEl = createShadow(params, $slideEl, isHorizontal ? 'left' : 'top'); 12863 } 12864 12865 if ($shadowAfterEl.length === 0) { 12866 $shadowAfterEl = createShadow(params, $slideEl, isHorizontal ? 'right' : 'bottom'); 12867 } 12868 12869 if ($shadowBeforeEl.length) $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0; 12870 if ($shadowAfterEl.length) $shadowAfterEl[0].style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0; 12871 } 12872 } 12873 }; 12874 12875 const setTransition = duration => { 12876 const { 12877 transformEl 12878 } = swiper.params.coverflowEffect; 12879 const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides; 12880 $transitionElements.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration); 12881 }; 12882 12883 effectInit({ 12884 effect: 'coverflow', 12885 swiper, 12886 on, 12887 setTranslate, 12888 setTransition, 12889 perspective: () => true, 12890 overwriteParams: () => ({ 12891 watchSlidesProgress: true 12892 }) 12893 }); 12894 } 12895 12896 function EffectCreative(_ref) { 12897 let { 12898 swiper, 12899 extendParams, 12900 on 12901 } = _ref; 12902 extendParams({ 12903 creativeEffect: { 12904 transformEl: null, 12905 limitProgress: 1, 12906 shadowPerProgress: false, 12907 progressMultiplier: 1, 12908 perspective: true, 12909 prev: { 12910 translate: [0, 0, 0], 12911 rotate: [0, 0, 0], 12912 opacity: 1, 12913 scale: 1 12914 }, 12915 next: { 12916 translate: [0, 0, 0], 12917 rotate: [0, 0, 0], 12918 opacity: 1, 12919 scale: 1 12920 } 12921 } 12922 }); 12923 12924 const getTranslateValue = value => { 12925 if (typeof value === 'string') return value; 12926 return `${value}px`; 12927 }; 12928 12929 const setTranslate = () => { 12930 const { 12931 slides, 12932 $wrapperEl, 12933 slidesSizesGrid 12934 } = swiper; 12935 const params = swiper.params.creativeEffect; 12936 const { 12937 progressMultiplier: multiplier 12938 } = params; 12939 const isCenteredSlides = swiper.params.centeredSlides; 12940 12941 if (isCenteredSlides) { 12942 const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0; 12943 $wrapperEl.transform(`translateX(calc(50% - ${margin}px))`); 12944 } 12945 12946 for (let i = 0; i < slides.length; i += 1) { 12947 const $slideEl = slides.eq(i); 12948 const slideProgress = $slideEl[0].progress; 12949 const progress = Math.min(Math.max($slideEl[0].progress, -params.limitProgress), params.limitProgress); 12950 let originalProgress = progress; 12951 12952 if (!isCenteredSlides) { 12953 originalProgress = Math.min(Math.max($slideEl[0].originalProgress, -params.limitProgress), params.limitProgress); 12954 } 12955 12956 const offset = $slideEl[0].swiperSlideOffset; 12957 const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0]; 12958 const r = [0, 0, 0]; 12959 let custom = false;
12960 12961 if (!swiper.isHorizontal()) { 12962 t[1] = t[0]; 12963 t[0] = 0; 12964 } 12965 12966 let data = { 12967 translate: [0, 0, 0], 12968 rotate: [0, 0, 0], 12969 scale: 1, 12970 opacity: 1 12971 }; 12972 12973 if (progress < 0) { 12974 data = params.next; 12975 custom = true; 12976 } else if (progress > 0) { 12977 data = params.prev; 12978 custom = true; 12979 } // set translate 12980 12981 12982 t.forEach((value, index) => { 12983 t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(progress * multiplier)}))`; 12984 }); // set rotates 12985 12986 r.forEach((value, index) => { 12987 r[index] = data.rotate[index] * Math.abs(progress * multiplier); 12988 }); 12989 $slideEl[0].style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length; 12990 const translateString = t.join(', '); 12991 const rotateString = `rotateX(${r[0]}deg) rotateY(${r[1]}deg) rotateZ(${r[2]}deg)`; 12992 const scaleString = originalProgress < 0 ? `scale(${1 + (1 - data.scale) * originalProgress * multiplier})` : `scale(${1 - (1 - data.scale) * originalProgress * multiplier})`; 12993 const opacityString = originalProgress < 0 ? 1 + (1 - data.opacity) * originalProgress * multiplier : 1 - (1 - data.opacity) * originalProgress * multiplier; 12994 const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`; // Set shadows 12995 12996 if (custom && data.shadow || !custom) { 12997 let $shadowEl = $slideEl.children('.swiper-slide-shadow'); 12998 12999 if ($shadowEl.length === 0 && data.shadow) { 13000 $shadowEl = createShadow(params, $slideEl); 13001 } 13002 13003 if ($shadowEl.length) { 13004 const shadowOpacity = params.shadowPerProgress ? progress * (1 / params.limitProgress) : progress; 13005 $shadowEl[0].style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1); 13006 } 13007 } 13008 13009 const $targetEl = effectTarget(params, $slideEl); 13010 $targetEl.transform(transform).css({ 13011 opacity: opacityString 13012 }); 13013 13014 if (data.origin) { 13015 $targetEl.css('transform-origin', data.origin); 13016 } 13017 } 13018 }; 13019 13020 const setTransition = duration => { 13021 const { 13022 transformEl 13023 } = swiper.params.creativeEffect; 13024 const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides; 13025 $transitionElements.transition(duration).find('.swiper-slide-shadow').transition(duration); 13026 effectVirtualTransitionEnd({ 13027 swiper, 13028 duration, 13029 transformEl, 13030 allSlides: true 13031 }); 13032 }; 13033 13034 effectInit({ 13035 effect: 'creative', 13036 swiper, 13037 on, 13038 setTranslate, 13039 setTransition, 13040 perspective: () => swiper.params.creativeEffect.perspective, 13041 overwriteParams: () => ({ 13042 watchSlidesProgress: true, 13043 virtualTranslate: !swiper.params.cssMode 13044 }) 13045 }); 13046 } 13047 13048 function EffectCards(_ref) { 13049 let { 13050 swiper, 13051 extendParams, 13052 on 13053 } = _ref; 13054 extendParams({ 13055 cardsEffect: { 13056 slideShadows: true, 13057 transformEl: null, 13058 rotate: true, 13059 perSlideRotate: 2, 13060 perSlideOffset: 8 13061 } 13062 }); 13063 13064 const setTranslate = () => { 13065 const { 13066 slides, 13067 activeIndex 13068 } = swiper; 13069 const params = swiper.params.cardsEffect; 13070 const { 13071 startTranslate, 13072 isTouched 13073 } = swiper.touchEventsData; 13074 const currentTranslate = swiper.translate; 13075 13076 for (let i = 0; i < slides.length; i += 1) { 13077 const $slideEl = slides.eq(i); 13078 const slideProgress = $slideEl[0].progress; 13079 const progress = Math.min(Math.max(slideProgress, -4), 4); 13080 let offset = $slideEl[0].swiperSlideOffset; 13081 13082 if (swiper.params.centeredSlides && !swiper.params.cssMode) { 13083 swiper.$wrapperEl.transform(`translateX(${swiper.minTranslate()}px)`); 13084 } 13085 13086 if (swiper.params.centeredSlides && swiper.params.cssMode) { 13087 offset -= slides[0].swiperSlideOffset; 13088 } 13089 13090 let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset; 13091 let tY = 0; 13092 const tZ = -100 * Math.abs(progress); 13093 let scale = 1; 13094 let rotate = -params.perSlideRotate * progress; 13095 let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75; 13096 const slideIndex = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.from + i : i; 13097 const isSwipeToNext = (slideIndex === activeIndex || slideIndex === activeIndex - 1) && progress > 0 && progress < 1 && (isTouched || swiper.params.cssMode) && currentTranslate < startTranslate; 13098 const isSwipeToPrev = (slideIndex === activeIndex || slideIndex === activeIndex + 1) && progress < 0 && progress > -1 && (isTouched || swiper.params.cssMode) && currentTranslate > startTranslate; 13099 13100 if (isSwipeToNext || isSwipeToPrev) { 13101 const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5; 13102 rotate += -28 * progress * subProgress; 13103 scale += -0.5 * subProgress; 13104 tXAdd += 96 * subProgress; 13105 tY = `${-25 * subProgress * Math.abs(progress)}%`; 13106 } 13107 13108 if (progress < 0) { 13109 // next 13110 tX = `calc(${tX}px + (${tXAdd * Math.abs(progress)}%))`;
13111 } else if (progress > 0) { 13112 // prev 13113 tX = `calc(${tX}px + (-${tXAdd * Math.abs(progress)}%))`; 13114 } else { 13115 tX = `${tX}px`; 13116 } 13117 13118 if (!swiper.isHorizontal()) { 13119 const prevY = tY; 13120 tY = tX; 13121 tX = prevY; 13122 } 13123 13124 const scaleString = progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`; 13125 const transform = ` 13126 translate3d(${tX}, ${tY}, ${tZ}px) 13127 rotateZ(${params.rotate ? rotate : 0}deg) 13128 scale(${scaleString}) 13129 `; 13130 13131 if (params.slideShadows) { 13132 // Set shadows 13133 let $shadowEl = $slideEl.find('.swiper-slide-shadow'); 13134 13135 if ($shadowEl.length === 0) { 13136 $shadowEl = createShadow(params, $slideEl); 13137 } 13138 13139 if ($shadowEl.length) $shadowEl[0].style.opacity = Math.min(Math.max((Math.abs(progress) - 0.5) / 0.5, 0), 1); 13140 } 13141 13142 $slideEl[0].style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length; 13143 const $targetEl = effectTarget(params, $slideEl); 13144 $targetEl.transform(transform); 13145 } 13146 }; 13147 13148 const setTransition = duration => { 13149 const { 13150 transformEl 13151 } = swiper.params.cardsEffect; 13152 const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides; 13153 $transitionElements.transition(duration).find('.swiper-slide-shadow').transition(duration); 13154 effectVirtualTransitionEnd({ 13155 swiper, 13156 duration, 13157 transformEl 13158 }); 13159 }; 13160 13161 effectInit({ 13162 effect: 'cards', 13163 swiper, 13164 on, 13165 setTranslate, 13166 setTransition, 13167 perspective: () => true, 13168 overwriteParams: () => ({ 13169 watchSlidesProgress: true, 13170 virtualTranslate: !swiper.params.cssMode 13171 }) 13172 }); 13173 } 13174 13175 // Swiper Class 13176 const modules = [Virtual, Keyboard, Mousewheel, Navigation, Pagination, Scrollbar, Parallax, Zoom, Lazy, Controller, A11y, History, HashNavigation, Autoplay, Thumb, freeMode, Grid, Manipulation, EffectFade, EffectCube, EffectFlip, EffectCoverflow, EffectCreative, EffectCards]; 13177 Swiper.use(modules); 13178 13179 return Swiper; 13180 13181})); 13182//# sourceMappingURL=swiper-bundle.js.map; 13183/* 13184 * jQuery Numerator Plugin 0.2.1 13185 * https://github.com/garethdn/jquery-numerator 13186 * 13187 * Copyright 2015, Gareth Nolan 13188 * http://ie.linkedin.com/in/garethnolan/ 13189 13190 * Based on jQuery Boilerplate by Zeno Rocha with the help of Addy Osmani 13191 * http://jqueryboilerplate.com 13192 * 13193 * Licensed under the MIT license: 13194 * http://www.opensource.org/licenses/MIT 13195 */ 13196 13197;(function (factory) { 13198 'use strict'; 13199 if (typeof define === 'function' && define.amd) { 13200 // AMD is used - Register as an anonymous module. 13201 define(['jquery'], factory); 13202 } else if (typeof exports === 'object') { 13203 factory(require('jquery')); 13204 } else { 13205 // Neither AMD nor CommonJS used. Use global variables. 13206 if (typeof jQuery === 'undefined') { 13207 throw 'jquery-numerator requires jQuery to be loaded first'; 13208 } 13209 factory(jQuery); 13210 } 13211}(function ($) { 13212 13213 var pluginName = "numerator", 13214 defaults = { 13215 easing: 'swing', 13216 duration: 500, 13217 delimiter: undefined, 13218 rounding: 0, 13219 toValue: undefined, 13220 fromValue: undefined, 13221 queue: false, 13222 onStart: function(){}, 13223 onStep: function(){}, 13224 onProgress: function(){}, 13225 onComplete: function(){} 13226 }; 13227 13228 function Plugin ( element, options ) { 13229 this.element = element; 13230 this.settings = $.extend( {}, defaults, options ); 13231 this._defaults = defaults; 13232 this._name = pluginName; 13233 this.init(); 13234 } 13235 13236 Plugin.prototype = { 13237 13238 init: function () { 13239 this.parseElement(); 13240 this.setValue(); 13241 }, 13242 13243 parseElement: function () { 13244 var elText = $.trim($(this.element).text()); 13245 13246 this.settings.fromValue = this.settings.fromValue || this.format(elText); 13247 }, 13248 13249 setValue: function() { 13250 var self = this; 13251 13252 $({value: self.settings.fromValue}).animate({value: self.settings.toValue}, { 13253 13254 duration: parseInt(self.settings.duration, 10), 13255 13256 easing: self.settings.easing, 13257 13258 start: self.settings.onStart, 13259 13260 step: function(now, fx) { 13261 $(self.element).text(self.format(now)); 13262 // accepts two params - (now, fx) 13263 self.settings.onStep(now, fx); 13264 }, 13265 13266 // accepts three params - (animation object, progress ratio, time remaining(ms)) 13267 progress: self.settings.onProgress, 13268 13269 complete: self.settings.onComplete 13270 }); 13271 }, 13272 13273 format: function(value){ 13274 var self = this; 13275 13276 if ( parseInt(this.settings.rounding ) < 1) { 13277 value = parseInt(value, 10); 13278 } else { 13279 value = parseFloat(value).toFixed( parseInt(this.settings.rounding) ); 13280 } 13281 13282 if (self.settings.delimiter) { 13283 return this.delimit(value) 13284 } else { 13285 return value; 13286 } 13287 }, 13288 13289 // TODO: Add comments to this function 13290 delimit: function(value){ 13291 var self = this; 13292 13293 value = value.toString(); 13294 13295 if (self.settings.rounding && parseInt(self.settings.rounding, 10) > 0) { 13296 var decimals = value.substring( (value.length - (self.settings.rounding + 1)), value.length ), 13297 wholeValue = value.substring( 0, (value.length - (self.settings.rounding + 1))); 13298 13299 return self.addDelimiter(wholeValue) + decimals; 13300 } else { 13301 return self.addDelimiter(value); 13302 } 13303 }, 13304 13305 addDelimiter: function(value){ 13306 return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, this.settings.delimiter); 13307 } 13308 }; 13309 13310 $.fn[ pluginName ] = function ( options ) { 13311 return this.each(function() { 13312 if ( $.data( this, "plugin_" + pluginName ) ) { 13313 $.data(this, 'plugin_' + pluginName, null); 13314 } 13315 $.data( this, "plugin_" + pluginName, new Plugin( this, options ) ); 13316 }); 13317 }; 13318 13319}));;
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.