UNPKG

340 kBJavaScriptView Raw
1/**
2 * Swiper 11.1.4
3 * Most modern mobile touch slider and framework with hardware accelerated transitions
4 * https://swiperjs.com
5 *
6 * Copyright 2014-2024 Vladimir Kharlampidi
7 *
8 * Released under the MIT License
9 *
10 * Released on: May 30, 2024
11 */
12
13var Swiper = (function () {
14 'use strict';
15
16 /**
17 * SSR Window 4.0.2
18 * Better handling for window object in SSR environment
19 * https://github.com/nolimits4web/ssr-window
20 *
21 * Copyright 2021, Vladimir Kharlampidi
22 *
23 * Licensed under MIT
24 *
25 * Released on: December 13, 2021
26 */
27 /* eslint-disable no-param-reassign */
28 function isObject$1(obj) {
29 return obj !== null && typeof obj === 'object' && 'constructor' in obj && obj.constructor === Object;
30 }
31 function extend$1(target, src) {
32 if (target === void 0) {
33 target = {};
34 }
35 if (src === void 0) {
36 src = {};
37 }
38 Object.keys(src).forEach(key => {
39 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) {
40 extend$1(target[key], src[key]);
41 }
42 });
43 }
44 const ssrDocument = {
45 body: {},
46 addEventListener() {},
47 removeEventListener() {},
48 activeElement: {
49 blur() {},
50 nodeName: ''
51 },
52 querySelector() {
53 return null;
54 },
55 querySelectorAll() {
56 return [];
57 },
58 getElementById() {
59 return null;
60 },
61 createEvent() {
62 return {
63 initEvent() {}
64 };
65 },
66 createElement() {
67 return {
68 children: [],
69 childNodes: [],
70 style: {},
71 setAttribute() {},
72 getElementsByTagName() {
73 return [];
74 }
75 };
76 },
77 createElementNS() {
78 return {};
79 },
80 importNode() {
81 return null;
82 },
83 location: {
84 hash: '',
85 host: '',
86 hostname: '',
87 href: '',
88 origin: '',
89 pathname: '',
90 protocol: '',
91 search: ''
92 }
93 };
94 function getDocument() {
95 const doc = typeof document !== 'undefined' ? document : {};
96 extend$1(doc, ssrDocument);
97 return doc;
98 }
99 const ssrWindow = {
100 document: ssrDocument,
101 navigator: {
102 userAgent: ''
103 },
104 location: {
105 hash: '',
106 host: '',
107 hostname: '',
108 href: '',
109 origin: '',
110 pathname: '',
111 protocol: '',
112 search: ''
113 },
114 history: {
115 replaceState() {},
116 pushState() {},
117 go() {},
118 back() {}
119 },
120 CustomEvent: function CustomEvent() {
121 return this;
122 },
123 addEventListener() {},
124 removeEventListener() {},
125 getComputedStyle() {
126 return {
127 getPropertyValue() {
128 return '';
129 }
130 };
131 },
132 Image() {},
133 Date() {},
134 screen: {},
135 setTimeout() {},
136 clearTimeout() {},
137 matchMedia() {
138 return {};
139 },
140 requestAnimationFrame(callback) {
141 if (typeof setTimeout === 'undefined') {
142 callback();
143 return null;
144 }
145 return setTimeout(callback, 0);
146 },
147 cancelAnimationFrame(id) {
148 if (typeof setTimeout === 'undefined') {
149 return;
150 }
151 clearTimeout(id);
152 }
153 };
154 function getWindow() {
155 const win = typeof window !== 'undefined' ? window : {};
156 extend$1(win, ssrWindow);
157 return win;
158 }
159
160 function classesToTokens(classes) {
161 if (classes === void 0) {
162 classes = '';
163 }
164 return classes.trim().split(' ').filter(c => !!c.trim());
165 }
166
167 function deleteProps(obj) {
168 const object = obj;
169 Object.keys(object).forEach(key => {
170 try {
171 object[key] = null;
172 } catch (e) {
173 // no getter for object
174 }
175 try {
176 delete object[key];
177 } catch (e) {
178 // something got wrong
179 }
180 });
181 }
182 function nextTick(callback, delay) {
183 if (delay === void 0) {
184 delay = 0;
185 }
186 return setTimeout(callback, delay);
187 }
188 function now() {
189 return Date.now();
190 }
191 function getComputedStyle$1(el) {
192 const window = getWindow();
193 let style;
194 if (window.getComputedStyle) {
195 style = window.getComputedStyle(el, null);
196 }
197 if (!style && el.currentStyle) {
198 style = el.currentStyle;
199 }
200 if (!style) {
201 style = el.style;
202 }
203 return style;
204 }
205 function getTranslate(el, axis) {
206 if (axis === void 0) {
207 axis = 'x';
208 }
209 const window = getWindow();
210 let matrix;
211 let curTransform;
212 let transformMatrix;
213 const curStyle = getComputedStyle$1(el);
214 if (window.WebKitCSSMatrix) {
215 curTransform = curStyle.transform || curStyle.webkitTransform;
216 if (curTransform.split(',').length > 6) {
217 curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', ');
218 }
219 // Some old versions of Webkit choke when 'none' is passed; pass
220 // empty string instead in this case
221 transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
222 } else {
223 transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
224 matrix = transformMatrix.toString().split(',');
225 }
226 if (axis === 'x') {
227 // Latest Chrome and webkits Fix
228 if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41;
229 // Crazy IE10 Matrix
230 else if (matrix.length === 16) curTransform = parseFloat(matrix[12]);
231 // Normal Browsers
232 else curTransform = parseFloat(matrix[4]);
233 }
234 if (axis === 'y') {
235 // Latest Chrome and webkits Fix
236 if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42;
237 // Crazy IE10 Matrix
238 else if (matrix.length === 16) curTransform = parseFloat(matrix[13]);
239 // Normal Browsers
240 else curTransform = parseFloat(matrix[5]);
241 }
242 return curTransform || 0;
243 }
244 function isObject(o) {
245 return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object';
246 }
247 function isNode(node) {
248 // eslint-disable-next-line
249 if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') {
250 return node instanceof HTMLElement;
251 }
252 return node && (node.nodeType === 1 || node.nodeType === 11);
253 }
254 function extend() {
255 const to = Object(arguments.length <= 0 ? undefined : arguments[0]);
256 const noExtend = ['__proto__', 'constructor', 'prototype'];
257 for (let i = 1; i < arguments.length; i += 1) {
258 const nextSource = i < 0 || arguments.length <= i ? undefined : arguments[i];
259 if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) {
260 const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0);
261 for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
262 const nextKey = keysArray[nextIndex];
263 const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
264 if (desc !== undefined && desc.enumerable) {
265 if (isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
266 if (nextSource[nextKey].__swiper__) {
267 to[nextKey] = nextSource[nextKey];
268 } else {
269 extend(to[nextKey], nextSource[nextKey]);
270 }
271 } else if (!isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
272 to[nextKey] = {};
273 if (nextSource[nextKey].__swiper__) {
274 to[nextKey] = nextSource[nextKey];
275 } else {
276 extend(to[nextKey], nextSource[nextKey]);
277 }
278 } else {
279 to[nextKey] = nextSource[nextKey];
280 }
281 }
282 }
283 }
284 }
285 return to;
286 }
287 function setCSSProperty(el, varName, varValue) {
288 el.style.setProperty(varName, varValue);
289 }
290 function animateCSSModeScroll(_ref) {
291 let {
292 swiper,
293 targetPosition,
294 side
295 } = _ref;
296 const window = getWindow();
297 const startPosition = -swiper.translate;
298 let startTime = null;
299 let time;
300 const duration = swiper.params.speed;
301 swiper.wrapperEl.style.scrollSnapType = 'none';
302 window.cancelAnimationFrame(swiper.cssModeFrameID);
303 const dir = targetPosition > startPosition ? 'next' : 'prev';
304 const isOutOfBound = (current, target) => {
305 return dir === 'next' && current >= target || dir === 'prev' && current <= target;
306 };
307 const animate = () => {
308 time = new Date().getTime();
309 if (startTime === null) {
310 startTime = time;
311 }
312 const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
313 const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
314 let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);
315 if (isOutOfBound(currentPosition, targetPosition)) {
316 currentPosition = targetPosition;
317 }
318 swiper.wrapperEl.scrollTo({
319 [side]: currentPosition
320 });
321 if (isOutOfBound(currentPosition, targetPosition)) {
322 swiper.wrapperEl.style.overflow = 'hidden';
323 swiper.wrapperEl.style.scrollSnapType = '';
324 setTimeout(() => {
325 swiper.wrapperEl.style.overflow = '';
326 swiper.wrapperEl.scrollTo({
327 [side]: currentPosition
328 });
329 });
330 window.cancelAnimationFrame(swiper.cssModeFrameID);
331 return;
332 }
333 swiper.cssModeFrameID = window.requestAnimationFrame(animate);
334 };
335 animate();
336 }
337 function getSlideTransformEl(slideEl) {
338 return slideEl.querySelector('.swiper-slide-transform') || slideEl.shadowRoot && slideEl.shadowRoot.querySelector('.swiper-slide-transform') || slideEl;
339 }
340 function elementChildren(element, selector) {
341 if (selector === void 0) {
342 selector = '';
343 }
344 return [...element.children].filter(el => el.matches(selector));
345 }
346 function showWarning(text) {
347 try {
348 console.warn(text);
349 return;
350 } catch (err) {
351 // err
352 }
353 }
354 function createElement(tag, classes) {
355 if (classes === void 0) {
356 classes = [];
357 }
358 const el = document.createElement(tag);
359 el.classList.add(...(Array.isArray(classes) ? classes : classesToTokens(classes)));
360 return el;
361 }
362 function elementOffset(el) {
363 const window = getWindow();
364 const document = getDocument();
365 const box = el.getBoundingClientRect();
366 const body = document.body;
367 const clientTop = el.clientTop || body.clientTop || 0;
368 const clientLeft = el.clientLeft || body.clientLeft || 0;
369 const scrollTop = el === window ? window.scrollY : el.scrollTop;
370 const scrollLeft = el === window ? window.scrollX : el.scrollLeft;
371 return {
372 top: box.top + scrollTop - clientTop,
373 left: box.left + scrollLeft - clientLeft
374 };
375 }
376 function elementPrevAll(el, selector) {
377 const prevEls = [];
378 while (el.previousElementSibling) {
379 const prev = el.previousElementSibling; // eslint-disable-line
380 if (selector) {
381 if (prev.matches(selector)) prevEls.push(prev);
382 } else prevEls.push(prev);
383 el = prev;
384 }
385 return prevEls;
386 }
387 function elementNextAll(el, selector) {
388 const nextEls = [];
389 while (el.nextElementSibling) {
390 const next = el.nextElementSibling; // eslint-disable-line
391 if (selector) {
392 if (next.matches(selector)) nextEls.push(next);
393 } else nextEls.push(next);
394 el = next;
395 }
396 return nextEls;
397 }
398 function elementStyle(el, prop) {
399 const window = getWindow();
400 return window.getComputedStyle(el, null).getPropertyValue(prop);
401 }
402 function elementIndex(el) {
403 let child = el;
404 let i;
405 if (child) {
406 i = 0;
407 // eslint-disable-next-line
408 while ((child = child.previousSibling) !== null) {
409 if (child.nodeType === 1) i += 1;
410 }
411 return i;
412 }
413 return undefined;
414 }
415 function elementParents(el, selector) {
416 const parents = []; // eslint-disable-line
417 let parent = el.parentElement; // eslint-disable-line
418 while (parent) {
419 if (selector) {
420 if (parent.matches(selector)) parents.push(parent);
421 } else {
422 parents.push(parent);
423 }
424 parent = parent.parentElement;
425 }
426 return parents;
427 }
428 function elementTransitionEnd(el, callback) {
429 function fireCallBack(e) {
430 if (e.target !== el) return;
431 callback.call(el, e);
432 el.removeEventListener('transitionend', fireCallBack);
433 }
434 if (callback) {
435 el.addEventListener('transitionend', fireCallBack);
436 }
437 }
438 function elementOuterSize(el, size, includeMargins) {
439 const window = getWindow();
440 if (includeMargins) {
441 return el[size === 'width' ? 'offsetWidth' : 'offsetHeight'] + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-right' : 'margin-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-left' : 'margin-bottom'));
442 }
443 return el.offsetWidth;
444 }
445 function makeElementsArray(el) {
446 return (Array.isArray(el) ? el : [el]).filter(e => !!e);
447 }
448
449 let support;
450 function calcSupport() {
451 const window = getWindow();
452 const document = getDocument();
453 return {
454 smoothScroll: document.documentElement && document.documentElement.style && 'scrollBehavior' in document.documentElement.style,
455 touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch)
456 };
457 }
458 function getSupport() {
459 if (!support) {
460 support = calcSupport();
461 }
462 return support;
463 }
464
465 let deviceCached;
466 function calcDevice(_temp) {
467 let {
468 userAgent
469 } = _temp === void 0 ? {} : _temp;
470 const support = getSupport();
471 const window = getWindow();
472 const platform = window.navigator.platform;
473 const ua = userAgent || window.navigator.userAgent;
474 const device = {
475 ios: false,
476 android: false
477 };
478 const screenWidth = window.screen.width;
479 const screenHeight = window.screen.height;
480 const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
481 let ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
482 const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
483 const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
484 const windows = platform === 'Win32';
485 let macos = platform === 'MacIntel';
486
487 // iPadOs 13 fix
488 const iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768', '820x1180', '1180x820', '810x1080', '1080x810'];
489 if (!ipad && macos && support.touch && iPadScreens.indexOf(`${screenWidth}x${screenHeight}`) >= 0) {
490 ipad = ua.match(/(Version)\/([\d.]+)/);
491 if (!ipad) ipad = [0, 1, '13_0_0'];
492 macos = false;
493 }
494
495 // Android
496 if (android && !windows) {
497 device.os = 'android';
498 device.android = true;
499 }
500 if (ipad || iphone || ipod) {
501 device.os = 'ios';
502 device.ios = true;
503 }
504
505 // Export object
506 return device;
507 }
508 function getDevice(overrides) {
509 if (overrides === void 0) {
510 overrides = {};
511 }
512 if (!deviceCached) {
513 deviceCached = calcDevice(overrides);
514 }
515 return deviceCached;
516 }
517
518 let browser;
519 function calcBrowser() {
520 const window = getWindow();
521 const device = getDevice();
522 let needPerspectiveFix = false;
523 function isSafari() {
524 const ua = window.navigator.userAgent.toLowerCase();
525 return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;
526 }
527 if (isSafari()) {
528 const ua = String(window.navigator.userAgent);
529 if (ua.includes('Version/')) {
530 const [major, minor] = ua.split('Version/')[1].split(' ')[0].split('.').map(num => Number(num));
531 needPerspectiveFix = major < 16 || major === 16 && minor < 2;
532 }
533 }
534 const isWebView = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent);
535 const isSafariBrowser = isSafari();
536 const need3dFix = isSafariBrowser || isWebView && device.ios;
537 return {
538 isSafari: needPerspectiveFix || isSafariBrowser,
539 needPerspectiveFix,
540 need3dFix,
541 isWebView
542 };
543 }
544 function getBrowser() {
545 if (!browser) {
546 browser = calcBrowser();
547 }
548 return browser;
549 }
550
551 function Resize(_ref) {
552 let {
553 swiper,
554 on,
555 emit
556 } = _ref;
557 const window = getWindow();
558 let observer = null;
559 let animationFrame = null;
560 const resizeHandler = () => {
561 if (!swiper || swiper.destroyed || !swiper.initialized) return;
562 emit('beforeResize');
563 emit('resize');
564 };
565 const createObserver = () => {
566 if (!swiper || swiper.destroyed || !swiper.initialized) return;
567 observer = new ResizeObserver(entries => {
568 animationFrame = window.requestAnimationFrame(() => {
569 const {
570 width,
571 height
572 } = swiper;
573 let newWidth = width;
574 let newHeight = height;
575 entries.forEach(_ref2 => {
576 let {
577 contentBoxSize,
578 contentRect,
579 target
580 } = _ref2;
581 if (target && target !== swiper.el) return;
582 newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize;
583 newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize;
584 });
585 if (newWidth !== width || newHeight !== height) {
586 resizeHandler();
587 }
588 });
589 });
590 observer.observe(swiper.el);
591 };
592 const removeObserver = () => {
593 if (animationFrame) {
594 window.cancelAnimationFrame(animationFrame);
595 }
596 if (observer && observer.unobserve && swiper.el) {
597 observer.unobserve(swiper.el);
598 observer = null;
599 }
600 };
601 const orientationChangeHandler = () => {
602 if (!swiper || swiper.destroyed || !swiper.initialized) return;
603 emit('orientationchange');
604 };
605 on('init', () => {
606 if (swiper.params.resizeObserver && typeof window.ResizeObserver !== 'undefined') {
607 createObserver();
608 return;
609 }
610 window.addEventListener('resize', resizeHandler);
611 window.addEventListener('orientationchange', orientationChangeHandler);
612 });
613 on('destroy', () => {
614 removeObserver();
615 window.removeEventListener('resize', resizeHandler);
616 window.removeEventListener('orientationchange', orientationChangeHandler);
617 });
618 }
619
620 function Observer(_ref) {
621 let {
622 swiper,
623 extendParams,
624 on,
625 emit
626 } = _ref;
627 const observers = [];
628 const window = getWindow();
629 const attach = function (target, options) {
630 if (options === void 0) {
631 options = {};
632 }
633 const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
634 const observer = new ObserverFunc(mutations => {
635 // The observerUpdate event should only be triggered
636 // once despite the number of mutations. Additional
637 // triggers are redundant and are very costly
638 if (swiper.__preventObserver__) return;
639 if (mutations.length === 1) {
640 emit('observerUpdate', mutations[0]);
641 return;
642 }
643 const observerUpdate = function observerUpdate() {
644 emit('observerUpdate', mutations[0]);
645 };
646 if (window.requestAnimationFrame) {
647 window.requestAnimationFrame(observerUpdate);
648 } else {
649 window.setTimeout(observerUpdate, 0);
650 }
651 });
652 observer.observe(target, {
653 attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
654 childList: typeof options.childList === 'undefined' ? true : options.childList,
655 characterData: typeof options.characterData === 'undefined' ? true : options.characterData
656 });
657 observers.push(observer);
658 };
659 const init = () => {
660 if (!swiper.params.observer) return;
661 if (swiper.params.observeParents) {
662 const containerParents = elementParents(swiper.hostEl);
663 for (let i = 0; i < containerParents.length; i += 1) {
664 attach(containerParents[i]);
665 }
666 }
667 // Observe container
668 attach(swiper.hostEl, {
669 childList: swiper.params.observeSlideChildren
670 });
671
672 // Observe wrapper
673 attach(swiper.wrapperEl, {
674 attributes: false
675 });
676 };
677 const destroy = () => {
678 observers.forEach(observer => {
679 observer.disconnect();
680 });
681 observers.splice(0, observers.length);
682 };
683 extendParams({
684 observer: false,
685 observeParents: false,
686 observeSlideChildren: false
687 });
688 on('init', init);
689 on('destroy', destroy);
690 }
691
692 /* eslint-disable no-underscore-dangle */
693
694 var eventsEmitter = {
695 on(events, handler, priority) {
696 const self = this;
697 if (!self.eventsListeners || self.destroyed) return self;
698 if (typeof handler !== 'function') return self;
699 const method = priority ? 'unshift' : 'push';
700 events.split(' ').forEach(event => {
701 if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
702 self.eventsListeners[event][method](handler);
703 });
704 return self;
705 },
706 once(events, handler, priority) {
707 const self = this;
708 if (!self.eventsListeners || self.destroyed) return self;
709 if (typeof handler !== 'function') return self;
710 function onceHandler() {
711 self.off(events, onceHandler);
712 if (onceHandler.__emitterProxy) {
713 delete onceHandler.__emitterProxy;
714 }
715 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
716 args[_key] = arguments[_key];
717 }
718 handler.apply(self, args);
719 }
720 onceHandler.__emitterProxy = handler;
721 return self.on(events, onceHandler, priority);
722 },
723 onAny(handler, priority) {
724 const self = this;
725 if (!self.eventsListeners || self.destroyed) return self;
726 if (typeof handler !== 'function') return self;
727 const method = priority ? 'unshift' : 'push';
728 if (self.eventsAnyListeners.indexOf(handler) < 0) {
729 self.eventsAnyListeners[method](handler);
730 }
731 return self;
732 },
733 offAny(handler) {
734 const self = this;
735 if (!self.eventsListeners || self.destroyed) return self;
736 if (!self.eventsAnyListeners) return self;
737 const index = self.eventsAnyListeners.indexOf(handler);
738 if (index >= 0) {
739 self.eventsAnyListeners.splice(index, 1);
740 }
741 return self;
742 },
743 off(events, handler) {
744 const self = this;
745 if (!self.eventsListeners || self.destroyed) return self;
746 if (!self.eventsListeners) return self;
747 events.split(' ').forEach(event => {
748 if (typeof handler === 'undefined') {
749 self.eventsListeners[event] = [];
750 } else if (self.eventsListeners[event]) {
751 self.eventsListeners[event].forEach((eventHandler, index) => {
752 if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) {
753 self.eventsListeners[event].splice(index, 1);
754 }
755 });
756 }
757 });
758 return self;
759 },
760 emit() {
761 const self = this;
762 if (!self.eventsListeners || self.destroyed) return self;
763 if (!self.eventsListeners) return self;
764 let events;
765 let data;
766 let context;
767 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
768 args[_key2] = arguments[_key2];
769 }
770 if (typeof args[0] === 'string' || Array.isArray(args[0])) {
771 events = args[0];
772 data = args.slice(1, args.length);
773 context = self;
774 } else {
775 events = args[0].events;
776 data = args[0].data;
777 context = args[0].context || self;
778 }
779 data.unshift(context);
780 const eventsArray = Array.isArray(events) ? events : events.split(' ');
781 eventsArray.forEach(event => {
782 if (self.eventsAnyListeners && self.eventsAnyListeners.length) {
783 self.eventsAnyListeners.forEach(eventHandler => {
784 eventHandler.apply(context, [event, ...data]);
785 });
786 }
787 if (self.eventsListeners && self.eventsListeners[event]) {
788 self.eventsListeners[event].forEach(eventHandler => {
789 eventHandler.apply(context, data);
790 });
791 }
792 });
793 return self;
794 }
795 };
796
797 function updateSize() {
798 const swiper = this;
799 let width;
800 let height;
801 const el = swiper.el;
802 if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
803 width = swiper.params.width;
804 } else {
805 width = el.clientWidth;
806 }
807 if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
808 height = swiper.params.height;
809 } else {
810 height = el.clientHeight;
811 }
812 if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {
813 return;
814 }
815
816 // Subtract paddings
817 width = width - parseInt(elementStyle(el, 'padding-left') || 0, 10) - parseInt(elementStyle(el, 'padding-right') || 0, 10);
818 height = height - parseInt(elementStyle(el, 'padding-top') || 0, 10) - parseInt(elementStyle(el, 'padding-bottom') || 0, 10);
819 if (Number.isNaN(width)) width = 0;
820 if (Number.isNaN(height)) height = 0;
821 Object.assign(swiper, {
822 width,
823 height,
824 size: swiper.isHorizontal() ? width : height
825 });
826 }
827
828 function updateSlides() {
829 const swiper = this;
830 function getDirectionPropertyValue(node, label) {
831 return parseFloat(node.getPropertyValue(swiper.getDirectionLabel(label)) || 0);
832 }
833 const params = swiper.params;
834 const {
835 wrapperEl,
836 slidesEl,
837 size: swiperSize,
838 rtlTranslate: rtl,
839 wrongRTL
840 } = swiper;
841 const isVirtual = swiper.virtual && params.virtual.enabled;
842 const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
843 const slides = elementChildren(slidesEl, `.${swiper.params.slideClass}, swiper-slide`);
844 const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
845 let snapGrid = [];
846 const slidesGrid = [];
847 const slidesSizesGrid = [];
848 let offsetBefore = params.slidesOffsetBefore;
849 if (typeof offsetBefore === 'function') {
850 offsetBefore = params.slidesOffsetBefore.call(swiper);
851 }
852 let offsetAfter = params.slidesOffsetAfter;
853 if (typeof offsetAfter === 'function') {
854 offsetAfter = params.slidesOffsetAfter.call(swiper);
855 }
856 const previousSnapGridLength = swiper.snapGrid.length;
857 const previousSlidesGridLength = swiper.slidesGrid.length;
858 let spaceBetween = params.spaceBetween;
859 let slidePosition = -offsetBefore;
860 let prevSlideSize = 0;
861 let index = 0;
862 if (typeof swiperSize === 'undefined') {
863 return;
864 }
865 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
866 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
867 } else if (typeof spaceBetween === 'string') {
868 spaceBetween = parseFloat(spaceBetween);
869 }
870 swiper.virtualSize = -spaceBetween;
871
872 // reset margins
873 slides.forEach(slideEl => {
874 if (rtl) {
875 slideEl.style.marginLeft = '';
876 } else {
877 slideEl.style.marginRight = '';
878 }
879 slideEl.style.marginBottom = '';
880 slideEl.style.marginTop = '';
881 });
882
883 // reset cssMode offsets
884 if (params.centeredSlides && params.cssMode) {
885 setCSSProperty(wrapperEl, '--swiper-centered-offset-before', '');
886 setCSSProperty(wrapperEl, '--swiper-centered-offset-after', '');
887 }
888 const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
889 if (gridEnabled) {
890 swiper.grid.initSlides(slides);
891 } else if (swiper.grid) {
892 swiper.grid.unsetSlides();
893 }
894
895 // Calc slides
896 let slideSize;
897 const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => {
898 return typeof params.breakpoints[key].slidesPerView !== 'undefined';
899 }).length > 0;
900 for (let i = 0; i < slidesLength; i += 1) {
901 slideSize = 0;
902 let slide;
903 if (slides[i]) slide = slides[i];
904 if (gridEnabled) {
905 swiper.grid.updateSlide(i, slide, slides);
906 }
907 if (slides[i] && elementStyle(slide, 'display') === 'none') continue; // eslint-disable-line
908
909 if (params.slidesPerView === 'auto') {
910 if (shouldResetSlideSize) {
911 slides[i].style[swiper.getDirectionLabel('width')] = ``;
912 }
913 const slideStyles = getComputedStyle(slide);
914 const currentTransform = slide.style.transform;
915 const currentWebKitTransform = slide.style.webkitTransform;
916 if (currentTransform) {
917 slide.style.transform = 'none';
918 }
919 if (currentWebKitTransform) {
920 slide.style.webkitTransform = 'none';
921 }
922 if (params.roundLengths) {
923 slideSize = swiper.isHorizontal() ? elementOuterSize(slide, 'width', true) : elementOuterSize(slide, 'height', true);
924 } else {
925 // eslint-disable-next-line
926 const width = getDirectionPropertyValue(slideStyles, 'width');
927 const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
928 const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
929 const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
930 const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
931 const boxSizing = slideStyles.getPropertyValue('box-sizing');
932 if (boxSizing && boxSizing === 'border-box') {
933 slideSize = width + marginLeft + marginRight;
934 } else {
935 const {
936 clientWidth,
937 offsetWidth
938 } = slide;
939 slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);
940 }
941 }
942 if (currentTransform) {
943 slide.style.transform = currentTransform;
944 }
945 if (currentWebKitTransform) {
946 slide.style.webkitTransform = currentWebKitTransform;
947 }
948 if (params.roundLengths) slideSize = Math.floor(slideSize);
949 } else {
950 slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
951 if (params.roundLengths) slideSize = Math.floor(slideSize);
952 if (slides[i]) {
953 slides[i].style[swiper.getDirectionLabel('width')] = `${slideSize}px`;
954 }
955 }
956 if (slides[i]) {
957 slides[i].swiperSlideSize = slideSize;
958 }
959 slidesSizesGrid.push(slideSize);
960 if (params.centeredSlides) {
961 slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
962 if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
963 if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
964 if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
965 if (params.roundLengths) slidePosition = Math.floor(slidePosition);
966 if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
967 slidesGrid.push(slidePosition);
968 } else {
969 if (params.roundLengths) slidePosition = Math.floor(slidePosition);
970 if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);
971 slidesGrid.push(slidePosition);
972 slidePosition = slidePosition + slideSize + spaceBetween;
973 }
974 swiper.virtualSize += slideSize + spaceBetween;
975 prevSlideSize = slideSize;
976 index += 1;
977 }
978 swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
979 if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
980 wrapperEl.style.width = `${swiper.virtualSize + spaceBetween}px`;
981 }
982 if (params.setWrapperSize) {
983 wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
984 }
985 if (gridEnabled) {
986 swiper.grid.updateWrapperSize(slideSize, snapGrid);
987 }
988
989 // Remove last grid elements depending on width
990 if (!params.centeredSlides) {
991 const newSlidesGrid = [];
992 for (let i = 0; i < snapGrid.length; i += 1) {
993 let slidesGridItem = snapGrid[i];
994 if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
995 if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
996 newSlidesGrid.push(slidesGridItem);
997 }
998 }
999 snapGrid = newSlidesGrid;
1000 if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
1001 snapGrid.push(swiper.virtualSize - swiperSize);
1002 }
1003 }
1004 if (isVirtual && params.loop) {
1005 const size = slidesSizesGrid[0] + spaceBetween;
1006 if (params.slidesPerGroup > 1) {
1007 const groups = Math.ceil((swiper.virtual.slidesBefore + swiper.virtual.slidesAfter) / params.slidesPerGroup);
1008 const groupSize = size * params.slidesPerGroup;
1009 for (let i = 0; i < groups; i += 1) {
1010 snapGrid.push(snapGrid[snapGrid.length - 1] + groupSize);
1011 }
1012 }
1013 for (let i = 0; i < swiper.virtual.slidesBefore + swiper.virtual.slidesAfter; i += 1) {
1014 if (params.slidesPerGroup === 1) {
1015 snapGrid.push(snapGrid[snapGrid.length - 1] + size);
1016 }
1017 slidesGrid.push(slidesGrid[slidesGrid.length - 1] + size);
1018 swiper.virtualSize += size;
1019 }
1020 }
1021 if (snapGrid.length === 0) snapGrid = [0];
1022 if (spaceBetween !== 0) {
1023 const key = swiper.isHorizontal() && rtl ? 'marginLeft' : swiper.getDirectionLabel('marginRight');
1024 slides.filter((_, slideIndex) => {
1025 if (!params.cssMode || params.loop) return true;
1026 if (slideIndex === slides.length - 1) {
1027 return false;
1028 }
1029 return true;
1030 }).forEach(slideEl => {
1031 slideEl.style[key] = `${spaceBetween}px`;
1032 });
1033 }
1034 if (params.centeredSlides && params.centeredSlidesBounds) {
1035 let allSlidesSize = 0;
1036 slidesSizesGrid.forEach(slideSizeValue => {
1037 allSlidesSize += slideSizeValue + (spaceBetween || 0);
1038 });
1039 allSlidesSize -= spaceBetween;
1040 const maxSnap = allSlidesSize - swiperSize;
1041 snapGrid = snapGrid.map(snap => {
1042 if (snap <= 0) return -offsetBefore;
1043 if (snap > maxSnap) return maxSnap + offsetAfter;
1044 return snap;
1045 });
1046 }
1047 if (params.centerInsufficientSlides) {
1048 let allSlidesSize = 0;
1049 slidesSizesGrid.forEach(slideSizeValue => {
1050 allSlidesSize += slideSizeValue + (spaceBetween || 0);
1051 });
1052 allSlidesSize -= spaceBetween;
1053 const offsetSize = (params.slidesOffsetBefore || 0) + (params.slidesOffsetAfter || 0);
1054 if (allSlidesSize + offsetSize < swiperSize) {
1055 const allSlidesOffset = (swiperSize - allSlidesSize - offsetSize) / 2;
1056 snapGrid.forEach((snap, snapIndex) => {
1057 snapGrid[snapIndex] = snap - allSlidesOffset;
1058 });
1059 slidesGrid.forEach((snap, snapIndex) => {
1060 slidesGrid[snapIndex] = snap + allSlidesOffset;
1061 });
1062 }
1063 }
1064 Object.assign(swiper, {
1065 slides,
1066 snapGrid,
1067 slidesGrid,
1068 slidesSizesGrid
1069 });
1070 if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) {
1071 setCSSProperty(wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`);
1072 setCSSProperty(wrapperEl, '--swiper-centered-offset-after', `${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`);
1073 const addToSnapGrid = -swiper.snapGrid[0];
1074 const addToSlidesGrid = -swiper.slidesGrid[0];
1075 swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);
1076 swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);
1077 }
1078 if (slidesLength !== previousSlidesLength) {
1079 swiper.emit('slidesLengthChange');
1080 }
1081 if (snapGrid.length !== previousSnapGridLength) {
1082 if (swiper.params.watchOverflow) swiper.checkOverflow();
1083 swiper.emit('snapGridLengthChange');
1084 }
1085 if (slidesGrid.length !== previousSlidesGridLength) {
1086 swiper.emit('slidesGridLengthChange');
1087 }
1088 if (params.watchSlidesProgress) {
1089 swiper.updateSlidesOffset();
1090 }
1091 swiper.emit('slidesUpdated');
1092 if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) {
1093 const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`;
1094 const hasClassBackfaceClassAdded = swiper.el.classList.contains(backFaceHiddenClass);
1095 if (slidesLength <= params.maxBackfaceHiddenSlides) {
1096 if (!hasClassBackfaceClassAdded) swiper.el.classList.add(backFaceHiddenClass);
1097 } else if (hasClassBackfaceClassAdded) {
1098 swiper.el.classList.remove(backFaceHiddenClass);
1099 }
1100 }
1101 }
1102
1103 function updateAutoHeight(speed) {
1104 const swiper = this;
1105 const activeSlides = [];
1106 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
1107 let newHeight = 0;
1108 let i;
1109 if (typeof speed === 'number') {
1110 swiper.setTransition(speed);
1111 } else if (speed === true) {
1112 swiper.setTransition(swiper.params.speed);
1113 }
1114 const getSlideByIndex = index => {
1115 if (isVirtual) {
1116 return swiper.slides[swiper.getSlideIndexByData(index)];
1117 }
1118 return swiper.slides[index];
1119 };
1120 // Find slides currently in view
1121 if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
1122 if (swiper.params.centeredSlides) {
1123 (swiper.visibleSlides || []).forEach(slide => {
1124 activeSlides.push(slide);
1125 });
1126 } else {
1127 for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
1128 const index = swiper.activeIndex + i;
1129 if (index > swiper.slides.length && !isVirtual) break;
1130 activeSlides.push(getSlideByIndex(index));
1131 }
1132 }
1133 } else {
1134 activeSlides.push(getSlideByIndex(swiper.activeIndex));
1135 }
1136
1137 // Find new height from highest slide in view
1138 for (i = 0; i < activeSlides.length; i += 1) {
1139 if (typeof activeSlides[i] !== 'undefined') {
1140 const height = activeSlides[i].offsetHeight;
1141 newHeight = height > newHeight ? height : newHeight;
1142 }
1143 }
1144
1145 // Update Height
1146 if (newHeight || newHeight === 0) swiper.wrapperEl.style.height = `${newHeight}px`;
1147 }
1148
1149 function updateSlidesOffset() {
1150 const swiper = this;
1151 const slides = swiper.slides;
1152 // eslint-disable-next-line
1153 const minusOffset = swiper.isElement ? swiper.isHorizontal() ? swiper.wrapperEl.offsetLeft : swiper.wrapperEl.offsetTop : 0;
1154 for (let i = 0; i < slides.length; i += 1) {
1155 slides[i].swiperSlideOffset = (swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop) - minusOffset - swiper.cssOverflowAdjustment();
1156 }
1157 }
1158
1159 const toggleSlideClasses$1 = (slideEl, condition, className) => {
1160 if (condition && !slideEl.classList.contains(className)) {
1161 slideEl.classList.add(className);
1162 } else if (!condition && slideEl.classList.contains(className)) {
1163 slideEl.classList.remove(className);
1164 }
1165 };
1166 function updateSlidesProgress(translate) {
1167 if (translate === void 0) {
1168 translate = this && this.translate || 0;
1169 }
1170 const swiper = this;
1171 const params = swiper.params;
1172 const {
1173 slides,
1174 rtlTranslate: rtl,
1175 snapGrid
1176 } = swiper;
1177 if (slides.length === 0) return;
1178 if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();
1179 let offsetCenter = -translate;
1180 if (rtl) offsetCenter = translate;
1181 swiper.visibleSlidesIndexes = [];
1182 swiper.visibleSlides = [];
1183 let spaceBetween = params.spaceBetween;
1184 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
1185 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
1186 } else if (typeof spaceBetween === 'string') {
1187 spaceBetween = parseFloat(spaceBetween);
1188 }
1189 for (let i = 0; i < slides.length; i += 1) {
1190 const slide = slides[i];
1191 let slideOffset = slide.swiperSlideOffset;
1192 if (params.cssMode && params.centeredSlides) {
1193 slideOffset -= slides[0].swiperSlideOffset;
1194 }
1195 const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
1196 const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
1197 const slideBefore = -(offsetCenter - slideOffset);
1198 const slideAfter = slideBefore + swiper.slidesSizesGrid[i];
1199 const isFullyVisible = slideBefore >= 0 && slideBefore <= swiper.size - swiper.slidesSizesGrid[i];
1200 const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size;
1201 if (isVisible) {
1202 swiper.visibleSlides.push(slide);
1203 swiper.visibleSlidesIndexes.push(i);
1204 }
1205 toggleSlideClasses$1(slide, isVisible, params.slideVisibleClass);
1206 toggleSlideClasses$1(slide, isFullyVisible, params.slideFullyVisibleClass);
1207 slide.progress = rtl ? -slideProgress : slideProgress;
1208 slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;
1209 }
1210 }
1211
1212 function updateProgress(translate) {
1213 const swiper = this;
1214 if (typeof translate === 'undefined') {
1215 const multiplier = swiper.rtlTranslate ? -1 : 1;
1216 // eslint-disable-next-line
1217 translate = swiper && swiper.translate && swiper.translate * multiplier || 0;
1218 }
1219 const params = swiper.params;
1220 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
1221 let {
1222 progress,
1223 isBeginning,
1224 isEnd,
1225 progressLoop
1226 } = swiper;
1227 const wasBeginning = isBeginning;
1228 const wasEnd = isEnd;
1229 if (translatesDiff === 0) {
1230 progress = 0;
1231 isBeginning = true;
1232 isEnd = true;
1233 } else {
1234 progress = (translate - swiper.minTranslate()) / translatesDiff;
1235 const isBeginningRounded = Math.abs(translate - swiper.minTranslate()) < 1;
1236 const isEndRounded = Math.abs(translate - swiper.maxTranslate()) < 1;
1237 isBeginning = isBeginningRounded || progress <= 0;
1238 isEnd = isEndRounded || progress >= 1;
1239 if (isBeginningRounded) progress = 0;
1240 if (isEndRounded) progress = 1;
1241 }
1242 if (params.loop) {
1243 const firstSlideIndex = swiper.getSlideIndexByData(0);
1244 const lastSlideIndex = swiper.getSlideIndexByData(swiper.slides.length - 1);
1245 const firstSlideTranslate = swiper.slidesGrid[firstSlideIndex];
1246 const lastSlideTranslate = swiper.slidesGrid[lastSlideIndex];
1247 const translateMax = swiper.slidesGrid[swiper.slidesGrid.length - 1];
1248 const translateAbs = Math.abs(translate);
1249 if (translateAbs >= firstSlideTranslate) {
1250 progressLoop = (translateAbs - firstSlideTranslate) / translateMax;
1251 } else {
1252 progressLoop = (translateAbs + translateMax - lastSlideTranslate) / translateMax;
1253 }
1254 if (progressLoop > 1) progressLoop -= 1;
1255 }
1256 Object.assign(swiper, {
1257 progress,
1258 progressLoop,
1259 isBeginning,
1260 isEnd
1261 });
1262 if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);
1263 if (isBeginning && !wasBeginning) {
1264 swiper.emit('reachBeginning toEdge');
1265 }
1266 if (isEnd && !wasEnd) {
1267 swiper.emit('reachEnd toEdge');
1268 }
1269 if (wasBeginning && !isBeginning || wasEnd && !isEnd) {
1270 swiper.emit('fromEdge');
1271 }
1272 swiper.emit('progress', progress);
1273 }
1274
1275 const toggleSlideClasses = (slideEl, condition, className) => {
1276 if (condition && !slideEl.classList.contains(className)) {
1277 slideEl.classList.add(className);
1278 } else if (!condition && slideEl.classList.contains(className)) {
1279 slideEl.classList.remove(className);
1280 }
1281 };
1282 function updateSlidesClasses() {
1283 const swiper = this;
1284 const {
1285 slides,
1286 params,
1287 slidesEl,
1288 activeIndex
1289 } = swiper;
1290 const isVirtual = swiper.virtual && params.virtual.enabled;
1291 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
1292 const getFilteredSlide = selector => {
1293 return elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0];
1294 };
1295 let activeSlide;
1296 let prevSlide;
1297 let nextSlide;
1298 if (isVirtual) {
1299 if (params.loop) {
1300 let slideIndex = activeIndex - swiper.virtual.slidesBefore;
1301 if (slideIndex < 0) slideIndex = swiper.virtual.slides.length + slideIndex;
1302 if (slideIndex >= swiper.virtual.slides.length) slideIndex -= swiper.virtual.slides.length;
1303 activeSlide = getFilteredSlide(`[data-swiper-slide-index="${slideIndex}"]`);
1304 } else {
1305 activeSlide = getFilteredSlide(`[data-swiper-slide-index="${activeIndex}"]`);
1306 }
1307 } else {
1308 if (gridEnabled) {
1309 activeSlide = slides.filter(slideEl => slideEl.column === activeIndex)[0];
1310 nextSlide = slides.filter(slideEl => slideEl.column === activeIndex + 1)[0];
1311 prevSlide = slides.filter(slideEl => slideEl.column === activeIndex - 1)[0];
1312 } else {
1313 activeSlide = slides[activeIndex];
1314 }
1315 }
1316 if (activeSlide) {
1317 if (!gridEnabled) {
1318 // Next Slide
1319 nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
1320 if (params.loop && !nextSlide) {
1321 nextSlide = slides[0];
1322 }
1323
1324 // Prev Slide
1325 prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
1326 if (params.loop && !prevSlide === 0) {
1327 prevSlide = slides[slides.length - 1];
1328 }
1329 }
1330 }
1331 slides.forEach(slideEl => {
1332 toggleSlideClasses(slideEl, slideEl === activeSlide, params.slideActiveClass);
1333 toggleSlideClasses(slideEl, slideEl === nextSlide, params.slideNextClass);
1334 toggleSlideClasses(slideEl, slideEl === prevSlide, params.slidePrevClass);
1335 });
1336 swiper.emitSlidesClasses();
1337 }
1338
1339 const processLazyPreloader = (swiper, imageEl) => {
1340 if (!swiper || swiper.destroyed || !swiper.params) return;
1341 const slideSelector = () => swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
1342 const slideEl = imageEl.closest(slideSelector());
1343 if (slideEl) {
1344 let lazyEl = slideEl.querySelector(`.${swiper.params.lazyPreloaderClass}`);
1345 if (!lazyEl && swiper.isElement) {
1346 if (slideEl.shadowRoot) {
1347 lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
1348 } else {
1349 // init later
1350 requestAnimationFrame(() => {
1351 if (slideEl.shadowRoot) {
1352 lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
1353 if (lazyEl) lazyEl.remove();
1354 }
1355 });
1356 }
1357 }
1358 if (lazyEl) lazyEl.remove();
1359 }
1360 };
1361 const unlazy = (swiper, index) => {
1362 if (!swiper.slides[index]) return;
1363 const imageEl = swiper.slides[index].querySelector('[loading="lazy"]');
1364 if (imageEl) imageEl.removeAttribute('loading');
1365 };
1366 const preload = swiper => {
1367 if (!swiper || swiper.destroyed || !swiper.params) return;
1368 let amount = swiper.params.lazyPreloadPrevNext;
1369 const len = swiper.slides.length;
1370 if (!len || !amount || amount < 0) return;
1371 amount = Math.min(amount, len);
1372 const slidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(swiper.params.slidesPerView);
1373 const activeIndex = swiper.activeIndex;
1374 if (swiper.params.grid && swiper.params.grid.rows > 1) {
1375 const activeColumn = activeIndex;
1376 const preloadColumns = [activeColumn - amount];
1377 preloadColumns.push(...Array.from({
1378 length: amount
1379 }).map((_, i) => {
1380 return activeColumn + slidesPerView + i;
1381 }));
1382 swiper.slides.forEach((slideEl, i) => {
1383 if (preloadColumns.includes(slideEl.column)) unlazy(swiper, i);
1384 });
1385 return;
1386 }
1387 const slideIndexLastInView = activeIndex + slidesPerView - 1;
1388 if (swiper.params.rewind || swiper.params.loop) {
1389 for (let i = activeIndex - amount; i <= slideIndexLastInView + amount; i += 1) {
1390 const realIndex = (i % len + len) % len;
1391 if (realIndex < activeIndex || realIndex > slideIndexLastInView) unlazy(swiper, realIndex);
1392 }
1393 } else {
1394 for (let i = Math.max(activeIndex - amount, 0); i <= Math.min(slideIndexLastInView + amount, len - 1); i += 1) {
1395 if (i !== activeIndex && (i > slideIndexLastInView || i < activeIndex)) {
1396 unlazy(swiper, i);
1397 }
1398 }
1399 }
1400 };
1401
1402 function getActiveIndexByTranslate(swiper) {
1403 const {
1404 slidesGrid,
1405 params
1406 } = swiper;
1407 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
1408 let activeIndex;
1409 for (let i = 0; i < slidesGrid.length; i += 1) {
1410 if (typeof slidesGrid[i + 1] !== 'undefined') {
1411 if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) {
1412 activeIndex = i;
1413 } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
1414 activeIndex = i + 1;
1415 }
1416 } else if (translate >= slidesGrid[i]) {
1417 activeIndex = i;
1418 }
1419 }
1420 // Normalize slideIndex
1421 if (params.normalizeSlideIndex) {
1422 if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
1423 }
1424 return activeIndex;
1425 }
1426 function updateActiveIndex(newActiveIndex) {
1427 const swiper = this;
1428 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
1429 const {
1430 snapGrid,
1431 params,
1432 activeIndex: previousIndex,
1433 realIndex: previousRealIndex,
1434 snapIndex: previousSnapIndex
1435 } = swiper;
1436 let activeIndex = newActiveIndex;
1437 let snapIndex;
1438 const getVirtualRealIndex = aIndex => {
1439 let realIndex = aIndex - swiper.virtual.slidesBefore;
1440 if (realIndex < 0) {
1441 realIndex = swiper.virtual.slides.length + realIndex;
1442 }
1443 if (realIndex >= swiper.virtual.slides.length) {
1444 realIndex -= swiper.virtual.slides.length;
1445 }
1446 return realIndex;
1447 };
1448 if (typeof activeIndex === 'undefined') {
1449 activeIndex = getActiveIndexByTranslate(swiper);
1450 }
1451 if (snapGrid.indexOf(translate) >= 0) {
1452 snapIndex = snapGrid.indexOf(translate);
1453 } else {
1454 const skip = Math.min(params.slidesPerGroupSkip, activeIndex);
1455 snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
1456 }
1457 if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
1458 if (activeIndex === previousIndex && !swiper.params.loop) {
1459 if (snapIndex !== previousSnapIndex) {
1460 swiper.snapIndex = snapIndex;
1461 swiper.emit('snapIndexChange');
1462 }
1463 return;
1464 }
1465 if (activeIndex === previousIndex && swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
1466 swiper.realIndex = getVirtualRealIndex(activeIndex);
1467 return;
1468 }
1469 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
1470
1471 // Get real index
1472 let realIndex;
1473 if (swiper.virtual && params.virtual.enabled && params.loop) {
1474 realIndex = getVirtualRealIndex(activeIndex);
1475 } else if (gridEnabled) {
1476 const firstSlideInColumn = swiper.slides.filter(slideEl => slideEl.column === activeIndex)[0];
1477 let activeSlideIndex = parseInt(firstSlideInColumn.getAttribute('data-swiper-slide-index'), 10);
1478 if (Number.isNaN(activeSlideIndex)) {
1479 activeSlideIndex = Math.max(swiper.slides.indexOf(firstSlideInColumn), 0);
1480 }
1481 realIndex = Math.floor(activeSlideIndex / params.grid.rows);
1482 } else if (swiper.slides[activeIndex]) {
1483 const slideIndex = swiper.slides[activeIndex].getAttribute('data-swiper-slide-index');
1484 if (slideIndex) {
1485 realIndex = parseInt(slideIndex, 10);
1486 } else {
1487 realIndex = activeIndex;
1488 }
1489 } else {
1490 realIndex = activeIndex;
1491 }
1492 Object.assign(swiper, {
1493 previousSnapIndex,
1494 snapIndex,
1495 previousRealIndex,
1496 realIndex,
1497 previousIndex,
1498 activeIndex
1499 });
1500 if (swiper.initialized) {
1501 preload(swiper);
1502 }
1503 swiper.emit('activeIndexChange');
1504 swiper.emit('snapIndexChange');
1505 if (swiper.initialized || swiper.params.runCallbacksOnInit) {
1506 if (previousRealIndex !== realIndex) {
1507 swiper.emit('realIndexChange');
1508 }
1509 swiper.emit('slideChange');
1510 }
1511 }
1512
1513 function updateClickedSlide(el, path) {
1514 const swiper = this;
1515 const params = swiper.params;
1516 let slide = el.closest(`.${params.slideClass}, swiper-slide`);
1517 if (!slide && swiper.isElement && path && path.length > 1 && path.includes(el)) {
1518 [...path.slice(path.indexOf(el) + 1, path.length)].forEach(pathEl => {
1519 if (!slide && pathEl.matches && pathEl.matches(`.${params.slideClass}, swiper-slide`)) {
1520 slide = pathEl;
1521 }
1522 });
1523 }
1524 let slideFound = false;
1525 let slideIndex;
1526 if (slide) {
1527 for (let i = 0; i < swiper.slides.length; i += 1) {
1528 if (swiper.slides[i] === slide) {
1529 slideFound = true;
1530 slideIndex = i;
1531 break;
1532 }
1533 }
1534 }
1535 if (slide && slideFound) {
1536 swiper.clickedSlide = slide;
1537 if (swiper.virtual && swiper.params.virtual.enabled) {
1538 swiper.clickedIndex = parseInt(slide.getAttribute('data-swiper-slide-index'), 10);
1539 } else {
1540 swiper.clickedIndex = slideIndex;
1541 }
1542 } else {
1543 swiper.clickedSlide = undefined;
1544 swiper.clickedIndex = undefined;
1545 return;
1546 }
1547 if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
1548 swiper.slideToClickedSlide();
1549 }
1550 }
1551
1552 var update = {
1553 updateSize,
1554 updateSlides,
1555 updateAutoHeight,
1556 updateSlidesOffset,
1557 updateSlidesProgress,
1558 updateProgress,
1559 updateSlidesClasses,
1560 updateActiveIndex,
1561 updateClickedSlide
1562 };
1563
1564 function getSwiperTranslate(axis) {
1565 if (axis === void 0) {
1566 axis = this.isHorizontal() ? 'x' : 'y';
1567 }
1568 const swiper = this;
1569 const {
1570 params,
1571 rtlTranslate: rtl,
1572 translate,
1573 wrapperEl
1574 } = swiper;
1575 if (params.virtualTranslate) {
1576 return rtl ? -translate : translate;
1577 }
1578 if (params.cssMode) {
1579 return translate;
1580 }
1581 let currentTranslate = getTranslate(wrapperEl, axis);
1582 currentTranslate += swiper.cssOverflowAdjustment();
1583 if (rtl) currentTranslate = -currentTranslate;
1584 return currentTranslate || 0;
1585 }
1586
1587 function setTranslate(translate, byController) {
1588 const swiper = this;
1589 const {
1590 rtlTranslate: rtl,
1591 params,
1592 wrapperEl,
1593 progress
1594 } = swiper;
1595 let x = 0;
1596 let y = 0;
1597 const z = 0;
1598 if (swiper.isHorizontal()) {
1599 x = rtl ? -translate : translate;
1600 } else {
1601 y = translate;
1602 }
1603 if (params.roundLengths) {
1604 x = Math.floor(x);
1605 y = Math.floor(y);
1606 }
1607 swiper.previousTranslate = swiper.translate;
1608 swiper.translate = swiper.isHorizontal() ? x : y;
1609 if (params.cssMode) {
1610 wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
1611 } else if (!params.virtualTranslate) {
1612 if (swiper.isHorizontal()) {
1613 x -= swiper.cssOverflowAdjustment();
1614 } else {
1615 y -= swiper.cssOverflowAdjustment();
1616 }
1617 wrapperEl.style.transform = `translate3d(${x}px, ${y}px, ${z}px)`;
1618 }
1619
1620 // Check if we need to update progress
1621 let newProgress;
1622 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
1623 if (translatesDiff === 0) {
1624 newProgress = 0;
1625 } else {
1626 newProgress = (translate - swiper.minTranslate()) / translatesDiff;
1627 }
1628 if (newProgress !== progress) {
1629 swiper.updateProgress(translate);
1630 }
1631 swiper.emit('setTranslate', swiper.translate, byController);
1632 }
1633
1634 function minTranslate() {
1635 return -this.snapGrid[0];
1636 }
1637
1638 function maxTranslate() {
1639 return -this.snapGrid[this.snapGrid.length - 1];
1640 }
1641
1642 function translateTo(translate, speed, runCallbacks, translateBounds, internal) {
1643 if (translate === void 0) {
1644 translate = 0;
1645 }
1646 if (speed === void 0) {
1647 speed = this.params.speed;
1648 }
1649 if (runCallbacks === void 0) {
1650 runCallbacks = true;
1651 }
1652 if (translateBounds === void 0) {
1653 translateBounds = true;
1654 }
1655 const swiper = this;
1656 const {
1657 params,
1658 wrapperEl
1659 } = swiper;
1660 if (swiper.animating && params.preventInteractionOnTransition) {
1661 return false;
1662 }
1663 const minTranslate = swiper.minTranslate();
1664 const maxTranslate = swiper.maxTranslate();
1665 let newTranslate;
1666 if (translateBounds && translate > minTranslate) newTranslate = minTranslate;else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;else newTranslate = translate;
1667
1668 // Update progress
1669 swiper.updateProgress(newTranslate);
1670 if (params.cssMode) {
1671 const isH = swiper.isHorizontal();
1672 if (speed === 0) {
1673 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
1674 } else {
1675 if (!swiper.support.smoothScroll) {
1676 animateCSSModeScroll({
1677 swiper,
1678 targetPosition: -newTranslate,
1679 side: isH ? 'left' : 'top'
1680 });
1681 return true;
1682 }
1683 wrapperEl.scrollTo({
1684 [isH ? 'left' : 'top']: -newTranslate,
1685 behavior: 'smooth'
1686 });
1687 }
1688 return true;
1689 }
1690 if (speed === 0) {
1691 swiper.setTransition(0);
1692 swiper.setTranslate(newTranslate);
1693 if (runCallbacks) {
1694 swiper.emit('beforeTransitionStart', speed, internal);
1695 swiper.emit('transitionEnd');
1696 }
1697 } else {
1698 swiper.setTransition(speed);
1699 swiper.setTranslate(newTranslate);
1700 if (runCallbacks) {
1701 swiper.emit('beforeTransitionStart', speed, internal);
1702 swiper.emit('transitionStart');
1703 }
1704 if (!swiper.animating) {
1705 swiper.animating = true;
1706 if (!swiper.onTranslateToWrapperTransitionEnd) {
1707 swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
1708 if (!swiper || swiper.destroyed) return;
1709 if (e.target !== this) return;
1710 swiper.wrapperEl.removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
1711 swiper.onTranslateToWrapperTransitionEnd = null;
1712 delete swiper.onTranslateToWrapperTransitionEnd;
1713 swiper.animating = false;
1714 if (runCallbacks) {
1715 swiper.emit('transitionEnd');
1716 }
1717 };
1718 }
1719 swiper.wrapperEl.addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
1720 }
1721 }
1722 return true;
1723 }
1724
1725 var translate = {
1726 getTranslate: getSwiperTranslate,
1727 setTranslate,
1728 minTranslate,
1729 maxTranslate,
1730 translateTo
1731 };
1732
1733 function setTransition(duration, byController) {
1734 const swiper = this;
1735 if (!swiper.params.cssMode) {
1736 swiper.wrapperEl.style.transitionDuration = `${duration}ms`;
1737 swiper.wrapperEl.style.transitionDelay = duration === 0 ? `0ms` : '';
1738 }
1739 swiper.emit('setTransition', duration, byController);
1740 }
1741
1742 function transitionEmit(_ref) {
1743 let {
1744 swiper,
1745 runCallbacks,
1746 direction,
1747 step
1748 } = _ref;
1749 const {
1750 activeIndex,
1751 previousIndex
1752 } = swiper;
1753 let dir = direction;
1754 if (!dir) {
1755 if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset';
1756 }
1757 swiper.emit(`transition${step}`);
1758 if (runCallbacks && activeIndex !== previousIndex) {
1759 if (dir === 'reset') {
1760 swiper.emit(`slideResetTransition${step}`);
1761 return;
1762 }
1763 swiper.emit(`slideChangeTransition${step}`);
1764 if (dir === 'next') {
1765 swiper.emit(`slideNextTransition${step}`);
1766 } else {
1767 swiper.emit(`slidePrevTransition${step}`);
1768 }
1769 }
1770 }
1771
1772 function transitionStart(runCallbacks, direction) {
1773 if (runCallbacks === void 0) {
1774 runCallbacks = true;
1775 }
1776 const swiper = this;
1777 const {
1778 params
1779 } = swiper;
1780 if (params.cssMode) return;
1781 if (params.autoHeight) {
1782 swiper.updateAutoHeight();
1783 }
1784 transitionEmit({
1785 swiper,
1786 runCallbacks,
1787 direction,
1788 step: 'Start'
1789 });
1790 }
1791
1792 function transitionEnd(runCallbacks, direction) {
1793 if (runCallbacks === void 0) {
1794 runCallbacks = true;
1795 }
1796 const swiper = this;
1797 const {
1798 params
1799 } = swiper;
1800 swiper.animating = false;
1801 if (params.cssMode) return;
1802 swiper.setTransition(0);
1803 transitionEmit({
1804 swiper,
1805 runCallbacks,
1806 direction,
1807 step: 'End'
1808 });
1809 }
1810
1811 var transition = {
1812 setTransition,
1813 transitionStart,
1814 transitionEnd
1815 };
1816
1817 function slideTo(index, speed, runCallbacks, internal, initial) {
1818 if (index === void 0) {
1819 index = 0;
1820 }
1821 if (runCallbacks === void 0) {
1822 runCallbacks = true;
1823 }
1824 if (typeof index === 'string') {
1825 index = parseInt(index, 10);
1826 }
1827 const swiper = this;
1828 let slideIndex = index;
1829 if (slideIndex < 0) slideIndex = 0;
1830 const {
1831 params,
1832 snapGrid,
1833 slidesGrid,
1834 previousIndex,
1835 activeIndex,
1836 rtlTranslate: rtl,
1837 wrapperEl,
1838 enabled
1839 } = swiper;
1840 if (!enabled && !internal && !initial || swiper.destroyed || swiper.animating && params.preventInteractionOnTransition) {
1841 return false;
1842 }
1843 if (typeof speed === 'undefined') {
1844 speed = swiper.params.speed;
1845 }
1846 const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
1847 let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
1848 if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
1849 const translate = -snapGrid[snapIndex];
1850 // Normalize slideIndex
1851 if (params.normalizeSlideIndex) {
1852 for (let i = 0; i < slidesGrid.length; i += 1) {
1853 const normalizedTranslate = -Math.floor(translate * 100);
1854 const normalizedGrid = Math.floor(slidesGrid[i] * 100);
1855 const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
1856 if (typeof slidesGrid[i + 1] !== 'undefined') {
1857 if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) {
1858 slideIndex = i;
1859 } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
1860 slideIndex = i + 1;
1861 }
1862 } else if (normalizedTranslate >= normalizedGrid) {
1863 slideIndex = i;
1864 }
1865 }
1866 }
1867 // Directions locks
1868 if (swiper.initialized && slideIndex !== activeIndex) {
1869 if (!swiper.allowSlideNext && (rtl ? translate > swiper.translate && translate > swiper.minTranslate() : translate < swiper.translate && translate < swiper.minTranslate())) {
1870 return false;
1871 }
1872 if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
1873 if ((activeIndex || 0) !== slideIndex) {
1874 return false;
1875 }
1876 }
1877 }
1878 if (slideIndex !== (previousIndex || 0) && runCallbacks) {
1879 swiper.emit('beforeSlideChangeStart');
1880 }
1881
1882 // Update progress
1883 swiper.updateProgress(translate);
1884 let direction;
1885 if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset';
1886
1887 // Update Index
1888 if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {
1889 swiper.updateActiveIndex(slideIndex);
1890 // Update Height
1891 if (params.autoHeight) {
1892 swiper.updateAutoHeight();
1893 }
1894 swiper.updateSlidesClasses();
1895 if (params.effect !== 'slide') {
1896 swiper.setTranslate(translate);
1897 }
1898 if (direction !== 'reset') {
1899 swiper.transitionStart(runCallbacks, direction);
1900 swiper.transitionEnd(runCallbacks, direction);
1901 }
1902 return false;
1903 }
1904 if (params.cssMode) {
1905 const isH = swiper.isHorizontal();
1906 const t = rtl ? translate : -translate;
1907 if (speed === 0) {
1908 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
1909 if (isVirtual) {
1910 swiper.wrapperEl.style.scrollSnapType = 'none';
1911 swiper._immediateVirtual = true;
1912 }
1913 if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) {
1914 swiper._cssModeVirtualInitialSet = true;
1915 requestAnimationFrame(() => {
1916 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1917 });
1918 } else {
1919 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1920 }
1921 if (isVirtual) {
1922 requestAnimationFrame(() => {
1923 swiper.wrapperEl.style.scrollSnapType = '';
1924 swiper._immediateVirtual = false;
1925 });
1926 }
1927 } else {
1928 if (!swiper.support.smoothScroll) {
1929 animateCSSModeScroll({
1930 swiper,
1931 targetPosition: t,
1932 side: isH ? 'left' : 'top'
1933 });
1934 return true;
1935 }
1936 wrapperEl.scrollTo({
1937 [isH ? 'left' : 'top']: t,
1938 behavior: 'smooth'
1939 });
1940 }
1941 return true;
1942 }
1943 swiper.setTransition(speed);
1944 swiper.setTranslate(translate);
1945 swiper.updateActiveIndex(slideIndex);
1946 swiper.updateSlidesClasses();
1947 swiper.emit('beforeTransitionStart', speed, internal);
1948 swiper.transitionStart(runCallbacks, direction);
1949 if (speed === 0) {
1950 swiper.transitionEnd(runCallbacks, direction);
1951 } else if (!swiper.animating) {
1952 swiper.animating = true;
1953 if (!swiper.onSlideToWrapperTransitionEnd) {
1954 swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
1955 if (!swiper || swiper.destroyed) return;
1956 if (e.target !== this) return;
1957 swiper.wrapperEl.removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
1958 swiper.onSlideToWrapperTransitionEnd = null;
1959 delete swiper.onSlideToWrapperTransitionEnd;
1960 swiper.transitionEnd(runCallbacks, direction);
1961 };
1962 }
1963 swiper.wrapperEl.addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
1964 }
1965 return true;
1966 }
1967
1968 function slideToLoop(index, speed, runCallbacks, internal) {
1969 if (index === void 0) {
1970 index = 0;
1971 }
1972 if (runCallbacks === void 0) {
1973 runCallbacks = true;
1974 }
1975 if (typeof index === 'string') {
1976 const indexAsNumber = parseInt(index, 10);
1977 index = indexAsNumber;
1978 }
1979 const swiper = this;
1980 if (swiper.destroyed) return;
1981 if (typeof speed === 'undefined') {
1982 speed = swiper.params.speed;
1983 }
1984 const gridEnabled = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
1985 let newIndex = index;
1986 if (swiper.params.loop) {
1987 if (swiper.virtual && swiper.params.virtual.enabled) {
1988 // eslint-disable-next-line
1989 newIndex = newIndex + swiper.virtual.slidesBefore;
1990 } else {
1991 let targetSlideIndex;
1992 if (gridEnabled) {
1993 const slideIndex = newIndex * swiper.params.grid.rows;
1994 targetSlideIndex = swiper.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex)[0].column;
1995 } else {
1996 targetSlideIndex = swiper.getSlideIndexByData(newIndex);
1997 }
1998 const cols = gridEnabled ? Math.ceil(swiper.slides.length / swiper.params.grid.rows) : swiper.slides.length;
1999 const {
2000 centeredSlides
2001 } = swiper.params;
2002 let slidesPerView = swiper.params.slidesPerView;
2003 if (slidesPerView === 'auto') {
2004 slidesPerView = swiper.slidesPerViewDynamic();
2005 } else {
2006 slidesPerView = Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
2007 if (centeredSlides && slidesPerView % 2 === 0) {
2008 slidesPerView = slidesPerView + 1;
2009 }
2010 }
2011 let needLoopFix = cols - targetSlideIndex < slidesPerView;
2012 if (centeredSlides) {
2013 needLoopFix = needLoopFix || targetSlideIndex < Math.ceil(slidesPerView / 2);
2014 }
2015 if (internal && centeredSlides && swiper.params.slidesPerView !== 'auto' && !gridEnabled) {
2016 needLoopFix = false;
2017 }
2018 if (needLoopFix) {
2019 const direction = centeredSlides ? targetSlideIndex < swiper.activeIndex ? 'prev' : 'next' : targetSlideIndex - swiper.activeIndex - 1 < swiper.params.slidesPerView ? 'next' : 'prev';
2020 swiper.loopFix({
2021 direction,
2022 slideTo: true,
2023 activeSlideIndex: direction === 'next' ? targetSlideIndex + 1 : targetSlideIndex - cols + 1,
2024 slideRealIndex: direction === 'next' ? swiper.realIndex : undefined
2025 });
2026 }
2027 if (gridEnabled) {
2028 const slideIndex = newIndex * swiper.params.grid.rows;
2029 newIndex = swiper.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex)[0].column;
2030 } else {
2031 newIndex = swiper.getSlideIndexByData(newIndex);
2032 }
2033 }
2034 }
2035 requestAnimationFrame(() => {
2036 swiper.slideTo(newIndex, speed, runCallbacks, internal);
2037 });
2038 return swiper;
2039 }
2040
2041 /* eslint no-unused-vars: "off" */
2042 function slideNext(speed, runCallbacks, internal) {
2043 if (runCallbacks === void 0) {
2044 runCallbacks = true;
2045 }
2046 const swiper = this;
2047 const {
2048 enabled,
2049 params,
2050 animating
2051 } = swiper;
2052 if (!enabled || swiper.destroyed) return swiper;
2053 if (typeof speed === 'undefined') {
2054 speed = swiper.params.speed;
2055 }
2056 let perGroup = params.slidesPerGroup;
2057 if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
2058 perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
2059 }
2060 const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
2061 const isVirtual = swiper.virtual && params.virtual.enabled;
2062 if (params.loop) {
2063 if (animating && !isVirtual && params.loopPreventsSliding) return false;
2064 swiper.loopFix({
2065 direction: 'next'
2066 });
2067 // eslint-disable-next-line
2068 swiper._clientLeft = swiper.wrapperEl.clientLeft;
2069 if (swiper.activeIndex === swiper.slides.length - 1 && params.cssMode) {
2070 requestAnimationFrame(() => {
2071 swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
2072 });
2073 return true;
2074 }
2075 }
2076 if (params.rewind && swiper.isEnd) {
2077 return swiper.slideTo(0, speed, runCallbacks, internal);
2078 }
2079 return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
2080 }
2081
2082 /* eslint no-unused-vars: "off" */
2083 function slidePrev(speed, runCallbacks, internal) {
2084 if (runCallbacks === void 0) {
2085 runCallbacks = true;
2086 }
2087 const swiper = this;
2088 const {
2089 params,
2090 snapGrid,
2091 slidesGrid,
2092 rtlTranslate,
2093 enabled,
2094 animating
2095 } = swiper;
2096 if (!enabled || swiper.destroyed) return swiper;
2097 if (typeof speed === 'undefined') {
2098 speed = swiper.params.speed;
2099 }
2100 const isVirtual = swiper.virtual && params.virtual.enabled;
2101 if (params.loop) {
2102 if (animating && !isVirtual && params.loopPreventsSliding) return false;
2103 swiper.loopFix({
2104 direction: 'prev'
2105 });
2106 // eslint-disable-next-line
2107 swiper._clientLeft = swiper.wrapperEl.clientLeft;
2108 }
2109 const translate = rtlTranslate ? swiper.translate : -swiper.translate;
2110 function normalize(val) {
2111 if (val < 0) return -Math.floor(Math.abs(val));
2112 return Math.floor(val);
2113 }
2114 const normalizedTranslate = normalize(translate);
2115 const normalizedSnapGrid = snapGrid.map(val => normalize(val));
2116 let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
2117 if (typeof prevSnap === 'undefined' && params.cssMode) {
2118 let prevSnapIndex;
2119 snapGrid.forEach((snap, snapIndex) => {
2120 if (normalizedTranslate >= snap) {
2121 // prevSnap = snap;
2122 prevSnapIndex = snapIndex;
2123 }
2124 });
2125 if (typeof prevSnapIndex !== 'undefined') {
2126 prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
2127 }
2128 }
2129 let prevIndex = 0;
2130 if (typeof prevSnap !== 'undefined') {
2131 prevIndex = slidesGrid.indexOf(prevSnap);
2132 if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
2133 if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
2134 prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1;
2135 prevIndex = Math.max(prevIndex, 0);
2136 }
2137 }
2138 if (params.rewind && swiper.isBeginning) {
2139 const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
2140 return swiper.slideTo(lastIndex, speed, runCallbacks, internal);
2141 } else if (params.loop && swiper.activeIndex === 0 && params.cssMode) {
2142 requestAnimationFrame(() => {
2143 swiper.slideTo(prevIndex, speed, runCallbacks, internal);
2144 });
2145 return true;
2146 }
2147 return swiper.slideTo(prevIndex, speed, runCallbacks, internal);
2148 }
2149
2150 /* eslint no-unused-vars: "off" */
2151 function slideReset(speed, runCallbacks, internal) {
2152 if (runCallbacks === void 0) {
2153 runCallbacks = true;
2154 }
2155 const swiper = this;
2156 if (swiper.destroyed) return;
2157 if (typeof speed === 'undefined') {
2158 speed = swiper.params.speed;
2159 }
2160 return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
2161 }
2162
2163 /* eslint no-unused-vars: "off" */
2164 function slideToClosest(speed, runCallbacks, internal, threshold) {
2165 if (runCallbacks === void 0) {
2166 runCallbacks = true;
2167 }
2168 if (threshold === void 0) {
2169 threshold = 0.5;
2170 }
2171 const swiper = this;
2172 if (swiper.destroyed) return;
2173 if (typeof speed === 'undefined') {
2174 speed = swiper.params.speed;
2175 }
2176 let index = swiper.activeIndex;
2177 const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
2178 const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
2179 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
2180 if (translate >= swiper.snapGrid[snapIndex]) {
2181 // The current translate is on or after the current snap index, so the choice
2182 // is between the current index and the one after it.
2183 const currentSnap = swiper.snapGrid[snapIndex];
2184 const nextSnap = swiper.snapGrid[snapIndex + 1];
2185 if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {
2186 index += swiper.params.slidesPerGroup;
2187 }
2188 } else {
2189 // The current translate is before the current snap index, so the choice
2190 // is between the current index and the one before it.
2191 const prevSnap = swiper.snapGrid[snapIndex - 1];
2192 const currentSnap = swiper.snapGrid[snapIndex];
2193 if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) {
2194 index -= swiper.params.slidesPerGroup;
2195 }
2196 }
2197 index = Math.max(index, 0);
2198 index = Math.min(index, swiper.slidesGrid.length - 1);
2199 return swiper.slideTo(index, speed, runCallbacks, internal);
2200 }
2201
2202 function slideToClickedSlide() {
2203 const swiper = this;
2204 if (swiper.destroyed) return;
2205 const {
2206 params,
2207 slidesEl
2208 } = swiper;
2209 const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
2210 let slideToIndex = swiper.clickedIndex;
2211 let realIndex;
2212 const slideSelector = swiper.isElement ? `swiper-slide` : `.${params.slideClass}`;
2213 if (params.loop) {
2214 if (swiper.animating) return;
2215 realIndex = parseInt(swiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
2216 if (params.centeredSlides) {
2217 if (slideToIndex < swiper.loopedSlides - slidesPerView / 2 || slideToIndex > swiper.slides.length - swiper.loopedSlides + slidesPerView / 2) {
2218 swiper.loopFix();
2219 slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
2220 nextTick(() => {
2221 swiper.slideTo(slideToIndex);
2222 });
2223 } else {
2224 swiper.slideTo(slideToIndex);
2225 }
2226 } else if (slideToIndex > swiper.slides.length - slidesPerView) {
2227 swiper.loopFix();
2228 slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
2229 nextTick(() => {
2230 swiper.slideTo(slideToIndex);
2231 });
2232 } else {
2233 swiper.slideTo(slideToIndex);
2234 }
2235 } else {
2236 swiper.slideTo(slideToIndex);
2237 }
2238 }
2239
2240 var slide = {
2241 slideTo,
2242 slideToLoop,
2243 slideNext,
2244 slidePrev,
2245 slideReset,
2246 slideToClosest,
2247 slideToClickedSlide
2248 };
2249
2250 function loopCreate(slideRealIndex) {
2251 const swiper = this;
2252 const {
2253 params,
2254 slidesEl
2255 } = swiper;
2256 if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
2257 const initSlides = () => {
2258 const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
2259 slides.forEach((el, index) => {
2260 el.setAttribute('data-swiper-slide-index', index);
2261 });
2262 };
2263 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
2264 const slidesPerGroup = params.slidesPerGroup * (gridEnabled ? params.grid.rows : 1);
2265 const shouldFillGroup = swiper.slides.length % slidesPerGroup !== 0;
2266 const shouldFillGrid = gridEnabled && swiper.slides.length % params.grid.rows !== 0;
2267 const addBlankSlides = amountOfSlides => {
2268 for (let i = 0; i < amountOfSlides; i += 1) {
2269 const slideEl = swiper.isElement ? createElement('swiper-slide', [params.slideBlankClass]) : createElement('div', [params.slideClass, params.slideBlankClass]);
2270 swiper.slidesEl.append(slideEl);
2271 }
2272 };
2273 if (shouldFillGroup) {
2274 if (params.loopAddBlankSlides) {
2275 const slidesToAdd = slidesPerGroup - swiper.slides.length % slidesPerGroup;
2276 addBlankSlides(slidesToAdd);
2277 swiper.recalcSlides();
2278 swiper.updateSlides();
2279 } else {
2280 showWarning('Swiper Loop Warning: The number of slides is not even to slidesPerGroup, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
2281 }
2282 initSlides();
2283 } else if (shouldFillGrid) {
2284 if (params.loopAddBlankSlides) {
2285 const slidesToAdd = params.grid.rows - swiper.slides.length % params.grid.rows;
2286 addBlankSlides(slidesToAdd);
2287 swiper.recalcSlides();
2288 swiper.updateSlides();
2289 } else {
2290 showWarning('Swiper Loop Warning: The number of slides is not even to grid.rows, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
2291 }
2292 initSlides();
2293 } else {
2294 initSlides();
2295 }
2296 swiper.loopFix({
2297 slideRealIndex,
2298 direction: params.centeredSlides ? undefined : 'next'
2299 });
2300 }
2301
2302 function loopFix(_temp) {
2303 let {
2304 slideRealIndex,
2305 slideTo = true,
2306 direction,
2307 setTranslate,
2308 activeSlideIndex,
2309 byController,
2310 byMousewheel
2311 } = _temp === void 0 ? {} : _temp;
2312 const swiper = this;
2313 if (!swiper.params.loop) return;
2314 swiper.emit('beforeLoopFix');
2315 const {
2316 slides,
2317 allowSlidePrev,
2318 allowSlideNext,
2319 slidesEl,
2320 params
2321 } = swiper;
2322 const {
2323 centeredSlides
2324 } = params;
2325 swiper.allowSlidePrev = true;
2326 swiper.allowSlideNext = true;
2327 if (swiper.virtual && params.virtual.enabled) {
2328 if (slideTo) {
2329 if (!params.centeredSlides && swiper.snapIndex === 0) {
2330 swiper.slideTo(swiper.virtual.slides.length, 0, false, true);
2331 } else if (params.centeredSlides && swiper.snapIndex < params.slidesPerView) {
2332 swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true);
2333 } else if (swiper.snapIndex === swiper.snapGrid.length - 1) {
2334 swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true);
2335 }
2336 }
2337 swiper.allowSlidePrev = allowSlidePrev;
2338 swiper.allowSlideNext = allowSlideNext;
2339 swiper.emit('loopFix');
2340 return;
2341 }
2342 let slidesPerView = params.slidesPerView;
2343 if (slidesPerView === 'auto') {
2344 slidesPerView = swiper.slidesPerViewDynamic();
2345 } else {
2346 slidesPerView = Math.ceil(parseFloat(params.slidesPerView, 10));
2347 if (centeredSlides && slidesPerView % 2 === 0) {
2348 slidesPerView = slidesPerView + 1;
2349 }
2350 }
2351 const slidesPerGroup = params.slidesPerGroupAuto ? slidesPerView : params.slidesPerGroup;
2352 let loopedSlides = slidesPerGroup;
2353 if (loopedSlides % slidesPerGroup !== 0) {
2354 loopedSlides += slidesPerGroup - loopedSlides % slidesPerGroup;
2355 }
2356 loopedSlides += params.loopAdditionalSlides;
2357 swiper.loopedSlides = loopedSlides;
2358 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
2359 if (slides.length < slidesPerView + loopedSlides) {
2360 showWarning('Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled and not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters');
2361 } else if (gridEnabled && params.grid.fill === 'row') {
2362 showWarning('Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`');
2363 }
2364 const prependSlidesIndexes = [];
2365 const appendSlidesIndexes = [];
2366 let activeIndex = swiper.activeIndex;
2367 if (typeof activeSlideIndex === 'undefined') {
2368 activeSlideIndex = swiper.getSlideIndex(slides.filter(el => el.classList.contains(params.slideActiveClass))[0]);
2369 } else {
2370 activeIndex = activeSlideIndex;
2371 }
2372 const isNext = direction === 'next' || !direction;
2373 const isPrev = direction === 'prev' || !direction;
2374 let slidesPrepended = 0;
2375 let slidesAppended = 0;
2376 const cols = gridEnabled ? Math.ceil(slides.length / params.grid.rows) : slides.length;
2377 const activeColIndex = gridEnabled ? slides[activeSlideIndex].column : activeSlideIndex;
2378 const activeColIndexWithShift = activeColIndex + (centeredSlides && typeof setTranslate === 'undefined' ? -slidesPerView / 2 + 0.5 : 0);
2379 // prepend last slides before start
2380 if (activeColIndexWithShift < loopedSlides) {
2381 slidesPrepended = Math.max(loopedSlides - activeColIndexWithShift, slidesPerGroup);
2382 for (let i = 0; i < loopedSlides - activeColIndexWithShift; i += 1) {
2383 const index = i - Math.floor(i / cols) * cols;
2384 if (gridEnabled) {
2385 const colIndexToPrepend = cols - index - 1;
2386 for (let i = slides.length - 1; i >= 0; i -= 1) {
2387 if (slides[i].column === colIndexToPrepend) prependSlidesIndexes.push(i);
2388 }
2389 // slides.forEach((slide, slideIndex) => {
2390 // if (slide.column === colIndexToPrepend) prependSlidesIndexes.push(slideIndex);
2391 // });
2392 } else {
2393 prependSlidesIndexes.push(cols - index - 1);
2394 }
2395 }
2396 } else if (activeColIndexWithShift + slidesPerView > cols - loopedSlides) {
2397 slidesAppended = Math.max(activeColIndexWithShift - (cols - loopedSlides * 2), slidesPerGroup);
2398 for (let i = 0; i < slidesAppended; i += 1) {
2399 const index = i - Math.floor(i / cols) * cols;
2400 if (gridEnabled) {
2401 slides.forEach((slide, slideIndex) => {
2402 if (slide.column === index) appendSlidesIndexes.push(slideIndex);
2403 });
2404 } else {
2405 appendSlidesIndexes.push(index);
2406 }
2407 }
2408 }
2409 swiper.__preventObserver__ = true;
2410 requestAnimationFrame(() => {
2411 swiper.__preventObserver__ = false;
2412 });
2413 if (isPrev) {
2414 prependSlidesIndexes.forEach(index => {
2415 slides[index].swiperLoopMoveDOM = true;
2416 slidesEl.prepend(slides[index]);
2417 slides[index].swiperLoopMoveDOM = false;
2418 });
2419 }
2420 if (isNext) {
2421 appendSlidesIndexes.forEach(index => {
2422 slides[index].swiperLoopMoveDOM = true;
2423 slidesEl.append(slides[index]);
2424 slides[index].swiperLoopMoveDOM = false;
2425 });
2426 }
2427 swiper.recalcSlides();
2428 if (params.slidesPerView === 'auto') {
2429 swiper.updateSlides();
2430 } else if (gridEnabled && (prependSlidesIndexes.length > 0 && isPrev || appendSlidesIndexes.length > 0 && isNext)) {
2431 swiper.slides.forEach((slide, slideIndex) => {
2432 swiper.grid.updateSlide(slideIndex, slide, swiper.slides);
2433 });
2434 }
2435 if (params.watchSlidesProgress) {
2436 swiper.updateSlidesOffset();
2437 }
2438 if (slideTo) {
2439 if (prependSlidesIndexes.length > 0 && isPrev) {
2440 if (typeof slideRealIndex === 'undefined') {
2441 const currentSlideTranslate = swiper.slidesGrid[activeIndex];
2442 const newSlideTranslate = swiper.slidesGrid[activeIndex + slidesPrepended];
2443 const diff = newSlideTranslate - currentSlideTranslate;
2444 if (byMousewheel) {
2445 swiper.setTranslate(swiper.translate - diff);
2446 } else {
2447 swiper.slideTo(activeIndex + Math.ceil(slidesPrepended), 0, false, true);
2448 if (setTranslate) {
2449 swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
2450 swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
2451 }
2452 }
2453 } else {
2454 if (setTranslate) {
2455 const shift = gridEnabled ? prependSlidesIndexes.length / params.grid.rows : prependSlidesIndexes.length;
2456 swiper.slideTo(swiper.activeIndex + shift, 0, false, true);
2457 swiper.touchEventsData.currentTranslate = swiper.translate;
2458 }
2459 }
2460 } else if (appendSlidesIndexes.length > 0 && isNext) {
2461 if (typeof slideRealIndex === 'undefined') {
2462 const currentSlideTranslate = swiper.slidesGrid[activeIndex];
2463 const newSlideTranslate = swiper.slidesGrid[activeIndex - slidesAppended];
2464 const diff = newSlideTranslate - currentSlideTranslate;
2465 if (byMousewheel) {
2466 swiper.setTranslate(swiper.translate - diff);
2467 } else {
2468 swiper.slideTo(activeIndex - slidesAppended, 0, false, true);
2469 if (setTranslate) {
2470 swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
2471 swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
2472 }
2473 }
2474 } else {
2475 const shift = gridEnabled ? appendSlidesIndexes.length / params.grid.rows : appendSlidesIndexes.length;
2476 swiper.slideTo(swiper.activeIndex - shift, 0, false, true);
2477 }
2478 }
2479 }
2480 swiper.allowSlidePrev = allowSlidePrev;
2481 swiper.allowSlideNext = allowSlideNext;
2482 if (swiper.controller && swiper.controller.control && !byController) {
2483 const loopParams = {
2484 slideRealIndex,
2485 direction,
2486 setTranslate,
2487 activeSlideIndex,
2488 byController: true
2489 };
2490 if (Array.isArray(swiper.controller.control)) {
2491 swiper.controller.control.forEach(c => {
2492 if (!c.destroyed && c.params.loop) c.loopFix({
2493 ...loopParams,
2494 slideTo: c.params.slidesPerView === params.slidesPerView ? slideTo : false
2495 });
2496 });
2497 } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) {
2498 swiper.controller.control.loopFix({
2499 ...loopParams,
2500 slideTo: swiper.controller.control.params.slidesPerView === params.slidesPerView ? slideTo : false
2501 });
2502 }
2503 }
2504 swiper.emit('loopFix');
2505 }
2506
2507 function loopDestroy() {
2508 const swiper = this;
2509 const {
2510 params,
2511 slidesEl
2512 } = swiper;
2513 if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
2514 swiper.recalcSlides();
2515 const newSlidesOrder = [];
2516 swiper.slides.forEach(slideEl => {
2517 const index = typeof slideEl.swiperSlideIndex === 'undefined' ? slideEl.getAttribute('data-swiper-slide-index') * 1 : slideEl.swiperSlideIndex;
2518 newSlidesOrder[index] = slideEl;
2519 });
2520 swiper.slides.forEach(slideEl => {
2521 slideEl.removeAttribute('data-swiper-slide-index');
2522 });
2523 newSlidesOrder.forEach(slideEl => {
2524 slidesEl.append(slideEl);
2525 });
2526 swiper.recalcSlides();
2527 swiper.slideTo(swiper.realIndex, 0);
2528 }
2529
2530 var loop = {
2531 loopCreate,
2532 loopFix,
2533 loopDestroy
2534 };
2535
2536 function setGrabCursor(moving) {
2537 const swiper = this;
2538 if (!swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return;
2539 const el = swiper.params.touchEventsTarget === 'container' ? swiper.el : swiper.wrapperEl;
2540 if (swiper.isElement) {
2541 swiper.__preventObserver__ = true;
2542 }
2543 el.style.cursor = 'move';
2544 el.style.cursor = moving ? 'grabbing' : 'grab';
2545 if (swiper.isElement) {
2546 requestAnimationFrame(() => {
2547 swiper.__preventObserver__ = false;
2548 });
2549 }
2550 }
2551
2552 function unsetGrabCursor() {
2553 const swiper = this;
2554 if (swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {
2555 return;
2556 }
2557 if (swiper.isElement) {
2558 swiper.__preventObserver__ = true;
2559 }
2560 swiper[swiper.params.touchEventsTarget === 'container' ? 'el' : 'wrapperEl'].style.cursor = '';
2561 if (swiper.isElement) {
2562 requestAnimationFrame(() => {
2563 swiper.__preventObserver__ = false;
2564 });
2565 }
2566 }
2567
2568 var grabCursor = {
2569 setGrabCursor,
2570 unsetGrabCursor
2571 };
2572
2573 // Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
2574 function closestElement(selector, base) {
2575 if (base === void 0) {
2576 base = this;
2577 }
2578 function __closestFrom(el) {
2579 if (!el || el === getDocument() || el === getWindow()) return null;
2580 if (el.assignedSlot) el = el.assignedSlot;
2581 const found = el.closest(selector);
2582 if (!found && !el.getRootNode) {
2583 return null;
2584 }
2585 return found || __closestFrom(el.getRootNode().host);
2586 }
2587 return __closestFrom(base);
2588 }
2589 function preventEdgeSwipe(swiper, event, startX) {
2590 const window = getWindow();
2591 const {
2592 params
2593 } = swiper;
2594 const edgeSwipeDetection = params.edgeSwipeDetection;
2595 const edgeSwipeThreshold = params.edgeSwipeThreshold;
2596 if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {
2597 if (edgeSwipeDetection === 'prevent') {
2598 event.preventDefault();
2599 return true;
2600 }
2601 return false;
2602 }
2603 return true;
2604 }
2605 function onTouchStart(event) {
2606 const swiper = this;
2607 const document = getDocument();
2608 let e = event;
2609 if (e.originalEvent) e = e.originalEvent;
2610 const data = swiper.touchEventsData;
2611 if (e.type === 'pointerdown') {
2612 if (data.pointerId !== null && data.pointerId !== e.pointerId) {
2613 return;
2614 }
2615 data.pointerId = e.pointerId;
2616 } else if (e.type === 'touchstart' && e.targetTouches.length === 1) {
2617 data.touchId = e.targetTouches[0].identifier;
2618 }
2619 if (e.type === 'touchstart') {
2620 // don't proceed touch event
2621 preventEdgeSwipe(swiper, e, e.targetTouches[0].pageX);
2622 return;
2623 }
2624 const {
2625 params,
2626 touches,
2627 enabled
2628 } = swiper;
2629 if (!enabled) return;
2630 if (!params.simulateTouch && e.pointerType === 'mouse') return;
2631 if (swiper.animating && params.preventInteractionOnTransition) {
2632 return;
2633 }
2634 if (!swiper.animating && params.cssMode && params.loop) {
2635 swiper.loopFix();
2636 }
2637 let targetEl = e.target;
2638 if (params.touchEventsTarget === 'wrapper') {
2639 if (!swiper.wrapperEl.contains(targetEl)) return;
2640 }
2641 if ('which' in e && e.which === 3) return;
2642 if ('button' in e && e.button > 0) return;
2643 if (data.isTouched && data.isMoved) return;
2644
2645 // change target el for shadow root component
2646 const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
2647 // eslint-disable-next-line
2648 const eventPath = e.composedPath ? e.composedPath() : e.path;
2649 if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) {
2650 targetEl = eventPath[0];
2651 }
2652 const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
2653 const isTargetShadow = !!(e.target && e.target.shadowRoot);
2654
2655 // use closestElement for shadow root element to get the actual closest for nested shadow root element
2656 if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))) {
2657 swiper.allowClick = true;
2658 return;
2659 }
2660 if (params.swipeHandler) {
2661 if (!targetEl.closest(params.swipeHandler)) return;
2662 }
2663 touches.currentX = e.pageX;
2664 touches.currentY = e.pageY;
2665 const startX = touches.currentX;
2666 const startY = touches.currentY;
2667
2668 // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
2669
2670 if (!preventEdgeSwipe(swiper, e, startX)) {
2671 return;
2672 }
2673 Object.assign(data, {
2674 isTouched: true,
2675 isMoved: false,
2676 allowTouchCallbacks: true,
2677 isScrolling: undefined,
2678 startMoving: undefined
2679 });
2680 touches.startX = startX;
2681 touches.startY = startY;
2682 data.touchStartTime = now();
2683 swiper.allowClick = true;
2684 swiper.updateSize();
2685 swiper.swipeDirection = undefined;
2686 if (params.threshold > 0) data.allowThresholdMove = false;
2687 let preventDefault = true;
2688 if (targetEl.matches(data.focusableElements)) {
2689 preventDefault = false;
2690 if (targetEl.nodeName === 'SELECT') {
2691 data.isTouched = false;
2692 }
2693 }
2694 if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== targetEl) {
2695 document.activeElement.blur();
2696 }
2697 const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
2698 if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) {
2699 e.preventDefault();
2700 }
2701 if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {
2702 swiper.freeMode.onTouchStart();
2703 }
2704 swiper.emit('touchStart', e);
2705 }
2706
2707 function onTouchMove(event) {
2708 const document = getDocument();
2709 const swiper = this;
2710 const data = swiper.touchEventsData;
2711 const {
2712 params,
2713 touches,
2714 rtlTranslate: rtl,
2715 enabled
2716 } = swiper;
2717 if (!enabled) return;
2718 if (!params.simulateTouch && event.pointerType === 'mouse') return;
2719 let e = event;
2720 if (e.originalEvent) e = e.originalEvent;
2721 if (e.type === 'pointermove') {
2722 if (data.touchId !== null) return; // return from pointer if we use touch
2723 const id = e.pointerId;
2724 if (id !== data.pointerId) return;
2725 }
2726 let targetTouch;
2727 if (e.type === 'touchmove') {
2728 targetTouch = [...e.changedTouches].filter(t => t.identifier === data.touchId)[0];
2729 if (!targetTouch || targetTouch.identifier !== data.touchId) return;
2730 } else {
2731 targetTouch = e;
2732 }
2733 if (!data.isTouched) {
2734 if (data.startMoving && data.isScrolling) {
2735 swiper.emit('touchMoveOpposite', e);
2736 }
2737 return;
2738 }
2739 const pageX = targetTouch.pageX;
2740 const pageY = targetTouch.pageY;
2741 if (e.preventedByNestedSwiper) {
2742 touches.startX = pageX;
2743 touches.startY = pageY;
2744 return;
2745 }
2746 if (!swiper.allowTouchMove) {
2747 if (!e.target.matches(data.focusableElements)) {
2748 swiper.allowClick = false;
2749 }
2750 if (data.isTouched) {
2751 Object.assign(touches, {
2752 startX: pageX,
2753 startY: pageY,
2754 currentX: pageX,
2755 currentY: pageY
2756 });
2757 data.touchStartTime = now();
2758 }
2759 return;
2760 }
2761 if (params.touchReleaseOnEdges && !params.loop) {
2762 if (swiper.isVertical()) {
2763 // Vertical
2764 if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {
2765 data.isTouched = false;
2766 data.isMoved = false;
2767 return;
2768 }
2769 } else if (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate()) {
2770 return;
2771 }
2772 }
2773 if (document.activeElement) {
2774 if (e.target === document.activeElement && e.target.matches(data.focusableElements)) {
2775 data.isMoved = true;
2776 swiper.allowClick = false;
2777 return;
2778 }
2779 }
2780 if (data.allowTouchCallbacks) {
2781 swiper.emit('touchMove', e);
2782 }
2783 touches.previousX = touches.currentX;
2784 touches.previousY = touches.currentY;
2785 touches.currentX = pageX;
2786 touches.currentY = pageY;
2787 const diffX = touches.currentX - touches.startX;
2788 const diffY = touches.currentY - touches.startY;
2789 if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return;
2790 if (typeof data.isScrolling === 'undefined') {
2791 let touchAngle;
2792 if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) {
2793 data.isScrolling = false;
2794 } else {
2795 // eslint-disable-next-line
2796 if (diffX * diffX + diffY * diffY >= 25) {
2797 touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
2798 data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle;
2799 }
2800 }
2801 }
2802 if (data.isScrolling) {
2803 swiper.emit('touchMoveOpposite', e);
2804 }
2805 if (typeof data.startMoving === 'undefined') {
2806 if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
2807 data.startMoving = true;
2808 }
2809 }
2810 if (data.isScrolling || e.type === 'touchmove' && data.preventTouchMoveFromPointerMove) {
2811 data.isTouched = false;
2812 return;
2813 }
2814 if (!data.startMoving) {
2815 return;
2816 }
2817 swiper.allowClick = false;
2818 if (!params.cssMode && e.cancelable) {
2819 e.preventDefault();
2820 }
2821 if (params.touchMoveStopPropagation && !params.nested) {
2822 e.stopPropagation();
2823 }
2824 let diff = swiper.isHorizontal() ? diffX : diffY;
2825 let touchesDiff = swiper.isHorizontal() ? touches.currentX - touches.previousX : touches.currentY - touches.previousY;
2826 if (params.oneWayMovement) {
2827 diff = Math.abs(diff) * (rtl ? 1 : -1);
2828 touchesDiff = Math.abs(touchesDiff) * (rtl ? 1 : -1);
2829 }
2830 touches.diff = diff;
2831 diff *= params.touchRatio;
2832 if (rtl) {
2833 diff = -diff;
2834 touchesDiff = -touchesDiff;
2835 }
2836 const prevTouchesDirection = swiper.touchesDirection;
2837 swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
2838 swiper.touchesDirection = touchesDiff > 0 ? 'prev' : 'next';
2839 const isLoop = swiper.params.loop && !params.cssMode;
2840 const allowLoopFix = swiper.touchesDirection === 'next' && swiper.allowSlideNext || swiper.touchesDirection === 'prev' && swiper.allowSlidePrev;
2841 if (!data.isMoved) {
2842 if (isLoop && allowLoopFix) {
2843 swiper.loopFix({
2844 direction: swiper.swipeDirection
2845 });
2846 }
2847 data.startTranslate = swiper.getTranslate();
2848 swiper.setTransition(0);
2849 if (swiper.animating) {
2850 const evt = new window.CustomEvent('transitionend', {
2851 bubbles: true,
2852 cancelable: true,
2853 detail: {
2854 bySwiperTouchMove: true
2855 }
2856 });
2857 swiper.wrapperEl.dispatchEvent(evt);
2858 }
2859 data.allowMomentumBounce = false;
2860 // Grab Cursor
2861 if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
2862 swiper.setGrabCursor(true);
2863 }
2864 swiper.emit('sliderFirstMove', e);
2865 }
2866 let loopFixed;
2867 new Date().getTime();
2868 if (data.isMoved && data.allowThresholdMove && prevTouchesDirection !== swiper.touchesDirection && isLoop && allowLoopFix && Math.abs(diff) >= 1) {
2869 Object.assign(touches, {
2870 startX: pageX,
2871 startY: pageY,
2872 currentX: pageX,
2873 currentY: pageY,
2874 startTranslate: data.currentTranslate
2875 });
2876 data.loopSwapReset = true;
2877 data.startTranslate = data.currentTranslate;
2878 return;
2879 }
2880 swiper.emit('sliderMove', e);
2881 data.isMoved = true;
2882 data.currentTranslate = diff + data.startTranslate;
2883 let disableParentSwiper = true;
2884 let resistanceRatio = params.resistanceRatio;
2885 if (params.touchReleaseOnEdges) {
2886 resistanceRatio = 0;
2887 }
2888 if (diff > 0) {
2889 if (isLoop && allowLoopFix && !loopFixed && data.allowThresholdMove && data.currentTranslate > (params.centeredSlides ? swiper.minTranslate() - swiper.slidesSizesGrid[swiper.activeIndex + 1] : swiper.minTranslate())) {
2890 swiper.loopFix({
2891 direction: 'prev',
2892 setTranslate: true,
2893 activeSlideIndex: 0
2894 });
2895 }
2896 if (data.currentTranslate > swiper.minTranslate()) {
2897 disableParentSwiper = false;
2898 if (params.resistance) {
2899 data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio;
2900 }
2901 }
2902 } else if (diff < 0) {
2903 if (isLoop && allowLoopFix && !loopFixed && data.allowThresholdMove && data.currentTranslate < (params.centeredSlides ? swiper.maxTranslate() + swiper.slidesSizesGrid[swiper.slidesSizesGrid.length - 1] : swiper.maxTranslate())) {
2904 swiper.loopFix({
2905 direction: 'next',
2906 setTranslate: true,
2907 activeSlideIndex: swiper.slides.length - (params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10)))
2908 });
2909 }
2910 if (data.currentTranslate < swiper.maxTranslate()) {
2911 disableParentSwiper = false;
2912 if (params.resistance) {
2913 data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio;
2914 }
2915 }
2916 }
2917 if (disableParentSwiper) {
2918 e.preventedByNestedSwiper = true;
2919 }
2920
2921 // Directions locks
2922 if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
2923 data.currentTranslate = data.startTranslate;
2924 }
2925 if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
2926 data.currentTranslate = data.startTranslate;
2927 }
2928 if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
2929 data.currentTranslate = data.startTranslate;
2930 }
2931
2932 // Threshold
2933 if (params.threshold > 0) {
2934 if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
2935 if (!data.allowThresholdMove) {
2936 data.allowThresholdMove = true;
2937 touches.startX = touches.currentX;
2938 touches.startY = touches.currentY;
2939 data.currentTranslate = data.startTranslate;
2940 touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;
2941 return;
2942 }
2943 } else {
2944 data.currentTranslate = data.startTranslate;
2945 return;
2946 }
2947 }
2948 if (!params.followFinger || params.cssMode) return;
2949
2950 // Update active index in free mode
2951 if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {
2952 swiper.updateActiveIndex();
2953 swiper.updateSlidesClasses();
2954 }
2955 if (params.freeMode && params.freeMode.enabled && swiper.freeMode) {
2956 swiper.freeMode.onTouchMove();
2957 }
2958 // Update progress
2959 swiper.updateProgress(data.currentTranslate);
2960 // Update translate
2961 swiper.setTranslate(data.currentTranslate);
2962 }
2963
2964 function onTouchEnd(event) {
2965 const swiper = this;
2966 const data = swiper.touchEventsData;
2967 let e = event;
2968 if (e.originalEvent) e = e.originalEvent;
2969 let targetTouch;
2970 const isTouchEvent = e.type === 'touchend' || e.type === 'touchcancel';
2971 if (!isTouchEvent) {
2972 if (data.touchId !== null) return; // return from pointer if we use touch
2973 if (e.pointerId !== data.pointerId) return;
2974 targetTouch = e;
2975 } else {
2976 targetTouch = [...e.changedTouches].filter(t => t.identifier === data.touchId)[0];
2977 if (!targetTouch || targetTouch.identifier !== data.touchId) return;
2978 }
2979 if (['pointercancel', 'pointerout', 'pointerleave', 'contextmenu'].includes(e.type)) {
2980 const proceed = ['pointercancel', 'contextmenu'].includes(e.type) && (swiper.browser.isSafari || swiper.browser.isWebView);
2981 if (!proceed) {
2982 return;
2983 }
2984 }
2985 data.pointerId = null;
2986 data.touchId = null;
2987 const {
2988 params,
2989 touches,
2990 rtlTranslate: rtl,
2991 slidesGrid,
2992 enabled
2993 } = swiper;
2994 if (!enabled) return;
2995 if (!params.simulateTouch && e.pointerType === 'mouse') return;
2996 if (data.allowTouchCallbacks) {
2997 swiper.emit('touchEnd', e);
2998 }
2999 data.allowTouchCallbacks = false;
3000 if (!data.isTouched) {
3001 if (data.isMoved && params.grabCursor) {
3002 swiper.setGrabCursor(false);
3003 }
3004 data.isMoved = false;
3005 data.startMoving = false;
3006 return;
3007 }
3008
3009 // Return Grab Cursor
3010 if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
3011 swiper.setGrabCursor(false);
3012 }
3013
3014 // Time diff
3015 const touchEndTime = now();
3016 const timeDiff = touchEndTime - data.touchStartTime;
3017
3018 // Tap, doubleTap, Click
3019 if (swiper.allowClick) {
3020 const pathTree = e.path || e.composedPath && e.composedPath();
3021 swiper.updateClickedSlide(pathTree && pathTree[0] || e.target, pathTree);
3022 swiper.emit('tap click', e);
3023 if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {
3024 swiper.emit('doubleTap doubleClick', e);
3025 }
3026 }
3027 data.lastClickTime = now();
3028 nextTick(() => {
3029 if (!swiper.destroyed) swiper.allowClick = true;
3030 });
3031 if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 && !data.loopSwapReset || data.currentTranslate === data.startTranslate && !data.loopSwapReset) {
3032 data.isTouched = false;
3033 data.isMoved = false;
3034 data.startMoving = false;
3035 return;
3036 }
3037 data.isTouched = false;
3038 data.isMoved = false;
3039 data.startMoving = false;
3040 let currentPos;
3041 if (params.followFinger) {
3042 currentPos = rtl ? swiper.translate : -swiper.translate;
3043 } else {
3044 currentPos = -data.currentTranslate;
3045 }
3046 if (params.cssMode) {
3047 return;
3048 }
3049 if (params.freeMode && params.freeMode.enabled) {
3050 swiper.freeMode.onTouchEnd({
3051 currentPos
3052 });
3053 return;
3054 }
3055
3056 // Find current slide
3057 const swipeToLast = currentPos >= -swiper.maxTranslate() && !swiper.params.loop;
3058 let stopIndex = 0;
3059 let groupSize = swiper.slidesSizesGrid[0];
3060 for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {
3061 const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
3062 if (typeof slidesGrid[i + increment] !== 'undefined') {
3063 if (swipeToLast || currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {
3064 stopIndex = i;
3065 groupSize = slidesGrid[i + increment] - slidesGrid[i];
3066 }
3067 } else if (swipeToLast || currentPos >= slidesGrid[i]) {
3068 stopIndex = i;
3069 groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
3070 }
3071 }
3072 let rewindFirstIndex = null;
3073 let rewindLastIndex = null;
3074 if (params.rewind) {
3075 if (swiper.isBeginning) {
3076 rewindLastIndex = params.virtual && params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
3077 } else if (swiper.isEnd) {
3078 rewindFirstIndex = 0;
3079 }
3080 }
3081 // Find current slide size
3082 const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
3083 const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
3084 if (timeDiff > params.longSwipesMs) {
3085 // Long touches
3086 if (!params.longSwipes) {
3087 swiper.slideTo(swiper.activeIndex);
3088 return;
3089 }
3090 if (swiper.swipeDirection === 'next') {
3091 if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);else swiper.slideTo(stopIndex);
3092 }
3093 if (swiper.swipeDirection === 'prev') {
3094 if (ratio > 1 - params.longSwipesRatio) {
3095 swiper.slideTo(stopIndex + increment);
3096 } else if (rewindLastIndex !== null && ratio < 0 && Math.abs(ratio) > params.longSwipesRatio) {
3097 swiper.slideTo(rewindLastIndex);
3098 } else {
3099 swiper.slideTo(stopIndex);
3100 }
3101 }
3102 } else {
3103 // Short swipes
3104 if (!params.shortSwipes) {
3105 swiper.slideTo(swiper.activeIndex);
3106 return;
3107 }
3108 const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);
3109 if (!isNavButtonTarget) {
3110 if (swiper.swipeDirection === 'next') {
3111 swiper.slideTo(rewindFirstIndex !== null ? rewindFirstIndex : stopIndex + increment);
3112 }
3113 if (swiper.swipeDirection === 'prev') {
3114 swiper.slideTo(rewindLastIndex !== null ? rewindLastIndex : stopIndex);
3115 }
3116 } else if (e.target === swiper.navigation.nextEl) {
3117 swiper.slideTo(stopIndex + increment);
3118 } else {
3119 swiper.slideTo(stopIndex);
3120 }
3121 }
3122 }
3123
3124 function onResize() {
3125 const swiper = this;
3126 const {
3127 params,
3128 el
3129 } = swiper;
3130 if (el && el.offsetWidth === 0) return;
3131
3132 // Breakpoints
3133 if (params.breakpoints) {
3134 swiper.setBreakpoint();
3135 }
3136
3137 // Save locks
3138 const {
3139 allowSlideNext,
3140 allowSlidePrev,
3141 snapGrid
3142 } = swiper;
3143 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
3144
3145 // Disable locks on resize
3146 swiper.allowSlideNext = true;
3147 swiper.allowSlidePrev = true;
3148 swiper.updateSize();
3149 swiper.updateSlides();
3150 swiper.updateSlidesClasses();
3151 const isVirtualLoop = isVirtual && params.loop;
3152 if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides && !isVirtualLoop) {
3153 swiper.slideTo(swiper.slides.length - 1, 0, false, true);
3154 } else {
3155 if (swiper.params.loop && !isVirtual) {
3156 swiper.slideToLoop(swiper.realIndex, 0, false, true);
3157 } else {
3158 swiper.slideTo(swiper.activeIndex, 0, false, true);
3159 }
3160 }
3161 if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
3162 clearTimeout(swiper.autoplay.resizeTimeout);
3163 swiper.autoplay.resizeTimeout = setTimeout(() => {
3164 if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
3165 swiper.autoplay.resume();
3166 }
3167 }, 500);
3168 }
3169 // Return locks after resize
3170 swiper.allowSlidePrev = allowSlidePrev;
3171 swiper.allowSlideNext = allowSlideNext;
3172 if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
3173 swiper.checkOverflow();
3174 }
3175 }
3176
3177 function onClick(e) {
3178 const swiper = this;
3179 if (!swiper.enabled) return;
3180 if (!swiper.allowClick) {
3181 if (swiper.params.preventClicks) e.preventDefault();
3182 if (swiper.params.preventClicksPropagation && swiper.animating) {
3183 e.stopPropagation();
3184 e.stopImmediatePropagation();
3185 }
3186 }
3187 }
3188
3189 function onScroll() {
3190 const swiper = this;
3191 const {
3192 wrapperEl,
3193 rtlTranslate,
3194 enabled
3195 } = swiper;
3196 if (!enabled) return;
3197 swiper.previousTranslate = swiper.translate;
3198 if (swiper.isHorizontal()) {
3199 swiper.translate = -wrapperEl.scrollLeft;
3200 } else {
3201 swiper.translate = -wrapperEl.scrollTop;
3202 }
3203 // eslint-disable-next-line
3204 if (swiper.translate === 0) swiper.translate = 0;
3205 swiper.updateActiveIndex();
3206 swiper.updateSlidesClasses();
3207 let newProgress;
3208 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
3209 if (translatesDiff === 0) {
3210 newProgress = 0;
3211 } else {
3212 newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;
3213 }
3214 if (newProgress !== swiper.progress) {
3215 swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
3216 }
3217 swiper.emit('setTranslate', swiper.translate, false);
3218 }
3219
3220 function onLoad(e) {
3221 const swiper = this;
3222 processLazyPreloader(swiper, e.target);
3223 if (swiper.params.cssMode || swiper.params.slidesPerView !== 'auto' && !swiper.params.autoHeight) {
3224 return;
3225 }
3226 swiper.update();
3227 }
3228
3229 function onDocumentTouchStart() {
3230 const swiper = this;
3231 if (swiper.documentTouchHandlerProceeded) return;
3232 swiper.documentTouchHandlerProceeded = true;
3233 if (swiper.params.touchReleaseOnEdges) {
3234 swiper.el.style.touchAction = 'auto';
3235 }
3236 }
3237
3238 const events = (swiper, method) => {
3239 const document = getDocument();
3240 const {
3241 params,
3242 el,
3243 wrapperEl,
3244 device
3245 } = swiper;
3246 const capture = !!params.nested;
3247 const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
3248 const swiperMethod = method;
3249 if (!el || typeof el === 'string') return;
3250
3251 // Touch Events
3252 document[domMethod]('touchstart', swiper.onDocumentTouchStart, {
3253 passive: false,
3254 capture
3255 });
3256 el[domMethod]('touchstart', swiper.onTouchStart, {
3257 passive: false
3258 });
3259 el[domMethod]('pointerdown', swiper.onTouchStart, {
3260 passive: false
3261 });
3262 document[domMethod]('touchmove', swiper.onTouchMove, {
3263 passive: false,
3264 capture
3265 });
3266 document[domMethod]('pointermove', swiper.onTouchMove, {
3267 passive: false,
3268 capture
3269 });
3270 document[domMethod]('touchend', swiper.onTouchEnd, {
3271 passive: true
3272 });
3273 document[domMethod]('pointerup', swiper.onTouchEnd, {
3274 passive: true
3275 });
3276 document[domMethod]('pointercancel', swiper.onTouchEnd, {
3277 passive: true
3278 });
3279 document[domMethod]('touchcancel', swiper.onTouchEnd, {
3280 passive: true
3281 });
3282 document[domMethod]('pointerout', swiper.onTouchEnd, {
3283 passive: true
3284 });
3285 document[domMethod]('pointerleave', swiper.onTouchEnd, {
3286 passive: true
3287 });
3288 document[domMethod]('contextmenu', swiper.onTouchEnd, {
3289 passive: true
3290 });
3291
3292 // Prevent Links Clicks
3293 if (params.preventClicks || params.preventClicksPropagation) {
3294 el[domMethod]('click', swiper.onClick, true);
3295 }
3296 if (params.cssMode) {
3297 wrapperEl[domMethod]('scroll', swiper.onScroll);
3298 }
3299
3300 // Resize handler
3301 if (params.updateOnWindowResize) {
3302 swiper[swiperMethod](device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize, true);
3303 } else {
3304 swiper[swiperMethod]('observerUpdate', onResize, true);
3305 }
3306
3307 // Images loader
3308 el[domMethod]('load', swiper.onLoad, {
3309 capture: true
3310 });
3311 };
3312 function attachEvents() {
3313 const swiper = this;
3314 const {
3315 params
3316 } = swiper;
3317 swiper.onTouchStart = onTouchStart.bind(swiper);
3318 swiper.onTouchMove = onTouchMove.bind(swiper);
3319 swiper.onTouchEnd = onTouchEnd.bind(swiper);
3320 swiper.onDocumentTouchStart = onDocumentTouchStart.bind(swiper);
3321 if (params.cssMode) {
3322 swiper.onScroll = onScroll.bind(swiper);
3323 }
3324 swiper.onClick = onClick.bind(swiper);
3325 swiper.onLoad = onLoad.bind(swiper);
3326 events(swiper, 'on');
3327 }
3328 function detachEvents() {
3329 const swiper = this;
3330 events(swiper, 'off');
3331 }
3332 var events$1 = {
3333 attachEvents,
3334 detachEvents
3335 };
3336
3337 const isGridEnabled = (swiper, params) => {
3338 return swiper.grid && params.grid && params.grid.rows > 1;
3339 };
3340 function setBreakpoint() {
3341 const swiper = this;
3342 const {
3343 realIndex,
3344 initialized,
3345 params,
3346 el
3347 } = swiper;
3348 const breakpoints = params.breakpoints;
3349 if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return;
3350
3351 // Get breakpoint for window width and update parameters
3352 const breakpoint = swiper.getBreakpoint(breakpoints, swiper.params.breakpointsBase, swiper.el);
3353 if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;
3354 const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
3355 const breakpointParams = breakpointOnlyParams || swiper.originalParams;
3356 const wasMultiRow = isGridEnabled(swiper, params);
3357 const isMultiRow = isGridEnabled(swiper, breakpointParams);
3358 const wasGrabCursor = swiper.params.grabCursor;
3359 const isGrabCursor = breakpointParams.grabCursor;
3360 const wasEnabled = params.enabled;
3361 if (wasMultiRow && !isMultiRow) {
3362 el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
3363 swiper.emitContainerClasses();
3364 } else if (!wasMultiRow && isMultiRow) {
3365 el.classList.add(`${params.containerModifierClass}grid`);
3366 if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') {
3367 el.classList.add(`${params.containerModifierClass}grid-column`);
3368 }
3369 swiper.emitContainerClasses();
3370 }
3371 if (wasGrabCursor && !isGrabCursor) {
3372 swiper.unsetGrabCursor();
3373 } else if (!wasGrabCursor && isGrabCursor) {
3374 swiper.setGrabCursor();
3375 }
3376
3377 // Toggle navigation, pagination, scrollbar
3378 ['navigation', 'pagination', 'scrollbar'].forEach(prop => {
3379 if (typeof breakpointParams[prop] === 'undefined') return;
3380 const wasModuleEnabled = params[prop] && params[prop].enabled;
3381 const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
3382 if (wasModuleEnabled && !isModuleEnabled) {
3383 swiper[prop].disable();
3384 }
3385 if (!wasModuleEnabled && isModuleEnabled) {
3386 swiper[prop].enable();
3387 }
3388 });
3389 const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
3390 const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
3391 const wasLoop = params.loop;
3392 if (directionChanged && initialized) {
3393 swiper.changeDirection();
3394 }
3395 extend(swiper.params, breakpointParams);
3396 const isEnabled = swiper.params.enabled;
3397 const hasLoop = swiper.params.loop;
3398 Object.assign(swiper, {
3399 allowTouchMove: swiper.params.allowTouchMove,
3400 allowSlideNext: swiper.params.allowSlideNext,
3401 allowSlidePrev: swiper.params.allowSlidePrev
3402 });
3403 if (wasEnabled && !isEnabled) {
3404 swiper.disable();
3405 } else if (!wasEnabled && isEnabled) {
3406 swiper.enable();
3407 }
3408 swiper.currentBreakpoint = breakpoint;
3409 swiper.emit('_beforeBreakpoint', breakpointParams);
3410 if (initialized) {
3411 if (needsReLoop) {
3412 swiper.loopDestroy();
3413 swiper.loopCreate(realIndex);
3414 swiper.updateSlides();
3415 } else if (!wasLoop && hasLoop) {
3416 swiper.loopCreate(realIndex);
3417 swiper.updateSlides();
3418 } else if (wasLoop && !hasLoop) {
3419 swiper.loopDestroy();
3420 }
3421 }
3422 swiper.emit('breakpoint', breakpointParams);
3423 }
3424
3425 function getBreakpoint(breakpoints, base, containerEl) {
3426 if (base === void 0) {
3427 base = 'window';
3428 }
3429 if (!breakpoints || base === 'container' && !containerEl) return undefined;
3430 let breakpoint = false;
3431 const window = getWindow();
3432 const currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight;
3433 const points = Object.keys(breakpoints).map(point => {
3434 if (typeof point === 'string' && point.indexOf('@') === 0) {
3435 const minRatio = parseFloat(point.substr(1));
3436 const value = currentHeight * minRatio;
3437 return {
3438 value,
3439 point
3440 };
3441 }
3442 return {
3443 value: point,
3444 point
3445 };
3446 });
3447 points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10));
3448 for (let i = 0; i < points.length; i += 1) {
3449 const {
3450 point,
3451 value
3452 } = points[i];
3453 if (base === 'window') {
3454 if (window.matchMedia(`(min-width: ${value}px)`).matches) {
3455 breakpoint = point;
3456 }
3457 } else if (value <= containerEl.clientWidth) {
3458 breakpoint = point;
3459 }
3460 }
3461 return breakpoint || 'max';
3462 }
3463
3464 var breakpoints = {
3465 setBreakpoint,
3466 getBreakpoint
3467 };
3468
3469 function prepareClasses(entries, prefix) {
3470 const resultClasses = [];
3471 entries.forEach(item => {
3472 if (typeof item === 'object') {
3473 Object.keys(item).forEach(classNames => {
3474 if (item[classNames]) {
3475 resultClasses.push(prefix + classNames);
3476 }
3477 });
3478 } else if (typeof item === 'string') {
3479 resultClasses.push(prefix + item);
3480 }
3481 });
3482 return resultClasses;
3483 }
3484 function addClasses() {
3485 const swiper = this;
3486 const {
3487 classNames,
3488 params,
3489 rtl,
3490 el,
3491 device
3492 } = swiper;
3493 // prettier-ignore
3494 const suffixes = prepareClasses(['initialized', params.direction, {
3495 'free-mode': swiper.params.freeMode && params.freeMode.enabled
3496 }, {
3497 'autoheight': params.autoHeight
3498 }, {
3499 'rtl': rtl
3500 }, {
3501 'grid': params.grid && params.grid.rows > 1
3502 }, {
3503 'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
3504 }, {
3505 'android': device.android
3506 }, {
3507 'ios': device.ios
3508 }, {
3509 'css-mode': params.cssMode
3510 }, {
3511 'centered': params.cssMode && params.centeredSlides
3512 }, {
3513 'watch-progress': params.watchSlidesProgress
3514 }], params.containerModifierClass);
3515 classNames.push(...suffixes);
3516 el.classList.add(...classNames);
3517 swiper.emitContainerClasses();
3518 }
3519
3520 function removeClasses() {
3521 const swiper = this;
3522 const {
3523 el,
3524 classNames
3525 } = swiper;
3526 if (!el || typeof el === 'string') return;
3527 el.classList.remove(...classNames);
3528 swiper.emitContainerClasses();
3529 }
3530
3531 var classes = {
3532 addClasses,
3533 removeClasses
3534 };
3535
3536 function checkOverflow() {
3537 const swiper = this;
3538 const {
3539 isLocked: wasLocked,
3540 params
3541 } = swiper;
3542 const {
3543 slidesOffsetBefore
3544 } = params;
3545 if (slidesOffsetBefore) {
3546 const lastSlideIndex = swiper.slides.length - 1;
3547 const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] + slidesOffsetBefore * 2;
3548 swiper.isLocked = swiper.size > lastSlideRightEdge;
3549 } else {
3550 swiper.isLocked = swiper.snapGrid.length === 1;
3551 }
3552 if (params.allowSlideNext === true) {
3553 swiper.allowSlideNext = !swiper.isLocked;
3554 }
3555 if (params.allowSlidePrev === true) {
3556 swiper.allowSlidePrev = !swiper.isLocked;
3557 }
3558 if (wasLocked && wasLocked !== swiper.isLocked) {
3559 swiper.isEnd = false;
3560 }
3561 if (wasLocked !== swiper.isLocked) {
3562 swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
3563 }
3564 }
3565 var checkOverflow$1 = {
3566 checkOverflow
3567 };
3568
3569 var defaults = {
3570 init: true,
3571 direction: 'horizontal',
3572 oneWayMovement: false,
3573 swiperElementNodeName: 'SWIPER-CONTAINER',
3574 touchEventsTarget: 'wrapper',
3575 initialSlide: 0,
3576 speed: 300,
3577 cssMode: false,
3578 updateOnWindowResize: true,
3579 resizeObserver: true,
3580 nested: false,
3581 createElements: false,
3582 eventsPrefix: 'swiper',
3583 enabled: true,
3584 focusableElements: 'input, select, option, textarea, button, video, label',
3585 // Overrides
3586 width: null,
3587 height: null,
3588 //
3589 preventInteractionOnTransition: false,
3590 // ssr
3591 userAgent: null,
3592 url: null,
3593 // To support iOS's swipe-to-go-back gesture (when being used in-app).
3594 edgeSwipeDetection: false,
3595 edgeSwipeThreshold: 20,
3596 // Autoheight
3597 autoHeight: false,
3598 // Set wrapper width
3599 setWrapperSize: false,
3600 // Virtual Translate
3601 virtualTranslate: false,
3602 // Effects
3603 effect: 'slide',
3604 // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
3605
3606 // Breakpoints
3607 breakpoints: undefined,
3608 breakpointsBase: 'window',
3609 // Slides grid
3610 spaceBetween: 0,
3611 slidesPerView: 1,
3612 slidesPerGroup: 1,
3613 slidesPerGroupSkip: 0,
3614 slidesPerGroupAuto: false,
3615 centeredSlides: false,
3616 centeredSlidesBounds: false,
3617 slidesOffsetBefore: 0,
3618 // in px
3619 slidesOffsetAfter: 0,
3620 // in px
3621 normalizeSlideIndex: true,
3622 centerInsufficientSlides: false,
3623 // Disable swiper and hide navigation when container not overflow
3624 watchOverflow: true,
3625 // Round length
3626 roundLengths: false,
3627 // Touches
3628 touchRatio: 1,
3629 touchAngle: 45,
3630 simulateTouch: true,
3631 shortSwipes: true,
3632 longSwipes: true,
3633 longSwipesRatio: 0.5,
3634 longSwipesMs: 300,
3635 followFinger: true,
3636 allowTouchMove: true,
3637 threshold: 5,
3638 touchMoveStopPropagation: false,
3639 touchStartPreventDefault: true,
3640 touchStartForcePreventDefault: false,
3641 touchReleaseOnEdges: false,
3642 // Unique Navigation Elements
3643 uniqueNavElements: true,
3644 // Resistance
3645 resistance: true,
3646 resistanceRatio: 0.85,
3647 // Progress
3648 watchSlidesProgress: false,
3649 // Cursor
3650 grabCursor: false,
3651 // Clicks
3652 preventClicks: true,
3653 preventClicksPropagation: true,
3654 slideToClickedSlide: false,
3655 // loop
3656 loop: false,
3657 loopAddBlankSlides: true,
3658 loopAdditionalSlides: 0,
3659 loopPreventsSliding: true,
3660 // rewind
3661 rewind: false,
3662 // Swiping/no swiping
3663 allowSlidePrev: true,
3664 allowSlideNext: true,
3665 swipeHandler: null,
3666 // '.swipe-handler',
3667 noSwiping: true,
3668 noSwipingClass: 'swiper-no-swiping',
3669 noSwipingSelector: null,
3670 // Passive Listeners
3671 passiveListeners: true,
3672 maxBackfaceHiddenSlides: 10,
3673 // NS
3674 containerModifierClass: 'swiper-',
3675 // NEW
3676 slideClass: 'swiper-slide',
3677 slideBlankClass: 'swiper-slide-blank',
3678 slideActiveClass: 'swiper-slide-active',
3679 slideVisibleClass: 'swiper-slide-visible',
3680 slideFullyVisibleClass: 'swiper-slide-fully-visible',
3681 slideNextClass: 'swiper-slide-next',
3682 slidePrevClass: 'swiper-slide-prev',
3683 wrapperClass: 'swiper-wrapper',
3684 lazyPreloaderClass: 'swiper-lazy-preloader',
3685 lazyPreloadPrevNext: 0,
3686 // Callbacks
3687 runCallbacksOnInit: true,
3688 // Internals
3689 _emitClasses: false
3690 };
3691
3692 function moduleExtendParams(params, allModulesParams) {
3693 return function extendParams(obj) {
3694 if (obj === void 0) {
3695 obj = {};
3696 }
3697 const moduleParamName = Object.keys(obj)[0];
3698 const moduleParams = obj[moduleParamName];
3699 if (typeof moduleParams !== 'object' || moduleParams === null) {
3700 extend(allModulesParams, obj);
3701 return;
3702 }
3703 if (params[moduleParamName] === true) {
3704 params[moduleParamName] = {
3705 enabled: true
3706 };
3707 }
3708 if (moduleParamName === 'navigation' && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].prevEl && !params[moduleParamName].nextEl) {
3709 params[moduleParamName].auto = true;
3710 }
3711 if (['pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].el) {
3712 params[moduleParamName].auto = true;
3713 }
3714 if (!(moduleParamName in params && 'enabled' in moduleParams)) {
3715 extend(allModulesParams, obj);
3716 return;
3717 }
3718 if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {
3719 params[moduleParamName].enabled = true;
3720 }
3721 if (!params[moduleParamName]) params[moduleParamName] = {
3722 enabled: false
3723 };
3724 extend(allModulesParams, obj);
3725 };
3726 }
3727
3728 /* eslint no-param-reassign: "off" */
3729 const prototypes = {
3730 eventsEmitter,
3731 update,
3732 translate,
3733 transition,
3734 slide,
3735 loop,
3736 grabCursor,
3737 events: events$1,
3738 breakpoints,
3739 checkOverflow: checkOverflow$1,
3740 classes
3741 };
3742 const extendedDefaults = {};
3743 class Swiper {
3744 constructor() {
3745 let el;
3746 let params;
3747 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
3748 args[_key] = arguments[_key];
3749 }
3750 if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') {
3751 params = args[0];
3752 } else {
3753 [el, params] = args;
3754 }
3755 if (!params) params = {};
3756 params = extend({}, params);
3757 if (el && !params.el) params.el = el;
3758 const document = getDocument();
3759 if (params.el && typeof params.el === 'string' && document.querySelectorAll(params.el).length > 1) {
3760 const swipers = [];
3761 document.querySelectorAll(params.el).forEach(containerEl => {
3762 const newParams = extend({}, params, {
3763 el: containerEl
3764 });
3765 swipers.push(new Swiper(newParams));
3766 });
3767 // eslint-disable-next-line no-constructor-return
3768 return swipers;
3769 }
3770
3771 // Swiper Instance
3772 const swiper = this;
3773 swiper.__swiper__ = true;
3774 swiper.support = getSupport();
3775 swiper.device = getDevice({
3776 userAgent: params.userAgent
3777 });
3778 swiper.browser = getBrowser();
3779 swiper.eventsListeners = {};
3780 swiper.eventsAnyListeners = [];
3781 swiper.modules = [...swiper.__modules__];
3782 if (params.modules && Array.isArray(params.modules)) {
3783 swiper.modules.push(...params.modules);
3784 }
3785 const allModulesParams = {};
3786 swiper.modules.forEach(mod => {
3787 mod({
3788 params,
3789 swiper,
3790 extendParams: moduleExtendParams(params, allModulesParams),
3791 on: swiper.on.bind(swiper),
3792 once: swiper.once.bind(swiper),
3793 off: swiper.off.bind(swiper),
3794 emit: swiper.emit.bind(swiper)
3795 });
3796 });
3797
3798 // Extend defaults with modules params
3799 const swiperParams = extend({}, defaults, allModulesParams);
3800
3801 // Extend defaults with passed params
3802 swiper.params = extend({}, swiperParams, extendedDefaults, params);
3803 swiper.originalParams = extend({}, swiper.params);
3804 swiper.passedParams = extend({}, params);
3805
3806 // add event listeners
3807 if (swiper.params && swiper.params.on) {
3808 Object.keys(swiper.params.on).forEach(eventName => {
3809 swiper.on(eventName, swiper.params.on[eventName]);
3810 });
3811 }
3812 if (swiper.params && swiper.params.onAny) {
3813 swiper.onAny(swiper.params.onAny);
3814 }
3815
3816 // Extend Swiper
3817 Object.assign(swiper, {
3818 enabled: swiper.params.enabled,
3819 el,
3820 // Classes
3821 classNames: [],
3822 // Slides
3823 slides: [],
3824 slidesGrid: [],
3825 snapGrid: [],
3826 slidesSizesGrid: [],
3827 // isDirection
3828 isHorizontal() {
3829 return swiper.params.direction === 'horizontal';
3830 },
3831 isVertical() {
3832 return swiper.params.direction === 'vertical';
3833 },
3834 // Indexes
3835 activeIndex: 0,
3836 realIndex: 0,
3837 //
3838 isBeginning: true,
3839 isEnd: false,
3840 // Props
3841 translate: 0,
3842 previousTranslate: 0,
3843 progress: 0,
3844 velocity: 0,
3845 animating: false,
3846 cssOverflowAdjustment() {
3847 // Returns 0 unless `translate` is > 2**23
3848 // Should be subtracted from css values to prevent overflow
3849 return Math.trunc(this.translate / 2 ** 23) * 2 ** 23;
3850 },
3851 // Locks
3852 allowSlideNext: swiper.params.allowSlideNext,
3853 allowSlidePrev: swiper.params.allowSlidePrev,
3854 // Touch Events
3855 touchEventsData: {
3856 isTouched: undefined,
3857 isMoved: undefined,
3858 allowTouchCallbacks: undefined,
3859 touchStartTime: undefined,
3860 isScrolling: undefined,
3861 currentTranslate: undefined,
3862 startTranslate: undefined,
3863 allowThresholdMove: undefined,
3864 // Form elements to match
3865 focusableElements: swiper.params.focusableElements,
3866 // Last click time
3867 lastClickTime: 0,
3868 clickTimeout: undefined,
3869 // Velocities
3870 velocities: [],
3871 allowMomentumBounce: undefined,
3872 startMoving: undefined,
3873 pointerId: null,
3874 touchId: null
3875 },
3876 // Clicks
3877 allowClick: true,
3878 // Touches
3879 allowTouchMove: swiper.params.allowTouchMove,
3880 touches: {
3881 startX: 0,
3882 startY: 0,
3883 currentX: 0,
3884 currentY: 0,
3885 diff: 0
3886 },
3887 // Images
3888 imagesToLoad: [],
3889 imagesLoaded: 0
3890 });
3891 swiper.emit('_swiper');
3892
3893 // Init
3894 if (swiper.params.init) {
3895 swiper.init();
3896 }
3897
3898 // Return app instance
3899 // eslint-disable-next-line no-constructor-return
3900 return swiper;
3901 }
3902 getDirectionLabel(property) {
3903 if (this.isHorizontal()) {
3904 return property;
3905 }
3906 // prettier-ignore
3907 return {
3908 'width': 'height',
3909 'margin-top': 'margin-left',
3910 'margin-bottom ': 'margin-right',
3911 'margin-left': 'margin-top',
3912 'margin-right': 'margin-bottom',
3913 'padding-left': 'padding-top',
3914 'padding-right': 'padding-bottom',
3915 'marginRight': 'marginBottom'
3916 }[property];
3917 }
3918 getSlideIndex(slideEl) {
3919 const {
3920 slidesEl,
3921 params
3922 } = this;
3923 const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
3924 const firstSlideIndex = elementIndex(slides[0]);
3925 return elementIndex(slideEl) - firstSlideIndex;
3926 }
3927 getSlideIndexByData(index) {
3928 return this.getSlideIndex(this.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === index)[0]);
3929 }
3930 recalcSlides() {
3931 const swiper = this;
3932 const {
3933 slidesEl,
3934 params
3935 } = swiper;
3936 swiper.slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
3937 }
3938 enable() {
3939 const swiper = this;
3940 if (swiper.enabled) return;
3941 swiper.enabled = true;
3942 if (swiper.params.grabCursor) {
3943 swiper.setGrabCursor();
3944 }
3945 swiper.emit('enable');
3946 }
3947 disable() {
3948 const swiper = this;
3949 if (!swiper.enabled) return;
3950 swiper.enabled = false;
3951 if (swiper.params.grabCursor) {
3952 swiper.unsetGrabCursor();
3953 }
3954 swiper.emit('disable');
3955 }
3956 setProgress(progress, speed) {
3957 const swiper = this;
3958 progress = Math.min(Math.max(progress, 0), 1);
3959 const min = swiper.minTranslate();
3960 const max = swiper.maxTranslate();
3961 const current = (max - min) * progress + min;
3962 swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
3963 swiper.updateActiveIndex();
3964 swiper.updateSlidesClasses();
3965 }
3966 emitContainerClasses() {
3967 const swiper = this;
3968 if (!swiper.params._emitClasses || !swiper.el) return;
3969 const cls = swiper.el.className.split(' ').filter(className => {
3970 return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;
3971 });
3972 swiper.emit('_containerClasses', cls.join(' '));
3973 }
3974 getSlideClasses(slideEl) {
3975 const swiper = this;
3976 if (swiper.destroyed) return '';
3977 return slideEl.className.split(' ').filter(className => {
3978 return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;
3979 }).join(' ');
3980 }
3981 emitSlidesClasses() {
3982 const swiper = this;
3983 if (!swiper.params._emitClasses || !swiper.el) return;
3984 const updates = [];
3985 swiper.slides.forEach(slideEl => {
3986 const classNames = swiper.getSlideClasses(slideEl);
3987 updates.push({
3988 slideEl,
3989 classNames
3990 });
3991 swiper.emit('_slideClass', slideEl, classNames);
3992 });
3993 swiper.emit('_slideClasses', updates);
3994 }
3995 slidesPerViewDynamic(view, exact) {
3996 if (view === void 0) {
3997 view = 'current';
3998 }
3999 if (exact === void 0) {
4000 exact = false;
4001 }
4002 const swiper = this;
4003 const {
4004 params,
4005 slides,
4006 slidesGrid,
4007 slidesSizesGrid,
4008 size: swiperSize,
4009 activeIndex
4010 } = swiper;
4011 let spv = 1;
4012 if (typeof params.slidesPerView === 'number') return params.slidesPerView;
4013 if (params.centeredSlides) {
4014 let slideSize = slides[activeIndex] ? Math.ceil(slides[activeIndex].swiperSlideSize) : 0;
4015 let breakLoop;
4016 for (let i = activeIndex + 1; i < slides.length; i += 1) {
4017 if (slides[i] && !breakLoop) {
4018 slideSize += Math.ceil(slides[i].swiperSlideSize);
4019 spv += 1;
4020 if (slideSize > swiperSize) breakLoop = true;
4021 }
4022 }
4023 for (let i = activeIndex - 1; i >= 0; i -= 1) {
4024 if (slides[i] && !breakLoop) {
4025 slideSize += slides[i].swiperSlideSize;
4026 spv += 1;
4027 if (slideSize > swiperSize) breakLoop = true;
4028 }
4029 }
4030 } else {
4031 // eslint-disable-next-line
4032 if (view === 'current') {
4033 for (let i = activeIndex + 1; i < slides.length; i += 1) {
4034 const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
4035 if (slideInView) {
4036 spv += 1;
4037 }
4038 }
4039 } else {
4040 // previous
4041 for (let i = activeIndex - 1; i >= 0; i -= 1) {
4042 const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
4043 if (slideInView) {
4044 spv += 1;
4045 }
4046 }
4047 }
4048 }
4049 return spv;
4050 }
4051 update() {
4052 const swiper = this;
4053 if (!swiper || swiper.destroyed) return;
4054 const {
4055 snapGrid,
4056 params
4057 } = swiper;
4058 // Breakpoints
4059 if (params.breakpoints) {
4060 swiper.setBreakpoint();
4061 }
4062 [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach(imageEl => {
4063 if (imageEl.complete) {
4064 processLazyPreloader(swiper, imageEl);
4065 }
4066 });
4067 swiper.updateSize();
4068 swiper.updateSlides();
4069 swiper.updateProgress();
4070 swiper.updateSlidesClasses();
4071 function setTranslate() {
4072 const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
4073 const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
4074 swiper.setTranslate(newTranslate);
4075 swiper.updateActiveIndex();
4076 swiper.updateSlidesClasses();
4077 }
4078 let translated;
4079 if (params.freeMode && params.freeMode.enabled && !params.cssMode) {
4080 setTranslate();
4081 if (params.autoHeight) {
4082 swiper.updateAutoHeight();
4083 }
4084 } else {
4085 if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
4086 const slides = swiper.virtual && params.virtual.enabled ? swiper.virtual.slides : swiper.slides;
4087 translated = swiper.slideTo(slides.length - 1, 0, false, true);
4088 } else {
4089 translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
4090 }
4091 if (!translated) {
4092 setTranslate();
4093 }
4094 }
4095 if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
4096 swiper.checkOverflow();
4097 }
4098 swiper.emit('update');
4099 }
4100 changeDirection(newDirection, needUpdate) {
4101 if (needUpdate === void 0) {
4102 needUpdate = true;
4103 }
4104 const swiper = this;
4105 const currentDirection = swiper.params.direction;
4106 if (!newDirection) {
4107 // eslint-disable-next-line
4108 newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
4109 }
4110 if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
4111 return swiper;
4112 }
4113 swiper.el.classList.remove(`${swiper.params.containerModifierClass}${currentDirection}`);
4114 swiper.el.classList.add(`${swiper.params.containerModifierClass}${newDirection}`);
4115 swiper.emitContainerClasses();
4116 swiper.params.direction = newDirection;
4117 swiper.slides.forEach(slideEl => {
4118 if (newDirection === 'vertical') {
4119 slideEl.style.width = '';
4120 } else {
4121 slideEl.style.height = '';
4122 }
4123 });
4124 swiper.emit('changeDirection');
4125 if (needUpdate) swiper.update();
4126 return swiper;
4127 }
4128 changeLanguageDirection(direction) {
4129 const swiper = this;
4130 if (swiper.rtl && direction === 'rtl' || !swiper.rtl && direction === 'ltr') return;
4131 swiper.rtl = direction === 'rtl';
4132 swiper.rtlTranslate = swiper.params.direction === 'horizontal' && swiper.rtl;
4133 if (swiper.rtl) {
4134 swiper.el.classList.add(`${swiper.params.containerModifierClass}rtl`);
4135 swiper.el.dir = 'rtl';
4136 } else {
4137 swiper.el.classList.remove(`${swiper.params.containerModifierClass}rtl`);
4138 swiper.el.dir = 'ltr';
4139 }
4140 swiper.update();
4141 }
4142 mount(element) {
4143 const swiper = this;
4144 if (swiper.mounted) return true;
4145
4146 // Find el
4147 let el = element || swiper.params.el;
4148 if (typeof el === 'string') {
4149 el = document.querySelector(el);
4150 }
4151 if (!el) {
4152 return false;
4153 }
4154 el.swiper = swiper;
4155 if (el.parentNode && el.parentNode.host && el.parentNode.host.nodeName === swiper.params.swiperElementNodeName.toUpperCase()) {
4156 swiper.isElement = true;
4157 }
4158 const getWrapperSelector = () => {
4159 return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`;
4160 };
4161 const getWrapper = () => {
4162 if (el && el.shadowRoot && el.shadowRoot.querySelector) {
4163 const res = el.shadowRoot.querySelector(getWrapperSelector());
4164 // Children needs to return slot items
4165 return res;
4166 }
4167 return elementChildren(el, getWrapperSelector())[0];
4168 };
4169 // Find Wrapper
4170 let wrapperEl = getWrapper();
4171 if (!wrapperEl && swiper.params.createElements) {
4172 wrapperEl = createElement('div', swiper.params.wrapperClass);
4173 el.append(wrapperEl);
4174 elementChildren(el, `.${swiper.params.slideClass}`).forEach(slideEl => {
4175 wrapperEl.append(slideEl);
4176 });
4177 }
4178 Object.assign(swiper, {
4179 el,
4180 wrapperEl,
4181 slidesEl: swiper.isElement && !el.parentNode.host.slideSlots ? el.parentNode.host : wrapperEl,
4182 hostEl: swiper.isElement ? el.parentNode.host : el,
4183 mounted: true,
4184 // RTL
4185 rtl: el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl',
4186 rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl'),
4187 wrongRTL: elementStyle(wrapperEl, 'display') === '-webkit-box'
4188 });
4189 return true;
4190 }
4191 init(el) {
4192 const swiper = this;
4193 if (swiper.initialized) return swiper;
4194 const mounted = swiper.mount(el);
4195 if (mounted === false) return swiper;
4196 swiper.emit('beforeInit');
4197
4198 // Set breakpoint
4199 if (swiper.params.breakpoints) {
4200 swiper.setBreakpoint();
4201 }
4202
4203 // Add Classes
4204 swiper.addClasses();
4205
4206 // Update size
4207 swiper.updateSize();
4208
4209 // Update slides
4210 swiper.updateSlides();
4211 if (swiper.params.watchOverflow) {
4212 swiper.checkOverflow();
4213 }
4214
4215 // Set Grab Cursor
4216 if (swiper.params.grabCursor && swiper.enabled) {
4217 swiper.setGrabCursor();
4218 }
4219
4220 // Slide To Initial Slide
4221 if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
4222 swiper.slideTo(swiper.params.initialSlide + swiper.virtual.slidesBefore, 0, swiper.params.runCallbacksOnInit, false, true);
4223 } else {
4224 swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
4225 }
4226
4227 // Create loop
4228 if (swiper.params.loop) {
4229 swiper.loopCreate();
4230 }
4231
4232 // Attach events
4233 swiper.attachEvents();
4234 const lazyElements = [...swiper.el.querySelectorAll('[loading="lazy"]')];
4235 if (swiper.isElement) {
4236 lazyElements.push(...swiper.hostEl.querySelectorAll('[loading="lazy"]'));
4237 }
4238 lazyElements.forEach(imageEl => {
4239 if (imageEl.complete) {
4240 processLazyPreloader(swiper, imageEl);
4241 } else {
4242 imageEl.addEventListener('load', e => {
4243 processLazyPreloader(swiper, e.target);
4244 });
4245 }
4246 });
4247 preload(swiper);
4248
4249 // Init Flag
4250 swiper.initialized = true;
4251 preload(swiper);
4252
4253 // Emit
4254 swiper.emit('init');
4255 swiper.emit('afterInit');
4256 return swiper;
4257 }
4258 destroy(deleteInstance, cleanStyles) {
4259 if (deleteInstance === void 0) {
4260 deleteInstance = true;
4261 }
4262 if (cleanStyles === void 0) {
4263 cleanStyles = true;
4264 }
4265 const swiper = this;
4266 const {
4267 params,
4268 el,
4269 wrapperEl,
4270 slides
4271 } = swiper;
4272 if (typeof swiper.params === 'undefined' || swiper.destroyed) {
4273 return null;
4274 }
4275 swiper.emit('beforeDestroy');
4276
4277 // Init Flag
4278 swiper.initialized = false;
4279
4280 // Detach events
4281 swiper.detachEvents();
4282
4283 // Destroy loop
4284 if (params.loop) {
4285 swiper.loopDestroy();
4286 }
4287
4288 // Cleanup styles
4289 if (cleanStyles) {
4290 swiper.removeClasses();
4291 if (el && typeof el !== 'string') {
4292 el.removeAttribute('style');
4293 }
4294 if (wrapperEl) {
4295 wrapperEl.removeAttribute('style');
4296 }
4297 if (slides && slides.length) {
4298 slides.forEach(slideEl => {
4299 slideEl.classList.remove(params.slideVisibleClass, params.slideFullyVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
4300 slideEl.removeAttribute('style');
4301 slideEl.removeAttribute('data-swiper-slide-index');
4302 });
4303 }
4304 }
4305 swiper.emit('destroy');
4306
4307 // Detach emitter events
4308 Object.keys(swiper.eventsListeners).forEach(eventName => {
4309 swiper.off(eventName);
4310 });
4311 if (deleteInstance !== false) {
4312 if (swiper.el && typeof swiper.el !== 'string') {
4313 swiper.el.swiper = null;
4314 }
4315 deleteProps(swiper);
4316 }
4317 swiper.destroyed = true;
4318 return null;
4319 }
4320 static extendDefaults(newDefaults) {
4321 extend(extendedDefaults, newDefaults);
4322 }
4323 static get extendedDefaults() {
4324 return extendedDefaults;
4325 }
4326 static get defaults() {
4327 return defaults;
4328 }
4329 static installModule(mod) {
4330 if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];
4331 const modules = Swiper.prototype.__modules__;
4332 if (typeof mod === 'function' && modules.indexOf(mod) < 0) {
4333 modules.push(mod);
4334 }
4335 }
4336 static use(module) {
4337 if (Array.isArray(module)) {
4338 module.forEach(m => Swiper.installModule(m));
4339 return Swiper;
4340 }
4341 Swiper.installModule(module);
4342 return Swiper;
4343 }
4344 }
4345 Object.keys(prototypes).forEach(prototypeGroup => {
4346 Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => {
4347 Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
4348 });
4349 });
4350 Swiper.use([Resize, Observer]);
4351
4352 function Virtual(_ref) {
4353 let {
4354 swiper,
4355 extendParams,
4356 on,
4357 emit
4358 } = _ref;
4359 extendParams({
4360 virtual: {
4361 enabled: false,
4362 slides: [],
4363 cache: true,
4364 renderSlide: null,
4365 renderExternal: null,
4366 renderExternalUpdate: true,
4367 addSlidesBefore: 0,
4368 addSlidesAfter: 0
4369 }
4370 });
4371 let cssModeTimeout;
4372 const document = getDocument();
4373 swiper.virtual = {
4374 cache: {},
4375 from: undefined,
4376 to: undefined,
4377 slides: [],
4378 offset: 0,
4379 slidesGrid: []
4380 };
4381 const tempDOM = document.createElement('div');
4382 function renderSlide(slide, index) {
4383 const params = swiper.params.virtual;
4384 if (params.cache && swiper.virtual.cache[index]) {
4385 return swiper.virtual.cache[index];
4386 }
4387 // eslint-disable-next-line
4388 let slideEl;
4389 if (params.renderSlide) {
4390 slideEl = params.renderSlide.call(swiper, slide, index);
4391 if (typeof slideEl === 'string') {
4392 tempDOM.innerHTML = slideEl;
4393 slideEl = tempDOM.children[0];
4394 }
4395 } else if (swiper.isElement) {
4396 slideEl = createElement('swiper-slide');
4397 } else {
4398 slideEl = createElement('div', swiper.params.slideClass);
4399 }
4400 slideEl.setAttribute('data-swiper-slide-index', index);
4401 if (!params.renderSlide) {
4402 slideEl.innerHTML = slide;
4403 }
4404 if (params.cache) {
4405 swiper.virtual.cache[index] = slideEl;
4406 }
4407 return slideEl;
4408 }
4409 function update(force, beforeInit) {
4410 const {
4411 slidesPerView,
4412 slidesPerGroup,
4413 centeredSlides,
4414 loop: isLoop,
4415 initialSlide
4416 } = swiper.params;
4417 if (beforeInit && !isLoop && initialSlide > 0) {
4418 return;
4419 }
4420 const {
4421 addSlidesBefore,
4422 addSlidesAfter
4423 } = swiper.params.virtual;
4424 const {
4425 from: previousFrom,
4426 to: previousTo,
4427 slides,
4428 slidesGrid: previousSlidesGrid,
4429 offset: previousOffset
4430 } = swiper.virtual;
4431 if (!swiper.params.cssMode) {
4432 swiper.updateActiveIndex();
4433 }
4434 const activeIndex = swiper.activeIndex || 0;
4435 let offsetProp;
4436 if (swiper.rtlTranslate) offsetProp = 'right';else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
4437 let slidesAfter;
4438 let slidesBefore;
4439 if (centeredSlides) {
4440 slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;
4441 slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;
4442 } else {
4443 slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;
4444 slidesBefore = (isLoop ? slidesPerView : slidesPerGroup) + addSlidesBefore;
4445 }
4446 let from = activeIndex - slidesBefore;
4447 let to = activeIndex + slidesAfter;
4448 if (!isLoop) {
4449 from = Math.max(from, 0);
4450 to = Math.min(to, slides.length - 1);
4451 }
4452 let offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
4453 if (isLoop && activeIndex >= slidesBefore) {
4454 from -= slidesBefore;
4455 if (!centeredSlides) offset += swiper.slidesGrid[0];
4456 } else if (isLoop && activeIndex < slidesBefore) {
4457 from = -slidesBefore;
4458 if (centeredSlides) offset += swiper.slidesGrid[0];
4459 }
4460 Object.assign(swiper.virtual, {
4461 from,
4462 to,
4463 offset,
4464 slidesGrid: swiper.slidesGrid,
4465 slidesBefore,
4466 slidesAfter
4467 });
4468 function onRendered() {
4469 swiper.updateSlides();
4470 swiper.updateProgress();
4471 swiper.updateSlidesClasses();
4472 emit('virtualUpdate');
4473 }
4474 if (previousFrom === from && previousTo === to && !force) {
4475 if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
4476 swiper.slides.forEach(slideEl => {
4477 slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
4478 });
4479 }
4480 swiper.updateProgress();
4481 emit('virtualUpdate');
4482 return;
4483 }
4484 if (swiper.params.virtual.renderExternal) {
4485 swiper.params.virtual.renderExternal.call(swiper, {
4486 offset,
4487 from,
4488 to,
4489 slides: function getSlides() {
4490 const slidesToRender = [];
4491 for (let i = from; i <= to; i += 1) {
4492 slidesToRender.push(slides[i]);
4493 }
4494 return slidesToRender;
4495 }()
4496 });
4497 if (swiper.params.virtual.renderExternalUpdate) {
4498 onRendered();
4499 } else {
4500 emit('virtualUpdate');
4501 }
4502 return;
4503 }
4504 const prependIndexes = [];
4505 const appendIndexes = [];
4506 const getSlideIndex = index => {
4507 let slideIndex = index;
4508 if (index < 0) {
4509 slideIndex = slides.length + index;
4510 } else if (slideIndex >= slides.length) {
4511 // eslint-disable-next-line
4512 slideIndex = slideIndex - slides.length;
4513 }
4514 return slideIndex;
4515 };
4516 if (force) {
4517 swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`)).forEach(slideEl => {
4518 slideEl.remove();
4519 });
4520 } else {
4521 for (let i = previousFrom; i <= previousTo; i += 1) {
4522 if (i < from || i > to) {
4523 const slideIndex = getSlideIndex(i);
4524 swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}[data-swiper-slide-index="${slideIndex}"], swiper-slide[data-swiper-slide-index="${slideIndex}"]`)).forEach(slideEl => {
4525 slideEl.remove();
4526 });
4527 }
4528 }
4529 }
4530 const loopFrom = isLoop ? -slides.length : 0;
4531 const loopTo = isLoop ? slides.length * 2 : slides.length;
4532 for (let i = loopFrom; i < loopTo; i += 1) {
4533 if (i >= from && i <= to) {
4534 const slideIndex = getSlideIndex(i);
4535 if (typeof previousTo === 'undefined' || force) {
4536 appendIndexes.push(slideIndex);
4537 } else {
4538 if (i > previousTo) appendIndexes.push(slideIndex);
4539 if (i < previousFrom) prependIndexes.push(slideIndex);
4540 }
4541 }
4542 }
4543 appendIndexes.forEach(index => {
4544 swiper.slidesEl.append(renderSlide(slides[index], index));
4545 });
4546 if (isLoop) {
4547 for (let i = prependIndexes.length - 1; i >= 0; i -= 1) {
4548 const index = prependIndexes[i];
4549 swiper.slidesEl.prepend(renderSlide(slides[index], index));
4550 }
4551 } else {
4552 prependIndexes.sort((a, b) => b - a);
4553 prependIndexes.forEach(index => {
4554 swiper.slidesEl.prepend(renderSlide(slides[index], index));
4555 });
4556 }
4557 elementChildren(swiper.slidesEl, '.swiper-slide, swiper-slide').forEach(slideEl => {
4558 slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
4559 });
4560 onRendered();
4561 }
4562 function appendSlide(slides) {
4563 if (typeof slides === 'object' && 'length' in slides) {
4564 for (let i = 0; i < slides.length; i += 1) {
4565 if (slides[i]) swiper.virtual.slides.push(slides[i]);
4566 }
4567 } else {
4568 swiper.virtual.slides.push(slides);
4569 }
4570 update(true);
4571 }
4572 function prependSlide(slides) {
4573 const activeIndex = swiper.activeIndex;
4574 let newActiveIndex = activeIndex + 1;
4575 let numberOfNewSlides = 1;
4576 if (Array.isArray(slides)) {
4577 for (let i = 0; i < slides.length; i += 1) {
4578 if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
4579 }
4580 newActiveIndex = activeIndex + slides.length;
4581 numberOfNewSlides = slides.length;
4582 } else {
4583 swiper.virtual.slides.unshift(slides);
4584 }
4585 if (swiper.params.virtual.cache) {
4586 const cache = swiper.virtual.cache;
4587 const newCache = {};
4588 Object.keys(cache).forEach(cachedIndex => {
4589 const cachedEl = cache[cachedIndex];
4590 const cachedElIndex = cachedEl.getAttribute('data-swiper-slide-index');
4591 if (cachedElIndex) {
4592 cachedEl.setAttribute('data-swiper-slide-index', parseInt(cachedElIndex, 10) + numberOfNewSlides);
4593 }
4594 newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cachedEl;
4595 });
4596 swiper.virtual.cache = newCache;
4597 }
4598 update(true);
4599 swiper.slideTo(newActiveIndex, 0);
4600 }
4601 function removeSlide(slidesIndexes) {
4602 if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
4603 let activeIndex = swiper.activeIndex;
4604 if (Array.isArray(slidesIndexes)) {
4605 for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {
4606 if (swiper.params.virtual.cache) {
4607 delete swiper.virtual.cache[slidesIndexes[i]];
4608 // shift cache indexes
4609 Object.keys(swiper.virtual.cache).forEach(key => {
4610 if (key > slidesIndexes) {
4611 swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
4612 swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
4613 delete swiper.virtual.cache[key];
4614 }
4615 });
4616 }
4617 swiper.virtual.slides.splice(slidesIndexes[i], 1);
4618 if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
4619 activeIndex = Math.max(activeIndex, 0);
4620 }
4621 } else {
4622 if (swiper.params.virtual.cache) {
4623 delete swiper.virtual.cache[slidesIndexes];
4624 // shift cache indexes
4625 Object.keys(swiper.virtual.cache).forEach(key => {
4626 if (key > slidesIndexes) {
4627 swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
4628 swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
4629 delete swiper.virtual.cache[key];
4630 }
4631 });
4632 }
4633 swiper.virtual.slides.splice(slidesIndexes, 1);
4634 if (slidesIndexes < activeIndex) activeIndex -= 1;
4635 activeIndex = Math.max(activeIndex, 0);
4636 }
4637 update(true);
4638 swiper.slideTo(activeIndex, 0);
4639 }
4640 function removeAllSlides() {
4641 swiper.virtual.slides = [];
4642 if (swiper.params.virtual.cache) {
4643 swiper.virtual.cache = {};
4644 }
4645 update(true);
4646 swiper.slideTo(0, 0);
4647 }
4648 on('beforeInit', () => {
4649 if (!swiper.params.virtual.enabled) return;
4650 let domSlidesAssigned;
4651 if (typeof swiper.passedParams.virtual.slides === 'undefined') {
4652 const slides = [...swiper.slidesEl.children].filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`));
4653 if (slides && slides.length) {
4654 swiper.virtual.slides = [...slides];
4655 domSlidesAssigned = true;
4656 slides.forEach((slideEl, slideIndex) => {
4657 slideEl.setAttribute('data-swiper-slide-index', slideIndex);
4658 swiper.virtual.cache[slideIndex] = slideEl;
4659 slideEl.remove();
4660 });
4661 }
4662 }
4663 if (!domSlidesAssigned) {
4664 swiper.virtual.slides = swiper.params.virtual.slides;
4665 }
4666 swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
4667 swiper.params.watchSlidesProgress = true;
4668 swiper.originalParams.watchSlidesProgress = true;
4669 update(false, true);
4670 });
4671 on('setTranslate', () => {
4672 if (!swiper.params.virtual.enabled) return;
4673 if (swiper.params.cssMode && !swiper._immediateVirtual) {
4674 clearTimeout(cssModeTimeout);
4675 cssModeTimeout = setTimeout(() => {
4676 update();
4677 }, 100);
4678 } else {
4679 update();
4680 }
4681 });
4682 on('init update resize', () => {
4683 if (!swiper.params.virtual.enabled) return;
4684 if (swiper.params.cssMode) {
4685 setCSSProperty(swiper.wrapperEl, '--swiper-virtual-size', `${swiper.virtualSize}px`);
4686 }
4687 });
4688 Object.assign(swiper.virtual, {
4689 appendSlide,
4690 prependSlide,
4691 removeSlide,
4692 removeAllSlides,
4693 update
4694 });
4695 }
4696
4697 /* eslint-disable consistent-return */
4698 function Keyboard(_ref) {
4699 let {
4700 swiper,
4701 extendParams,
4702 on,
4703 emit
4704 } = _ref;
4705 const document = getDocument();
4706 const window = getWindow();
4707 swiper.keyboard = {
4708 enabled: false
4709 };
4710 extendParams({
4711 keyboard: {
4712 enabled: false,
4713 onlyInViewport: true,
4714 pageUpDown: true
4715 }
4716 });
4717 function handle(event) {
4718 if (!swiper.enabled) return;
4719 const {
4720 rtlTranslate: rtl
4721 } = swiper;
4722 let e = event;
4723 if (e.originalEvent) e = e.originalEvent; // jquery fix
4724 const kc = e.keyCode || e.charCode;
4725 const pageUpDown = swiper.params.keyboard.pageUpDown;
4726 const isPageUp = pageUpDown && kc === 33;
4727 const isPageDown = pageUpDown && kc === 34;
4728 const isArrowLeft = kc === 37;
4729 const isArrowRight = kc === 39;
4730 const isArrowUp = kc === 38;
4731 const isArrowDown = kc === 40;
4732 // Directions locks
4733 if (!swiper.allowSlideNext && (swiper.isHorizontal() && isArrowRight || swiper.isVertical() && isArrowDown || isPageDown)) {
4734 return false;
4735 }
4736 if (!swiper.allowSlidePrev && (swiper.isHorizontal() && isArrowLeft || swiper.isVertical() && isArrowUp || isPageUp)) {
4737 return false;
4738 }
4739 if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
4740 return undefined;
4741 }
4742 if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {
4743 return undefined;
4744 }
4745 if (swiper.params.keyboard.onlyInViewport && (isPageUp || isPageDown || isArrowLeft || isArrowRight || isArrowUp || isArrowDown)) {
4746 let inView = false;
4747 // Check that swiper should be inside of visible area of window
4748 if (elementParents(swiper.el, `.${swiper.params.slideClass}, swiper-slide`).length > 0 && elementParents(swiper.el, `.${swiper.params.slideActiveClass}`).length === 0) {
4749 return undefined;
4750 }
4751 const el = swiper.el;
4752 const swiperWidth = el.clientWidth;
4753 const swiperHeight = el.clientHeight;
4754 const windowWidth = window.innerWidth;
4755 const windowHeight = window.innerHeight;
4756 const swiperOffset = elementOffset(el);
4757 if (rtl) swiperOffset.left -= el.scrollLeft;
4758 const swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiperWidth, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiperHeight], [swiperOffset.left + swiperWidth, swiperOffset.top + swiperHeight]];
4759 for (let i = 0; i < swiperCoord.length; i += 1) {
4760 const point = swiperCoord[i];
4761 if (point[0] >= 0 && point[0] <= windowWidth && point[1] >= 0 && point[1] <= windowHeight) {
4762 if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line
4763 inView = true;
4764 }
4765 }
4766 if (!inView) return undefined;
4767 }
4768 if (swiper.isHorizontal()) {
4769 if (isPageUp || isPageDown || isArrowLeft || isArrowRight) {
4770 if (e.preventDefault) e.preventDefault();else e.returnValue = false;
4771 }
4772 if ((isPageDown || isArrowRight) && !rtl || (isPageUp || isArrowLeft) && rtl) swiper.slideNext();
4773 if ((isPageUp || isArrowLeft) && !rtl || (isPageDown || isArrowRight) && rtl) swiper.slidePrev();
4774 } else {
4775 if (isPageUp || isPageDown || isArrowUp || isArrowDown) {
4776 if (e.preventDefault) e.preventDefault();else e.returnValue = false;
4777 }
4778 if (isPageDown || isArrowDown) swiper.slideNext();
4779 if (isPageUp || isArrowUp) swiper.slidePrev();
4780 }
4781 emit('keyPress', kc);
4782 return undefined;
4783 }
4784 function enable() {
4785 if (swiper.keyboard.enabled) return;
4786 document.addEventListener('keydown', handle);
4787 swiper.keyboard.enabled = true;
4788 }
4789 function disable() {
4790 if (!swiper.keyboard.enabled) return;
4791 document.removeEventListener('keydown', handle);
4792 swiper.keyboard.enabled = false;
4793 }
4794 on('init', () => {
4795 if (swiper.params.keyboard.enabled) {
4796 enable();
4797 }
4798 });
4799 on('destroy', () => {
4800 if (swiper.keyboard.enabled) {
4801 disable();
4802 }
4803 });
4804 Object.assign(swiper.keyboard, {
4805 enable,
4806 disable
4807 });
4808 }
4809
4810 /* eslint-disable consistent-return */
4811 function Mousewheel(_ref) {
4812 let {
4813 swiper,
4814 extendParams,
4815 on,
4816 emit
4817 } = _ref;
4818 const window = getWindow();
4819 extendParams({
4820 mousewheel: {
4821 enabled: false,
4822 releaseOnEdges: false,
4823 invert: false,
4824 forceToAxis: false,
4825 sensitivity: 1,
4826 eventsTarget: 'container',
4827 thresholdDelta: null,
4828 thresholdTime: null,
4829 noMousewheelClass: 'swiper-no-mousewheel'
4830 }
4831 });
4832 swiper.mousewheel = {
4833 enabled: false
4834 };
4835 let timeout;
4836 let lastScrollTime = now();
4837 let lastEventBeforeSnap;
4838 const recentWheelEvents = [];
4839 function normalize(e) {
4840 // Reasonable defaults
4841 const PIXEL_STEP = 10;
4842 const LINE_HEIGHT = 40;
4843 const PAGE_HEIGHT = 800;
4844 let sX = 0;
4845 let sY = 0; // spinX, spinY
4846 let pX = 0;
4847 let pY = 0; // pixelX, pixelY
4848
4849 // Legacy
4850 if ('detail' in e) {
4851 sY = e.detail;
4852 }
4853 if ('wheelDelta' in e) {
4854 sY = -e.wheelDelta / 120;
4855 }
4856 if ('wheelDeltaY' in e) {
4857 sY = -e.wheelDeltaY / 120;
4858 }
4859 if ('wheelDeltaX' in e) {
4860 sX = -e.wheelDeltaX / 120;
4861 }
4862
4863 // side scrolling on FF with DOMMouseScroll
4864 if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {
4865 sX = sY;
4866 sY = 0;
4867 }
4868 pX = sX * PIXEL_STEP;
4869 pY = sY * PIXEL_STEP;
4870 if ('deltaY' in e) {
4871 pY = e.deltaY;
4872 }
4873 if ('deltaX' in e) {
4874 pX = e.deltaX;
4875 }
4876 if (e.shiftKey && !pX) {
4877 // if user scrolls with shift he wants horizontal scroll
4878 pX = pY;
4879 pY = 0;
4880 }
4881 if ((pX || pY) && e.deltaMode) {
4882 if (e.deltaMode === 1) {
4883 // delta in LINE units
4884 pX *= LINE_HEIGHT;
4885 pY *= LINE_HEIGHT;
4886 } else {
4887 // delta in PAGE units
4888 pX *= PAGE_HEIGHT;
4889 pY *= PAGE_HEIGHT;
4890 }
4891 }
4892
4893 // Fall-back if spin cannot be determined
4894 if (pX && !sX) {
4895 sX = pX < 1 ? -1 : 1;
4896 }
4897 if (pY && !sY) {
4898 sY = pY < 1 ? -1 : 1;
4899 }
4900 return {
4901 spinX: sX,
4902 spinY: sY,
4903 pixelX: pX,
4904 pixelY: pY
4905 };
4906 }
4907 function handleMouseEnter() {
4908 if (!swiper.enabled) return;
4909 swiper.mouseEntered = true;
4910 }
4911 function handleMouseLeave() {
4912 if (!swiper.enabled) return;
4913 swiper.mouseEntered = false;
4914 }
4915 function animateSlider(newEvent) {
4916 if (swiper.params.mousewheel.thresholdDelta && newEvent.delta < swiper.params.mousewheel.thresholdDelta) {
4917 // Prevent if delta of wheel scroll delta is below configured threshold
4918 return false;
4919 }
4920 if (swiper.params.mousewheel.thresholdTime && now() - lastScrollTime < swiper.params.mousewheel.thresholdTime) {
4921 // Prevent if time between scrolls is below configured threshold
4922 return false;
4923 }
4924
4925 // If the movement is NOT big enough and
4926 // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):
4927 // Don't go any further (avoid insignificant scroll movement).
4928 if (newEvent.delta >= 6 && now() - lastScrollTime < 60) {
4929 // Return false as a default
4930 return true;
4931 }
4932 // If user is scrolling towards the end:
4933 // If the slider hasn't hit the latest slide or
4934 // if the slider is a loop and
4935 // if the slider isn't moving right now:
4936 // Go to next slide and
4937 // emit a scroll event.
4938 // Else (the user is scrolling towards the beginning) and
4939 // if the slider hasn't hit the first slide or
4940 // if the slider is a loop and
4941 // if the slider isn't moving right now:
4942 // Go to prev slide and
4943 // emit a scroll event.
4944 if (newEvent.direction < 0) {
4945 if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {
4946 swiper.slideNext();
4947 emit('scroll', newEvent.raw);
4948 }
4949 } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {
4950 swiper.slidePrev();
4951 emit('scroll', newEvent.raw);
4952 }
4953 // If you got here is because an animation has been triggered so store the current time
4954 lastScrollTime = new window.Date().getTime();
4955 // Return false as a default
4956 return false;
4957 }
4958 function releaseScroll(newEvent) {
4959 const params = swiper.params.mousewheel;
4960 if (newEvent.direction < 0) {
4961 if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {
4962 // Return true to animate scroll on edges
4963 return true;
4964 }
4965 } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {
4966 // Return true to animate scroll on edges
4967 return true;
4968 }
4969 return false;
4970 }
4971 function handle(event) {
4972 let e = event;
4973 let disableParentSwiper = true;
4974 if (!swiper.enabled) return;
4975
4976 // Ignore event if the target or its parents have the swiper-no-mousewheel class
4977 if (event.target.closest(`.${swiper.params.mousewheel.noMousewheelClass}`)) return;
4978 const params = swiper.params.mousewheel;
4979 if (swiper.params.cssMode) {
4980 e.preventDefault();
4981 }
4982 let targetEl = swiper.el;
4983 if (swiper.params.mousewheel.eventsTarget !== 'container') {
4984 targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
4985 }
4986 const targetElContainsTarget = targetEl && targetEl.contains(e.target);
4987 if (!swiper.mouseEntered && !targetElContainsTarget && !params.releaseOnEdges) return true;
4988 if (e.originalEvent) e = e.originalEvent; // jquery fix
4989 let delta = 0;
4990 const rtlFactor = swiper.rtlTranslate ? -1 : 1;
4991 const data = normalize(e);
4992 if (params.forceToAxis) {
4993 if (swiper.isHorizontal()) {
4994 if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = -data.pixelX * rtlFactor;else return true;
4995 } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = -data.pixelY;else return true;
4996 } else {
4997 delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;
4998 }
4999 if (delta === 0) return true;
5000 if (params.invert) delta = -delta;
5001
5002 // Get the scroll positions
5003 let positions = swiper.getTranslate() + delta * params.sensitivity;
5004 if (positions >= swiper.minTranslate()) positions = swiper.minTranslate();
5005 if (positions <= swiper.maxTranslate()) positions = swiper.maxTranslate();
5006
5007 // When loop is true:
5008 // the disableParentSwiper will be true.
5009 // When loop is false:
5010 // if the scroll positions is not on edge,
5011 // then the disableParentSwiper will be true.
5012 // if the scroll on edge positions,
5013 // then the disableParentSwiper will be false.
5014 disableParentSwiper = swiper.params.loop ? true : !(positions === swiper.minTranslate() || positions === swiper.maxTranslate());
5015 if (disableParentSwiper && swiper.params.nested) e.stopPropagation();
5016 if (!swiper.params.freeMode || !swiper.params.freeMode.enabled) {
5017 // Register the new event in a variable which stores the relevant data
5018 const newEvent = {
5019 time: now(),
5020 delta: Math.abs(delta),
5021 direction: Math.sign(delta),
5022 raw: event
5023 };
5024
5025 // Keep the most recent events
5026 if (recentWheelEvents.length >= 2) {
5027 recentWheelEvents.shift(); // only store the last N events
5028 }
5029
5030 const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
5031 recentWheelEvents.push(newEvent);
5032
5033 // If there is at least one previous recorded event:
5034 // If direction has changed or
5035 // if the scroll is quicker than the previous one:
5036 // Animate the slider.
5037 // Else (this is the first time the wheel is moved):
5038 // Animate the slider.
5039 if (prevEvent) {
5040 if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) {
5041 animateSlider(newEvent);
5042 }
5043 } else {
5044 animateSlider(newEvent);
5045 }
5046
5047 // If it's time to release the scroll:
5048 // Return now so you don't hit the preventDefault.
5049 if (releaseScroll(newEvent)) {
5050 return true;
5051 }
5052 } else {
5053 // Freemode or scrollContainer:
5054
5055 // If we recently snapped after a momentum scroll, then ignore wheel events
5056 // to give time for the deceleration to finish. Stop ignoring after 500 msecs
5057 // or if it's a new scroll (larger delta or inverse sign as last event before
5058 // an end-of-momentum snap).
5059 const newEvent = {
5060 time: now(),
5061 delta: Math.abs(delta),
5062 direction: Math.sign(delta)
5063 };
5064 const ignoreWheelEvents = lastEventBeforeSnap && newEvent.time < lastEventBeforeSnap.time + 500 && newEvent.delta <= lastEventBeforeSnap.delta && newEvent.direction === lastEventBeforeSnap.direction;
5065 if (!ignoreWheelEvents) {
5066 lastEventBeforeSnap = undefined;
5067 let position = swiper.getTranslate() + delta * params.sensitivity;
5068 const wasBeginning = swiper.isBeginning;
5069 const wasEnd = swiper.isEnd;
5070 if (position >= swiper.minTranslate()) position = swiper.minTranslate();
5071 if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();
5072 swiper.setTransition(0);
5073 swiper.setTranslate(position);
5074 swiper.updateProgress();
5075 swiper.updateActiveIndex();
5076 swiper.updateSlidesClasses();
5077 if (!wasBeginning && swiper.isBeginning || !wasEnd && swiper.isEnd) {
5078 swiper.updateSlidesClasses();
5079 }
5080 if (swiper.params.loop) {
5081 swiper.loopFix({
5082 direction: newEvent.direction < 0 ? 'next' : 'prev',
5083 byMousewheel: true
5084 });
5085 }
5086 if (swiper.params.freeMode.sticky) {
5087 // When wheel scrolling starts with sticky (aka snap) enabled, then detect
5088 // the end of a momentum scroll by storing recent (N=15?) wheel events.
5089 // 1. do all N events have decreasing or same (absolute value) delta?
5090 // 2. did all N events arrive in the last M (M=500?) msecs?
5091 // 3. does the earliest event have an (absolute value) delta that's
5092 // at least P (P=1?) larger than the most recent event's delta?
5093 // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?
5094 // If 1-4 are "yes" then we're near the end of a momentum scroll deceleration.
5095 // Snap immediately and ignore remaining wheel events in this scroll.
5096 // See comment above for "remaining wheel events in this scroll" determination.
5097 // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.
5098 clearTimeout(timeout);
5099 timeout = undefined;
5100 if (recentWheelEvents.length >= 15) {
5101 recentWheelEvents.shift(); // only store the last N events
5102 }
5103
5104 const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
5105 const firstEvent = recentWheelEvents[0];
5106 recentWheelEvents.push(newEvent);
5107 if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) {
5108 // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.
5109 recentWheelEvents.splice(0);
5110 } else if (recentWheelEvents.length >= 15 && newEvent.time - firstEvent.time < 500 && firstEvent.delta - newEvent.delta >= 1 && newEvent.delta <= 6) {
5111 // We're at the end of the deceleration of a momentum scroll, so there's no need
5112 // to wait for more events. Snap ASAP on the next tick.
5113 // Also, because there's some remaining momentum we'll bias the snap in the
5114 // direction of the ongoing scroll because it's better UX for the scroll to snap
5115 // in the same direction as the scroll instead of reversing to snap. Therefore,
5116 // if it's already scrolled more than 20% in the current direction, keep going.
5117 const snapToThreshold = delta > 0 ? 0.8 : 0.2;
5118 lastEventBeforeSnap = newEvent;
5119 recentWheelEvents.splice(0);
5120 timeout = nextTick(() => {
5121 swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
5122 }, 0); // no delay; move on next tick
5123 }
5124
5125 if (!timeout) {
5126 // if we get here, then we haven't detected the end of a momentum scroll, so
5127 // we'll consider a scroll "complete" when there haven't been any wheel events
5128 // for 500ms.
5129 timeout = nextTick(() => {
5130 const snapToThreshold = 0.5;
5131 lastEventBeforeSnap = newEvent;
5132 recentWheelEvents.splice(0);
5133 swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
5134 }, 500);
5135 }
5136 }
5137
5138 // Emit event
5139 if (!ignoreWheelEvents) emit('scroll', e);
5140
5141 // Stop autoplay
5142 if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop();
5143 // Return page scroll on edge positions
5144 if (params.releaseOnEdges && (position === swiper.minTranslate() || position === swiper.maxTranslate())) {
5145 return true;
5146 }
5147 }
5148 }
5149 if (e.preventDefault) e.preventDefault();else e.returnValue = false;
5150 return false;
5151 }
5152 function events(method) {
5153 let targetEl = swiper.el;
5154 if (swiper.params.mousewheel.eventsTarget !== 'container') {
5155 targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
5156 }
5157 targetEl[method]('mouseenter', handleMouseEnter);
5158 targetEl[method]('mouseleave', handleMouseLeave);
5159 targetEl[method]('wheel', handle);
5160 }
5161 function enable() {
5162 if (swiper.params.cssMode) {
5163 swiper.wrapperEl.removeEventListener('wheel', handle);
5164 return true;
5165 }
5166 if (swiper.mousewheel.enabled) return false;
5167 events('addEventListener');
5168 swiper.mousewheel.enabled = true;
5169 return true;
5170 }
5171 function disable() {
5172 if (swiper.params.cssMode) {
5173 swiper.wrapperEl.addEventListener(event, handle);
5174 return true;
5175 }
5176 if (!swiper.mousewheel.enabled) return false;
5177 events('removeEventListener');
5178 swiper.mousewheel.enabled = false;
5179 return true;
5180 }
5181 on('init', () => {
5182 if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) {
5183 disable();
5184 }
5185 if (swiper.params.mousewheel.enabled) enable();
5186 });
5187 on('destroy', () => {
5188 if (swiper.params.cssMode) {
5189 enable();
5190 }
5191 if (swiper.mousewheel.enabled) disable();
5192 });
5193 Object.assign(swiper.mousewheel, {
5194 enable,
5195 disable
5196 });
5197 }
5198
5199 function createElementIfNotDefined(swiper, originalParams, params, checkProps) {
5200 if (swiper.params.createElements) {
5201 Object.keys(checkProps).forEach(key => {
5202 if (!params[key] && params.auto === true) {
5203 let element = elementChildren(swiper.el, `.${checkProps[key]}`)[0];
5204 if (!element) {
5205 element = createElement('div', checkProps[key]);
5206 element.className = checkProps[key];
5207 swiper.el.append(element);
5208 }
5209 params[key] = element;
5210 originalParams[key] = element;
5211 }
5212 });
5213 }
5214 return params;
5215 }
5216
5217 function Navigation(_ref) {
5218 let {
5219 swiper,
5220 extendParams,
5221 on,
5222 emit
5223 } = _ref;
5224 extendParams({
5225 navigation: {
5226 nextEl: null,
5227 prevEl: null,
5228 hideOnClick: false,
5229 disabledClass: 'swiper-button-disabled',
5230 hiddenClass: 'swiper-button-hidden',
5231 lockClass: 'swiper-button-lock',
5232 navigationDisabledClass: 'swiper-navigation-disabled'
5233 }
5234 });
5235 swiper.navigation = {
5236 nextEl: null,
5237 prevEl: null
5238 };
5239 function getEl(el) {
5240 let res;
5241 if (el && typeof el === 'string' && swiper.isElement) {
5242 res = swiper.el.querySelector(el);
5243 if (res) return res;
5244 }
5245 if (el) {
5246 if (typeof el === 'string') res = [...document.querySelectorAll(el)];
5247 if (swiper.params.uniqueNavElements && typeof el === 'string' && res && res.length > 1 && swiper.el.querySelectorAll(el).length === 1) {
5248 res = swiper.el.querySelector(el);
5249 } else if (res && res.length === 1) {
5250 res = res[0];
5251 }
5252 }
5253 if (el && !res) return el;
5254 // if (Array.isArray(res) && res.length === 1) res = res[0];
5255 return res;
5256 }
5257 function toggleEl(el, disabled) {
5258 const params = swiper.params.navigation;
5259 el = makeElementsArray(el);
5260 el.forEach(subEl => {
5261 if (subEl) {
5262 subEl.classList[disabled ? 'add' : 'remove'](...params.disabledClass.split(' '));
5263 if (subEl.tagName === 'BUTTON') subEl.disabled = disabled;
5264 if (swiper.params.watchOverflow && swiper.enabled) {
5265 subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
5266 }
5267 }
5268 });
5269 }
5270 function update() {
5271 // Update Navigation Buttons
5272 const {
5273 nextEl,
5274 prevEl
5275 } = swiper.navigation;
5276 if (swiper.params.loop) {
5277 toggleEl(prevEl, false);
5278 toggleEl(nextEl, false);
5279 return;
5280 }
5281 toggleEl(prevEl, swiper.isBeginning && !swiper.params.rewind);
5282 toggleEl(nextEl, swiper.isEnd && !swiper.params.rewind);
5283 }
5284 function onPrevClick(e) {
5285 e.preventDefault();
5286 if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;
5287 swiper.slidePrev();
5288 emit('navigationPrev');
5289 }
5290 function onNextClick(e) {
5291 e.preventDefault();
5292 if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;
5293 swiper.slideNext();
5294 emit('navigationNext');
5295 }
5296 function init() {
5297 const params = swiper.params.navigation;
5298 swiper.params.navigation = createElementIfNotDefined(swiper, swiper.originalParams.navigation, swiper.params.navigation, {
5299 nextEl: 'swiper-button-next',
5300 prevEl: 'swiper-button-prev'
5301 });
5302 if (!(params.nextEl || params.prevEl)) return;
5303 let nextEl = getEl(params.nextEl);
5304 let prevEl = getEl(params.prevEl);
5305 Object.assign(swiper.navigation, {
5306 nextEl,
5307 prevEl
5308 });
5309 nextEl = makeElementsArray(nextEl);
5310 prevEl = makeElementsArray(prevEl);
5311 const initButton = (el, dir) => {
5312 if (el) {
5313 el.addEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
5314 }
5315 if (!swiper.enabled && el) {
5316 el.classList.add(...params.lockClass.split(' '));
5317 }
5318 };
5319 nextEl.forEach(el => initButton(el, 'next'));
5320 prevEl.forEach(el => initButton(el, 'prev'));
5321 }
5322 function destroy() {
5323 let {
5324 nextEl,
5325 prevEl
5326 } = swiper.navigation;
5327 nextEl = makeElementsArray(nextEl);
5328 prevEl = makeElementsArray(prevEl);
5329 const destroyButton = (el, dir) => {
5330 el.removeEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
5331 el.classList.remove(...swiper.params.navigation.disabledClass.split(' '));
5332 };
5333 nextEl.forEach(el => destroyButton(el, 'next'));
5334 prevEl.forEach(el => destroyButton(el, 'prev'));
5335 }
5336 on('init', () => {
5337 if (swiper.params.navigation.enabled === false) {
5338 // eslint-disable-next-line
5339 disable();
5340 } else {
5341 init();
5342 update();
5343 }
5344 });
5345 on('toEdge fromEdge lock unlock', () => {
5346 update();
5347 });
5348 on('destroy', () => {
5349 destroy();
5350 });
5351 on('enable disable', () => {
5352 let {
5353 nextEl,
5354 prevEl
5355 } = swiper.navigation;
5356 nextEl = makeElementsArray(nextEl);
5357 prevEl = makeElementsArray(prevEl);
5358 if (swiper.enabled) {
5359 update();
5360 return;
5361 }
5362 [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.add(swiper.params.navigation.lockClass));
5363 });
5364 on('click', (_s, e) => {
5365 let {
5366 nextEl,
5367 prevEl
5368 } = swiper.navigation;
5369 nextEl = makeElementsArray(nextEl);
5370 prevEl = makeElementsArray(prevEl);
5371 const targetEl = e.target;
5372 let targetIsButton = prevEl.includes(targetEl) || nextEl.includes(targetEl);
5373 if (swiper.isElement && !targetIsButton) {
5374 const path = e.path || e.composedPath && e.composedPath();
5375 if (path) {
5376 targetIsButton = path.find(pathEl => nextEl.includes(pathEl) || prevEl.includes(pathEl));
5377 }
5378 }
5379 if (swiper.params.navigation.hideOnClick && !targetIsButton) {
5380 if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return;
5381 let isHidden;
5382 if (nextEl.length) {
5383 isHidden = nextEl[0].classList.contains(swiper.params.navigation.hiddenClass);
5384 } else if (prevEl.length) {
5385 isHidden = prevEl[0].classList.contains(swiper.params.navigation.hiddenClass);
5386 }
5387 if (isHidden === true) {
5388 emit('navigationShow');
5389 } else {
5390 emit('navigationHide');
5391 }
5392 [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.toggle(swiper.params.navigation.hiddenClass));
5393 }
5394 });
5395 const enable = () => {
5396 swiper.el.classList.remove(...swiper.params.navigation.navigationDisabledClass.split(' '));
5397 init();
5398 update();
5399 };
5400 const disable = () => {
5401 swiper.el.classList.add(...swiper.params.navigation.navigationDisabledClass.split(' '));
5402 destroy();
5403 };
5404 Object.assign(swiper.navigation, {
5405 enable,
5406 disable,
5407 update,
5408 init,
5409 destroy
5410 });
5411 }
5412
5413 function classesToSelector(classes) {
5414 if (classes === void 0) {
5415 classes = '';
5416 }
5417 return `.${classes.trim().replace(/([\.:!+\/])/g, '\\$1') // eslint-disable-line
5418 .replace(/ /g, '.')}`;
5419 }
5420
5421 function Pagination(_ref) {
5422 let {
5423 swiper,
5424 extendParams,
5425 on,
5426 emit
5427 } = _ref;
5428 const pfx = 'swiper-pagination';
5429 extendParams({
5430 pagination: {
5431 el: null,
5432 bulletElement: 'span',
5433 clickable: false,
5434 hideOnClick: false,
5435 renderBullet: null,
5436 renderProgressbar: null,
5437 renderFraction: null,
5438 renderCustom: null,
5439 progressbarOpposite: false,
5440 type: 'bullets',
5441 // 'bullets' or 'progressbar' or 'fraction' or 'custom'
5442 dynamicBullets: false,
5443 dynamicMainBullets: 1,
5444 formatFractionCurrent: number => number,
5445 formatFractionTotal: number => number,
5446 bulletClass: `${pfx}-bullet`,
5447 bulletActiveClass: `${pfx}-bullet-active`,
5448 modifierClass: `${pfx}-`,
5449 currentClass: `${pfx}-current`,
5450 totalClass: `${pfx}-total`,
5451 hiddenClass: `${pfx}-hidden`,
5452 progressbarFillClass: `${pfx}-progressbar-fill`,
5453 progressbarOppositeClass: `${pfx}-progressbar-opposite`,
5454 clickableClass: `${pfx}-clickable`,
5455 lockClass: `${pfx}-lock`,
5456 horizontalClass: `${pfx}-horizontal`,
5457 verticalClass: `${pfx}-vertical`,
5458 paginationDisabledClass: `${pfx}-disabled`
5459 }
5460 });
5461 swiper.pagination = {
5462 el: null,
5463 bullets: []
5464 };
5465 let bulletSize;
5466 let dynamicBulletIndex = 0;
5467 function isPaginationDisabled() {
5468 return !swiper.params.pagination.el || !swiper.pagination.el || Array.isArray(swiper.pagination.el) && swiper.pagination.el.length === 0;
5469 }
5470 function setSideBullets(bulletEl, position) {
5471 const {
5472 bulletActiveClass
5473 } = swiper.params.pagination;
5474 if (!bulletEl) return;
5475 bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
5476 if (bulletEl) {
5477 bulletEl.classList.add(`${bulletActiveClass}-${position}`);
5478 bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
5479 if (bulletEl) {
5480 bulletEl.classList.add(`${bulletActiveClass}-${position}-${position}`);
5481 }
5482 }
5483 }
5484 function onBulletClick(e) {
5485 const bulletEl = e.target.closest(classesToSelector(swiper.params.pagination.bulletClass));
5486 if (!bulletEl) {
5487 return;
5488 }
5489 e.preventDefault();
5490 const index = elementIndex(bulletEl) * swiper.params.slidesPerGroup;
5491 if (swiper.params.loop) {
5492 if (swiper.realIndex === index) return;
5493 swiper.slideToLoop(index);
5494 } else {
5495 swiper.slideTo(index);
5496 }
5497 }
5498 function update() {
5499 // Render || Update Pagination bullets/items
5500 const rtl = swiper.rtl;
5501 const params = swiper.params.pagination;
5502 if (isPaginationDisabled()) return;
5503 let el = swiper.pagination.el;
5504 el = makeElementsArray(el);
5505 // Current/Total
5506 let current;
5507 let previousIndex;
5508 const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
5509 const total = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
5510 if (swiper.params.loop) {
5511 previousIndex = swiper.previousRealIndex || 0;
5512 current = swiper.params.slidesPerGroup > 1 ? Math.floor(swiper.realIndex / swiper.params.slidesPerGroup) : swiper.realIndex;
5513 } else if (typeof swiper.snapIndex !== 'undefined') {
5514 current = swiper.snapIndex;
5515 previousIndex = swiper.previousSnapIndex;
5516 } else {
5517 previousIndex = swiper.previousIndex || 0;
5518 current = swiper.activeIndex || 0;
5519 }
5520 // Types
5521 if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {
5522 const bullets = swiper.pagination.bullets;
5523 let firstIndex;
5524 let lastIndex;
5525 let midIndex;
5526 if (params.dynamicBullets) {
5527 bulletSize = elementOuterSize(bullets[0], swiper.isHorizontal() ? 'width' : 'height', true);
5528 el.forEach(subEl => {
5529 subEl.style[swiper.isHorizontal() ? 'width' : 'height'] = `${bulletSize * (params.dynamicMainBullets + 4)}px`;
5530 });
5531 if (params.dynamicMainBullets > 1 && previousIndex !== undefined) {
5532 dynamicBulletIndex += current - (previousIndex || 0);
5533 if (dynamicBulletIndex > params.dynamicMainBullets - 1) {
5534 dynamicBulletIndex = params.dynamicMainBullets - 1;
5535 } else if (dynamicBulletIndex < 0) {
5536 dynamicBulletIndex = 0;
5537 }
5538 }
5539 firstIndex = Math.max(current - dynamicBulletIndex, 0);
5540 lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
5541 midIndex = (lastIndex + firstIndex) / 2;
5542 }
5543 bullets.forEach(bulletEl => {
5544 const classesToRemove = [...['', '-next', '-next-next', '-prev', '-prev-prev', '-main'].map(suffix => `${params.bulletActiveClass}${suffix}`)].map(s => typeof s === 'string' && s.includes(' ') ? s.split(' ') : s).flat();
5545 bulletEl.classList.remove(...classesToRemove);
5546 });
5547 if (el.length > 1) {
5548 bullets.forEach(bullet => {
5549 const bulletIndex = elementIndex(bullet);
5550 if (bulletIndex === current) {
5551 bullet.classList.add(...params.bulletActiveClass.split(' '));
5552 } else if (swiper.isElement) {
5553 bullet.setAttribute('part', 'bullet');
5554 }
5555 if (params.dynamicBullets) {
5556 if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
5557 bullet.classList.add(...`${params.bulletActiveClass}-main`.split(' '));
5558 }
5559 if (bulletIndex === firstIndex) {
5560 setSideBullets(bullet, 'prev');
5561 }
5562 if (bulletIndex === lastIndex) {
5563 setSideBullets(bullet, 'next');
5564 }
5565 }
5566 });
5567 } else {
5568 const bullet = bullets[current];
5569 if (bullet) {
5570 bullet.classList.add(...params.bulletActiveClass.split(' '));
5571 }
5572 if (swiper.isElement) {
5573 bullets.forEach((bulletEl, bulletIndex) => {
5574 bulletEl.setAttribute('part', bulletIndex === current ? 'bullet-active' : 'bullet');
5575 });
5576 }
5577 if (params.dynamicBullets) {
5578 const firstDisplayedBullet = bullets[firstIndex];
5579 const lastDisplayedBullet = bullets[lastIndex];
5580 for (let i = firstIndex; i <= lastIndex; i += 1) {
5581 if (bullets[i]) {
5582 bullets[i].classList.add(...`${params.bulletActiveClass}-main`.split(' '));
5583 }
5584 }
5585 setSideBullets(firstDisplayedBullet, 'prev');
5586 setSideBullets(lastDisplayedBullet, 'next');
5587 }
5588 }
5589 if (params.dynamicBullets) {
5590 const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
5591 const bulletsOffset = (bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;
5592 const offsetProp = rtl ? 'right' : 'left';
5593 bullets.forEach(bullet => {
5594 bullet.style[swiper.isHorizontal() ? offsetProp : 'top'] = `${bulletsOffset}px`;
5595 });
5596 }
5597 }
5598 el.forEach((subEl, subElIndex) => {
5599 if (params.type === 'fraction') {
5600 subEl.querySelectorAll(classesToSelector(params.currentClass)).forEach(fractionEl => {
5601 fractionEl.textContent = params.formatFractionCurrent(current + 1);
5602 });
5603 subEl.querySelectorAll(classesToSelector(params.totalClass)).forEach(totalEl => {
5604 totalEl.textContent = params.formatFractionTotal(total);
5605 });
5606 }
5607 if (params.type === 'progressbar') {
5608 let progressbarDirection;
5609 if (params.progressbarOpposite) {
5610 progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
5611 } else {
5612 progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
5613 }
5614 const scale = (current + 1) / total;
5615 let scaleX = 1;
5616 let scaleY = 1;
5617 if (progressbarDirection === 'horizontal') {
5618 scaleX = scale;
5619 } else {
5620 scaleY = scale;
5621 }
5622 subEl.querySelectorAll(classesToSelector(params.progressbarFillClass)).forEach(progressEl => {
5623 progressEl.style.transform = `translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`;
5624 progressEl.style.transitionDuration = `${swiper.params.speed}ms`;
5625 });
5626 }
5627 if (params.type === 'custom' && params.renderCustom) {
5628 subEl.innerHTML = params.renderCustom(swiper, current + 1, total);
5629 if (subElIndex === 0) emit('paginationRender', subEl);
5630 } else {
5631 if (subElIndex === 0) emit('paginationRender', subEl);
5632 emit('paginationUpdate', subEl);
5633 }
5634 if (swiper.params.watchOverflow && swiper.enabled) {
5635 subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
5636 }
5637 });
5638 }
5639 function render() {
5640 // Render Container
5641 const params = swiper.params.pagination;
5642 if (isPaginationDisabled()) return;
5643 const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.grid && swiper.params.grid.rows > 1 ? swiper.slides.length / Math.ceil(swiper.params.grid.rows) : swiper.slides.length;
5644 let el = swiper.pagination.el;
5645 el = makeElementsArray(el);
5646 let paginationHTML = '';
5647 if (params.type === 'bullets') {
5648 let numberOfBullets = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
5649 if (swiper.params.freeMode && swiper.params.freeMode.enabled && numberOfBullets > slidesLength) {
5650 numberOfBullets = slidesLength;
5651 }
5652 for (let i = 0; i < numberOfBullets; i += 1) {
5653 if (params.renderBullet) {
5654 paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
5655 } else {
5656 // prettier-ignore
5657 paginationHTML += `<${params.bulletElement} ${swiper.isElement ? 'part="bullet"' : ''} class="${params.bulletClass}"></${params.bulletElement}>`;
5658 }
5659 }
5660 }
5661 if (params.type === 'fraction') {
5662 if (params.renderFraction) {
5663 paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
5664 } else {
5665 paginationHTML = `<span class="${params.currentClass}"></span>` + ' / ' + `<span class="${params.totalClass}"></span>`;
5666 }
5667 }
5668 if (params.type === 'progressbar') {
5669 if (params.renderProgressbar) {
5670 paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
5671 } else {
5672 paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
5673 }
5674 }
5675 swiper.pagination.bullets = [];
5676 el.forEach(subEl => {
5677 if (params.type !== 'custom') {
5678 subEl.innerHTML = paginationHTML || '';
5679 }
5680 if (params.type === 'bullets') {
5681 swiper.pagination.bullets.push(...subEl.querySelectorAll(classesToSelector(params.bulletClass)));
5682 }
5683 });
5684 if (params.type !== 'custom') {
5685 emit('paginationRender', el[0]);
5686 }
5687 }
5688 function init() {
5689 swiper.params.pagination = createElementIfNotDefined(swiper, swiper.originalParams.pagination, swiper.params.pagination, {
5690 el: 'swiper-pagination'
5691 });
5692 const params = swiper.params.pagination;
5693 if (!params.el) return;
5694 let el;
5695 if (typeof params.el === 'string' && swiper.isElement) {
5696 el = swiper.el.querySelector(params.el);
5697 }
5698 if (!el && typeof params.el === 'string') {
5699 el = [...document.querySelectorAll(params.el)];
5700 }
5701 if (!el) {
5702 el = params.el;
5703 }
5704 if (!el || el.length === 0) return;
5705 if (swiper.params.uniqueNavElements && typeof params.el === 'string' && Array.isArray(el) && el.length > 1) {
5706 el = [...swiper.el.querySelectorAll(params.el)];
5707 // check if it belongs to another nested Swiper
5708 if (el.length > 1) {
5709 el = el.filter(subEl => {
5710 if (elementParents(subEl, '.swiper')[0] !== swiper.el) return false;
5711 return true;
5712 })[0];
5713 }
5714 }
5715 if (Array.isArray(el) && el.length === 1) el = el[0];
5716 Object.assign(swiper.pagination, {
5717 el
5718 });
5719 el = makeElementsArray(el);
5720 el.forEach(subEl => {
5721 if (params.type === 'bullets' && params.clickable) {
5722 subEl.classList.add(...(params.clickableClass || '').split(' '));
5723 }
5724 subEl.classList.add(params.modifierClass + params.type);
5725 subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5726 if (params.type === 'bullets' && params.dynamicBullets) {
5727 subEl.classList.add(`${params.modifierClass}${params.type}-dynamic`);
5728 dynamicBulletIndex = 0;
5729 if (params.dynamicMainBullets < 1) {
5730 params.dynamicMainBullets = 1;
5731 }
5732 }
5733 if (params.type === 'progressbar' && params.progressbarOpposite) {
5734 subEl.classList.add(params.progressbarOppositeClass);
5735 }
5736 if (params.clickable) {
5737 subEl.addEventListener('click', onBulletClick);
5738 }
5739 if (!swiper.enabled) {
5740 subEl.classList.add(params.lockClass);
5741 }
5742 });
5743 }
5744 function destroy() {
5745 const params = swiper.params.pagination;
5746 if (isPaginationDisabled()) return;
5747 let el = swiper.pagination.el;
5748 if (el) {
5749 el = makeElementsArray(el);
5750 el.forEach(subEl => {
5751 subEl.classList.remove(params.hiddenClass);
5752 subEl.classList.remove(params.modifierClass + params.type);
5753 subEl.classList.remove(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5754 if (params.clickable) {
5755 subEl.classList.remove(...(params.clickableClass || '').split(' '));
5756 subEl.removeEventListener('click', onBulletClick);
5757 }
5758 });
5759 }
5760 if (swiper.pagination.bullets) swiper.pagination.bullets.forEach(subEl => subEl.classList.remove(...params.bulletActiveClass.split(' ')));
5761 }
5762 on('changeDirection', () => {
5763 if (!swiper.pagination || !swiper.pagination.el) return;
5764 const params = swiper.params.pagination;
5765 let {
5766 el
5767 } = swiper.pagination;
5768 el = makeElementsArray(el);
5769 el.forEach(subEl => {
5770 subEl.classList.remove(params.horizontalClass, params.verticalClass);
5771 subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5772 });
5773 });
5774 on('init', () => {
5775 if (swiper.params.pagination.enabled === false) {
5776 // eslint-disable-next-line
5777 disable();
5778 } else {
5779 init();
5780 render();
5781 update();
5782 }
5783 });
5784 on('activeIndexChange', () => {
5785 if (typeof swiper.snapIndex === 'undefined') {
5786 update();
5787 }
5788 });
5789 on('snapIndexChange', () => {
5790 update();
5791 });
5792 on('snapGridLengthChange', () => {
5793 render();
5794 update();
5795 });
5796 on('destroy', () => {
5797 destroy();
5798 });
5799 on('enable disable', () => {
5800 let {
5801 el
5802 } = swiper.pagination;
5803 if (el) {
5804 el = makeElementsArray(el);
5805 el.forEach(subEl => subEl.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.pagination.lockClass));
5806 }
5807 });
5808 on('lock unlock', () => {
5809 update();
5810 });
5811 on('click', (_s, e) => {
5812 const targetEl = e.target;
5813 const el = makeElementsArray(swiper.pagination.el);
5814 if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && el && el.length > 0 && !targetEl.classList.contains(swiper.params.pagination.bulletClass)) {
5815 if (swiper.navigation && (swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl || swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl)) return;
5816 const isHidden = el[0].classList.contains(swiper.params.pagination.hiddenClass);
5817 if (isHidden === true) {
5818 emit('paginationShow');
5819 } else {
5820 emit('paginationHide');
5821 }
5822 el.forEach(subEl => subEl.classList.toggle(swiper.params.pagination.hiddenClass));
5823 }
5824 });
5825 const enable = () => {
5826 swiper.el.classList.remove(swiper.params.pagination.paginationDisabledClass);
5827 let {
5828 el
5829 } = swiper.pagination;
5830 if (el) {
5831 el = makeElementsArray(el);
5832 el.forEach(subEl => subEl.classList.remove(swiper.params.pagination.paginationDisabledClass));
5833 }
5834 init();
5835 render();
5836 update();
5837 };
5838 const disable = () => {
5839 swiper.el.classList.add(swiper.params.pagination.paginationDisabledClass);
5840 let {
5841 el
5842 } = swiper.pagination;
5843 if (el) {
5844 el = makeElementsArray(el);
5845 el.forEach(subEl => subEl.classList.add(swiper.params.pagination.paginationDisabledClass));
5846 }
5847 destroy();
5848 };
5849 Object.assign(swiper.pagination, {
5850 enable,
5851 disable,
5852 render,
5853 update,
5854 init,
5855 destroy
5856 });
5857 }
5858
5859 function Scrollbar(_ref) {
5860 let {
5861 swiper,
5862 extendParams,
5863 on,
5864 emit
5865 } = _ref;
5866 const document = getDocument();
5867 let isTouched = false;
5868 let timeout = null;
5869 let dragTimeout = null;
5870 let dragStartPos;
5871 let dragSize;
5872 let trackSize;
5873 let divider;
5874 extendParams({
5875 scrollbar: {
5876 el: null,
5877 dragSize: 'auto',
5878 hide: false,
5879 draggable: false,
5880 snapOnRelease: true,
5881 lockClass: 'swiper-scrollbar-lock',
5882 dragClass: 'swiper-scrollbar-drag',
5883 scrollbarDisabledClass: 'swiper-scrollbar-disabled',
5884 horizontalClass: `swiper-scrollbar-horizontal`,
5885 verticalClass: `swiper-scrollbar-vertical`
5886 }
5887 });
5888 swiper.scrollbar = {
5889 el: null,
5890 dragEl: null
5891 };
5892 function setTranslate() {
5893 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5894 const {
5895 scrollbar,
5896 rtlTranslate: rtl
5897 } = swiper;
5898 const {
5899 dragEl,
5900 el
5901 } = scrollbar;
5902 const params = swiper.params.scrollbar;
5903 const progress = swiper.params.loop ? swiper.progressLoop : swiper.progress;
5904 let newSize = dragSize;
5905 let newPos = (trackSize - dragSize) * progress;
5906 if (rtl) {
5907 newPos = -newPos;
5908 if (newPos > 0) {
5909 newSize = dragSize - newPos;
5910 newPos = 0;
5911 } else if (-newPos + dragSize > trackSize) {
5912 newSize = trackSize + newPos;
5913 }
5914 } else if (newPos < 0) {
5915 newSize = dragSize + newPos;
5916 newPos = 0;
5917 } else if (newPos + dragSize > trackSize) {
5918 newSize = trackSize - newPos;
5919 }
5920 if (swiper.isHorizontal()) {
5921 dragEl.style.transform = `translate3d(${newPos}px, 0, 0)`;
5922 dragEl.style.width = `${newSize}px`;
5923 } else {
5924 dragEl.style.transform = `translate3d(0px, ${newPos}px, 0)`;
5925 dragEl.style.height = `${newSize}px`;
5926 }
5927 if (params.hide) {
5928 clearTimeout(timeout);
5929 el.style.opacity = 1;
5930 timeout = setTimeout(() => {
5931 el.style.opacity = 0;
5932 el.style.transitionDuration = '400ms';
5933 }, 1000);
5934 }
5935 }
5936 function setTransition(duration) {
5937 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5938 swiper.scrollbar.dragEl.style.transitionDuration = `${duration}ms`;
5939 }
5940 function updateSize() {
5941 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5942 const {
5943 scrollbar
5944 } = swiper;
5945 const {
5946 dragEl,
5947 el
5948 } = scrollbar;
5949 dragEl.style.width = '';
5950 dragEl.style.height = '';
5951 trackSize = swiper.isHorizontal() ? el.offsetWidth : el.offsetHeight;
5952 divider = swiper.size / (swiper.virtualSize + swiper.params.slidesOffsetBefore - (swiper.params.centeredSlides ? swiper.snapGrid[0] : 0));
5953 if (swiper.params.scrollbar.dragSize === 'auto') {
5954 dragSize = trackSize * divider;
5955 } else {
5956 dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
5957 }
5958 if (swiper.isHorizontal()) {
5959 dragEl.style.width = `${dragSize}px`;
5960 } else {
5961 dragEl.style.height = `${dragSize}px`;
5962 }
5963 if (divider >= 1) {
5964 el.style.display = 'none';
5965 } else {
5966 el.style.display = '';
5967 }
5968 if (swiper.params.scrollbar.hide) {
5969 el.style.opacity = 0;
5970 }
5971 if (swiper.params.watchOverflow && swiper.enabled) {
5972 scrollbar.el.classList[swiper.isLocked ? 'add' : 'remove'](swiper.params.scrollbar.lockClass);
5973 }
5974 }
5975 function getPointerPosition(e) {
5976 return swiper.isHorizontal() ? e.clientX : e.clientY;
5977 }
5978 function setDragPosition(e) {
5979 const {
5980 scrollbar,
5981 rtlTranslate: rtl
5982 } = swiper;
5983 const {
5984 el
5985 } = scrollbar;
5986 let positionRatio;
5987 positionRatio = (getPointerPosition(e) - elementOffset(el)[swiper.isHorizontal() ? 'left' : 'top'] - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize);
5988 positionRatio = Math.max(Math.min(positionRatio, 1), 0);
5989 if (rtl) {
5990 positionRatio = 1 - positionRatio;
5991 }
5992 const position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;
5993 swiper.updateProgress(position);
5994 swiper.setTranslate(position);
5995 swiper.updateActiveIndex();
5996 swiper.updateSlidesClasses();
5997 }
5998 function onDragStart(e) {
5999 const params = swiper.params.scrollbar;
6000 const {
6001 scrollbar,
6002 wrapperEl
6003 } = swiper;
6004 const {
6005 el,
6006 dragEl
6007 } = scrollbar;
6008 isTouched = true;
6009 dragStartPos = e.target === dragEl ? getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null;
6010 e.preventDefault();
6011 e.stopPropagation();
6012 wrapperEl.style.transitionDuration = '100ms';
6013 dragEl.style.transitionDuration = '100ms';
6014 setDragPosition(e);
6015 clearTimeout(dragTimeout);
6016 el.style.transitionDuration = '0ms';
6017 if (params.hide) {
6018 el.style.opacity = 1;
6019 }
6020 if (swiper.params.cssMode) {
6021 swiper.wrapperEl.style['scroll-snap-type'] = 'none';
6022 }
6023 emit('scrollbarDragStart', e);
6024 }
6025 function onDragMove(e) {
6026 const {
6027 scrollbar,
6028 wrapperEl
6029 } = swiper;
6030 const {
6031 el,
6032 dragEl
6033 } = scrollbar;
6034 if (!isTouched) return;
6035 if (e.preventDefault && e.cancelable) e.preventDefault();else e.returnValue = false;
6036 setDragPosition(e);
6037 wrapperEl.style.transitionDuration = '0ms';
6038 el.style.transitionDuration = '0ms';
6039 dragEl.style.transitionDuration = '0ms';
6040 emit('scrollbarDragMove', e);
6041 }
6042 function onDragEnd(e) {
6043 const params = swiper.params.scrollbar;
6044 const {
6045 scrollbar,
6046 wrapperEl
6047 } = swiper;
6048 const {
6049 el
6050 } = scrollbar;
6051 if (!isTouched) return;
6052 isTouched = false;
6053 if (swiper.params.cssMode) {
6054 swiper.wrapperEl.style['scroll-snap-type'] = '';
6055 wrapperEl.style.transitionDuration = '';
6056 }
6057 if (params.hide) {
6058 clearTimeout(dragTimeout);
6059 dragTimeout = nextTick(() => {
6060 el.style.opacity = 0;
6061 el.style.transitionDuration = '400ms';
6062 }, 1000);
6063 }
6064 emit('scrollbarDragEnd', e);
6065 if (params.snapOnRelease) {
6066 swiper.slideToClosest();
6067 }
6068 }
6069 function events(method) {
6070 const {
6071 scrollbar,
6072 params
6073 } = swiper;
6074 const el = scrollbar.el;
6075 if (!el) return;
6076 const target = el;
6077 const activeListener = params.passiveListeners ? {
6078 passive: false,
6079 capture: false
6080 } : false;
6081 const passiveListener = params.passiveListeners ? {
6082 passive: true,
6083 capture: false
6084 } : false;
6085 if (!target) return;
6086 const eventMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
6087 target[eventMethod]('pointerdown', onDragStart, activeListener);
6088 document[eventMethod]('pointermove', onDragMove, activeListener);
6089 document[eventMethod]('pointerup', onDragEnd, passiveListener);
6090 }
6091 function enableDraggable() {
6092 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
6093 events('on');
6094 }
6095 function disableDraggable() {
6096 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
6097 events('off');
6098 }
6099 function init() {
6100 const {
6101 scrollbar,
6102 el: swiperEl
6103 } = swiper;
6104 swiper.params.scrollbar = createElementIfNotDefined(swiper, swiper.originalParams.scrollbar, swiper.params.scrollbar, {
6105 el: 'swiper-scrollbar'
6106 });
6107 const params = swiper.params.scrollbar;
6108 if (!params.el) return;
6109 let el;
6110 if (typeof params.el === 'string' && swiper.isElement) {
6111 el = swiper.el.querySelector(params.el);
6112 }
6113 if (!el && typeof params.el === 'string') {
6114 el = document.querySelectorAll(params.el);
6115 if (!el.length) return;
6116 } else if (!el) {
6117 el = params.el;
6118 }
6119 if (swiper.params.uniqueNavElements && typeof params.el === 'string' && el.length > 1 && swiperEl.querySelectorAll(params.el).length === 1) {
6120 el = swiperEl.querySelector(params.el);
6121 }
6122 if (el.length > 0) el = el[0];
6123 el.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
6124 let dragEl;
6125 if (el) {
6126 dragEl = el.querySelector(classesToSelector(swiper.params.scrollbar.dragClass));
6127 if (!dragEl) {
6128 dragEl = createElement('div', swiper.params.scrollbar.dragClass);
6129 el.append(dragEl);
6130 }
6131 }
6132 Object.assign(scrollbar, {
6133 el,
6134 dragEl
6135 });
6136 if (params.draggable) {
6137 enableDraggable();
6138 }
6139 if (el) {
6140 el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass));
6141 }
6142 }
6143 function destroy() {
6144 const params = swiper.params.scrollbar;
6145 const el = swiper.scrollbar.el;
6146 if (el) {
6147 el.classList.remove(...classesToTokens(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass));
6148 }
6149 disableDraggable();
6150 }
6151 on('changeDirection', () => {
6152 if (!swiper.scrollbar || !swiper.scrollbar.el) return;
6153 const params = swiper.params.scrollbar;
6154 let {
6155 el
6156 } = swiper.scrollbar;
6157 el = makeElementsArray(el);
6158 el.forEach(subEl => {
6159 subEl.classList.remove(params.horizontalClass, params.verticalClass);
6160 subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
6161 });
6162 });
6163 on('init', () => {
6164 if (swiper.params.scrollbar.enabled === false) {
6165 // eslint-disable-next-line
6166 disable();
6167 } else {
6168 init();
6169 updateSize();
6170 setTranslate();
6171 }
6172 });
6173 on('update resize observerUpdate lock unlock changeDirection', () => {
6174 updateSize();
6175 });
6176 on('setTranslate', () => {
6177 setTranslate();
6178 });
6179 on('setTransition', (_s, duration) => {
6180 setTransition(duration);
6181 });
6182 on('enable disable', () => {
6183 const {
6184 el
6185 } = swiper.scrollbar;
6186 if (el) {
6187 el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass));
6188 }
6189 });
6190 on('destroy', () => {
6191 destroy();
6192 });
6193 const enable = () => {
6194 swiper.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
6195 if (swiper.scrollbar.el) {
6196 swiper.scrollbar.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
6197 }
6198 init();
6199 updateSize();
6200 setTranslate();
6201 };
6202 const disable = () => {
6203 swiper.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
6204 if (swiper.scrollbar.el) {
6205 swiper.scrollbar.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
6206 }
6207 destroy();
6208 };
6209 Object.assign(swiper.scrollbar, {
6210 enable,
6211 disable,
6212 updateSize,
6213 setTranslate,
6214 init,
6215 destroy
6216 });
6217 }
6218
6219 function Parallax(_ref) {
6220 let {
6221 swiper,
6222 extendParams,
6223 on
6224 } = _ref;
6225 extendParams({
6226 parallax: {
6227 enabled: false
6228 }
6229 });
6230 const elementsSelector = '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]';
6231 const setTransform = (el, progress) => {
6232 const {
6233 rtl
6234 } = swiper;
6235 const rtlFactor = rtl ? -1 : 1;
6236 const p = el.getAttribute('data-swiper-parallax') || '0';
6237 let x = el.getAttribute('data-swiper-parallax-x');
6238 let y = el.getAttribute('data-swiper-parallax-y');
6239 const scale = el.getAttribute('data-swiper-parallax-scale');
6240 const opacity = el.getAttribute('data-swiper-parallax-opacity');
6241 const rotate = el.getAttribute('data-swiper-parallax-rotate');
6242 if (x || y) {
6243 x = x || '0';
6244 y = y || '0';
6245 } else if (swiper.isHorizontal()) {
6246 x = p;
6247 y = '0';
6248 } else {
6249 y = p;
6250 x = '0';
6251 }
6252 if (x.indexOf('%') >= 0) {
6253 x = `${parseInt(x, 10) * progress * rtlFactor}%`;
6254 } else {
6255 x = `${x * progress * rtlFactor}px`;
6256 }
6257 if (y.indexOf('%') >= 0) {
6258 y = `${parseInt(y, 10) * progress}%`;
6259 } else {
6260 y = `${y * progress}px`;
6261 }
6262 if (typeof opacity !== 'undefined' && opacity !== null) {
6263 const currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress));
6264 el.style.opacity = currentOpacity;
6265 }
6266 let transform = `translate3d(${x}, ${y}, 0px)`;
6267 if (typeof scale !== 'undefined' && scale !== null) {
6268 const currentScale = scale - (scale - 1) * (1 - Math.abs(progress));
6269 transform += ` scale(${currentScale})`;
6270 }
6271 if (rotate && typeof rotate !== 'undefined' && rotate !== null) {
6272 const currentRotate = rotate * progress * -1;
6273 transform += ` rotate(${currentRotate}deg)`;
6274 }
6275 el.style.transform = transform;
6276 };
6277 const setTranslate = () => {
6278 const {
6279 el,
6280 slides,
6281 progress,
6282 snapGrid,
6283 isElement
6284 } = swiper;
6285 const elements = elementChildren(el, elementsSelector);
6286 if (swiper.isElement) {
6287 elements.push(...elementChildren(swiper.hostEl, elementsSelector));
6288 }
6289 elements.forEach(subEl => {
6290 setTransform(subEl, progress);
6291 });
6292 slides.forEach((slideEl, slideIndex) => {
6293 let slideProgress = slideEl.progress;
6294 if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {
6295 slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);
6296 }
6297 slideProgress = Math.min(Math.max(slideProgress, -1), 1);
6298 slideEl.querySelectorAll(`${elementsSelector}, [data-swiper-parallax-rotate]`).forEach(subEl => {
6299 setTransform(subEl, slideProgress);
6300 });
6301 });
6302 };
6303 const setTransition = function (duration) {
6304 if (duration === void 0) {
6305 duration = swiper.params.speed;
6306 }
6307 const {
6308 el,
6309 hostEl
6310 } = swiper;
6311 const elements = [...el.querySelectorAll(elementsSelector)];
6312 if (swiper.isElement) {
6313 elements.push(...hostEl.querySelectorAll(elementsSelector));
6314 }
6315 elements.forEach(parallaxEl => {
6316 let parallaxDuration = parseInt(parallaxEl.getAttribute('data-swiper-parallax-duration'), 10) || duration;
6317 if (duration === 0) parallaxDuration = 0;
6318 parallaxEl.style.transitionDuration = `${parallaxDuration}ms`;
6319 });
6320 };
6321 on('beforeInit', () => {
6322 if (!swiper.params.parallax.enabled) return;
6323 swiper.params.watchSlidesProgress = true;
6324 swiper.originalParams.watchSlidesProgress = true;
6325 });
6326 on('init', () => {
6327 if (!swiper.params.parallax.enabled) return;
6328 setTranslate();
6329 });
6330 on('setTranslate', () => {
6331 if (!swiper.params.parallax.enabled) return;
6332 setTranslate();
6333 });
6334 on('setTransition', (_swiper, duration) => {
6335 if (!swiper.params.parallax.enabled) return;
6336 setTransition(duration);
6337 });
6338 }
6339
6340 function Zoom(_ref) {
6341 let {
6342 swiper,
6343 extendParams,
6344 on,
6345 emit
6346 } = _ref;
6347 const window = getWindow();
6348 extendParams({
6349 zoom: {
6350 enabled: false,
6351 limitToOriginalSize: false,
6352 maxRatio: 3,
6353 minRatio: 1,
6354 toggle: true,
6355 containerClass: 'swiper-zoom-container',
6356 zoomedSlideClass: 'swiper-slide-zoomed'
6357 }
6358 });
6359 swiper.zoom = {
6360 enabled: false
6361 };
6362 let currentScale = 1;
6363 let isScaling = false;
6364 let fakeGestureTouched;
6365 let fakeGestureMoved;
6366 const evCache = [];
6367 const gesture = {
6368 originX: 0,
6369 originY: 0,
6370 slideEl: undefined,
6371 slideWidth: undefined,
6372 slideHeight: undefined,
6373 imageEl: undefined,
6374 imageWrapEl: undefined,
6375 maxRatio: 3
6376 };
6377 const image = {
6378 isTouched: undefined,
6379 isMoved: undefined,
6380 currentX: undefined,
6381 currentY: undefined,
6382 minX: undefined,
6383 minY: undefined,
6384 maxX: undefined,
6385 maxY: undefined,
6386 width: undefined,
6387 height: undefined,
6388 startX: undefined,
6389 startY: undefined,
6390 touchesStart: {},
6391 touchesCurrent: {}
6392 };
6393 const velocity = {
6394 x: undefined,
6395 y: undefined,
6396 prevPositionX: undefined,
6397 prevPositionY: undefined,
6398 prevTime: undefined
6399 };
6400 let scale = 1;
6401 Object.defineProperty(swiper.zoom, 'scale', {
6402 get() {
6403 return scale;
6404 },
6405 set(value) {
6406 if (scale !== value) {
6407 const imageEl = gesture.imageEl;
6408 const slideEl = gesture.slideEl;
6409 emit('zoomChange', value, imageEl, slideEl);
6410 }
6411 scale = value;
6412 }
6413 });
6414 function getDistanceBetweenTouches() {
6415 if (evCache.length < 2) return 1;
6416 const x1 = evCache[0].pageX;
6417 const y1 = evCache[0].pageY;
6418 const x2 = evCache[1].pageX;
6419 const y2 = evCache[1].pageY;
6420 const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
6421 return distance;
6422 }
6423 function getMaxRatio() {
6424 const params = swiper.params.zoom;
6425 const maxRatio = gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;
6426 if (params.limitToOriginalSize && gesture.imageEl && gesture.imageEl.naturalWidth) {
6427 const imageMaxRatio = gesture.imageEl.naturalWidth / gesture.imageEl.offsetWidth;
6428 return Math.min(imageMaxRatio, maxRatio);
6429 }
6430 return maxRatio;
6431 }
6432 function getScaleOrigin() {
6433 if (evCache.length < 2) return {
6434 x: null,
6435 y: null
6436 };
6437 const box = gesture.imageEl.getBoundingClientRect();
6438 return [(evCache[0].pageX + (evCache[1].pageX - evCache[0].pageX) / 2 - box.x - window.scrollX) / currentScale, (evCache[0].pageY + (evCache[1].pageY - evCache[0].pageY) / 2 - box.y - window.scrollY) / currentScale];
6439 }
6440 function getSlideSelector() {
6441 return swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
6442 }
6443 function eventWithinSlide(e) {
6444 const slideSelector = getSlideSelector();
6445 if (e.target.matches(slideSelector)) return true;
6446 if (swiper.slides.filter(slideEl => slideEl.contains(e.target)).length > 0) return true;
6447 return false;
6448 }
6449 function eventWithinZoomContainer(e) {
6450 const selector = `.${swiper.params.zoom.containerClass}`;
6451 if (e.target.matches(selector)) return true;
6452 if ([...swiper.hostEl.querySelectorAll(selector)].filter(containerEl => containerEl.contains(e.target)).length > 0) return true;
6453 return false;
6454 }
6455
6456 // Events
6457 function onGestureStart(e) {
6458 if (e.pointerType === 'mouse') {
6459 evCache.splice(0, evCache.length);
6460 }
6461 if (!eventWithinSlide(e)) return;
6462 const params = swiper.params.zoom;
6463 fakeGestureTouched = false;
6464 fakeGestureMoved = false;
6465 evCache.push(e);
6466 if (evCache.length < 2) {
6467 return;
6468 }
6469 fakeGestureTouched = true;
6470 gesture.scaleStart = getDistanceBetweenTouches();
6471 if (!gesture.slideEl) {
6472 gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
6473 if (!gesture.slideEl) gesture.slideEl = swiper.slides[swiper.activeIndex];
6474 let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
6475 if (imageEl) {
6476 imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
6477 }
6478 gesture.imageEl = imageEl;
6479 if (imageEl) {
6480 gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
6481 } else {
6482 gesture.imageWrapEl = undefined;
6483 }
6484 if (!gesture.imageWrapEl) {
6485 gesture.imageEl = undefined;
6486 return;
6487 }
6488 gesture.maxRatio = getMaxRatio();
6489 }
6490 if (gesture.imageEl) {
6491 const [originX, originY] = getScaleOrigin();
6492 gesture.originX = originX;
6493 gesture.originY = originY;
6494 gesture.imageEl.style.transitionDuration = '0ms';
6495 }
6496 isScaling = true;
6497 }
6498 function onGestureChange(e) {
6499 if (!eventWithinSlide(e)) return;
6500 const params = swiper.params.zoom;
6501 const zoom = swiper.zoom;
6502 const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);
6503 if (pointerIndex >= 0) evCache[pointerIndex] = e;
6504 if (evCache.length < 2) {
6505 return;
6506 }
6507 fakeGestureMoved = true;
6508 gesture.scaleMove = getDistanceBetweenTouches();
6509 if (!gesture.imageEl) {
6510 return;
6511 }
6512 zoom.scale = gesture.scaleMove / gesture.scaleStart * currentScale;
6513 if (zoom.scale > gesture.maxRatio) {
6514 zoom.scale = gesture.maxRatio - 1 + (zoom.scale - gesture.maxRatio + 1) ** 0.5;
6515 }
6516 if (zoom.scale < params.minRatio) {
6517 zoom.scale = params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5;
6518 }
6519 gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
6520 }
6521 function onGestureEnd(e) {
6522 if (!eventWithinSlide(e)) return;
6523 if (e.pointerType === 'mouse' && e.type === 'pointerout') return;
6524 const params = swiper.params.zoom;
6525 const zoom = swiper.zoom;
6526 const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);
6527 if (pointerIndex >= 0) evCache.splice(pointerIndex, 1);
6528 if (!fakeGestureTouched || !fakeGestureMoved) {
6529 return;
6530 }
6531 fakeGestureTouched = false;
6532 fakeGestureMoved = false;
6533 if (!gesture.imageEl) return;
6534 zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);
6535 gesture.imageEl.style.transitionDuration = `${swiper.params.speed}ms`;
6536 gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
6537 currentScale = zoom.scale;
6538 isScaling = false;
6539 if (zoom.scale > 1 && gesture.slideEl) {
6540 gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
6541 } else if (zoom.scale <= 1 && gesture.slideEl) {
6542 gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
6543 }
6544 if (zoom.scale === 1) {
6545 gesture.originX = 0;
6546 gesture.originY = 0;
6547 gesture.slideEl = undefined;
6548 }
6549 }
6550 let allowTouchMoveTimeout;
6551 function allowTouchMove() {
6552 swiper.touchEventsData.preventTouchMoveFromPointerMove = false;
6553 }
6554 function preventTouchMove() {
6555 clearTimeout(allowTouchMoveTimeout);
6556 swiper.touchEventsData.preventTouchMoveFromPointerMove = true;
6557 allowTouchMoveTimeout = setTimeout(() => {
6558 allowTouchMove();
6559 });
6560 }
6561 function onTouchStart(e) {
6562 const device = swiper.device;
6563 if (!gesture.imageEl) return;
6564 if (image.isTouched) return;
6565 if (device.android && e.cancelable) e.preventDefault();
6566 image.isTouched = true;
6567 const event = evCache.length > 0 ? evCache[0] : e;
6568 image.touchesStart.x = event.pageX;
6569 image.touchesStart.y = event.pageY;
6570 }
6571 function onTouchMove(e) {
6572 if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) {
6573 return;
6574 }
6575 const zoom = swiper.zoom;
6576 if (!gesture.imageEl) {
6577 return;
6578 }
6579 if (!image.isTouched || !gesture.slideEl) {
6580 return;
6581 }
6582 if (!image.isMoved) {
6583 image.width = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth;
6584 image.height = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight;
6585 image.startX = getTranslate(gesture.imageWrapEl, 'x') || 0;
6586 image.startY = getTranslate(gesture.imageWrapEl, 'y') || 0;
6587 gesture.slideWidth = gesture.slideEl.offsetWidth;
6588 gesture.slideHeight = gesture.slideEl.offsetHeight;
6589 gesture.imageWrapEl.style.transitionDuration = '0ms';
6590 }
6591 // Define if we need image drag
6592 const scaledWidth = image.width * zoom.scale;
6593 const scaledHeight = image.height * zoom.scale;
6594 image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
6595 image.maxX = -image.minX;
6596 image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
6597 image.maxY = -image.minY;
6598 image.touchesCurrent.x = evCache.length > 0 ? evCache[0].pageX : e.pageX;
6599 image.touchesCurrent.y = evCache.length > 0 ? evCache[0].pageY : e.pageY;
6600 const touchesDiff = Math.max(Math.abs(image.touchesCurrent.x - image.touchesStart.x), Math.abs(image.touchesCurrent.y - image.touchesStart.y));
6601 if (touchesDiff > 5) {
6602 swiper.allowClick = false;
6603 }
6604 if (!image.isMoved && !isScaling) {
6605 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)) {
6606 image.isTouched = false;
6607 allowTouchMove();
6608 return;
6609 }
6610 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)) {
6611 image.isTouched = false;
6612 allowTouchMove();
6613 return;
6614 }
6615 }
6616 if (e.cancelable) {
6617 e.preventDefault();
6618 }
6619 e.stopPropagation();
6620 preventTouchMove();
6621 image.isMoved = true;
6622 const scaleRatio = (zoom.scale - currentScale) / (gesture.maxRatio - swiper.params.zoom.minRatio);
6623 const {
6624 originX,
6625 originY
6626 } = gesture;
6627 image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX + scaleRatio * (image.width - originX * 2);
6628 image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY + scaleRatio * (image.height - originY * 2);
6629 if (image.currentX < image.minX) {
6630 image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8;
6631 }
6632 if (image.currentX > image.maxX) {
6633 image.currentX = image.maxX - 1 + (image.currentX - image.maxX + 1) ** 0.8;
6634 }
6635 if (image.currentY < image.minY) {
6636 image.currentY = image.minY + 1 - (image.minY - image.currentY + 1) ** 0.8;
6637 }
6638 if (image.currentY > image.maxY) {
6639 image.currentY = image.maxY - 1 + (image.currentY - image.maxY + 1) ** 0.8;
6640 }
6641
6642 // Velocity
6643 if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x;
6644 if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y;
6645 if (!velocity.prevTime) velocity.prevTime = Date.now();
6646 velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;
6647 velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;
6648 if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0;
6649 if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0;
6650 velocity.prevPositionX = image.touchesCurrent.x;
6651 velocity.prevPositionY = image.touchesCurrent.y;
6652 velocity.prevTime = Date.now();
6653 gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
6654 }
6655 function onTouchEnd() {
6656 const zoom = swiper.zoom;
6657 if (!gesture.imageEl) return;
6658 if (!image.isTouched || !image.isMoved) {
6659 image.isTouched = false;
6660 image.isMoved = false;
6661 return;
6662 }
6663 image.isTouched = false;
6664 image.isMoved = false;
6665 let momentumDurationX = 300;
6666 let momentumDurationY = 300;
6667 const momentumDistanceX = velocity.x * momentumDurationX;
6668 const newPositionX = image.currentX + momentumDistanceX;
6669 const momentumDistanceY = velocity.y * momentumDurationY;
6670 const newPositionY = image.currentY + momentumDistanceY;
6671
6672 // Fix duration
6673 if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x);
6674 if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y);
6675 const momentumDuration = Math.max(momentumDurationX, momentumDurationY);
6676 image.currentX = newPositionX;
6677 image.currentY = newPositionY;
6678 // Define if we need image drag
6679 const scaledWidth = image.width * zoom.scale;
6680 const scaledHeight = image.height * zoom.scale;
6681 image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
6682 image.maxX = -image.minX;
6683 image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
6684 image.maxY = -image.minY;
6685 image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);
6686 image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);
6687 gesture.imageWrapEl.style.transitionDuration = `${momentumDuration}ms`;
6688 gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
6689 }
6690 function onTransitionEnd() {
6691 const zoom = swiper.zoom;
6692 if (gesture.slideEl && swiper.activeIndex !== swiper.slides.indexOf(gesture.slideEl)) {
6693 if (gesture.imageEl) {
6694 gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
6695 }
6696 if (gesture.imageWrapEl) {
6697 gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
6698 }
6699 gesture.slideEl.classList.remove(`${swiper.params.zoom.zoomedSlideClass}`);
6700 zoom.scale = 1;
6701 currentScale = 1;
6702 gesture.slideEl = undefined;
6703 gesture.imageEl = undefined;
6704 gesture.imageWrapEl = undefined;
6705 gesture.originX = 0;
6706 gesture.originY = 0;
6707 }
6708 }
6709 function zoomIn(e) {
6710 const zoom = swiper.zoom;
6711 const params = swiper.params.zoom;
6712 if (!gesture.slideEl) {
6713 if (e && e.target) {
6714 gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
6715 }
6716 if (!gesture.slideEl) {
6717 if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
6718 gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
6719 } else {
6720 gesture.slideEl = swiper.slides[swiper.activeIndex];
6721 }
6722 }
6723 let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
6724 if (imageEl) {
6725 imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
6726 }
6727 gesture.imageEl = imageEl;
6728 if (imageEl) {
6729 gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
6730 } else {
6731 gesture.imageWrapEl = undefined;
6732 }
6733 }
6734 if (!gesture.imageEl || !gesture.imageWrapEl) return;
6735 if (swiper.params.cssMode) {
6736 swiper.wrapperEl.style.overflow = 'hidden';
6737 swiper.wrapperEl.style.touchAction = 'none';
6738 }
6739 gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
6740 let touchX;
6741 let touchY;
6742 let offsetX;
6743 let offsetY;
6744 let diffX;
6745 let diffY;
6746 let translateX;
6747 let translateY;
6748 let imageWidth;
6749 let imageHeight;
6750 let scaledWidth;
6751 let scaledHeight;
6752 let translateMinX;
6753 let translateMinY;
6754 let translateMaxX;
6755 let translateMaxY;
6756 let slideWidth;
6757 let slideHeight;
6758 if (typeof image.touchesStart.x === 'undefined' && e) {
6759 touchX = e.pageX;
6760 touchY = e.pageY;
6761 } else {
6762 touchX = image.touchesStart.x;
6763 touchY = image.touchesStart.y;
6764 }
6765 const forceZoomRatio = typeof e === 'number' ? e : null;
6766 if (currentScale === 1 && forceZoomRatio) {
6767 touchX = undefined;
6768 touchY = undefined;
6769 }
6770 const maxRatio = getMaxRatio();
6771 zoom.scale = forceZoomRatio || maxRatio;
6772 currentScale = forceZoomRatio || maxRatio;
6773 if (e && !(currentScale === 1 && forceZoomRatio)) {
6774 slideWidth = gesture.slideEl.offsetWidth;
6775 slideHeight = gesture.slideEl.offsetHeight;
6776 offsetX = elementOffset(gesture.slideEl).left + window.scrollX;
6777 offsetY = elementOffset(gesture.slideEl).top + window.scrollY;
6778 diffX = offsetX + slideWidth / 2 - touchX;
6779 diffY = offsetY + slideHeight / 2 - touchY;
6780 imageWidth = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth;
6781 imageHeight = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight;
6782 scaledWidth = imageWidth * zoom.scale;
6783 scaledHeight = imageHeight * zoom.scale;
6784 translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);
6785 translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);
6786 translateMaxX = -translateMinX;
6787 translateMaxY = -translateMinY;
6788 translateX = diffX * zoom.scale;
6789 translateY = diffY * zoom.scale;
6790 if (translateX < translateMinX) {
6791 translateX = translateMinX;
6792 }
6793 if (translateX > translateMaxX) {
6794 translateX = translateMaxX;
6795 }
6796 if (translateY < translateMinY) {
6797 translateY = translateMinY;
6798 }
6799 if (translateY > translateMaxY) {
6800 translateY = translateMaxY;
6801 }
6802 } else {
6803 translateX = 0;
6804 translateY = 0;
6805 }
6806 if (forceZoomRatio && zoom.scale === 1) {
6807 gesture.originX = 0;
6808 gesture.originY = 0;
6809 }
6810 gesture.imageWrapEl.style.transitionDuration = '300ms';
6811 gesture.imageWrapEl.style.transform = `translate3d(${translateX}px, ${translateY}px,0)`;
6812 gesture.imageEl.style.transitionDuration = '300ms';
6813 gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
6814 }
6815 function zoomOut() {
6816 const zoom = swiper.zoom;
6817 const params = swiper.params.zoom;
6818 if (!gesture.slideEl) {
6819 if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
6820 gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
6821 } else {
6822 gesture.slideEl = swiper.slides[swiper.activeIndex];
6823 }
6824 let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
6825 if (imageEl) {
6826 imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
6827 }
6828 gesture.imageEl = imageEl;
6829 if (imageEl) {
6830 gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
6831 } else {
6832 gesture.imageWrapEl = undefined;
6833 }
6834 }
6835 if (!gesture.imageEl || !gesture.imageWrapEl) return;
6836 if (swiper.params.cssMode) {
6837 swiper.wrapperEl.style.overflow = '';
6838 swiper.wrapperEl.style.touchAction = '';
6839 }
6840 zoom.scale = 1;
6841 currentScale = 1;
6842 gesture.imageWrapEl.style.transitionDuration = '300ms';
6843 gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
6844 gesture.imageEl.style.transitionDuration = '300ms';
6845 gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
6846 gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
6847 gesture.slideEl = undefined;
6848 gesture.originX = 0;
6849 gesture.originY = 0;
6850 }
6851
6852 // Toggle Zoom
6853 function zoomToggle(e) {
6854 const zoom = swiper.zoom;
6855 if (zoom.scale && zoom.scale !== 1) {
6856 // Zoom Out
6857 zoomOut();
6858 } else {
6859 // Zoom In
6860 zoomIn(e);
6861 }
6862 }
6863 function getListeners() {
6864 const passiveListener = swiper.params.passiveListeners ? {
6865 passive: true,
6866 capture: false
6867 } : false;
6868 const activeListenerWithCapture = swiper.params.passiveListeners ? {
6869 passive: false,
6870 capture: true
6871 } : true;
6872 return {
6873 passiveListener,
6874 activeListenerWithCapture
6875 };
6876 }
6877
6878 // Attach/Detach Events
6879 function enable() {
6880 const zoom = swiper.zoom;
6881 if (zoom.enabled) return;
6882 zoom.enabled = true;
6883 const {
6884 passiveListener,
6885 activeListenerWithCapture
6886 } = getListeners();
6887
6888 // Scale image
6889 swiper.wrapperEl.addEventListener('pointerdown', onGestureStart, passiveListener);
6890 swiper.wrapperEl.addEventListener('pointermove', onGestureChange, activeListenerWithCapture);
6891 ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {
6892 swiper.wrapperEl.addEventListener(eventName, onGestureEnd, passiveListener);
6893 });
6894
6895 // Move image
6896 swiper.wrapperEl.addEventListener('pointermove', onTouchMove, activeListenerWithCapture);
6897 }
6898 function disable() {
6899 const zoom = swiper.zoom;
6900 if (!zoom.enabled) return;
6901 zoom.enabled = false;
6902 const {
6903 passiveListener,
6904 activeListenerWithCapture
6905 } = getListeners();
6906
6907 // Scale image
6908 swiper.wrapperEl.removeEventListener('pointerdown', onGestureStart, passiveListener);
6909 swiper.wrapperEl.removeEventListener('pointermove', onGestureChange, activeListenerWithCapture);
6910 ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {
6911 swiper.wrapperEl.removeEventListener(eventName, onGestureEnd, passiveListener);
6912 });
6913
6914 // Move image
6915 swiper.wrapperEl.removeEventListener('pointermove', onTouchMove, activeListenerWithCapture);
6916 }
6917 on('init', () => {
6918 if (swiper.params.zoom.enabled) {
6919 enable();
6920 }
6921 });
6922 on('destroy', () => {
6923 disable();
6924 });
6925 on('touchStart', (_s, e) => {
6926 if (!swiper.zoom.enabled) return;
6927 onTouchStart(e);
6928 });
6929 on('touchEnd', (_s, e) => {
6930 if (!swiper.zoom.enabled) return;
6931 onTouchEnd();
6932 });
6933 on('doubleTap', (_s, e) => {
6934 if (!swiper.animating && swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {
6935 zoomToggle(e);
6936 }
6937 });
6938 on('transitionEnd', () => {
6939 if (swiper.zoom.enabled && swiper.params.zoom.enabled) {
6940 onTransitionEnd();
6941 }
6942 });
6943 on('slideChange', () => {
6944 if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) {
6945 onTransitionEnd();
6946 }
6947 });
6948 Object.assign(swiper.zoom, {
6949 enable,
6950 disable,
6951 in: zoomIn,
6952 out: zoomOut,
6953 toggle: zoomToggle
6954 });
6955 }
6956
6957 /* eslint no-bitwise: ["error", { "allow": [">>"] }] */
6958 function Controller(_ref) {
6959 let {
6960 swiper,
6961 extendParams,
6962 on
6963 } = _ref;
6964 extendParams({
6965 controller: {
6966 control: undefined,
6967 inverse: false,
6968 by: 'slide' // or 'container'
6969 }
6970 });
6971
6972 swiper.controller = {
6973 control: undefined
6974 };
6975 function LinearSpline(x, y) {
6976 const binarySearch = function search() {
6977 let maxIndex;
6978 let minIndex;
6979 let guess;
6980 return (array, val) => {
6981 minIndex = -1;
6982 maxIndex = array.length;
6983 while (maxIndex - minIndex > 1) {
6984 guess = maxIndex + minIndex >> 1;
6985 if (array[guess] <= val) {
6986 minIndex = guess;
6987 } else {
6988 maxIndex = guess;
6989 }
6990 }
6991 return maxIndex;
6992 };
6993 }();
6994 this.x = x;
6995 this.y = y;
6996 this.lastIndex = x.length - 1;
6997 // Given an x value (x2), return the expected y2 value:
6998 // (x1,y1) is the known point before given value,
6999 // (x3,y3) is the known point after given value.
7000 let i1;
7001 let i3;
7002 this.interpolate = function interpolate(x2) {
7003 if (!x2) return 0;
7004
7005 // Get the indexes of x1 and x3 (the array indexes before and after given x2):
7006 i3 = binarySearch(this.x, x2);
7007 i1 = i3 - 1;
7008
7009 // We have our indexes i1 & i3, so we can calculate already:
7010 // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
7011 return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1];
7012 };
7013 return this;
7014 }
7015 function getInterpolateFunction(c) {
7016 swiper.controller.spline = swiper.params.loop ? new LinearSpline(swiper.slidesGrid, c.slidesGrid) : new LinearSpline(swiper.snapGrid, c.snapGrid);
7017 }
7018 function setTranslate(_t, byController) {
7019 const controlled = swiper.controller.control;
7020 let multiplier;
7021 let controlledTranslate;
7022 const Swiper = swiper.constructor;
7023 function setControlledTranslate(c) {
7024 if (c.destroyed) return;
7025
7026 // this will create an Interpolate function based on the snapGrids
7027 // x is the Grid of the scrolled scroller and y will be the controlled scroller
7028 // it makes sense to create this only once and recall it for the interpolation
7029 // the function does a lot of value caching for performance
7030 const translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate;
7031 if (swiper.params.controller.by === 'slide') {
7032 getInterpolateFunction(c);
7033 // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
7034 // but it did not work out
7035 controlledTranslate = -swiper.controller.spline.interpolate(-translate);
7036 }
7037 if (!controlledTranslate || swiper.params.controller.by === 'container') {
7038 multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate());
7039 if (Number.isNaN(multiplier) || !Number.isFinite(multiplier)) {
7040 multiplier = 1;
7041 }
7042 controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate();
7043 }
7044 if (swiper.params.controller.inverse) {
7045 controlledTranslate = c.maxTranslate() - controlledTranslate;
7046 }
7047 c.updateProgress(controlledTranslate);
7048 c.setTranslate(controlledTranslate, swiper);
7049 c.updateActiveIndex();
7050 c.updateSlidesClasses();
7051 }
7052 if (Array.isArray(controlled)) {
7053 for (let i = 0; i < controlled.length; i += 1) {
7054 if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
7055 setControlledTranslate(controlled[i]);
7056 }
7057 }
7058 } else if (controlled instanceof Swiper && byController !== controlled) {
7059 setControlledTranslate(controlled);
7060 }
7061 }
7062 function setTransition(duration, byController) {
7063 const Swiper = swiper.constructor;
7064 const controlled = swiper.controller.control;
7065 let i;
7066 function setControlledTransition(c) {
7067 if (c.destroyed) return;
7068 c.setTransition(duration, swiper);
7069 if (duration !== 0) {
7070 c.transitionStart();
7071 if (c.params.autoHeight) {
7072 nextTick(() => {
7073 c.updateAutoHeight();
7074 });
7075 }
7076 elementTransitionEnd(c.wrapperEl, () => {
7077 if (!controlled) return;
7078 c.transitionEnd();
7079 });
7080 }
7081 }
7082 if (Array.isArray(controlled)) {
7083 for (i = 0; i < controlled.length; i += 1) {
7084 if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
7085 setControlledTransition(controlled[i]);
7086 }
7087 }
7088 } else if (controlled instanceof Swiper && byController !== controlled) {
7089 setControlledTransition(controlled);
7090 }
7091 }
7092 function removeSpline() {
7093 if (!swiper.controller.control) return;
7094 if (swiper.controller.spline) {
7095 swiper.controller.spline = undefined;
7096 delete swiper.controller.spline;
7097 }
7098 }
7099 on('beforeInit', () => {
7100 if (typeof window !== 'undefined' && (
7101 // eslint-disable-line
7102 typeof swiper.params.controller.control === 'string' || swiper.params.controller.control instanceof HTMLElement)) {
7103 const controlElement = document.querySelector(swiper.params.controller.control);
7104 if (controlElement && controlElement.swiper) {
7105 swiper.controller.control = controlElement.swiper;
7106 } else if (controlElement) {
7107 const onControllerSwiper = e => {
7108 swiper.controller.control = e.detail[0];
7109 swiper.update();
7110 controlElement.removeEventListener('init', onControllerSwiper);
7111 };
7112 controlElement.addEventListener('init', onControllerSwiper);
7113 }
7114 return;
7115 }
7116 swiper.controller.control = swiper.params.controller.control;
7117 });
7118 on('update', () => {
7119 removeSpline();
7120 });
7121 on('resize', () => {
7122 removeSpline();
7123 });
7124 on('observerUpdate', () => {
7125 removeSpline();
7126 });
7127 on('setTranslate', (_s, translate, byController) => {
7128 if (!swiper.controller.control || swiper.controller.control.destroyed) return;
7129 swiper.controller.setTranslate(translate, byController);
7130 });
7131 on('setTransition', (_s, duration, byController) => {
7132 if (!swiper.controller.control || swiper.controller.control.destroyed) return;
7133 swiper.controller.setTransition(duration, byController);
7134 });
7135 Object.assign(swiper.controller, {
7136 setTranslate,
7137 setTransition
7138 });
7139 }
7140
7141 function A11y(_ref) {
7142 let {
7143 swiper,
7144 extendParams,
7145 on
7146 } = _ref;
7147 extendParams({
7148 a11y: {
7149 enabled: true,
7150 notificationClass: 'swiper-notification',
7151 prevSlideMessage: 'Previous slide',
7152 nextSlideMessage: 'Next slide',
7153 firstSlideMessage: 'This is the first slide',
7154 lastSlideMessage: 'This is the last slide',
7155 paginationBulletMessage: 'Go to slide {{index}}',
7156 slideLabelMessage: '{{index}} / {{slidesLength}}',
7157 containerMessage: null,
7158 containerRoleDescriptionMessage: null,
7159 itemRoleDescriptionMessage: null,
7160 slideRole: 'group',
7161 id: null
7162 }
7163 });
7164 swiper.a11y = {
7165 clicked: false
7166 };
7167 let liveRegion = null;
7168 let preventFocusHandler;
7169 let focusTargetSlideEl;
7170 let visibilityChangedTimestamp = new Date().getTime();
7171 function notify(message) {
7172 const notification = liveRegion;
7173 if (notification.length === 0) return;
7174 notification.innerHTML = '';
7175 notification.innerHTML = message;
7176 }
7177 function getRandomNumber(size) {
7178 if (size === void 0) {
7179 size = 16;
7180 }
7181 const randomChar = () => Math.round(16 * Math.random()).toString(16);
7182 return 'x'.repeat(size).replace(/x/g, randomChar);
7183 }
7184 function makeElFocusable(el) {
7185 el = makeElementsArray(el);
7186 el.forEach(subEl => {
7187 subEl.setAttribute('tabIndex', '0');
7188 });
7189 }
7190 function makeElNotFocusable(el) {
7191 el = makeElementsArray(el);
7192 el.forEach(subEl => {
7193 subEl.setAttribute('tabIndex', '-1');
7194 });
7195 }
7196 function addElRole(el, role) {
7197 el = makeElementsArray(el);
7198 el.forEach(subEl => {
7199 subEl.setAttribute('role', role);
7200 });
7201 }
7202 function addElRoleDescription(el, description) {
7203 el = makeElementsArray(el);
7204 el.forEach(subEl => {
7205 subEl.setAttribute('aria-roledescription', description);
7206 });
7207 }
7208 function addElControls(el, controls) {
7209 el = makeElementsArray(el);
7210 el.forEach(subEl => {
7211 subEl.setAttribute('aria-controls', controls);
7212 });
7213 }
7214 function addElLabel(el, label) {
7215 el = makeElementsArray(el);
7216 el.forEach(subEl => {
7217 subEl.setAttribute('aria-label', label);
7218 });
7219 }
7220 function addElId(el, id) {
7221 el = makeElementsArray(el);
7222 el.forEach(subEl => {
7223 subEl.setAttribute('id', id);
7224 });
7225 }
7226 function addElLive(el, live) {
7227 el = makeElementsArray(el);
7228 el.forEach(subEl => {
7229 subEl.setAttribute('aria-live', live);
7230 });
7231 }
7232 function disableEl(el) {
7233 el = makeElementsArray(el);
7234 el.forEach(subEl => {
7235 subEl.setAttribute('aria-disabled', true);
7236 });
7237 }
7238 function enableEl(el) {
7239 el = makeElementsArray(el);
7240 el.forEach(subEl => {
7241 subEl.setAttribute('aria-disabled', false);
7242 });
7243 }
7244 function onEnterOrSpaceKey(e) {
7245 if (e.keyCode !== 13 && e.keyCode !== 32) return;
7246 const params = swiper.params.a11y;
7247 const targetEl = e.target;
7248 if (swiper.pagination && swiper.pagination.el && (targetEl === swiper.pagination.el || swiper.pagination.el.contains(e.target))) {
7249 if (!e.target.matches(classesToSelector(swiper.params.pagination.bulletClass))) return;
7250 }
7251 if (swiper.navigation && swiper.navigation.prevEl && swiper.navigation.nextEl) {
7252 const prevEls = makeElementsArray(swiper.navigation.prevEl);
7253 const nextEls = makeElementsArray(swiper.navigation.nextEl);
7254 if (nextEls.includes(targetEl)) {
7255 if (!(swiper.isEnd && !swiper.params.loop)) {
7256 swiper.slideNext();
7257 }
7258 if (swiper.isEnd) {
7259 notify(params.lastSlideMessage);
7260 } else {
7261 notify(params.nextSlideMessage);
7262 }
7263 }
7264 if (prevEls.includes(targetEl)) {
7265 if (!(swiper.isBeginning && !swiper.params.loop)) {
7266 swiper.slidePrev();
7267 }
7268 if (swiper.isBeginning) {
7269 notify(params.firstSlideMessage);
7270 } else {
7271 notify(params.prevSlideMessage);
7272 }
7273 }
7274 }
7275 if (swiper.pagination && targetEl.matches(classesToSelector(swiper.params.pagination.bulletClass))) {
7276 targetEl.click();
7277 }
7278 }
7279 function updateNavigation() {
7280 if (swiper.params.loop || swiper.params.rewind || !swiper.navigation) return;
7281 const {
7282 nextEl,
7283 prevEl
7284 } = swiper.navigation;
7285 if (prevEl) {
7286 if (swiper.isBeginning) {
7287 disableEl(prevEl);
7288 makeElNotFocusable(prevEl);
7289 } else {
7290 enableEl(prevEl);
7291 makeElFocusable(prevEl);
7292 }
7293 }
7294 if (nextEl) {
7295 if (swiper.isEnd) {
7296 disableEl(nextEl);
7297 makeElNotFocusable(nextEl);
7298 } else {
7299 enableEl(nextEl);
7300 makeElFocusable(nextEl);
7301 }
7302 }
7303 }
7304 function hasPagination() {
7305 return swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length;
7306 }
7307 function hasClickablePagination() {
7308 return hasPagination() && swiper.params.pagination.clickable;
7309 }
7310 function updatePagination() {
7311 const params = swiper.params.a11y;
7312 if (!hasPagination()) return;
7313 swiper.pagination.bullets.forEach(bulletEl => {
7314 if (swiper.params.pagination.clickable) {
7315 makeElFocusable(bulletEl);
7316 if (!swiper.params.pagination.renderBullet) {
7317 addElRole(bulletEl, 'button');
7318 addElLabel(bulletEl, params.paginationBulletMessage.replace(/\{\{index\}\}/, elementIndex(bulletEl) + 1));
7319 }
7320 }
7321 if (bulletEl.matches(classesToSelector(swiper.params.pagination.bulletActiveClass))) {
7322 bulletEl.setAttribute('aria-current', 'true');
7323 } else {
7324 bulletEl.removeAttribute('aria-current');
7325 }
7326 });
7327 }
7328 const initNavEl = (el, wrapperId, message) => {
7329 makeElFocusable(el);
7330 if (el.tagName !== 'BUTTON') {
7331 addElRole(el, 'button');
7332 el.addEventListener('keydown', onEnterOrSpaceKey);
7333 }
7334 addElLabel(el, message);
7335 addElControls(el, wrapperId);
7336 };
7337 const handlePointerDown = e => {
7338 if (focusTargetSlideEl && focusTargetSlideEl !== e.target && !focusTargetSlideEl.contains(e.target)) {
7339 preventFocusHandler = true;
7340 }
7341 swiper.a11y.clicked = true;
7342 };
7343 const handlePointerUp = () => {
7344 preventFocusHandler = false;
7345 requestAnimationFrame(() => {
7346 requestAnimationFrame(() => {
7347 if (!swiper.destroyed) {
7348 swiper.a11y.clicked = false;
7349 }
7350 });
7351 });
7352 };
7353 const onVisibilityChange = e => {
7354 visibilityChangedTimestamp = new Date().getTime();
7355 };
7356 const handleFocus = e => {
7357 if (swiper.a11y.clicked) return;
7358 if (new Date().getTime() - visibilityChangedTimestamp < 100) return;
7359 const slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
7360 if (!slideEl || !swiper.slides.includes(slideEl)) return;
7361 focusTargetSlideEl = slideEl;
7362 const isActive = swiper.slides.indexOf(slideEl) === swiper.activeIndex;
7363 const isVisible = swiper.params.watchSlidesProgress && swiper.visibleSlides && swiper.visibleSlides.includes(slideEl);
7364 if (isActive || isVisible) return;
7365 if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents) return;
7366 if (swiper.isHorizontal()) {
7367 swiper.el.scrollLeft = 0;
7368 } else {
7369 swiper.el.scrollTop = 0;
7370 }
7371 requestAnimationFrame(() => {
7372 if (preventFocusHandler) return;
7373 if (swiper.params.loop) {
7374 swiper.slideToLoop(parseInt(slideEl.getAttribute('data-swiper-slide-index')), 0);
7375 } else {
7376 swiper.slideTo(swiper.slides.indexOf(slideEl), 0);
7377 }
7378 preventFocusHandler = false;
7379 });
7380 };
7381 const initSlides = () => {
7382 const params = swiper.params.a11y;
7383 if (params.itemRoleDescriptionMessage) {
7384 addElRoleDescription(swiper.slides, params.itemRoleDescriptionMessage);
7385 }
7386 if (params.slideRole) {
7387 addElRole(swiper.slides, params.slideRole);
7388 }
7389 const slidesLength = swiper.slides.length;
7390 if (params.slideLabelMessage) {
7391 swiper.slides.forEach((slideEl, index) => {
7392 const slideIndex = swiper.params.loop ? parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10) : index;
7393 const ariaLabelMessage = params.slideLabelMessage.replace(/\{\{index\}\}/, slideIndex + 1).replace(/\{\{slidesLength\}\}/, slidesLength);
7394 addElLabel(slideEl, ariaLabelMessage);
7395 });
7396 }
7397 };
7398 const init = () => {
7399 const params = swiper.params.a11y;
7400 swiper.el.append(liveRegion);
7401
7402 // Container
7403 const containerEl = swiper.el;
7404 if (params.containerRoleDescriptionMessage) {
7405 addElRoleDescription(containerEl, params.containerRoleDescriptionMessage);
7406 }
7407 if (params.containerMessage) {
7408 addElLabel(containerEl, params.containerMessage);
7409 }
7410
7411 // Wrapper
7412 const wrapperEl = swiper.wrapperEl;
7413 const wrapperId = params.id || wrapperEl.getAttribute('id') || `swiper-wrapper-${getRandomNumber(16)}`;
7414 const live = swiper.params.autoplay && swiper.params.autoplay.enabled ? 'off' : 'polite';
7415 addElId(wrapperEl, wrapperId);
7416 addElLive(wrapperEl, live);
7417
7418 // Slide
7419 initSlides();
7420
7421 // Navigation
7422 let {
7423 nextEl,
7424 prevEl
7425 } = swiper.navigation ? swiper.navigation : {};
7426 nextEl = makeElementsArray(nextEl);
7427 prevEl = makeElementsArray(prevEl);
7428 if (nextEl) {
7429 nextEl.forEach(el => initNavEl(el, wrapperId, params.nextSlideMessage));
7430 }
7431 if (prevEl) {
7432 prevEl.forEach(el => initNavEl(el, wrapperId, params.prevSlideMessage));
7433 }
7434
7435 // Pagination
7436 if (hasClickablePagination()) {
7437 const paginationEl = makeElementsArray(swiper.pagination.el);
7438 paginationEl.forEach(el => {
7439 el.addEventListener('keydown', onEnterOrSpaceKey);
7440 });
7441 }
7442
7443 // Tab focus
7444 const document = getDocument();
7445 document.addEventListener('visibilitychange', onVisibilityChange);
7446 swiper.el.addEventListener('focus', handleFocus, true);
7447 swiper.el.addEventListener('focus', handleFocus, true);
7448 swiper.el.addEventListener('pointerdown', handlePointerDown, true);
7449 swiper.el.addEventListener('pointerup', handlePointerUp, true);
7450 };
7451 function destroy() {
7452 if (liveRegion) liveRegion.remove();
7453 let {
7454 nextEl,
7455 prevEl
7456 } = swiper.navigation ? swiper.navigation : {};
7457 nextEl = makeElementsArray(nextEl);
7458 prevEl = makeElementsArray(prevEl);
7459 if (nextEl) {
7460 nextEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey));
7461 }
7462 if (prevEl) {
7463 prevEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey));
7464 }
7465
7466 // Pagination
7467 if (hasClickablePagination()) {
7468 const paginationEl = makeElementsArray(swiper.pagination.el);
7469 paginationEl.forEach(el => {
7470 el.removeEventListener('keydown', onEnterOrSpaceKey);
7471 });
7472 }
7473 const document = getDocument();
7474 document.removeEventListener('visibilitychange', onVisibilityChange);
7475 // Tab focus
7476 if (swiper.el && typeof swiper.el !== 'string') {
7477 swiper.el.removeEventListener('focus', handleFocus, true);
7478 swiper.el.removeEventListener('pointerdown', handlePointerDown, true);
7479 swiper.el.removeEventListener('pointerup', handlePointerUp, true);
7480 }
7481 }
7482 on('beforeInit', () => {
7483 liveRegion = createElement('span', swiper.params.a11y.notificationClass);
7484 liveRegion.setAttribute('aria-live', 'assertive');
7485 liveRegion.setAttribute('aria-atomic', 'true');
7486 });
7487 on('afterInit', () => {
7488 if (!swiper.params.a11y.enabled) return;
7489 init();
7490 });
7491 on('slidesLengthChange snapGridLengthChange slidesGridLengthChange', () => {
7492 if (!swiper.params.a11y.enabled) return;
7493 initSlides();
7494 });
7495 on('fromEdge toEdge afterInit lock unlock', () => {
7496 if (!swiper.params.a11y.enabled) return;
7497 updateNavigation();
7498 });
7499 on('paginationUpdate', () => {
7500 if (!swiper.params.a11y.enabled) return;
7501 updatePagination();
7502 });
7503 on('destroy', () => {
7504 if (!swiper.params.a11y.enabled) return;
7505 destroy();
7506 });
7507 }
7508
7509 function History(_ref) {
7510 let {
7511 swiper,
7512 extendParams,
7513 on
7514 } = _ref;
7515 extendParams({
7516 history: {
7517 enabled: false,
7518 root: '',
7519 replaceState: false,
7520 key: 'slides',
7521 keepQuery: false
7522 }
7523 });
7524 let initialized = false;
7525 let paths = {};
7526 const slugify = text => {
7527 return text.toString().replace(/\s+/g, '-').replace(/[^\w-]+/g, '').replace(/--+/g, '-').replace(/^-+/, '').replace(/-+$/, '');
7528 };
7529 const getPathValues = urlOverride => {
7530 const window = getWindow();
7531 let location;
7532 if (urlOverride) {
7533 location = new URL(urlOverride);
7534 } else {
7535 location = window.location;
7536 }
7537 const pathArray = location.pathname.slice(1).split('/').filter(part => part !== '');
7538 const total = pathArray.length;
7539 const key = pathArray[total - 2];
7540 const value = pathArray[total - 1];
7541 return {
7542 key,
7543 value
7544 };
7545 };
7546 const setHistory = (key, index) => {
7547 const window = getWindow();
7548 if (!initialized || !swiper.params.history.enabled) return;
7549 let location;
7550 if (swiper.params.url) {
7551 location = new URL(swiper.params.url);
7552 } else {
7553 location = window.location;
7554 }
7555 const slide = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${index}"]`) : swiper.slides[index];
7556 let value = slugify(slide.getAttribute('data-history'));
7557 if (swiper.params.history.root.length > 0) {
7558 let root = swiper.params.history.root;
7559 if (root[root.length - 1] === '/') root = root.slice(0, root.length - 1);
7560 value = `${root}/${key ? `${key}/` : ''}${value}`;
7561 } else if (!location.pathname.includes(key)) {
7562 value = `${key ? `${key}/` : ''}${value}`;
7563 }
7564 if (swiper.params.history.keepQuery) {
7565 value += location.search;
7566 }
7567 const currentState = window.history.state;
7568 if (currentState && currentState.value === value) {
7569 return;
7570 }
7571 if (swiper.params.history.replaceState) {
7572 window.history.replaceState({
7573 value
7574 }, null, value);
7575 } else {
7576 window.history.pushState({
7577 value
7578 }, null, value);
7579 }
7580 };
7581 const scrollToSlide = (speed, value, runCallbacks) => {
7582 if (value) {
7583 for (let i = 0, length = swiper.slides.length; i < length; i += 1) {
7584 const slide = swiper.slides[i];
7585 const slideHistory = slugify(slide.getAttribute('data-history'));
7586 if (slideHistory === value) {
7587 const index = swiper.getSlideIndex(slide);
7588 swiper.slideTo(index, speed, runCallbacks);
7589 }
7590 }
7591 } else {
7592 swiper.slideTo(0, speed, runCallbacks);
7593 }
7594 };
7595 const setHistoryPopState = () => {
7596 paths = getPathValues(swiper.params.url);
7597 scrollToSlide(swiper.params.speed, paths.value, false);
7598 };
7599 const init = () => {
7600 const window = getWindow();
7601 if (!swiper.params.history) return;
7602 if (!window.history || !window.history.pushState) {
7603 swiper.params.history.enabled = false;
7604 swiper.params.hashNavigation.enabled = true;
7605 return;
7606 }
7607 initialized = true;
7608 paths = getPathValues(swiper.params.url);
7609 if (!paths.key && !paths.value) {
7610 if (!swiper.params.history.replaceState) {
7611 window.addEventListener('popstate', setHistoryPopState);
7612 }
7613 return;
7614 }
7615 scrollToSlide(0, paths.value, swiper.params.runCallbacksOnInit);
7616 if (!swiper.params.history.replaceState) {
7617 window.addEventListener('popstate', setHistoryPopState);
7618 }
7619 };
7620 const destroy = () => {
7621 const window = getWindow();
7622 if (!swiper.params.history.replaceState) {
7623 window.removeEventListener('popstate', setHistoryPopState);
7624 }
7625 };
7626 on('init', () => {
7627 if (swiper.params.history.enabled) {
7628 init();
7629 }
7630 });
7631 on('destroy', () => {
7632 if (swiper.params.history.enabled) {
7633 destroy();
7634 }
7635 });
7636 on('transitionEnd _freeModeNoMomentumRelease', () => {
7637 if (initialized) {
7638 setHistory(swiper.params.history.key, swiper.activeIndex);
7639 }
7640 });
7641 on('slideChange', () => {
7642 if (initialized && swiper.params.cssMode) {
7643 setHistory(swiper.params.history.key, swiper.activeIndex);
7644 }
7645 });
7646 }
7647
7648 function HashNavigation(_ref) {
7649 let {
7650 swiper,
7651 extendParams,
7652 emit,
7653 on
7654 } = _ref;
7655 let initialized = false;
7656 const document = getDocument();
7657 const window = getWindow();
7658 extendParams({
7659 hashNavigation: {
7660 enabled: false,
7661 replaceState: false,
7662 watchState: false,
7663 getSlideIndex(_s, hash) {
7664 if (swiper.virtual && swiper.params.virtual.enabled) {
7665 const slideWithHash = swiper.slides.filter(slideEl => slideEl.getAttribute('data-hash') === hash)[0];
7666 if (!slideWithHash) return 0;
7667 const index = parseInt(slideWithHash.getAttribute('data-swiper-slide-index'), 10);
7668 return index;
7669 }
7670 return swiper.getSlideIndex(elementChildren(swiper.slidesEl, `.${swiper.params.slideClass}[data-hash="${hash}"], swiper-slide[data-hash="${hash}"]`)[0]);
7671 }
7672 }
7673 });
7674 const onHashChange = () => {
7675 emit('hashChange');
7676 const newHash = document.location.hash.replace('#', '');
7677 const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex];
7678 const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') : '';
7679 if (newHash !== activeSlideHash) {
7680 const newIndex = swiper.params.hashNavigation.getSlideIndex(swiper, newHash);
7681 if (typeof newIndex === 'undefined' || Number.isNaN(newIndex)) return;
7682 swiper.slideTo(newIndex);
7683 }
7684 };
7685 const setHash = () => {
7686 if (!initialized || !swiper.params.hashNavigation.enabled) return;
7687 const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex];
7688 const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') || activeSlideEl.getAttribute('data-history') : '';
7689 if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) {
7690 window.history.replaceState(null, null, `#${activeSlideHash}` || '');
7691 emit('hashSet');
7692 } else {
7693 document.location.hash = activeSlideHash || '';
7694 emit('hashSet');
7695 }
7696 };
7697 const init = () => {
7698 if (!swiper.params.hashNavigation.enabled || swiper.params.history && swiper.params.history.enabled) return;
7699 initialized = true;
7700 const hash = document.location.hash.replace('#', '');
7701 if (hash) {
7702 const speed = 0;
7703 const index = swiper.params.hashNavigation.getSlideIndex(swiper, hash);
7704 swiper.slideTo(index || 0, speed, swiper.params.runCallbacksOnInit, true);
7705 }
7706 if (swiper.params.hashNavigation.watchState) {
7707 window.addEventListener('hashchange', onHashChange);
7708 }
7709 };
7710 const destroy = () => {
7711 if (swiper.params.hashNavigation.watchState) {
7712 window.removeEventListener('hashchange', onHashChange);
7713 }
7714 };
7715 on('init', () => {
7716 if (swiper.params.hashNavigation.enabled) {
7717 init();
7718 }
7719 });
7720 on('destroy', () => {
7721 if (swiper.params.hashNavigation.enabled) {
7722 destroy();
7723 }
7724 });
7725 on('transitionEnd _freeModeNoMomentumRelease', () => {
7726 if (initialized) {
7727 setHash();
7728 }
7729 });
7730 on('slideChange', () => {
7731 if (initialized && swiper.params.cssMode) {
7732 setHash();
7733 }
7734 });
7735 }
7736
7737 /* eslint no-underscore-dangle: "off" */
7738 /* eslint no-use-before-define: "off" */
7739 function Autoplay(_ref) {
7740 let {
7741 swiper,
7742 extendParams,
7743 on,
7744 emit,
7745 params
7746 } = _ref;
7747 swiper.autoplay = {
7748 running: false,
7749 paused: false,
7750 timeLeft: 0
7751 };
7752 extendParams({
7753 autoplay: {
7754 enabled: false,
7755 delay: 3000,
7756 waitForTransition: true,
7757 disableOnInteraction: false,
7758 stopOnLastSlide: false,
7759 reverseDirection: false,
7760 pauseOnMouseEnter: false
7761 }
7762 });
7763 let timeout;
7764 let raf;
7765 let autoplayDelayTotal = params && params.autoplay ? params.autoplay.delay : 3000;
7766 let autoplayDelayCurrent = params && params.autoplay ? params.autoplay.delay : 3000;
7767 let autoplayTimeLeft;
7768 let autoplayStartTime = new Date().getTime();
7769 let wasPaused;
7770 let isTouched;
7771 let pausedByTouch;
7772 let touchStartTimeout;
7773 let slideChanged;
7774 let pausedByInteraction;
7775 let pausedByPointerEnter;
7776 function onTransitionEnd(e) {
7777 if (!swiper || swiper.destroyed || !swiper.wrapperEl) return;
7778 if (e.target !== swiper.wrapperEl) return;
7779 swiper.wrapperEl.removeEventListener('transitionend', onTransitionEnd);
7780 if (pausedByPointerEnter || e.detail && e.detail.bySwiperTouchMove) {
7781 return;
7782 }
7783 resume();
7784 }
7785 const calcTimeLeft = () => {
7786 if (swiper.destroyed || !swiper.autoplay.running) return;
7787 if (swiper.autoplay.paused) {
7788 wasPaused = true;
7789 } else if (wasPaused) {
7790 autoplayDelayCurrent = autoplayTimeLeft;
7791 wasPaused = false;
7792 }
7793 const timeLeft = swiper.autoplay.paused ? autoplayTimeLeft : autoplayStartTime + autoplayDelayCurrent - new Date().getTime();
7794 swiper.autoplay.timeLeft = timeLeft;
7795 emit('autoplayTimeLeft', timeLeft, timeLeft / autoplayDelayTotal);
7796 raf = requestAnimationFrame(() => {
7797 calcTimeLeft();
7798 });
7799 };
7800 const getSlideDelay = () => {
7801 let activeSlideEl;
7802 if (swiper.virtual && swiper.params.virtual.enabled) {
7803 activeSlideEl = swiper.slides.filter(slideEl => slideEl.classList.contains('swiper-slide-active'))[0];
7804 } else {
7805 activeSlideEl = swiper.slides[swiper.activeIndex];
7806 }
7807 if (!activeSlideEl) return undefined;
7808 const currentSlideDelay = parseInt(activeSlideEl.getAttribute('data-swiper-autoplay'), 10);
7809 return currentSlideDelay;
7810 };
7811 const run = delayForce => {
7812 if (swiper.destroyed || !swiper.autoplay.running) return;
7813 cancelAnimationFrame(raf);
7814 calcTimeLeft();
7815 let delay = typeof delayForce === 'undefined' ? swiper.params.autoplay.delay : delayForce;
7816 autoplayDelayTotal = swiper.params.autoplay.delay;
7817 autoplayDelayCurrent = swiper.params.autoplay.delay;
7818 const currentSlideDelay = getSlideDelay();
7819 if (!Number.isNaN(currentSlideDelay) && currentSlideDelay > 0 && typeof delayForce === 'undefined') {
7820 delay = currentSlideDelay;
7821 autoplayDelayTotal = currentSlideDelay;
7822 autoplayDelayCurrent = currentSlideDelay;
7823 }
7824 autoplayTimeLeft = delay;
7825 const speed = swiper.params.speed;
7826 const proceed = () => {
7827 if (!swiper || swiper.destroyed) return;
7828 if (swiper.params.autoplay.reverseDirection) {
7829 if (!swiper.isBeginning || swiper.params.loop || swiper.params.rewind) {
7830 swiper.slidePrev(speed, true, true);
7831 emit('autoplay');
7832 } else if (!swiper.params.autoplay.stopOnLastSlide) {
7833 swiper.slideTo(swiper.slides.length - 1, speed, true, true);
7834 emit('autoplay');
7835 }
7836 } else {
7837 if (!swiper.isEnd || swiper.params.loop || swiper.params.rewind) {
7838 swiper.slideNext(speed, true, true);
7839 emit('autoplay');
7840 } else if (!swiper.params.autoplay.stopOnLastSlide) {
7841 swiper.slideTo(0, speed, true, true);
7842 emit('autoplay');
7843 }
7844 }
7845 if (swiper.params.cssMode) {
7846 autoplayStartTime = new Date().getTime();
7847 requestAnimationFrame(() => {
7848 run();
7849 });
7850 }
7851 };
7852 if (delay > 0) {
7853 clearTimeout(timeout);
7854 timeout = setTimeout(() => {
7855 proceed();
7856 }, delay);
7857 } else {
7858 requestAnimationFrame(() => {
7859 proceed();
7860 });
7861 }
7862
7863 // eslint-disable-next-line
7864 return delay;
7865 };
7866 const start = () => {
7867 autoplayStartTime = new Date().getTime();
7868 swiper.autoplay.running = true;
7869 run();
7870 emit('autoplayStart');
7871 };
7872 const stop = () => {
7873 swiper.autoplay.running = false;
7874 clearTimeout(timeout);
7875 cancelAnimationFrame(raf);
7876 emit('autoplayStop');
7877 };
7878 const pause = (internal, reset) => {
7879 if (swiper.destroyed || !swiper.autoplay.running) return;
7880 clearTimeout(timeout);
7881 if (!internal) {
7882 pausedByInteraction = true;
7883 }
7884 const proceed = () => {
7885 emit('autoplayPause');
7886 if (swiper.params.autoplay.waitForTransition) {
7887 swiper.wrapperEl.addEventListener('transitionend', onTransitionEnd);
7888 } else {
7889 resume();
7890 }
7891 };
7892 swiper.autoplay.paused = true;
7893 if (reset) {
7894 if (slideChanged) {
7895 autoplayTimeLeft = swiper.params.autoplay.delay;
7896 }
7897 slideChanged = false;
7898 proceed();
7899 return;
7900 }
7901 const delay = autoplayTimeLeft || swiper.params.autoplay.delay;
7902 autoplayTimeLeft = delay - (new Date().getTime() - autoplayStartTime);
7903 if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop) return;
7904 if (autoplayTimeLeft < 0) autoplayTimeLeft = 0;
7905 proceed();
7906 };
7907 const resume = () => {
7908 if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop || swiper.destroyed || !swiper.autoplay.running) return;
7909 autoplayStartTime = new Date().getTime();
7910 if (pausedByInteraction) {
7911 pausedByInteraction = false;
7912 run(autoplayTimeLeft);
7913 } else {
7914 run();
7915 }
7916 swiper.autoplay.paused = false;
7917 emit('autoplayResume');
7918 };
7919 const onVisibilityChange = () => {
7920 if (swiper.destroyed || !swiper.autoplay.running) return;
7921 const document = getDocument();
7922 if (document.visibilityState === 'hidden') {
7923 pausedByInteraction = true;
7924 pause(true);
7925 }
7926 if (document.visibilityState === 'visible') {
7927 resume();
7928 }
7929 };
7930 const onPointerEnter = e => {
7931 if (e.pointerType !== 'mouse') return;
7932 pausedByInteraction = true;
7933 pausedByPointerEnter = true;
7934 if (swiper.animating || swiper.autoplay.paused) return;
7935 pause(true);
7936 };
7937 const onPointerLeave = e => {
7938 if (e.pointerType !== 'mouse') return;
7939 pausedByPointerEnter = false;
7940 if (swiper.autoplay.paused) {
7941 resume();
7942 }
7943 };
7944 const attachMouseEvents = () => {
7945 if (swiper.params.autoplay.pauseOnMouseEnter) {
7946 swiper.el.addEventListener('pointerenter', onPointerEnter);
7947 swiper.el.addEventListener('pointerleave', onPointerLeave);
7948 }
7949 };
7950 const detachMouseEvents = () => {
7951 if (swiper.el && typeof swiper.el !== 'string') {
7952 swiper.el.removeEventListener('pointerenter', onPointerEnter);
7953 swiper.el.removeEventListener('pointerleave', onPointerLeave);
7954 }
7955 };
7956 const attachDocumentEvents = () => {
7957 const document = getDocument();
7958 document.addEventListener('visibilitychange', onVisibilityChange);
7959 };
7960 const detachDocumentEvents = () => {
7961 const document = getDocument();
7962 document.removeEventListener('visibilitychange', onVisibilityChange);
7963 };
7964 on('init', () => {
7965 if (swiper.params.autoplay.enabled) {
7966 attachMouseEvents();
7967 attachDocumentEvents();
7968 start();
7969 }
7970 });
7971 on('destroy', () => {
7972 detachMouseEvents();
7973 detachDocumentEvents();
7974 if (swiper.autoplay.running) {
7975 stop();
7976 }
7977 });
7978 on('_freeModeStaticRelease', () => {
7979 if (pausedByTouch || pausedByInteraction) {
7980 resume();
7981 }
7982 });
7983 on('_freeModeNoMomentumRelease', () => {
7984 if (!swiper.params.autoplay.disableOnInteraction) {
7985 pause(true, true);
7986 } else {
7987 stop();
7988 }
7989 });
7990 on('beforeTransitionStart', (_s, speed, internal) => {
7991 if (swiper.destroyed || !swiper.autoplay.running) return;
7992 if (internal || !swiper.params.autoplay.disableOnInteraction) {
7993 pause(true, true);
7994 } else {
7995 stop();
7996 }
7997 });
7998 on('sliderFirstMove', () => {
7999 if (swiper.destroyed || !swiper.autoplay.running) return;
8000 if (swiper.params.autoplay.disableOnInteraction) {
8001 stop();
8002 return;
8003 }
8004 isTouched = true;
8005 pausedByTouch = false;
8006 pausedByInteraction = false;
8007 touchStartTimeout = setTimeout(() => {
8008 pausedByInteraction = true;
8009 pausedByTouch = true;
8010 pause(true);
8011 }, 200);
8012 });
8013 on('touchEnd', () => {
8014 if (swiper.destroyed || !swiper.autoplay.running || !isTouched) return;
8015 clearTimeout(touchStartTimeout);
8016 clearTimeout(timeout);
8017 if (swiper.params.autoplay.disableOnInteraction) {
8018 pausedByTouch = false;
8019 isTouched = false;
8020 return;
8021 }
8022 if (pausedByTouch && swiper.params.cssMode) resume();
8023 pausedByTouch = false;
8024 isTouched = false;
8025 });
8026 on('slideChange', () => {
8027 if (swiper.destroyed || !swiper.autoplay.running) return;
8028 slideChanged = true;
8029 });
8030 Object.assign(swiper.autoplay, {
8031 start,
8032 stop,
8033 pause,
8034 resume
8035 });
8036 }
8037
8038 function Thumb(_ref) {
8039 let {
8040 swiper,
8041 extendParams,
8042 on
8043 } = _ref;
8044 extendParams({
8045 thumbs: {
8046 swiper: null,
8047 multipleActiveThumbs: true,
8048 autoScrollOffset: 0,
8049 slideThumbActiveClass: 'swiper-slide-thumb-active',
8050 thumbsContainerClass: 'swiper-thumbs'
8051 }
8052 });
8053 let initialized = false;
8054 let swiperCreated = false;
8055 swiper.thumbs = {
8056 swiper: null
8057 };
8058 function onThumbClick() {
8059 const thumbsSwiper = swiper.thumbs.swiper;
8060 if (!thumbsSwiper || thumbsSwiper.destroyed) return;
8061 const clickedIndex = thumbsSwiper.clickedIndex;
8062 const clickedSlide = thumbsSwiper.clickedSlide;
8063 if (clickedSlide && clickedSlide.classList.contains(swiper.params.thumbs.slideThumbActiveClass)) return;
8064 if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;
8065 let slideToIndex;
8066 if (thumbsSwiper.params.loop) {
8067 slideToIndex = parseInt(thumbsSwiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
8068 } else {
8069 slideToIndex = clickedIndex;
8070 }
8071 if (swiper.params.loop) {
8072 swiper.slideToLoop(slideToIndex);
8073 } else {
8074 swiper.slideTo(slideToIndex);
8075 }
8076 }
8077 function init() {
8078 const {
8079 thumbs: thumbsParams
8080 } = swiper.params;
8081 if (initialized) return false;
8082 initialized = true;
8083 const SwiperClass = swiper.constructor;
8084 if (thumbsParams.swiper instanceof SwiperClass) {
8085 swiper.thumbs.swiper = thumbsParams.swiper;
8086 Object.assign(swiper.thumbs.swiper.originalParams, {
8087 watchSlidesProgress: true,
8088 slideToClickedSlide: false
8089 });
8090 Object.assign(swiper.thumbs.swiper.params, {
8091 watchSlidesProgress: true,
8092 slideToClickedSlide: false
8093 });
8094 swiper.thumbs.swiper.update();
8095 } else if (isObject(thumbsParams.swiper)) {
8096 const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);
8097 Object.assign(thumbsSwiperParams, {
8098 watchSlidesProgress: true,
8099 slideToClickedSlide: false
8100 });
8101 swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);
8102 swiperCreated = true;
8103 }
8104 swiper.thumbs.swiper.el.classList.add(swiper.params.thumbs.thumbsContainerClass);
8105 swiper.thumbs.swiper.on('tap', onThumbClick);
8106 return true;
8107 }
8108 function update(initial) {
8109 const thumbsSwiper = swiper.thumbs.swiper;
8110 if (!thumbsSwiper || thumbsSwiper.destroyed) return;
8111 const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView;
8112
8113 // Activate thumbs
8114 let thumbsToActivate = 1;
8115 const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
8116 if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
8117 thumbsToActivate = swiper.params.slidesPerView;
8118 }
8119 if (!swiper.params.thumbs.multipleActiveThumbs) {
8120 thumbsToActivate = 1;
8121 }
8122 thumbsToActivate = Math.floor(thumbsToActivate);
8123 thumbsSwiper.slides.forEach(slideEl => slideEl.classList.remove(thumbActiveClass));
8124 if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) {
8125 for (let i = 0; i < thumbsToActivate; i += 1) {
8126 elementChildren(thumbsSwiper.slidesEl, `[data-swiper-slide-index="${swiper.realIndex + i}"]`).forEach(slideEl => {
8127 slideEl.classList.add(thumbActiveClass);
8128 });
8129 }
8130 } else {
8131 for (let i = 0; i < thumbsToActivate; i += 1) {
8132 if (thumbsSwiper.slides[swiper.realIndex + i]) {
8133 thumbsSwiper.slides[swiper.realIndex + i].classList.add(thumbActiveClass);
8134 }
8135 }
8136 }
8137 const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
8138 const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
8139 if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
8140 const currentThumbsIndex = thumbsSwiper.activeIndex;
8141 let newThumbsIndex;
8142 let direction;
8143 if (thumbsSwiper.params.loop) {
8144 const newThumbsSlide = thumbsSwiper.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') === `${swiper.realIndex}`)[0];
8145 newThumbsIndex = thumbsSwiper.slides.indexOf(newThumbsSlide);
8146 direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
8147 } else {
8148 newThumbsIndex = swiper.realIndex;
8149 direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
8150 }
8151 if (useOffset) {
8152 newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
8153 }
8154 if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {
8155 if (thumbsSwiper.params.centeredSlides) {
8156 if (newThumbsIndex > currentThumbsIndex) {
8157 newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
8158 } else {
8159 newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
8160 }
8161 } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1) ;
8162 thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
8163 }
8164 }
8165 }
8166 on('beforeInit', () => {
8167 const {
8168 thumbs
8169 } = swiper.params;
8170 if (!thumbs || !thumbs.swiper) return;
8171 if (typeof thumbs.swiper === 'string' || thumbs.swiper instanceof HTMLElement) {
8172 const document = getDocument();
8173 const getThumbsElementAndInit = () => {
8174 const thumbsElement = typeof thumbs.swiper === 'string' ? document.querySelector(thumbs.swiper) : thumbs.swiper;
8175 if (thumbsElement && thumbsElement.swiper) {
8176 thumbs.swiper = thumbsElement.swiper;
8177 init();
8178 update(true);
8179 } else if (thumbsElement) {
8180 const onThumbsSwiper = e => {
8181 thumbs.swiper = e.detail[0];
8182 thumbsElement.removeEventListener('init', onThumbsSwiper);
8183 init();
8184 update(true);
8185 thumbs.swiper.update();
8186 swiper.update();
8187 };
8188 thumbsElement.addEventListener('init', onThumbsSwiper);
8189 }
8190 return thumbsElement;
8191 };
8192 const watchForThumbsToAppear = () => {
8193 if (swiper.destroyed) return;
8194 const thumbsElement = getThumbsElementAndInit();
8195 if (!thumbsElement) {
8196 requestAnimationFrame(watchForThumbsToAppear);
8197 }
8198 };
8199 requestAnimationFrame(watchForThumbsToAppear);
8200 } else {
8201 init();
8202 update(true);
8203 }
8204 });
8205 on('slideChange update resize observerUpdate', () => {
8206 update();
8207 });
8208 on('setTransition', (_s, duration) => {
8209 const thumbsSwiper = swiper.thumbs.swiper;
8210 if (!thumbsSwiper || thumbsSwiper.destroyed) return;
8211 thumbsSwiper.setTransition(duration);
8212 });
8213 on('beforeDestroy', () => {
8214 const thumbsSwiper = swiper.thumbs.swiper;
8215 if (!thumbsSwiper || thumbsSwiper.destroyed) return;
8216 if (swiperCreated) {
8217 thumbsSwiper.destroy();
8218 }
8219 });
8220 Object.assign(swiper.thumbs, {
8221 init,
8222 update
8223 });
8224 }
8225
8226 function freeMode(_ref) {
8227 let {
8228 swiper,
8229 extendParams,
8230 emit,
8231 once
8232 } = _ref;
8233 extendParams({
8234 freeMode: {
8235 enabled: false,
8236 momentum: true,
8237 momentumRatio: 1,
8238 momentumBounce: true,
8239 momentumBounceRatio: 1,
8240 momentumVelocityRatio: 1,
8241 sticky: false,
8242 minimumVelocity: 0.02
8243 }
8244 });
8245 function onTouchStart() {
8246 if (swiper.params.cssMode) return;
8247 const translate = swiper.getTranslate();
8248 swiper.setTranslate(translate);
8249 swiper.setTransition(0);
8250 swiper.touchEventsData.velocities.length = 0;
8251 swiper.freeMode.onTouchEnd({
8252 currentPos: swiper.rtl ? swiper.translate : -swiper.translate
8253 });
8254 }
8255 function onTouchMove() {
8256 if (swiper.params.cssMode) return;
8257 const {
8258 touchEventsData: data,
8259 touches
8260 } = swiper;
8261 // Velocity
8262 if (data.velocities.length === 0) {
8263 data.velocities.push({
8264 position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],
8265 time: data.touchStartTime
8266 });
8267 }
8268 data.velocities.push({
8269 position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],
8270 time: now()
8271 });
8272 }
8273 function onTouchEnd(_ref2) {
8274 let {
8275 currentPos
8276 } = _ref2;
8277 if (swiper.params.cssMode) return;
8278 const {
8279 params,
8280 wrapperEl,
8281 rtlTranslate: rtl,
8282 snapGrid,
8283 touchEventsData: data
8284 } = swiper;
8285 // Time diff
8286 const touchEndTime = now();
8287 const timeDiff = touchEndTime - data.touchStartTime;
8288 if (currentPos < -swiper.minTranslate()) {
8289 swiper.slideTo(swiper.activeIndex);
8290 return;
8291 }
8292 if (currentPos > -swiper.maxTranslate()) {
8293 if (swiper.slides.length < snapGrid.length) {
8294 swiper.slideTo(snapGrid.length - 1);
8295 } else {
8296 swiper.slideTo(swiper.slides.length - 1);
8297 }
8298 return;
8299 }
8300 if (params.freeMode.momentum) {
8301 if (data.velocities.length > 1) {
8302 const lastMoveEvent = data.velocities.pop();
8303 const velocityEvent = data.velocities.pop();
8304 const distance = lastMoveEvent.position - velocityEvent.position;
8305 const time = lastMoveEvent.time - velocityEvent.time;
8306 swiper.velocity = distance / time;
8307 swiper.velocity /= 2;
8308 if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) {
8309 swiper.velocity = 0;
8310 }
8311 // this implies that the user stopped moving a finger then released.
8312 // There would be no events with distance zero, so the last event is stale.
8313 if (time > 150 || now() - lastMoveEvent.time > 300) {
8314 swiper.velocity = 0;
8315 }
8316 } else {
8317 swiper.velocity = 0;
8318 }
8319 swiper.velocity *= params.freeMode.momentumVelocityRatio;
8320 data.velocities.length = 0;
8321 let momentumDuration = 1000 * params.freeMode.momentumRatio;
8322 const momentumDistance = swiper.velocity * momentumDuration;
8323 let newPosition = swiper.translate + momentumDistance;
8324 if (rtl) newPosition = -newPosition;
8325 let doBounce = false;
8326 let afterBouncePosition;
8327 const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio;
8328 let needsLoopFix;
8329 if (newPosition < swiper.maxTranslate()) {
8330 if (params.freeMode.momentumBounce) {
8331 if (newPosition + swiper.maxTranslate() < -bounceAmount) {
8332 newPosition = swiper.maxTranslate() - bounceAmount;
8333 }
8334 afterBouncePosition = swiper.maxTranslate();
8335 doBounce = true;
8336 data.allowMomentumBounce = true;
8337 } else {
8338 newPosition = swiper.maxTranslate();
8339 }
8340 if (params.loop && params.centeredSlides) needsLoopFix = true;
8341 } else if (newPosition > swiper.minTranslate()) {
8342 if (params.freeMode.momentumBounce) {
8343 if (newPosition - swiper.minTranslate() > bounceAmount) {
8344 newPosition = swiper.minTranslate() + bounceAmount;
8345 }
8346 afterBouncePosition = swiper.minTranslate();
8347 doBounce = true;
8348 data.allowMomentumBounce = true;
8349 } else {
8350 newPosition = swiper.minTranslate();
8351 }
8352 if (params.loop && params.centeredSlides) needsLoopFix = true;
8353 } else if (params.freeMode.sticky) {
8354 let nextSlide;
8355 for (let j = 0; j < snapGrid.length; j += 1) {
8356 if (snapGrid[j] > -newPosition) {
8357 nextSlide = j;
8358 break;
8359 }
8360 }
8361 if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') {
8362 newPosition = snapGrid[nextSlide];
8363 } else {
8364 newPosition = snapGrid[nextSlide - 1];
8365 }
8366 newPosition = -newPosition;
8367 }
8368 if (needsLoopFix) {
8369 once('transitionEnd', () => {
8370 swiper.loopFix();
8371 });
8372 }
8373 // Fix duration
8374 if (swiper.velocity !== 0) {
8375 if (rtl) {
8376 momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);
8377 } else {
8378 momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);
8379 }
8380 if (params.freeMode.sticky) {
8381 // If freeMode.sticky is active and the user ends a swipe with a slow-velocity
8382 // event, then durations can be 20+ seconds to slide one (or zero!) slides.
8383 // It's easy to see this when simulating touch with mouse events. To fix this,
8384 // limit single-slide swipes to the default slide duration. This also has the
8385 // nice side effect of matching slide speed if the user stopped moving before
8386 // lifting finger or mouse vs. moving slowly before lifting the finger/mouse.
8387 // For faster swipes, also apply limits (albeit higher ones).
8388 const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);
8389 const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];
8390 if (moveDistance < currentSlideSize) {
8391 momentumDuration = params.speed;
8392 } else if (moveDistance < 2 * currentSlideSize) {
8393 momentumDuration = params.speed * 1.5;
8394 } else {
8395 momentumDuration = params.speed * 2.5;
8396 }
8397 }
8398 } else if (params.freeMode.sticky) {
8399 swiper.slideToClosest();
8400 return;
8401 }
8402 if (params.freeMode.momentumBounce && doBounce) {
8403 swiper.updateProgress(afterBouncePosition);
8404 swiper.setTransition(momentumDuration);
8405 swiper.setTranslate(newPosition);
8406 swiper.transitionStart(true, swiper.swipeDirection);
8407 swiper.animating = true;
8408 elementTransitionEnd(wrapperEl, () => {
8409 if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;
8410 emit('momentumBounce');
8411 swiper.setTransition(params.speed);
8412 setTimeout(() => {
8413 swiper.setTranslate(afterBouncePosition);
8414 elementTransitionEnd(wrapperEl, () => {
8415 if (!swiper || swiper.destroyed) return;
8416 swiper.transitionEnd();
8417 });
8418 }, 0);
8419 });
8420 } else if (swiper.velocity) {
8421 emit('_freeModeNoMomentumRelease');
8422 swiper.updateProgress(newPosition);
8423 swiper.setTransition(momentumDuration);
8424 swiper.setTranslate(newPosition);
8425 swiper.transitionStart(true, swiper.swipeDirection);
8426 if (!swiper.animating) {
8427 swiper.animating = true;
8428 elementTransitionEnd(wrapperEl, () => {
8429 if (!swiper || swiper.destroyed) return;
8430 swiper.transitionEnd();
8431 });
8432 }
8433 } else {
8434 swiper.updateProgress(newPosition);
8435 }
8436 swiper.updateActiveIndex();
8437 swiper.updateSlidesClasses();
8438 } else if (params.freeMode.sticky) {
8439 swiper.slideToClosest();
8440 return;
8441 } else if (params.freeMode) {
8442 emit('_freeModeNoMomentumRelease');
8443 }
8444 if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) {
8445 emit('_freeModeStaticRelease');
8446 swiper.updateProgress();
8447 swiper.updateActiveIndex();
8448 swiper.updateSlidesClasses();
8449 }
8450 }
8451 Object.assign(swiper, {
8452 freeMode: {
8453 onTouchStart,
8454 onTouchMove,
8455 onTouchEnd
8456 }
8457 });
8458 }
8459
8460 function Grid(_ref) {
8461 let {
8462 swiper,
8463 extendParams,
8464 on
8465 } = _ref;
8466 extendParams({
8467 grid: {
8468 rows: 1,
8469 fill: 'column'
8470 }
8471 });
8472 let slidesNumberEvenToRows;
8473 let slidesPerRow;
8474 let numFullColumns;
8475 let wasMultiRow;
8476 const getSpaceBetween = () => {
8477 let spaceBetween = swiper.params.spaceBetween;
8478 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
8479 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
8480 } else if (typeof spaceBetween === 'string') {
8481 spaceBetween = parseFloat(spaceBetween);
8482 }
8483 return spaceBetween;
8484 };
8485 const initSlides = slides => {
8486 const {
8487 slidesPerView
8488 } = swiper.params;
8489 const {
8490 rows,
8491 fill
8492 } = swiper.params.grid;
8493 const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : slides.length;
8494 numFullColumns = Math.floor(slidesLength / rows);
8495 if (Math.floor(slidesLength / rows) === slidesLength / rows) {
8496 slidesNumberEvenToRows = slidesLength;
8497 } else {
8498 slidesNumberEvenToRows = Math.ceil(slidesLength / rows) * rows;
8499 }
8500 if (slidesPerView !== 'auto' && fill === 'row') {
8501 slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, slidesPerView * rows);
8502 }
8503 slidesPerRow = slidesNumberEvenToRows / rows;
8504 };
8505 const unsetSlides = () => {
8506 if (swiper.slides) {
8507 swiper.slides.forEach(slide => {
8508 if (slide.swiperSlideGridSet) {
8509 slide.style.height = '';
8510 slide.style[swiper.getDirectionLabel('margin-top')] = '';
8511 }
8512 });
8513 }
8514 };
8515 const updateSlide = (i, slide, slides) => {
8516 const {
8517 slidesPerGroup
8518 } = swiper.params;
8519 const spaceBetween = getSpaceBetween();
8520 const {
8521 rows,
8522 fill
8523 } = swiper.params.grid;
8524 const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : slides.length;
8525 // Set slides order
8526 let newSlideOrderIndex;
8527 let column;
8528 let row;
8529 if (fill === 'row' && slidesPerGroup > 1) {
8530 const groupIndex = Math.floor(i / (slidesPerGroup * rows));
8531 const slideIndexInGroup = i - rows * slidesPerGroup * groupIndex;
8532 const columnsInGroup = groupIndex === 0 ? slidesPerGroup : Math.min(Math.ceil((slidesLength - groupIndex * rows * slidesPerGroup) / rows), slidesPerGroup);
8533 row = Math.floor(slideIndexInGroup / columnsInGroup);
8534 column = slideIndexInGroup - row * columnsInGroup + groupIndex * slidesPerGroup;
8535 newSlideOrderIndex = column + row * slidesNumberEvenToRows / rows;
8536 slide.style.order = newSlideOrderIndex;
8537 } else if (fill === 'column') {
8538 column = Math.floor(i / rows);
8539 row = i - column * rows;
8540 if (column > numFullColumns || column === numFullColumns && row === rows - 1) {
8541 row += 1;
8542 if (row >= rows) {
8543 row = 0;
8544 column += 1;
8545 }
8546 }
8547 } else {
8548 row = Math.floor(i / slidesPerRow);
8549 column = i - row * slidesPerRow;
8550 }
8551 slide.row = row;
8552 slide.column = column;
8553 slide.style.height = `calc((100% - ${(rows - 1) * spaceBetween}px) / ${rows})`;
8554 slide.style[swiper.getDirectionLabel('margin-top')] = row !== 0 ? spaceBetween && `${spaceBetween}px` : '';
8555 slide.swiperSlideGridSet = true;
8556 };
8557 const updateWrapperSize = (slideSize, snapGrid) => {
8558 const {
8559 centeredSlides,
8560 roundLengths
8561 } = swiper.params;
8562 const spaceBetween = getSpaceBetween();
8563 const {
8564 rows
8565 } = swiper.params.grid;
8566 swiper.virtualSize = (slideSize + spaceBetween) * slidesNumberEvenToRows;
8567 swiper.virtualSize = Math.ceil(swiper.virtualSize / rows) - spaceBetween;
8568 if (!swiper.params.cssMode) {
8569 swiper.wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
8570 }
8571 if (centeredSlides) {
8572 const newSlidesGrid = [];
8573 for (let i = 0; i < snapGrid.length; i += 1) {
8574 let slidesGridItem = snapGrid[i];
8575 if (roundLengths) slidesGridItem = Math.floor(slidesGridItem);
8576 if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem);
8577 }
8578 snapGrid.splice(0, snapGrid.length);
8579 snapGrid.push(...newSlidesGrid);
8580 }
8581 };
8582 const onInit = () => {
8583 wasMultiRow = swiper.params.grid && swiper.params.grid.rows > 1;
8584 };
8585 const onUpdate = () => {
8586 const {
8587 params,
8588 el
8589 } = swiper;
8590 const isMultiRow = params.grid && params.grid.rows > 1;
8591 if (wasMultiRow && !isMultiRow) {
8592 el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
8593 numFullColumns = 1;
8594 swiper.emitContainerClasses();
8595 } else if (!wasMultiRow && isMultiRow) {
8596 el.classList.add(`${params.containerModifierClass}grid`);
8597 if (params.grid.fill === 'column') {
8598 el.classList.add(`${params.containerModifierClass}grid-column`);
8599 }
8600 swiper.emitContainerClasses();
8601 }
8602 wasMultiRow = isMultiRow;
8603 };
8604 on('init', onInit);
8605 on('update', onUpdate);
8606 swiper.grid = {
8607 initSlides,
8608 unsetSlides,
8609 updateSlide,
8610 updateWrapperSize
8611 };
8612 }
8613
8614 function appendSlide(slides) {
8615 const swiper = this;
8616 const {
8617 params,
8618 slidesEl
8619 } = swiper;
8620 if (params.loop) {
8621 swiper.loopDestroy();
8622 }
8623 const appendElement = slideEl => {
8624 if (typeof slideEl === 'string') {
8625 const tempDOM = document.createElement('div');
8626 tempDOM.innerHTML = slideEl;
8627 slidesEl.append(tempDOM.children[0]);
8628 tempDOM.innerHTML = '';
8629 } else {
8630 slidesEl.append(slideEl);
8631 }
8632 };
8633 if (typeof slides === 'object' && 'length' in slides) {
8634 for (let i = 0; i < slides.length; i += 1) {
8635 if (slides[i]) appendElement(slides[i]);
8636 }
8637 } else {
8638 appendElement(slides);
8639 }
8640 swiper.recalcSlides();
8641 if (params.loop) {
8642 swiper.loopCreate();
8643 }
8644 if (!params.observer || swiper.isElement) {
8645 swiper.update();
8646 }
8647 }
8648
8649 function prependSlide(slides) {
8650 const swiper = this;
8651 const {
8652 params,
8653 activeIndex,
8654 slidesEl
8655 } = swiper;
8656 if (params.loop) {
8657 swiper.loopDestroy();
8658 }
8659 let newActiveIndex = activeIndex + 1;
8660 const prependElement = slideEl => {
8661 if (typeof slideEl === 'string') {
8662 const tempDOM = document.createElement('div');
8663 tempDOM.innerHTML = slideEl;
8664 slidesEl.prepend(tempDOM.children[0]);
8665 tempDOM.innerHTML = '';
8666 } else {
8667 slidesEl.prepend(slideEl);
8668 }
8669 };
8670 if (typeof slides === 'object' && 'length' in slides) {
8671 for (let i = 0; i < slides.length; i += 1) {
8672 if (slides[i]) prependElement(slides[i]);
8673 }
8674 newActiveIndex = activeIndex + slides.length;
8675 } else {
8676 prependElement(slides);
8677 }
8678 swiper.recalcSlides();
8679 if (params.loop) {
8680 swiper.loopCreate();
8681 }
8682 if (!params.observer || swiper.isElement) {
8683 swiper.update();
8684 }
8685 swiper.slideTo(newActiveIndex, 0, false);
8686 }
8687
8688 function addSlide(index, slides) {
8689 const swiper = this;
8690 const {
8691 params,
8692 activeIndex,
8693 slidesEl
8694 } = swiper;
8695 let activeIndexBuffer = activeIndex;
8696 if (params.loop) {
8697 activeIndexBuffer -= swiper.loopedSlides;
8698 swiper.loopDestroy();
8699 swiper.recalcSlides();
8700 }
8701 const baseLength = swiper.slides.length;
8702 if (index <= 0) {
8703 swiper.prependSlide(slides);
8704 return;
8705 }
8706 if (index >= baseLength) {
8707 swiper.appendSlide(slides);
8708 return;
8709 }
8710 let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer;
8711 const slidesBuffer = [];
8712 for (let i = baseLength - 1; i >= index; i -= 1) {
8713 const currentSlide = swiper.slides[i];
8714 currentSlide.remove();
8715 slidesBuffer.unshift(currentSlide);
8716 }
8717 if (typeof slides === 'object' && 'length' in slides) {
8718 for (let i = 0; i < slides.length; i += 1) {
8719 if (slides[i]) slidesEl.append(slides[i]);
8720 }
8721 newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer;
8722 } else {
8723 slidesEl.append(slides);
8724 }
8725 for (let i = 0; i < slidesBuffer.length; i += 1) {
8726 slidesEl.append(slidesBuffer[i]);
8727 }
8728 swiper.recalcSlides();
8729 if (params.loop) {
8730 swiper.loopCreate();
8731 }
8732 if (!params.observer || swiper.isElement) {
8733 swiper.update();
8734 }
8735 if (params.loop) {
8736 swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
8737 } else {
8738 swiper.slideTo(newActiveIndex, 0, false);
8739 }
8740 }
8741
8742 function removeSlide(slidesIndexes) {
8743 const swiper = this;
8744 const {
8745 params,
8746 activeIndex
8747 } = swiper;
8748 let activeIndexBuffer = activeIndex;
8749 if (params.loop) {
8750 activeIndexBuffer -= swiper.loopedSlides;
8751 swiper.loopDestroy();
8752 }
8753 let newActiveIndex = activeIndexBuffer;
8754 let indexToRemove;
8755 if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) {
8756 for (let i = 0; i < slidesIndexes.length; i += 1) {
8757 indexToRemove = slidesIndexes[i];
8758 if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
8759 if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
8760 }
8761 newActiveIndex = Math.max(newActiveIndex, 0);
8762 } else {
8763 indexToRemove = slidesIndexes;
8764 if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
8765 if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
8766 newActiveIndex = Math.max(newActiveIndex, 0);
8767 }
8768 swiper.recalcSlides();
8769 if (params.loop) {
8770 swiper.loopCreate();
8771 }
8772 if (!params.observer || swiper.isElement) {
8773 swiper.update();
8774 }
8775 if (params.loop) {
8776 swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
8777 } else {
8778 swiper.slideTo(newActiveIndex, 0, false);
8779 }
8780 }
8781
8782 function removeAllSlides() {
8783 const swiper = this;
8784 const slidesIndexes = [];
8785 for (let i = 0; i < swiper.slides.length; i += 1) {
8786 slidesIndexes.push(i);
8787 }
8788 swiper.removeSlide(slidesIndexes);
8789 }
8790
8791 function Manipulation(_ref) {
8792 let {
8793 swiper
8794 } = _ref;
8795 Object.assign(swiper, {
8796 appendSlide: appendSlide.bind(swiper),
8797 prependSlide: prependSlide.bind(swiper),
8798 addSlide: addSlide.bind(swiper),
8799 removeSlide: removeSlide.bind(swiper),
8800 removeAllSlides: removeAllSlides.bind(swiper)
8801 });
8802 }
8803
8804 function effectInit(params) {
8805 const {
8806 effect,
8807 swiper,
8808 on,
8809 setTranslate,
8810 setTransition,
8811 overwriteParams,
8812 perspective,
8813 recreateShadows,
8814 getEffectParams
8815 } = params;
8816 on('beforeInit', () => {
8817 if (swiper.params.effect !== effect) return;
8818 swiper.classNames.push(`${swiper.params.containerModifierClass}${effect}`);
8819 if (perspective && perspective()) {
8820 swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);
8821 }
8822 const overwriteParamsResult = overwriteParams ? overwriteParams() : {};
8823 Object.assign(swiper.params, overwriteParamsResult);
8824 Object.assign(swiper.originalParams, overwriteParamsResult);
8825 });
8826 on('setTranslate', () => {
8827 if (swiper.params.effect !== effect) return;
8828 setTranslate();
8829 });
8830 on('setTransition', (_s, duration) => {
8831 if (swiper.params.effect !== effect) return;
8832 setTransition(duration);
8833 });
8834 on('transitionEnd', () => {
8835 if (swiper.params.effect !== effect) return;
8836 if (recreateShadows) {
8837 if (!getEffectParams || !getEffectParams().slideShadows) return;
8838 // remove shadows
8839 swiper.slides.forEach(slideEl => {
8840 slideEl.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => shadowEl.remove());
8841 });
8842 // create new one
8843 recreateShadows();
8844 }
8845 });
8846 let requireUpdateOnVirtual;
8847 on('virtualUpdate', () => {
8848 if (swiper.params.effect !== effect) return;
8849 if (!swiper.slides.length) {
8850 requireUpdateOnVirtual = true;
8851 }
8852 requestAnimationFrame(() => {
8853 if (requireUpdateOnVirtual && swiper.slides && swiper.slides.length) {
8854 setTranslate();
8855 requireUpdateOnVirtual = false;
8856 }
8857 });
8858 });
8859 }
8860
8861 function effectTarget(effectParams, slideEl) {
8862 const transformEl = getSlideTransformEl(slideEl);
8863 if (transformEl !== slideEl) {
8864 transformEl.style.backfaceVisibility = 'hidden';
8865 transformEl.style['-webkit-backface-visibility'] = 'hidden';
8866 }
8867 return transformEl;
8868 }
8869
8870 function effectVirtualTransitionEnd(_ref) {
8871 let {
8872 swiper,
8873 duration,
8874 transformElements,
8875 allSlides
8876 } = _ref;
8877 const {
8878 activeIndex
8879 } = swiper;
8880 const getSlide = el => {
8881 if (!el.parentElement) {
8882 // assume shadow root
8883 const slide = swiper.slides.filter(slideEl => slideEl.shadowRoot && slideEl.shadowRoot === el.parentNode)[0];
8884 return slide;
8885 }
8886 return el.parentElement;
8887 };
8888 if (swiper.params.virtualTranslate && duration !== 0) {
8889 let eventTriggered = false;
8890 let transitionEndTarget;
8891 if (allSlides) {
8892 transitionEndTarget = transformElements;
8893 } else {
8894 transitionEndTarget = transformElements.filter(transformEl => {
8895 const el = transformEl.classList.contains('swiper-slide-transform') ? getSlide(transformEl) : transformEl;
8896 return swiper.getSlideIndex(el) === activeIndex;
8897 });
8898 }
8899 transitionEndTarget.forEach(el => {
8900 elementTransitionEnd(el, () => {
8901 if (eventTriggered) return;
8902 if (!swiper || swiper.destroyed) return;
8903 eventTriggered = true;
8904 swiper.animating = false;
8905 const evt = new window.CustomEvent('transitionend', {
8906 bubbles: true,
8907 cancelable: true
8908 });
8909 swiper.wrapperEl.dispatchEvent(evt);
8910 });
8911 });
8912 }
8913 }
8914
8915 function EffectFade(_ref) {
8916 let {
8917 swiper,
8918 extendParams,
8919 on
8920 } = _ref;
8921 extendParams({
8922 fadeEffect: {
8923 crossFade: false
8924 }
8925 });
8926 const setTranslate = () => {
8927 const {
8928 slides
8929 } = swiper;
8930 const params = swiper.params.fadeEffect;
8931 for (let i = 0; i < slides.length; i += 1) {
8932 const slideEl = swiper.slides[i];
8933 const offset = slideEl.swiperSlideOffset;
8934 let tx = -offset;
8935 if (!swiper.params.virtualTranslate) tx -= swiper.translate;
8936 let ty = 0;
8937 if (!swiper.isHorizontal()) {
8938 ty = tx;
8939 tx = 0;
8940 }
8941 const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs(slideEl.progress), 0) : 1 + Math.min(Math.max(slideEl.progress, -1), 0);
8942 const targetEl = effectTarget(params, slideEl);
8943 targetEl.style.opacity = slideOpacity;
8944 targetEl.style.transform = `translate3d(${tx}px, ${ty}px, 0px)`;
8945 }
8946 };
8947 const setTransition = duration => {
8948 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
8949 transformElements.forEach(el => {
8950 el.style.transitionDuration = `${duration}ms`;
8951 });
8952 effectVirtualTransitionEnd({
8953 swiper,
8954 duration,
8955 transformElements,
8956 allSlides: true
8957 });
8958 };
8959 effectInit({
8960 effect: 'fade',
8961 swiper,
8962 on,
8963 setTranslate,
8964 setTransition,
8965 overwriteParams: () => ({
8966 slidesPerView: 1,
8967 slidesPerGroup: 1,
8968 watchSlidesProgress: true,
8969 spaceBetween: 0,
8970 virtualTranslate: !swiper.params.cssMode
8971 })
8972 });
8973 }
8974
8975 function EffectCube(_ref) {
8976 let {
8977 swiper,
8978 extendParams,
8979 on
8980 } = _ref;
8981 extendParams({
8982 cubeEffect: {
8983 slideShadows: true,
8984 shadow: true,
8985 shadowOffset: 20,
8986 shadowScale: 0.94
8987 }
8988 });
8989 const createSlideShadows = (slideEl, progress, isHorizontal) => {
8990 let shadowBefore = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
8991 let shadowAfter = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
8992 if (!shadowBefore) {
8993 shadowBefore = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}`.split(' '));
8994 slideEl.append(shadowBefore);
8995 }
8996 if (!shadowAfter) {
8997 shadowAfter = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}`.split(' '));
8998 slideEl.append(shadowAfter);
8999 }
9000 if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
9001 if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
9002 };
9003 const recreateShadows = () => {
9004 // create new ones
9005 const isHorizontal = swiper.isHorizontal();
9006 swiper.slides.forEach(slideEl => {
9007 const progress = Math.max(Math.min(slideEl.progress, 1), -1);
9008 createSlideShadows(slideEl, progress, isHorizontal);
9009 });
9010 };
9011 const setTranslate = () => {
9012 const {
9013 el,
9014 wrapperEl,
9015 slides,
9016 width: swiperWidth,
9017 height: swiperHeight,
9018 rtlTranslate: rtl,
9019 size: swiperSize,
9020 browser
9021 } = swiper;
9022 const params = swiper.params.cubeEffect;
9023 const isHorizontal = swiper.isHorizontal();
9024 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
9025 let wrapperRotate = 0;
9026 let cubeShadowEl;
9027 if (params.shadow) {
9028 if (isHorizontal) {
9029 cubeShadowEl = swiper.wrapperEl.querySelector('.swiper-cube-shadow');
9030 if (!cubeShadowEl) {
9031 cubeShadowEl = createElement('div', 'swiper-cube-shadow');
9032 swiper.wrapperEl.append(cubeShadowEl);
9033 }
9034 cubeShadowEl.style.height = `${swiperWidth}px`;
9035 } else {
9036 cubeShadowEl = el.querySelector('.swiper-cube-shadow');
9037 if (!cubeShadowEl) {
9038 cubeShadowEl = createElement('div', 'swiper-cube-shadow');
9039 el.append(cubeShadowEl);
9040 }
9041 }
9042 }
9043 for (let i = 0; i < slides.length; i += 1) {
9044 const slideEl = slides[i];
9045 let slideIndex = i;
9046 if (isVirtual) {
9047 slideIndex = parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10);
9048 }
9049 let slideAngle = slideIndex * 90;
9050 let round = Math.floor(slideAngle / 360);
9051 if (rtl) {
9052 slideAngle = -slideAngle;
9053 round = Math.floor(-slideAngle / 360);
9054 }
9055 const progress = Math.max(Math.min(slideEl.progress, 1), -1);
9056 let tx = 0;
9057 let ty = 0;
9058 let tz = 0;
9059 if (slideIndex % 4 === 0) {
9060 tx = -round * 4 * swiperSize;
9061 tz = 0;
9062 } else if ((slideIndex - 1) % 4 === 0) {
9063 tx = 0;
9064 tz = -round * 4 * swiperSize;
9065 } else if ((slideIndex - 2) % 4 === 0) {
9066 tx = swiperSize + round * 4 * swiperSize;
9067 tz = swiperSize;
9068 } else if ((slideIndex - 3) % 4 === 0) {
9069 tx = -swiperSize;
9070 tz = 3 * swiperSize + swiperSize * 4 * round;
9071 }
9072 if (rtl) {
9073 tx = -tx;
9074 }
9075 if (!isHorizontal) {
9076 ty = tx;
9077 tx = 0;
9078 }
9079 const transform = `rotateX(${isHorizontal ? 0 : -slideAngle}deg) rotateY(${isHorizontal ? slideAngle : 0}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`;
9080 if (progress <= 1 && progress > -1) {
9081 wrapperRotate = slideIndex * 90 + progress * 90;
9082 if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;
9083 if (swiper.browser && swiper.browser.need3dFix && Math.abs(wrapperRotate) / 90 % 2 === 1) {
9084 wrapperRotate += 0.001;
9085 }
9086 }
9087 slideEl.style.transform = transform;
9088 if (params.slideShadows) {
9089 createSlideShadows(slideEl, progress, isHorizontal);
9090 }
9091 }
9092 wrapperEl.style.transformOrigin = `50% 50% -${swiperSize / 2}px`;
9093 wrapperEl.style['-webkit-transform-origin'] = `50% 50% -${swiperSize / 2}px`;
9094 if (params.shadow) {
9095 if (isHorizontal) {
9096 cubeShadowEl.style.transform = `translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${-swiperWidth / 2}px) rotateX(89.99deg) rotateZ(0deg) scale(${params.shadowScale})`;
9097 } else {
9098 const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
9099 const multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
9100 const scale1 = params.shadowScale;
9101 const scale2 = params.shadowScale / multiplier;
9102 const offset = params.shadowOffset;
9103 cubeShadowEl.style.transform = `scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${-swiperHeight / 2 / scale2}px) rotateX(-89.99deg)`;
9104 }
9105 }
9106 const zFactor = (browser.isSafari || browser.isWebView) && browser.needPerspectiveFix ? -swiperSize / 2 : 0;
9107 wrapperEl.style.transform = `translate3d(0px,0,${zFactor}px) rotateX(${swiper.isHorizontal() ? 0 : wrapperRotate}deg) rotateY(${swiper.isHorizontal() ? -wrapperRotate : 0}deg)`;
9108 wrapperEl.style.setProperty('--swiper-cube-translate-z', `${zFactor}px`);
9109 };
9110 const setTransition = duration => {
9111 const {
9112 el,
9113 slides
9114 } = swiper;
9115 slides.forEach(slideEl => {
9116 slideEl.style.transitionDuration = `${duration}ms`;
9117 slideEl.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(subEl => {
9118 subEl.style.transitionDuration = `${duration}ms`;
9119 });
9120 });
9121 if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {
9122 const shadowEl = el.querySelector('.swiper-cube-shadow');
9123 if (shadowEl) shadowEl.style.transitionDuration = `${duration}ms`;
9124 }
9125 };
9126 effectInit({
9127 effect: 'cube',
9128 swiper,
9129 on,
9130 setTranslate,
9131 setTransition,
9132 recreateShadows,
9133 getEffectParams: () => swiper.params.cubeEffect,
9134 perspective: () => true,
9135 overwriteParams: () => ({
9136 slidesPerView: 1,
9137 slidesPerGroup: 1,
9138 watchSlidesProgress: true,
9139 resistanceRatio: 0,
9140 spaceBetween: 0,
9141 centeredSlides: false,
9142 virtualTranslate: true
9143 })
9144 });
9145 }
9146
9147 function createShadow(suffix, slideEl, side) {
9148 const shadowClass = `swiper-slide-shadow${side ? `-${side}` : ''}${suffix ? ` swiper-slide-shadow-${suffix}` : ''}`;
9149 const shadowContainer = getSlideTransformEl(slideEl);
9150 let shadowEl = shadowContainer.querySelector(`.${shadowClass.split(' ').join('.')}`);
9151 if (!shadowEl) {
9152 shadowEl = createElement('div', shadowClass.split(' '));
9153 shadowContainer.append(shadowEl);
9154 }
9155 return shadowEl;
9156 }
9157
9158 function EffectFlip(_ref) {
9159 let {
9160 swiper,
9161 extendParams,
9162 on
9163 } = _ref;
9164 extendParams({
9165 flipEffect: {
9166 slideShadows: true,
9167 limitRotation: true
9168 }
9169 });
9170 const createSlideShadows = (slideEl, progress) => {
9171 let shadowBefore = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
9172 let shadowAfter = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
9173 if (!shadowBefore) {
9174 shadowBefore = createShadow('flip', slideEl, swiper.isHorizontal() ? 'left' : 'top');
9175 }
9176 if (!shadowAfter) {
9177 shadowAfter = createShadow('flip', slideEl, swiper.isHorizontal() ? 'right' : 'bottom');
9178 }
9179 if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
9180 if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
9181 };
9182 const recreateShadows = () => {
9183 // Set shadows
9184 swiper.params.flipEffect;
9185 swiper.slides.forEach(slideEl => {
9186 let progress = slideEl.progress;
9187 if (swiper.params.flipEffect.limitRotation) {
9188 progress = Math.max(Math.min(slideEl.progress, 1), -1);
9189 }
9190 createSlideShadows(slideEl, progress);
9191 });
9192 };
9193 const setTranslate = () => {
9194 const {
9195 slides,
9196 rtlTranslate: rtl
9197 } = swiper;
9198 const params = swiper.params.flipEffect;
9199 for (let i = 0; i < slides.length; i += 1) {
9200 const slideEl = slides[i];
9201 let progress = slideEl.progress;
9202 if (swiper.params.flipEffect.limitRotation) {
9203 progress = Math.max(Math.min(slideEl.progress, 1), -1);
9204 }
9205 const offset = slideEl.swiperSlideOffset;
9206 const rotate = -180 * progress;
9207 let rotateY = rotate;
9208 let rotateX = 0;
9209 let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset;
9210 let ty = 0;
9211 if (!swiper.isHorizontal()) {
9212 ty = tx;
9213 tx = 0;
9214 rotateX = -rotateY;
9215 rotateY = 0;
9216 } else if (rtl) {
9217 rotateY = -rotateY;
9218 }
9219 if (swiper.browser && swiper.browser.need3dFix) {
9220 if (Math.abs(rotateY) / 90 % 2 === 1) {
9221 rotateY += 0.001;
9222 }
9223 if (Math.abs(rotateX) / 90 % 2 === 1) {
9224 rotateX += 0.001;
9225 }
9226 }
9227 slideEl.style.zIndex = -Math.abs(Math.round(progress)) + slides.length;
9228 if (params.slideShadows) {
9229 createSlideShadows(slideEl, progress);
9230 }
9231 const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
9232 const targetEl = effectTarget(params, slideEl);
9233 targetEl.style.transform = transform;
9234 }
9235 };
9236 const setTransition = duration => {
9237 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
9238 transformElements.forEach(el => {
9239 el.style.transitionDuration = `${duration}ms`;
9240 el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => {
9241 shadowEl.style.transitionDuration = `${duration}ms`;
9242 });
9243 });
9244 effectVirtualTransitionEnd({
9245 swiper,
9246 duration,
9247 transformElements
9248 });
9249 };
9250 effectInit({
9251 effect: 'flip',
9252 swiper,
9253 on,
9254 setTranslate,
9255 setTransition,
9256 recreateShadows,
9257 getEffectParams: () => swiper.params.flipEffect,
9258 perspective: () => true,
9259 overwriteParams: () => ({
9260 slidesPerView: 1,
9261 slidesPerGroup: 1,
9262 watchSlidesProgress: true,
9263 spaceBetween: 0,
9264 virtualTranslate: !swiper.params.cssMode
9265 })
9266 });
9267 }
9268
9269 function EffectCoverflow(_ref) {
9270 let {
9271 swiper,
9272 extendParams,
9273 on
9274 } = _ref;
9275 extendParams({
9276 coverflowEffect: {
9277 rotate: 50,
9278 stretch: 0,
9279 depth: 100,
9280 scale: 1,
9281 modifier: 1,
9282 slideShadows: true
9283 }
9284 });
9285 const setTranslate = () => {
9286 const {
9287 width: swiperWidth,
9288 height: swiperHeight,
9289 slides,
9290 slidesSizesGrid
9291 } = swiper;
9292 const params = swiper.params.coverflowEffect;
9293 const isHorizontal = swiper.isHorizontal();
9294 const transform = swiper.translate;
9295 const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;
9296 const rotate = isHorizontal ? params.rotate : -params.rotate;
9297 const translate = params.depth;
9298 // Each slide offset from center
9299 for (let i = 0, length = slides.length; i < length; i += 1) {
9300 const slideEl = slides[i];
9301 const slideSize = slidesSizesGrid[i];
9302 const slideOffset = slideEl.swiperSlideOffset;
9303 const centerOffset = (center - slideOffset - slideSize / 2) / slideSize;
9304 const offsetMultiplier = typeof params.modifier === 'function' ? params.modifier(centerOffset) : centerOffset * params.modifier;
9305 let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
9306 let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier;
9307 // var rotateZ = 0
9308 let translateZ = -translate * Math.abs(offsetMultiplier);
9309 let stretch = params.stretch;
9310 // Allow percentage to make a relative stretch for responsive sliders
9311 if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {
9312 stretch = parseFloat(params.stretch) / 100 * slideSize;
9313 }
9314 let translateY = isHorizontal ? 0 : stretch * offsetMultiplier;
9315 let translateX = isHorizontal ? stretch * offsetMultiplier : 0;
9316 let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier);
9317
9318 // Fix for ultra small values
9319 if (Math.abs(translateX) < 0.001) translateX = 0;
9320 if (Math.abs(translateY) < 0.001) translateY = 0;
9321 if (Math.abs(translateZ) < 0.001) translateZ = 0;
9322 if (Math.abs(rotateY) < 0.001) rotateY = 0;
9323 if (Math.abs(rotateX) < 0.001) rotateX = 0;
9324 if (Math.abs(scale) < 0.001) scale = 0;
9325 if (swiper.browser && swiper.browser.need3dFix) {
9326 if (Math.abs(rotateY) / 90 % 2 === 1) {
9327 rotateY += 0.001;
9328 }
9329 if (Math.abs(rotateX) / 90 % 2 === 1) {
9330 rotateX += 0.001;
9331 }
9332 }
9333 const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(${scale})`;
9334 const targetEl = effectTarget(params, slideEl);
9335 targetEl.style.transform = slideTransform;
9336 slideEl.style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
9337 if (params.slideShadows) {
9338 // Set shadows
9339 let shadowBeforeEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
9340 let shadowAfterEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
9341 if (!shadowBeforeEl) {
9342 shadowBeforeEl = createShadow('coverflow', slideEl, isHorizontal ? 'left' : 'top');
9343 }
9344 if (!shadowAfterEl) {
9345 shadowAfterEl = createShadow('coverflow', slideEl, isHorizontal ? 'right' : 'bottom');
9346 }
9347 if (shadowBeforeEl) shadowBeforeEl.style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
9348 if (shadowAfterEl) shadowAfterEl.style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;
9349 }
9350 }
9351 };
9352 const setTransition = duration => {
9353 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
9354 transformElements.forEach(el => {
9355 el.style.transitionDuration = `${duration}ms`;
9356 el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => {
9357 shadowEl.style.transitionDuration = `${duration}ms`;
9358 });
9359 });
9360 };
9361 effectInit({
9362 effect: 'coverflow',
9363 swiper,
9364 on,
9365 setTranslate,
9366 setTransition,
9367 perspective: () => true,
9368 overwriteParams: () => ({
9369 watchSlidesProgress: true
9370 })
9371 });
9372 }
9373
9374 function EffectCreative(_ref) {
9375 let {
9376 swiper,
9377 extendParams,
9378 on
9379 } = _ref;
9380 extendParams({
9381 creativeEffect: {
9382 limitProgress: 1,
9383 shadowPerProgress: false,
9384 progressMultiplier: 1,
9385 perspective: true,
9386 prev: {
9387 translate: [0, 0, 0],
9388 rotate: [0, 0, 0],
9389 opacity: 1,
9390 scale: 1
9391 },
9392 next: {
9393 translate: [0, 0, 0],
9394 rotate: [0, 0, 0],
9395 opacity: 1,
9396 scale: 1
9397 }
9398 }
9399 });
9400 const getTranslateValue = value => {
9401 if (typeof value === 'string') return value;
9402 return `${value}px`;
9403 };
9404 const setTranslate = () => {
9405 const {
9406 slides,
9407 wrapperEl,
9408 slidesSizesGrid
9409 } = swiper;
9410 const params = swiper.params.creativeEffect;
9411 const {
9412 progressMultiplier: multiplier
9413 } = params;
9414 const isCenteredSlides = swiper.params.centeredSlides;
9415 if (isCenteredSlides) {
9416 const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0;
9417 wrapperEl.style.transform = `translateX(calc(50% - ${margin}px))`;
9418 }
9419 for (let i = 0; i < slides.length; i += 1) {
9420 const slideEl = slides[i];
9421 const slideProgress = slideEl.progress;
9422 const progress = Math.min(Math.max(slideEl.progress, -params.limitProgress), params.limitProgress);
9423 let originalProgress = progress;
9424 if (!isCenteredSlides) {
9425 originalProgress = Math.min(Math.max(slideEl.originalProgress, -params.limitProgress), params.limitProgress);
9426 }
9427 const offset = slideEl.swiperSlideOffset;
9428 const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];
9429 const r = [0, 0, 0];
9430 let custom = false;
9431 if (!swiper.isHorizontal()) {
9432 t[1] = t[0];
9433 t[0] = 0;
9434 }
9435 let data = {
9436 translate: [0, 0, 0],
9437 rotate: [0, 0, 0],
9438 scale: 1,
9439 opacity: 1
9440 };
9441 if (progress < 0) {
9442 data = params.next;
9443 custom = true;
9444 } else if (progress > 0) {
9445 data = params.prev;
9446 custom = true;
9447 }
9448 // set translate
9449 t.forEach((value, index) => {
9450 t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(progress * multiplier)}))`;
9451 });
9452 // set rotates
9453 r.forEach((value, index) => {
9454 let val = data.rotate[index] * Math.abs(progress * multiplier);
9455 if (swiper.browser && swiper.browser.need3dFix && Math.abs(val) / 90 % 2 === 1) {
9456 val += 0.001;
9457 }
9458 r[index] = val;
9459 });
9460 slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
9461 const translateString = t.join(', ');
9462 const rotateString = `rotateX(${r[0]}deg) rotateY(${r[1]}deg) rotateZ(${r[2]}deg)`;
9463 const scaleString = originalProgress < 0 ? `scale(${1 + (1 - data.scale) * originalProgress * multiplier})` : `scale(${1 - (1 - data.scale) * originalProgress * multiplier})`;
9464 const opacityString = originalProgress < 0 ? 1 + (1 - data.opacity) * originalProgress * multiplier : 1 - (1 - data.opacity) * originalProgress * multiplier;
9465 const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`;
9466
9467 // Set shadows
9468 if (custom && data.shadow || !custom) {
9469 let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
9470 if (!shadowEl && data.shadow) {
9471 shadowEl = createShadow('creative', slideEl);
9472 }
9473 if (shadowEl) {
9474 const shadowOpacity = params.shadowPerProgress ? progress * (1 / params.limitProgress) : progress;
9475 shadowEl.style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1);
9476 }
9477 }
9478 const targetEl = effectTarget(params, slideEl);
9479 targetEl.style.transform = transform;
9480 targetEl.style.opacity = opacityString;
9481 if (data.origin) {
9482 targetEl.style.transformOrigin = data.origin;
9483 }
9484 }
9485 };
9486 const setTransition = duration => {
9487 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
9488 transformElements.forEach(el => {
9489 el.style.transitionDuration = `${duration}ms`;
9490 el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => {
9491 shadowEl.style.transitionDuration = `${duration}ms`;
9492 });
9493 });
9494 effectVirtualTransitionEnd({
9495 swiper,
9496 duration,
9497 transformElements,
9498 allSlides: true
9499 });
9500 };
9501 effectInit({
9502 effect: 'creative',
9503 swiper,
9504 on,
9505 setTranslate,
9506 setTransition,
9507 perspective: () => swiper.params.creativeEffect.perspective,
9508 overwriteParams: () => ({
9509 watchSlidesProgress: true,
9510 virtualTranslate: !swiper.params.cssMode
9511 })
9512 });
9513 }
9514
9515 function EffectCards(_ref) {
9516 let {
9517 swiper,
9518 extendParams,
9519 on
9520 } = _ref;
9521 extendParams({
9522 cardsEffect: {
9523 slideShadows: true,
9524 rotate: true,
9525 perSlideRotate: 2,
9526 perSlideOffset: 8
9527 }
9528 });
9529 const setTranslate = () => {
9530 const {
9531 slides,
9532 activeIndex,
9533 rtlTranslate: rtl
9534 } = swiper;
9535 const params = swiper.params.cardsEffect;
9536 const {
9537 startTranslate,
9538 isTouched
9539 } = swiper.touchEventsData;
9540 const currentTranslate = rtl ? -swiper.translate : swiper.translate;
9541 for (let i = 0; i < slides.length; i += 1) {
9542 const slideEl = slides[i];
9543 const slideProgress = slideEl.progress;
9544 const progress = Math.min(Math.max(slideProgress, -4), 4);
9545 let offset = slideEl.swiperSlideOffset;
9546 if (swiper.params.centeredSlides && !swiper.params.cssMode) {
9547 swiper.wrapperEl.style.transform = `translateX(${swiper.minTranslate()}px)`;
9548 }
9549 if (swiper.params.centeredSlides && swiper.params.cssMode) {
9550 offset -= slides[0].swiperSlideOffset;
9551 }
9552 let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset;
9553 let tY = 0;
9554 const tZ = -100 * Math.abs(progress);
9555 let scale = 1;
9556 let rotate = -params.perSlideRotate * progress;
9557 let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75;
9558 const slideIndex = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.from + i : i;
9559 const isSwipeToNext = (slideIndex === activeIndex || slideIndex === activeIndex - 1) && progress > 0 && progress < 1 && (isTouched || swiper.params.cssMode) && currentTranslate < startTranslate;
9560 const isSwipeToPrev = (slideIndex === activeIndex || slideIndex === activeIndex + 1) && progress < 0 && progress > -1 && (isTouched || swiper.params.cssMode) && currentTranslate > startTranslate;
9561 if (isSwipeToNext || isSwipeToPrev) {
9562 const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5;
9563 rotate += -28 * progress * subProgress;
9564 scale += -0.5 * subProgress;
9565 tXAdd += 96 * subProgress;
9566 tY = `${-25 * subProgress * Math.abs(progress)}%`;
9567 }
9568 if (progress < 0) {
9569 // next
9570 tX = `calc(${tX}px ${rtl ? '-' : '+'} (${tXAdd * Math.abs(progress)}%))`;
9571 } else if (progress > 0) {
9572 // prev
9573 tX = `calc(${tX}px ${rtl ? '-' : '+'} (-${tXAdd * Math.abs(progress)}%))`;
9574 } else {
9575 tX = `${tX}px`;
9576 }
9577 if (!swiper.isHorizontal()) {
9578 const prevY = tY;
9579 tY = tX;
9580 tX = prevY;
9581 }
9582 const scaleString = progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`;
9583
9584 /* eslint-disable */
9585 const transform = `
9586 translate3d(${tX}, ${tY}, ${tZ}px)
9587 rotateZ(${params.rotate ? rtl ? -rotate : rotate : 0}deg)
9588 scale(${scaleString})
9589 `;
9590 /* eslint-enable */
9591
9592 if (params.slideShadows) {
9593 // Set shadows
9594 let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
9595 if (!shadowEl) {
9596 shadowEl = createShadow('cards', slideEl);
9597 }
9598 if (shadowEl) shadowEl.style.opacity = Math.min(Math.max((Math.abs(progress) - 0.5) / 0.5, 0), 1);
9599 }
9600 slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
9601 const targetEl = effectTarget(params, slideEl);
9602 targetEl.style.transform = transform;
9603 }
9604 };
9605 const setTransition = duration => {
9606 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
9607 transformElements.forEach(el => {
9608 el.style.transitionDuration = `${duration}ms`;
9609 el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => {
9610 shadowEl.style.transitionDuration = `${duration}ms`;
9611 });
9612 });
9613 effectVirtualTransitionEnd({
9614 swiper,
9615 duration,
9616 transformElements
9617 });
9618 };
9619 effectInit({
9620 effect: 'cards',
9621 swiper,
9622 on,
9623 setTranslate,
9624 setTransition,
9625 perspective: () => true,
9626 overwriteParams: () => ({
9627 watchSlidesProgress: true,
9628 virtualTranslate: !swiper.params.cssMode
9629 })
9630 });
9631 }
9632
9633 /**
9634 * Swiper 11.1.4
9635 * Most modern mobile touch slider and framework with hardware accelerated transitions
9636 * https://swiperjs.com
9637 *
9638 * Copyright 2014-2024 Vladimir Kharlampidi
9639 *
9640 * Released under the MIT License
9641 *
9642 * Released on: May 30, 2024
9643 */
9644
9645
9646 // Swiper Class
9647 const modules = [Virtual, Keyboard, Mousewheel, Navigation, Pagination, Scrollbar, Parallax, Zoom, Controller, A11y, History, HashNavigation, Autoplay, Thumb, freeMode, Grid, Manipulation, EffectFade, EffectCube, EffectFlip, EffectCoverflow, EffectCreative, EffectCards];
9648 Swiper.use(modules);
9649
9650 return Swiper;
9651
9652})();