UNPKG

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