UNPKG

149 kBJavaScriptView Raw
1/**
2 * Swiper 11.1.14
3 * Most modern mobile touch slider and framework with hardware accelerated transitions
4 * https://swiperjs.com
5 *
6 * Copyright 2014-2024 Vladimir Kharlampidi
7 *
8 * Released under the MIT License
9 *
10 * Released on: September 12, 2024
11 */
12
13var Swiper = (function () {
14 'use strict';
15
16 /**
17 * SSR Window 4.0.2
18 * Better handling for window object in SSR environment
19 * https://github.com/nolimits4web/ssr-window
20 *
21 * Copyright 2021, Vladimir Kharlampidi
22 *
23 * Licensed under MIT
24 *
25 * Released on: December 13, 2021
26 */
27 /* eslint-disable no-param-reassign */
28 function isObject$1(obj) {
29 return obj !== null && typeof obj === 'object' && 'constructor' in obj && obj.constructor === Object;
30 }
31 function extend$1(target, src) {
32 if (target === void 0) {
33 target = {};
34 }
35 if (src === void 0) {
36 src = {};
37 }
38 Object.keys(src).forEach(key => {
39 if (typeof target[key] === 'undefined') target[key] = src[key];else if (isObject$1(src[key]) && isObject$1(target[key]) && Object.keys(src[key]).length > 0) {
40 extend$1(target[key], src[key]);
41 }
42 });
43 }
44 const ssrDocument = {
45 body: {},
46 addEventListener() {},
47 removeEventListener() {},
48 activeElement: {
49 blur() {},
50 nodeName: ''
51 },
52 querySelector() {
53 return null;
54 },
55 querySelectorAll() {
56 return [];
57 },
58 getElementById() {
59 return null;
60 },
61 createEvent() {
62 return {
63 initEvent() {}
64 };
65 },
66 createElement() {
67 return {
68 children: [],
69 childNodes: [],
70 style: {},
71 setAttribute() {},
72 getElementsByTagName() {
73 return [];
74 }
75 };
76 },
77 createElementNS() {
78 return {};
79 },
80 importNode() {
81 return null;
82 },
83 location: {
84 hash: '',
85 host: '',
86 hostname: '',
87 href: '',
88 origin: '',
89 pathname: '',
90 protocol: '',
91 search: ''
92 }
93 };
94 function getDocument() {
95 const doc = typeof document !== 'undefined' ? document : {};
96 extend$1(doc, ssrDocument);
97 return doc;
98 }
99 const ssrWindow = {
100 document: ssrDocument,
101 navigator: {
102 userAgent: ''
103 },
104 location: {
105 hash: '',
106 host: '',
107 hostname: '',
108 href: '',
109 origin: '',
110 pathname: '',
111 protocol: '',
112 search: ''
113 },
114 history: {
115 replaceState() {},
116 pushState() {},
117 go() {},
118 back() {}
119 },
120 CustomEvent: function CustomEvent() {
121 return this;
122 },
123 addEventListener() {},
124 removeEventListener() {},
125 getComputedStyle() {
126 return {
127 getPropertyValue() {
128 return '';
129 }
130 };
131 },
132 Image() {},
133 Date() {},
134 screen: {},
135 setTimeout() {},
136 clearTimeout() {},
137 matchMedia() {
138 return {};
139 },
140 requestAnimationFrame(callback) {
141 if (typeof setTimeout === 'undefined') {
142 callback();
143 return null;
144 }
145 return setTimeout(callback, 0);
146 },
147 cancelAnimationFrame(id) {
148 if (typeof setTimeout === 'undefined') {
149 return;
150 }
151 clearTimeout(id);
152 }
153 };
154 function getWindow() {
155 const win = typeof window !== 'undefined' ? window : {};
156 extend$1(win, ssrWindow);
157 return win;
158 }
159
160 function classesToTokens(classes) {
161 if (classes === void 0) {
162 classes = '';
163 }
164 return classes.trim().split(' ').filter(c => !!c.trim());
165 }
166
167 function deleteProps(obj) {
168 const object = obj;
169 Object.keys(object).forEach(key => {
170 try {
171 object[key] = null;
172 } catch (e) {
173 // no getter for object
174 }
175 try {
176 delete object[key];
177 } catch (e) {
178 // something got wrong
179 }
180 });
181 }
182 function nextTick(callback, delay) {
183 if (delay === void 0) {
184 delay = 0;
185 }
186 return setTimeout(callback, delay);
187 }
188 function now() {
189 return Date.now();
190 }
191 function getComputedStyle$1(el) {
192 const window = getWindow();
193 let style;
194 if (window.getComputedStyle) {
195 style = window.getComputedStyle(el, null);
196 }
197 if (!style && el.currentStyle) {
198 style = el.currentStyle;
199 }
200 if (!style) {
201 style = el.style;
202 }
203 return style;
204 }
205 function getTranslate(el, axis) {
206 if (axis === void 0) {
207 axis = 'x';
208 }
209 const window = getWindow();
210 let matrix;
211 let curTransform;
212 let transformMatrix;
213 const curStyle = getComputedStyle$1(el);
214 if (window.WebKitCSSMatrix) {
215 curTransform = curStyle.transform || curStyle.webkitTransform;
216 if (curTransform.split(',').length > 6) {
217 curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', ');
218 }
219 // Some old versions of Webkit choke when 'none' is passed; pass
220 // empty string instead in this case
221 transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
222 } else {
223 transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
224 matrix = transformMatrix.toString().split(',');
225 }
226 if (axis === 'x') {
227 // Latest Chrome and webkits Fix
228 if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41;
229 // Crazy IE10 Matrix
230 else if (matrix.length === 16) curTransform = parseFloat(matrix[12]);
231 // Normal Browsers
232 else curTransform = parseFloat(matrix[4]);
233 }
234 if (axis === 'y') {
235 // Latest Chrome and webkits Fix
236 if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42;
237 // Crazy IE10 Matrix
238 else if (matrix.length === 16) curTransform = parseFloat(matrix[13]);
239 // Normal Browsers
240 else curTransform = parseFloat(matrix[5]);
241 }
242 return curTransform || 0;
243 }
244 function isObject(o) {
245 return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object';
246 }
247 function isNode(node) {
248 // eslint-disable-next-line
249 if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') {
250 return node instanceof HTMLElement;
251 }
252 return node && (node.nodeType === 1 || node.nodeType === 11);
253 }
254 function extend() {
255 const to = Object(arguments.length <= 0 ? undefined : arguments[0]);
256 const noExtend = ['__proto__', 'constructor', 'prototype'];
257 for (let i = 1; i < arguments.length; i += 1) {
258 const nextSource = i < 0 || arguments.length <= i ? undefined : arguments[i];
259 if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) {
260 const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0);
261 for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
262 const nextKey = keysArray[nextIndex];
263 const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
264 if (desc !== undefined && desc.enumerable) {
265 if (isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
266 if (nextSource[nextKey].__swiper__) {
267 to[nextKey] = nextSource[nextKey];
268 } else {
269 extend(to[nextKey], nextSource[nextKey]);
270 }
271 } else if (!isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
272 to[nextKey] = {};
273 if (nextSource[nextKey].__swiper__) {
274 to[nextKey] = nextSource[nextKey];
275 } else {
276 extend(to[nextKey], nextSource[nextKey]);
277 }
278 } else {
279 to[nextKey] = nextSource[nextKey];
280 }
281 }
282 }
283 }
284 }
285 return to;
286 }
287 function setCSSProperty(el, varName, varValue) {
288 el.style.setProperty(varName, varValue);
289 }
290 function animateCSSModeScroll(_ref) {
291 let {
292 swiper,
293 targetPosition,
294 side
295 } = _ref;
296 const window = getWindow();
297 const startPosition = -swiper.translate;
298 let startTime = null;
299 let time;
300 const duration = swiper.params.speed;
301 swiper.wrapperEl.style.scrollSnapType = 'none';
302 window.cancelAnimationFrame(swiper.cssModeFrameID);
303 const dir = targetPosition > startPosition ? 'next' : 'prev';
304 const isOutOfBound = (current, target) => {
305 return dir === 'next' && current >= target || dir === 'prev' && current <= target;
306 };
307 const animate = () => {
308 time = new Date().getTime();
309 if (startTime === null) {
310 startTime = time;
311 }
312 const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
313 const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
314 let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);
315 if (isOutOfBound(currentPosition, targetPosition)) {
316 currentPosition = targetPosition;
317 }
318 swiper.wrapperEl.scrollTo({
319 [side]: currentPosition
320 });
321 if (isOutOfBound(currentPosition, targetPosition)) {
322 swiper.wrapperEl.style.overflow = 'hidden';
323 swiper.wrapperEl.style.scrollSnapType = '';
324 setTimeout(() => {
325 swiper.wrapperEl.style.overflow = '';
326 swiper.wrapperEl.scrollTo({
327 [side]: currentPosition
328 });
329 });
330 window.cancelAnimationFrame(swiper.cssModeFrameID);
331 return;
332 }
333 swiper.cssModeFrameID = window.requestAnimationFrame(animate);
334 };
335 animate();
336 }
337 function elementChildren(element, selector) {
338 if (selector === void 0) {
339 selector = '';
340 }
341 const children = [...element.children];
342 if (element instanceof HTMLSlotElement) {
343 children.push(...element.assignedElements());
344 }
345 if (!selector) {
346 return children;
347 }
348 return children.filter(el => el.matches(selector));
349 }
350 function elementIsChildOf(el, parent) {
351 const isChild = parent.contains(el);
352 if (!isChild && parent instanceof HTMLSlotElement) {
353 const children = [...parent.assignedElements()];
354 return children.includes(el);
355 }
356 return isChild;
357 }
358 function showWarning(text) {
359 try {
360 console.warn(text);
361 return;
362 } catch (err) {
363 // err
364 }
365 }
366 function createElement(tag, classes) {
367 if (classes === void 0) {
368 classes = [];
369 }
370 const el = document.createElement(tag);
371 el.classList.add(...(Array.isArray(classes) ? classes : classesToTokens(classes)));
372 return el;
373 }
374 function elementPrevAll(el, selector) {
375 const prevEls = [];
376 while (el.previousElementSibling) {
377 const prev = el.previousElementSibling; // eslint-disable-line
378 if (selector) {
379 if (prev.matches(selector)) prevEls.push(prev);
380 } else prevEls.push(prev);
381 el = prev;
382 }
383 return prevEls;
384 }
385 function elementNextAll(el, selector) {
386 const nextEls = [];
387 while (el.nextElementSibling) {
388 const next = el.nextElementSibling; // eslint-disable-line
389 if (selector) {
390 if (next.matches(selector)) nextEls.push(next);
391 } else nextEls.push(next);
392 el = next;
393 }
394 return nextEls;
395 }
396 function elementStyle(el, prop) {
397 const window = getWindow();
398 return window.getComputedStyle(el, null).getPropertyValue(prop);
399 }
400 function elementIndex(el) {
401 let child = el;
402 let i;
403 if (child) {
404 i = 0;
405 // eslint-disable-next-line
406 while ((child = child.previousSibling) !== null) {
407 if (child.nodeType === 1) i += 1;
408 }
409 return i;
410 }
411 return undefined;
412 }
413 function elementParents(el, selector) {
414 const parents = []; // eslint-disable-line
415 let parent = el.parentElement; // eslint-disable-line
416 while (parent) {
417 if (selector) {
418 if (parent.matches(selector)) parents.push(parent);
419 } else {
420 parents.push(parent);
421 }
422 parent = parent.parentElement;
423 }
424 return parents;
425 }
426 function elementOuterSize(el, size, includeMargins) {
427 const window = getWindow();
428 if (includeMargins) {
429 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'));
430 }
431 return el.offsetWidth;
432 }
433
434 let support;
435 function calcSupport() {
436 const window = getWindow();
437 const document = getDocument();
438 return {
439 smoothScroll: document.documentElement && document.documentElement.style && 'scrollBehavior' in document.documentElement.style,
440 touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch)
441 };
442 }
443 function getSupport() {
444 if (!support) {
445 support = calcSupport();
446 }
447 return support;
448 }
449
450 let deviceCached;
451 function calcDevice(_temp) {
452 let {
453 userAgent
454 } = _temp === void 0 ? {} : _temp;
455 const support = getSupport();
456 const window = getWindow();
457 const platform = window.navigator.platform;
458 const ua = userAgent || window.navigator.userAgent;
459 const device = {
460 ios: false,
461 android: false
462 };
463 const screenWidth = window.screen.width;
464 const screenHeight = window.screen.height;
465 const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
466 let ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
467 const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
468 const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
469 const windows = platform === 'Win32';
470 let macos = platform === 'MacIntel';
471
472 // iPadOs 13 fix
473 const iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768', '820x1180', '1180x820', '810x1080', '1080x810'];
474 if (!ipad && macos && support.touch && iPadScreens.indexOf(`${screenWidth}x${screenHeight}`) >= 0) {
475 ipad = ua.match(/(Version)\/([\d.]+)/);
476 if (!ipad) ipad = [0, 1, '13_0_0'];
477 macos = false;
478 }
479
480 // Android
481 if (android && !windows) {
482 device.os = 'android';
483 device.android = true;
484 }
485 if (ipad || iphone || ipod) {
486 device.os = 'ios';
487 device.ios = true;
488 }
489
490 // Export object
491 return device;
492 }
493 function getDevice(overrides) {
494 if (overrides === void 0) {
495 overrides = {};
496 }
497 if (!deviceCached) {
498 deviceCached = calcDevice(overrides);
499 }
500 return deviceCached;
501 }
502
503 let browser;
504 function calcBrowser() {
505 const window = getWindow();
506 const device = getDevice();
507 let needPerspectiveFix = false;
508 function isSafari() {
509 const ua = window.navigator.userAgent.toLowerCase();
510 return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;
511 }
512 if (isSafari()) {
513 const ua = String(window.navigator.userAgent);
514 if (ua.includes('Version/')) {
515 const [major, minor] = ua.split('Version/')[1].split(' ')[0].split('.').map(num => Number(num));
516 needPerspectiveFix = major < 16 || major === 16 && minor < 2;
517 }
518 }
519 const isWebView = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent);
520 const isSafariBrowser = isSafari();
521 const need3dFix = isSafariBrowser || isWebView && device.ios;
522 return {
523 isSafari: needPerspectiveFix || isSafariBrowser,
524 needPerspectiveFix,
525 need3dFix,
526 isWebView
527 };
528 }
529 function getBrowser() {
530 if (!browser) {
531 browser = calcBrowser();
532 }
533 return browser;
534 }
535
536 function Resize(_ref) {
537 let {
538 swiper,
539 on,
540 emit
541 } = _ref;
542 const window = getWindow();
543 let observer = null;
544 let animationFrame = null;
545 const resizeHandler = () => {
546 if (!swiper || swiper.destroyed || !swiper.initialized) return;
547 emit('beforeResize');
548 emit('resize');
549 };
550 const createObserver = () => {
551 if (!swiper || swiper.destroyed || !swiper.initialized) return;
552 observer = new ResizeObserver(entries => {
553 animationFrame = window.requestAnimationFrame(() => {
554 const {
555 width,
556 height
557 } = swiper;
558 let newWidth = width;
559 let newHeight = height;
560 entries.forEach(_ref2 => {
561 let {
562 contentBoxSize,
563 contentRect,
564 target
565 } = _ref2;
566 if (target && target !== swiper.el) return;
567 newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize;
568 newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize;
569 });
570 if (newWidth !== width || newHeight !== height) {
571 resizeHandler();
572 }
573 });
574 });
575 observer.observe(swiper.el);
576 };
577 const removeObserver = () => {
578 if (animationFrame) {
579 window.cancelAnimationFrame(animationFrame);
580 }
581 if (observer && observer.unobserve && swiper.el) {
582 observer.unobserve(swiper.el);
583 observer = null;
584 }
585 };
586 const orientationChangeHandler = () => {
587 if (!swiper || swiper.destroyed || !swiper.initialized) return;
588 emit('orientationchange');
589 };
590 on('init', () => {
591 if (swiper.params.resizeObserver && typeof window.ResizeObserver !== 'undefined') {
592 createObserver();
593 return;
594 }
595 window.addEventListener('resize', resizeHandler);
596 window.addEventListener('orientationchange', orientationChangeHandler);
597 });
598 on('destroy', () => {
599 removeObserver();
600 window.removeEventListener('resize', resizeHandler);
601 window.removeEventListener('orientationchange', orientationChangeHandler);
602 });
603 }
604
605 function Observer(_ref) {
606 let {
607 swiper,
608 extendParams,
609 on,
610 emit
611 } = _ref;
612 const observers = [];
613 const window = getWindow();
614 const attach = function (target, options) {
615 if (options === void 0) {
616 options = {};
617 }
618 const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
619 const observer = new ObserverFunc(mutations => {
620 // The observerUpdate event should only be triggered
621 // once despite the number of mutations. Additional
622 // triggers are redundant and are very costly
623 if (swiper.__preventObserver__) return;
624 if (mutations.length === 1) {
625 emit('observerUpdate', mutations[0]);
626 return;
627 }
628 const observerUpdate = function observerUpdate() {
629 emit('observerUpdate', mutations[0]);
630 };
631 if (window.requestAnimationFrame) {
632 window.requestAnimationFrame(observerUpdate);
633 } else {
634 window.setTimeout(observerUpdate, 0);
635 }
636 });
637 observer.observe(target, {
638 attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
639 childList: swiper.isElement || (typeof options.childList === 'undefined' ? true : options).childList,
640 characterData: typeof options.characterData === 'undefined' ? true : options.characterData
641 });
642 observers.push(observer);
643 };
644 const init = () => {
645 if (!swiper.params.observer) return;
646 if (swiper.params.observeParents) {
647 const containerParents = elementParents(swiper.hostEl);
648 for (let i = 0; i < containerParents.length; i += 1) {
649 attach(containerParents[i]);
650 }
651 }
652 // Observe container
653 attach(swiper.hostEl, {
654 childList: swiper.params.observeSlideChildren
655 });
656
657 // Observe wrapper
658 attach(swiper.wrapperEl, {
659 attributes: false
660 });
661 };
662 const destroy = () => {
663 observers.forEach(observer => {
664 observer.disconnect();
665 });
666 observers.splice(0, observers.length);
667 };
668 extendParams({
669 observer: false,
670 observeParents: false,
671 observeSlideChildren: false
672 });
673 on('init', init);
674 on('destroy', destroy);
675 }
676
677 /* eslint-disable no-underscore-dangle */
678
679 var eventsEmitter = {
680 on(events, handler, priority) {
681 const self = this;
682 if (!self.eventsListeners || self.destroyed) return self;
683 if (typeof handler !== 'function') return self;
684 const method = priority ? 'unshift' : 'push';
685 events.split(' ').forEach(event => {
686 if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
687 self.eventsListeners[event][method](handler);
688 });
689 return self;
690 },
691 once(events, handler, priority) {
692 const self = this;
693 if (!self.eventsListeners || self.destroyed) return self;
694 if (typeof handler !== 'function') return self;
695 function onceHandler() {
696 self.off(events, onceHandler);
697 if (onceHandler.__emitterProxy) {
698 delete onceHandler.__emitterProxy;
699 }
700 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
701 args[_key] = arguments[_key];
702 }
703 handler.apply(self, args);
704 }
705 onceHandler.__emitterProxy = handler;
706 return self.on(events, onceHandler, priority);
707 },
708 onAny(handler, priority) {
709 const self = this;
710 if (!self.eventsListeners || self.destroyed) return self;
711 if (typeof handler !== 'function') return self;
712 const method = priority ? 'unshift' : 'push';
713 if (self.eventsAnyListeners.indexOf(handler) < 0) {
714 self.eventsAnyListeners[method](handler);
715 }
716 return self;
717 },
718 offAny(handler) {
719 const self = this;
720 if (!self.eventsListeners || self.destroyed) return self;
721 if (!self.eventsAnyListeners) return self;
722 const index = self.eventsAnyListeners.indexOf(handler);
723 if (index >= 0) {
724 self.eventsAnyListeners.splice(index, 1);
725 }
726 return self;
727 },
728 off(events, handler) {
729 const self = this;
730 if (!self.eventsListeners || self.destroyed) return self;
731 if (!self.eventsListeners) return self;
732 events.split(' ').forEach(event => {
733 if (typeof handler === 'undefined') {
734 self.eventsListeners[event] = [];
735 } else if (self.eventsListeners[event]) {
736 self.eventsListeners[event].forEach((eventHandler, index) => {
737 if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) {
738 self.eventsListeners[event].splice(index, 1);
739 }
740 });
741 }
742 });
743 return self;
744 },
745 emit() {
746 const self = this;
747 if (!self.eventsListeners || self.destroyed) return self;
748 if (!self.eventsListeners) return self;
749 let events;
750 let data;
751 let context;
752 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
753 args[_key2] = arguments[_key2];
754 }
755 if (typeof args[0] === 'string' || Array.isArray(args[0])) {
756 events = args[0];
757 data = args.slice(1, args.length);
758 context = self;
759 } else {
760 events = args[0].events;
761 data = args[0].data;
762 context = args[0].context || self;
763 }
764 data.unshift(context);
765 const eventsArray = Array.isArray(events) ? events : events.split(' ');
766 eventsArray.forEach(event => {
767 if (self.eventsAnyListeners && self.eventsAnyListeners.length) {
768 self.eventsAnyListeners.forEach(eventHandler => {
769 eventHandler.apply(context, [event, ...data]);
770 });
771 }
772 if (self.eventsListeners && self.eventsListeners[event]) {
773 self.eventsListeners[event].forEach(eventHandler => {
774 eventHandler.apply(context, data);
775 });
776 }
777 });
778 return self;
779 }
780 };
781
782 function updateSize() {
783 const swiper = this;
784 let width;
785 let height;
786 const el = swiper.el;
787 if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
788 width = swiper.params.width;
789 } else {
790 width = el.clientWidth;
791 }
792 if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
793 height = swiper.params.height;
794 } else {
795 height = el.clientHeight;
796 }
797 if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {
798 return;
799 }
800
801 // Subtract paddings
802 width = width - parseInt(elementStyle(el, 'padding-left') || 0, 10) - parseInt(elementStyle(el, 'padding-right') || 0, 10);
803 height = height - parseInt(elementStyle(el, 'padding-top') || 0, 10) - parseInt(elementStyle(el, 'padding-bottom') || 0, 10);
804 if (Number.isNaN(width)) width = 0;
805 if (Number.isNaN(height)) height = 0;
806 Object.assign(swiper, {
807 width,
808 height,
809 size: swiper.isHorizontal() ? width : height
810 });
811 }
812
813 function updateSlides() {
814 const swiper = this;
815 function getDirectionPropertyValue(node, label) {
816 return parseFloat(node.getPropertyValue(swiper.getDirectionLabel(label)) || 0);
817 }
818 const params = swiper.params;
819 const {
820 wrapperEl,
821 slidesEl,
822 size: swiperSize,
823 rtlTranslate: rtl,
824 wrongRTL
825 } = swiper;
826 const isVirtual = swiper.virtual && params.virtual.enabled;
827 const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
828 const slides = elementChildren(slidesEl, `.${swiper.params.slideClass}, swiper-slide`);
829 const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
830 let snapGrid = [];
831 const slidesGrid = [];
832 const slidesSizesGrid = [];
833 let offsetBefore = params.slidesOffsetBefore;
834 if (typeof offsetBefore === 'function') {
835 offsetBefore = params.slidesOffsetBefore.call(swiper);
836 }
837 let offsetAfter = params.slidesOffsetAfter;
838 if (typeof offsetAfter === 'function') {
839 offsetAfter = params.slidesOffsetAfter.call(swiper);
840 }
841 const previousSnapGridLength = swiper.snapGrid.length;
842 const previousSlidesGridLength = swiper.slidesGrid.length;
843 let spaceBetween = params.spaceBetween;
844 let slidePosition = -offsetBefore;
845 let prevSlideSize = 0;
846 let index = 0;
847 if (typeof swiperSize === 'undefined') {
848 return;
849 }
850 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
851 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
852 } else if (typeof spaceBetween === 'string') {
853 spaceBetween = parseFloat(spaceBetween);
854 }
855 swiper.virtualSize = -spaceBetween;
856
857 // reset margins
858 slides.forEach(slideEl => {
859 if (rtl) {
860 slideEl.style.marginLeft = '';
861 } else {
862 slideEl.style.marginRight = '';
863 }
864 slideEl.style.marginBottom = '';
865 slideEl.style.marginTop = '';
866 });
867
868 // reset cssMode offsets
869 if (params.centeredSlides && params.cssMode) {
870 setCSSProperty(wrapperEl, '--swiper-centered-offset-before', '');
871 setCSSProperty(wrapperEl, '--swiper-centered-offset-after', '');
872 }
873 const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
874 if (gridEnabled) {
875 swiper.grid.initSlides(slides);
876 } else if (swiper.grid) {
877 swiper.grid.unsetSlides();
878 }
879
880 // Calc slides
881 let slideSize;
882 const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => {
883 return typeof params.breakpoints[key].slidesPerView !== 'undefined';
884 }).length > 0;
885 for (let i = 0; i < slidesLength; i += 1) {
886 slideSize = 0;
887 let slide;
888 if (slides[i]) slide = slides[i];
889 if (gridEnabled) {
890 swiper.grid.updateSlide(i, slide, slides);
891 }
892 if (slides[i] && elementStyle(slide, 'display') === 'none') continue; // eslint-disable-line
893
894 if (params.slidesPerView === 'auto') {
895 if (shouldResetSlideSize) {
896 slides[i].style[swiper.getDirectionLabel('width')] = ``;
897 }
898 const slideStyles = getComputedStyle(slide);
899 const currentTransform = slide.style.transform;
900 const currentWebKitTransform = slide.style.webkitTransform;
901 if (currentTransform) {
902 slide.style.transform = 'none';
903 }
904 if (currentWebKitTransform) {
905 slide.style.webkitTransform = 'none';
906 }
907 if (params.roundLengths) {
908 slideSize = swiper.isHorizontal() ? elementOuterSize(slide, 'width', true) : elementOuterSize(slide, 'height', true);
909 } else {
910 // eslint-disable-next-line
911 const width = getDirectionPropertyValue(slideStyles, 'width');
912 const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
913 const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
914 const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
915 const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
916 const boxSizing = slideStyles.getPropertyValue('box-sizing');
917 if (boxSizing && boxSizing === 'border-box') {
918 slideSize = width + marginLeft + marginRight;
919 } else {
920 const {
921 clientWidth,
922 offsetWidth
923 } = slide;
924 slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);
925 }
926 }
927 if (currentTransform) {
928 slide.style.transform = currentTransform;
929 }
930 if (currentWebKitTransform) {
931 slide.style.webkitTransform = currentWebKitTransform;
932 }
933 if (params.roundLengths) slideSize = Math.floor(slideSize);
934 } else {
935 slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
936 if (params.roundLengths) slideSize = Math.floor(slideSize);
937 if (slides[i]) {
938 slides[i].style[swiper.getDirectionLabel('width')] = `${slideSize}px`;
939 }
940 }
941 if (slides[i]) {
942 slides[i].swiperSlideSize = slideSize;
943 }
944 slidesSizesGrid.push(slideSize);
945 if (params.centeredSlides) {
946 slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
947 if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
948 if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
949 if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
950 if (params.roundLengths) slidePosition = Math.floor(slidePosition);
951 if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
952 slidesGrid.push(slidePosition);
953 } else {
954 if (params.roundLengths) slidePosition = Math.floor(slidePosition);
955 if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);
956 slidesGrid.push(slidePosition);
957 slidePosition = slidePosition + slideSize + spaceBetween;
958 }
959 swiper.virtualSize += slideSize + spaceBetween;
960 prevSlideSize = slideSize;
961 index += 1;
962 }
963 swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
964 if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
965 wrapperEl.style.width = `${swiper.virtualSize + spaceBetween}px`;
966 }
967 if (params.setWrapperSize) {
968 wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
969 }
970 if (gridEnabled) {
971 swiper.grid.updateWrapperSize(slideSize, snapGrid);
972 }
973
974 // Remove last grid elements depending on width
975 if (!params.centeredSlides) {
976 const newSlidesGrid = [];
977 for (let i = 0; i < snapGrid.length; i += 1) {
978 let slidesGridItem = snapGrid[i];
979 if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
980 if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
981 newSlidesGrid.push(slidesGridItem);
982 }
983 }
984 snapGrid = newSlidesGrid;
985 if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
986 snapGrid.push(swiper.virtualSize - swiperSize);
987 }
988 }
989 if (isVirtual && params.loop) {
990 const size = slidesSizesGrid[0] + spaceBetween;
991 if (params.slidesPerGroup > 1) {
992 const groups = Math.ceil((swiper.virtual.slidesBefore + swiper.virtual.slidesAfter) / params.slidesPerGroup);
993 const groupSize = size * params.slidesPerGroup;
994 for (let i = 0; i < groups; i += 1) {
995 snapGrid.push(snapGrid[snapGrid.length - 1] + groupSize);
996 }
997 }
998 for (let i = 0; i < swiper.virtual.slidesBefore + swiper.virtual.slidesAfter; i += 1) {
999 if (params.slidesPerGroup === 1) {
1000 snapGrid.push(snapGrid[snapGrid.length - 1] + size);
1001 }
1002 slidesGrid.push(slidesGrid[slidesGrid.length - 1] + size);
1003 swiper.virtualSize += size;
1004 }
1005 }
1006 if (snapGrid.length === 0) snapGrid = [0];
1007 if (spaceBetween !== 0) {
1008 const key = swiper.isHorizontal() && rtl ? 'marginLeft' : swiper.getDirectionLabel('marginRight');
1009 slides.filter((_, slideIndex) => {
1010 if (!params.cssMode || params.loop) return true;
1011 if (slideIndex === slides.length - 1) {
1012 return false;
1013 }
1014 return true;
1015 }).forEach(slideEl => {
1016 slideEl.style[key] = `${spaceBetween}px`;
1017 });
1018 }
1019 if (params.centeredSlides && params.centeredSlidesBounds) {
1020 let allSlidesSize = 0;
1021 slidesSizesGrid.forEach(slideSizeValue => {
1022 allSlidesSize += slideSizeValue + (spaceBetween || 0);
1023 });
1024 allSlidesSize -= spaceBetween;
1025 const maxSnap = allSlidesSize > swiperSize ? allSlidesSize - swiperSize : 0;
1026 snapGrid = snapGrid.map(snap => {
1027 if (snap <= 0) return -offsetBefore;
1028 if (snap > maxSnap) return maxSnap + offsetAfter;
1029 return snap;
1030 });
1031 }
1032 if (params.centerInsufficientSlides) {
1033 let allSlidesSize = 0;
1034 slidesSizesGrid.forEach(slideSizeValue => {
1035 allSlidesSize += slideSizeValue + (spaceBetween || 0);
1036 });
1037 allSlidesSize -= spaceBetween;
1038 const offsetSize = (params.slidesOffsetBefore || 0) + (params.slidesOffsetAfter || 0);
1039 if (allSlidesSize + offsetSize < swiperSize) {
1040 const allSlidesOffset = (swiperSize - allSlidesSize - offsetSize) / 2;
1041 snapGrid.forEach((snap, snapIndex) => {
1042 snapGrid[snapIndex] = snap - allSlidesOffset;
1043 });
1044 slidesGrid.forEach((snap, snapIndex) => {
1045 slidesGrid[snapIndex] = snap + allSlidesOffset;
1046 });
1047 }
1048 }
1049 Object.assign(swiper, {
1050 slides,
1051 snapGrid,
1052 slidesGrid,
1053 slidesSizesGrid
1054 });
1055 if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) {
1056 setCSSProperty(wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`);
1057 setCSSProperty(wrapperEl, '--swiper-centered-offset-after', `${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`);
1058 const addToSnapGrid = -swiper.snapGrid[0];
1059 const addToSlidesGrid = -swiper.slidesGrid[0];
1060 swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);
1061 swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);
1062 }
1063 if (slidesLength !== previousSlidesLength) {
1064 swiper.emit('slidesLengthChange');
1065 }
1066 if (snapGrid.length !== previousSnapGridLength) {
1067 if (swiper.params.watchOverflow) swiper.checkOverflow();
1068 swiper.emit('snapGridLengthChange');
1069 }
1070 if (slidesGrid.length !== previousSlidesGridLength) {
1071 swiper.emit('slidesGridLengthChange');
1072 }
1073 if (params.watchSlidesProgress) {
1074 swiper.updateSlidesOffset();
1075 }
1076 swiper.emit('slidesUpdated');
1077 if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) {
1078 const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`;
1079 const hasClassBackfaceClassAdded = swiper.el.classList.contains(backFaceHiddenClass);
1080 if (slidesLength <= params.maxBackfaceHiddenSlides) {
1081 if (!hasClassBackfaceClassAdded) swiper.el.classList.add(backFaceHiddenClass);
1082 } else if (hasClassBackfaceClassAdded) {
1083 swiper.el.classList.remove(backFaceHiddenClass);
1084 }
1085 }
1086 }
1087
1088 function updateAutoHeight(speed) {
1089 const swiper = this;
1090 const activeSlides = [];
1091 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
1092 let newHeight = 0;
1093 let i;
1094 if (typeof speed === 'number') {
1095 swiper.setTransition(speed);
1096 } else if (speed === true) {
1097 swiper.setTransition(swiper.params.speed);
1098 }
1099 const getSlideByIndex = index => {
1100 if (isVirtual) {
1101 return swiper.slides[swiper.getSlideIndexByData(index)];
1102 }
1103 return swiper.slides[index];
1104 };
1105 // Find slides currently in view
1106 if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
1107 if (swiper.params.centeredSlides) {
1108 (swiper.visibleSlides || []).forEach(slide => {
1109 activeSlides.push(slide);
1110 });
1111 } else {
1112 for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
1113 const index = swiper.activeIndex + i;
1114 if (index > swiper.slides.length && !isVirtual) break;
1115 activeSlides.push(getSlideByIndex(index));
1116 }
1117 }
1118 } else {
1119 activeSlides.push(getSlideByIndex(swiper.activeIndex));
1120 }
1121
1122 // Find new height from highest slide in view
1123 for (i = 0; i < activeSlides.length; i += 1) {
1124 if (typeof activeSlides[i] !== 'undefined') {
1125 const height = activeSlides[i].offsetHeight;
1126 newHeight = height > newHeight ? height : newHeight;
1127 }
1128 }
1129
1130 // Update Height
1131 if (newHeight || newHeight === 0) swiper.wrapperEl.style.height = `${newHeight}px`;
1132 }
1133
1134 function updateSlidesOffset() {
1135 const swiper = this;
1136 const slides = swiper.slides;
1137 // eslint-disable-next-line
1138 const minusOffset = swiper.isElement ? swiper.isHorizontal() ? swiper.wrapperEl.offsetLeft : swiper.wrapperEl.offsetTop : 0;
1139 for (let i = 0; i < slides.length; i += 1) {
1140 slides[i].swiperSlideOffset = (swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop) - minusOffset - swiper.cssOverflowAdjustment();
1141 }
1142 }
1143
1144 const toggleSlideClasses$1 = (slideEl, condition, className) => {
1145 if (condition && !slideEl.classList.contains(className)) {
1146 slideEl.classList.add(className);
1147 } else if (!condition && slideEl.classList.contains(className)) {
1148 slideEl.classList.remove(className);
1149 }
1150 };
1151 function updateSlidesProgress(translate) {
1152 if (translate === void 0) {
1153 translate = this && this.translate || 0;
1154 }
1155 const swiper = this;
1156 const params = swiper.params;
1157 const {
1158 slides,
1159 rtlTranslate: rtl,
1160 snapGrid
1161 } = swiper;
1162 if (slides.length === 0) return;
1163 if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();
1164 let offsetCenter = -translate;
1165 if (rtl) offsetCenter = translate;
1166 swiper.visibleSlidesIndexes = [];
1167 swiper.visibleSlides = [];
1168 let spaceBetween = params.spaceBetween;
1169 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
1170 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
1171 } else if (typeof spaceBetween === 'string') {
1172 spaceBetween = parseFloat(spaceBetween);
1173 }
1174 for (let i = 0; i < slides.length; i += 1) {
1175 const slide = slides[i];
1176 let slideOffset = slide.swiperSlideOffset;
1177 if (params.cssMode && params.centeredSlides) {
1178 slideOffset -= slides[0].swiperSlideOffset;
1179 }
1180 const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
1181 const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
1182 const slideBefore = -(offsetCenter - slideOffset);
1183 const slideAfter = slideBefore + swiper.slidesSizesGrid[i];
1184 const isFullyVisible = slideBefore >= 0 && slideBefore <= swiper.size - swiper.slidesSizesGrid[i];
1185 const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size;
1186 if (isVisible) {
1187 swiper.visibleSlides.push(slide);
1188 swiper.visibleSlidesIndexes.push(i);
1189 }
1190 toggleSlideClasses$1(slide, isVisible, params.slideVisibleClass);
1191 toggleSlideClasses$1(slide, isFullyVisible, params.slideFullyVisibleClass);
1192 slide.progress = rtl ? -slideProgress : slideProgress;
1193 slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;
1194 }
1195 }
1196
1197 function updateProgress(translate) {
1198 const swiper = this;
1199 if (typeof translate === 'undefined') {
1200 const multiplier = swiper.rtlTranslate ? -1 : 1;
1201 // eslint-disable-next-line
1202 translate = swiper && swiper.translate && swiper.translate * multiplier || 0;
1203 }
1204 const params = swiper.params;
1205 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
1206 let {
1207 progress,
1208 isBeginning,
1209 isEnd,
1210 progressLoop
1211 } = swiper;
1212 const wasBeginning = isBeginning;
1213 const wasEnd = isEnd;
1214 if (translatesDiff === 0) {
1215 progress = 0;
1216 isBeginning = true;
1217 isEnd = true;
1218 } else {
1219 progress = (translate - swiper.minTranslate()) / translatesDiff;
1220 const isBeginningRounded = Math.abs(translate - swiper.minTranslate()) < 1;
1221 const isEndRounded = Math.abs(translate - swiper.maxTranslate()) < 1;
1222 isBeginning = isBeginningRounded || progress <= 0;
1223 isEnd = isEndRounded || progress >= 1;
1224 if (isBeginningRounded) progress = 0;
1225 if (isEndRounded) progress = 1;
1226 }
1227 if (params.loop) {
1228 const firstSlideIndex = swiper.getSlideIndexByData(0);
1229 const lastSlideIndex = swiper.getSlideIndexByData(swiper.slides.length - 1);
1230 const firstSlideTranslate = swiper.slidesGrid[firstSlideIndex];
1231 const lastSlideTranslate = swiper.slidesGrid[lastSlideIndex];
1232 const translateMax = swiper.slidesGrid[swiper.slidesGrid.length - 1];
1233 const translateAbs = Math.abs(translate);
1234 if (translateAbs >= firstSlideTranslate) {
1235 progressLoop = (translateAbs - firstSlideTranslate) / translateMax;
1236 } else {
1237 progressLoop = (translateAbs + translateMax - lastSlideTranslate) / translateMax;
1238 }
1239 if (progressLoop > 1) progressLoop -= 1;
1240 }
1241 Object.assign(swiper, {
1242 progress,
1243 progressLoop,
1244 isBeginning,
1245 isEnd
1246 });
1247 if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);
1248 if (isBeginning && !wasBeginning) {
1249 swiper.emit('reachBeginning toEdge');
1250 }
1251 if (isEnd && !wasEnd) {
1252 swiper.emit('reachEnd toEdge');
1253 }
1254 if (wasBeginning && !isBeginning || wasEnd && !isEnd) {
1255 swiper.emit('fromEdge');
1256 }
1257 swiper.emit('progress', progress);
1258 }
1259
1260 const toggleSlideClasses = (slideEl, condition, className) => {
1261 if (condition && !slideEl.classList.contains(className)) {
1262 slideEl.classList.add(className);
1263 } else if (!condition && slideEl.classList.contains(className)) {
1264 slideEl.classList.remove(className);
1265 }
1266 };
1267 function updateSlidesClasses() {
1268 const swiper = this;
1269 const {
1270 slides,
1271 params,
1272 slidesEl,
1273 activeIndex
1274 } = swiper;
1275 const isVirtual = swiper.virtual && params.virtual.enabled;
1276 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
1277 const getFilteredSlide = selector => {
1278 return elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0];
1279 };
1280 let activeSlide;
1281 let prevSlide;
1282 let nextSlide;
1283 if (isVirtual) {
1284 if (params.loop) {
1285 let slideIndex = activeIndex - swiper.virtual.slidesBefore;
1286 if (slideIndex < 0) slideIndex = swiper.virtual.slides.length + slideIndex;
1287 if (slideIndex >= swiper.virtual.slides.length) slideIndex -= swiper.virtual.slides.length;
1288 activeSlide = getFilteredSlide(`[data-swiper-slide-index="${slideIndex}"]`);
1289 } else {
1290 activeSlide = getFilteredSlide(`[data-swiper-slide-index="${activeIndex}"]`);
1291 }
1292 } else {
1293 if (gridEnabled) {
1294 activeSlide = slides.filter(slideEl => slideEl.column === activeIndex)[0];
1295 nextSlide = slides.filter(slideEl => slideEl.column === activeIndex + 1)[0];
1296 prevSlide = slides.filter(slideEl => slideEl.column === activeIndex - 1)[0];
1297 } else {
1298 activeSlide = slides[activeIndex];
1299 }
1300 }
1301 if (activeSlide) {
1302 if (!gridEnabled) {
1303 // Next Slide
1304 nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
1305 if (params.loop && !nextSlide) {
1306 nextSlide = slides[0];
1307 }
1308
1309 // Prev Slide
1310 prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
1311 if (params.loop && !prevSlide === 0) {
1312 prevSlide = slides[slides.length - 1];
1313 }
1314 }
1315 }
1316 slides.forEach(slideEl => {
1317 toggleSlideClasses(slideEl, slideEl === activeSlide, params.slideActiveClass);
1318 toggleSlideClasses(slideEl, slideEl === nextSlide, params.slideNextClass);
1319 toggleSlideClasses(slideEl, slideEl === prevSlide, params.slidePrevClass);
1320 });
1321 swiper.emitSlidesClasses();
1322 }
1323
1324 const processLazyPreloader = (swiper, imageEl) => {
1325 if (!swiper || swiper.destroyed || !swiper.params) return;
1326 const slideSelector = () => swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
1327 const slideEl = imageEl.closest(slideSelector());
1328 if (slideEl) {
1329 let lazyEl = slideEl.querySelector(`.${swiper.params.lazyPreloaderClass}`);
1330 if (!lazyEl && swiper.isElement) {
1331 if (slideEl.shadowRoot) {
1332 lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
1333 } else {
1334 // init later
1335 requestAnimationFrame(() => {
1336 if (slideEl.shadowRoot) {
1337 lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
1338 if (lazyEl) lazyEl.remove();
1339 }
1340 });
1341 }
1342 }
1343 if (lazyEl) lazyEl.remove();
1344 }
1345 };
1346 const unlazy = (swiper, index) => {
1347 if (!swiper.slides[index]) return;
1348 const imageEl = swiper.slides[index].querySelector('[loading="lazy"]');
1349 if (imageEl) imageEl.removeAttribute('loading');
1350 };
1351 const preload = swiper => {
1352 if (!swiper || swiper.destroyed || !swiper.params) return;
1353 let amount = swiper.params.lazyPreloadPrevNext;
1354 const len = swiper.slides.length;
1355 if (!len || !amount || amount < 0) return;
1356 amount = Math.min(amount, len);
1357 const slidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(swiper.params.slidesPerView);
1358 const activeIndex = swiper.activeIndex;
1359 if (swiper.params.grid && swiper.params.grid.rows > 1) {
1360 const activeColumn = activeIndex;
1361 const preloadColumns = [activeColumn - amount];
1362 preloadColumns.push(...Array.from({
1363 length: amount
1364 }).map((_, i) => {
1365 return activeColumn + slidesPerView + i;
1366 }));
1367 swiper.slides.forEach((slideEl, i) => {
1368 if (preloadColumns.includes(slideEl.column)) unlazy(swiper, i);
1369 });
1370 return;
1371 }
1372 const slideIndexLastInView = activeIndex + slidesPerView - 1;
1373 if (swiper.params.rewind || swiper.params.loop) {
1374 for (let i = activeIndex - amount; i <= slideIndexLastInView + amount; i += 1) {
1375 const realIndex = (i % len + len) % len;
1376 if (realIndex < activeIndex || realIndex > slideIndexLastInView) unlazy(swiper, realIndex);
1377 }
1378 } else {
1379 for (let i = Math.max(activeIndex - amount, 0); i <= Math.min(slideIndexLastInView + amount, len - 1); i += 1) {
1380 if (i !== activeIndex && (i > slideIndexLastInView || i < activeIndex)) {
1381 unlazy(swiper, i);
1382 }
1383 }
1384 }
1385 };
1386
1387 function getActiveIndexByTranslate(swiper) {
1388 const {
1389 slidesGrid,
1390 params
1391 } = swiper;
1392 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
1393 let activeIndex;
1394 for (let i = 0; i < slidesGrid.length; i += 1) {
1395 if (typeof slidesGrid[i + 1] !== 'undefined') {
1396 if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) {
1397 activeIndex = i;
1398 } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
1399 activeIndex = i + 1;
1400 }
1401 } else if (translate >= slidesGrid[i]) {
1402 activeIndex = i;
1403 }
1404 }
1405 // Normalize slideIndex
1406 if (params.normalizeSlideIndex) {
1407 if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
1408 }
1409 return activeIndex;
1410 }
1411 function updateActiveIndex(newActiveIndex) {
1412 const swiper = this;
1413 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
1414 const {
1415 snapGrid,
1416 params,
1417 activeIndex: previousIndex,
1418 realIndex: previousRealIndex,
1419 snapIndex: previousSnapIndex
1420 } = swiper;
1421 let activeIndex = newActiveIndex;
1422 let snapIndex;
1423 const getVirtualRealIndex = aIndex => {
1424 let realIndex = aIndex - swiper.virtual.slidesBefore;
1425 if (realIndex < 0) {
1426 realIndex = swiper.virtual.slides.length + realIndex;
1427 }
1428 if (realIndex >= swiper.virtual.slides.length) {
1429 realIndex -= swiper.virtual.slides.length;
1430 }
1431 return realIndex;
1432 };
1433 if (typeof activeIndex === 'undefined') {
1434 activeIndex = getActiveIndexByTranslate(swiper);
1435 }
1436 if (snapGrid.indexOf(translate) >= 0) {
1437 snapIndex = snapGrid.indexOf(translate);
1438 } else {
1439 const skip = Math.min(params.slidesPerGroupSkip, activeIndex);
1440 snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
1441 }
1442 if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
1443 if (activeIndex === previousIndex && !swiper.params.loop) {
1444 if (snapIndex !== previousSnapIndex) {
1445 swiper.snapIndex = snapIndex;
1446 swiper.emit('snapIndexChange');
1447 }
1448 return;
1449 }
1450 if (activeIndex === previousIndex && swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
1451 swiper.realIndex = getVirtualRealIndex(activeIndex);
1452 return;
1453 }
1454 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
1455
1456 // Get real index
1457 let realIndex;
1458 if (swiper.virtual && params.virtual.enabled && params.loop) {
1459 realIndex = getVirtualRealIndex(activeIndex);
1460 } else if (gridEnabled) {
1461 const firstSlideInColumn = swiper.slides.filter(slideEl => slideEl.column === activeIndex)[0];
1462 let activeSlideIndex = parseInt(firstSlideInColumn.getAttribute('data-swiper-slide-index'), 10);
1463 if (Number.isNaN(activeSlideIndex)) {
1464 activeSlideIndex = Math.max(swiper.slides.indexOf(firstSlideInColumn), 0);
1465 }
1466 realIndex = Math.floor(activeSlideIndex / params.grid.rows);
1467 } else if (swiper.slides[activeIndex]) {
1468 const slideIndex = swiper.slides[activeIndex].getAttribute('data-swiper-slide-index');
1469 if (slideIndex) {
1470 realIndex = parseInt(slideIndex, 10);
1471 } else {
1472 realIndex = activeIndex;
1473 }
1474 } else {
1475 realIndex = activeIndex;
1476 }
1477 Object.assign(swiper, {
1478 previousSnapIndex,
1479 snapIndex,
1480 previousRealIndex,
1481 realIndex,
1482 previousIndex,
1483 activeIndex
1484 });
1485 if (swiper.initialized) {
1486 preload(swiper);
1487 }
1488 swiper.emit('activeIndexChange');
1489 swiper.emit('snapIndexChange');
1490 if (swiper.initialized || swiper.params.runCallbacksOnInit) {
1491 if (previousRealIndex !== realIndex) {
1492 swiper.emit('realIndexChange');
1493 }
1494 swiper.emit('slideChange');
1495 }
1496 }
1497
1498 function updateClickedSlide(el, path) {
1499 const swiper = this;
1500 const params = swiper.params;
1501 let slide = el.closest(`.${params.slideClass}, swiper-slide`);
1502 if (!slide && swiper.isElement && path && path.length > 1 && path.includes(el)) {
1503 [...path.slice(path.indexOf(el) + 1, path.length)].forEach(pathEl => {
1504 if (!slide && pathEl.matches && pathEl.matches(`.${params.slideClass}, swiper-slide`)) {
1505 slide = pathEl;
1506 }
1507 });
1508 }
1509 let slideFound = false;
1510 let slideIndex;
1511 if (slide) {
1512 for (let i = 0; i < swiper.slides.length; i += 1) {
1513 if (swiper.slides[i] === slide) {
1514 slideFound = true;
1515 slideIndex = i;
1516 break;
1517 }
1518 }
1519 }
1520 if (slide && slideFound) {
1521 swiper.clickedSlide = slide;
1522 if (swiper.virtual && swiper.params.virtual.enabled) {
1523 swiper.clickedIndex = parseInt(slide.getAttribute('data-swiper-slide-index'), 10);
1524 } else {
1525 swiper.clickedIndex = slideIndex;
1526 }
1527 } else {
1528 swiper.clickedSlide = undefined;
1529 swiper.clickedIndex = undefined;
1530 return;
1531 }
1532 if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
1533 swiper.slideToClickedSlide();
1534 }
1535 }
1536
1537 var update = {
1538 updateSize,
1539 updateSlides,
1540 updateAutoHeight,
1541 updateSlidesOffset,
1542 updateSlidesProgress,
1543 updateProgress,
1544 updateSlidesClasses,
1545 updateActiveIndex,
1546 updateClickedSlide
1547 };
1548
1549 function getSwiperTranslate(axis) {
1550 if (axis === void 0) {
1551 axis = this.isHorizontal() ? 'x' : 'y';
1552 }
1553 const swiper = this;
1554 const {
1555 params,
1556 rtlTranslate: rtl,
1557 translate,
1558 wrapperEl
1559 } = swiper;
1560 if (params.virtualTranslate) {
1561 return rtl ? -translate : translate;
1562 }
1563 if (params.cssMode) {
1564 return translate;
1565 }
1566 let currentTranslate = getTranslate(wrapperEl, axis);
1567 currentTranslate += swiper.cssOverflowAdjustment();
1568 if (rtl) currentTranslate = -currentTranslate;
1569 return currentTranslate || 0;
1570 }
1571
1572 function setTranslate(translate, byController) {
1573 const swiper = this;
1574 const {
1575 rtlTranslate: rtl,
1576 params,
1577 wrapperEl,
1578 progress
1579 } = swiper;
1580 let x = 0;
1581 let y = 0;
1582 const z = 0;
1583 if (swiper.isHorizontal()) {
1584 x = rtl ? -translate : translate;
1585 } else {
1586 y = translate;
1587 }
1588 if (params.roundLengths) {
1589 x = Math.floor(x);
1590 y = Math.floor(y);
1591 }
1592 swiper.previousTranslate = swiper.translate;
1593 swiper.translate = swiper.isHorizontal() ? x : y;
1594 if (params.cssMode) {
1595 wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
1596 } else if (!params.virtualTranslate) {
1597 if (swiper.isHorizontal()) {
1598 x -= swiper.cssOverflowAdjustment();
1599 } else {
1600 y -= swiper.cssOverflowAdjustment();
1601 }
1602 wrapperEl.style.transform = `translate3d(${x}px, ${y}px, ${z}px)`;
1603 }
1604
1605 // Check if we need to update progress
1606 let newProgress;
1607 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
1608 if (translatesDiff === 0) {
1609 newProgress = 0;
1610 } else {
1611 newProgress = (translate - swiper.minTranslate()) / translatesDiff;
1612 }
1613 if (newProgress !== progress) {
1614 swiper.updateProgress(translate);
1615 }
1616 swiper.emit('setTranslate', swiper.translate, byController);
1617 }
1618
1619 function minTranslate() {
1620 return -this.snapGrid[0];
1621 }
1622
1623 function maxTranslate() {
1624 return -this.snapGrid[this.snapGrid.length - 1];
1625 }
1626
1627 function translateTo(translate, speed, runCallbacks, translateBounds, internal) {
1628 if (translate === void 0) {
1629 translate = 0;
1630 }
1631 if (speed === void 0) {
1632 speed = this.params.speed;
1633 }
1634 if (runCallbacks === void 0) {
1635 runCallbacks = true;
1636 }
1637 if (translateBounds === void 0) {
1638 translateBounds = true;
1639 }
1640 const swiper = this;
1641 const {
1642 params,
1643 wrapperEl
1644 } = swiper;
1645 if (swiper.animating && params.preventInteractionOnTransition) {
1646 return false;
1647 }
1648 const minTranslate = swiper.minTranslate();
1649 const maxTranslate = swiper.maxTranslate();
1650 let newTranslate;
1651 if (translateBounds && translate > minTranslate) newTranslate = minTranslate;else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;else newTranslate = translate;
1652
1653 // Update progress
1654 swiper.updateProgress(newTranslate);
1655 if (params.cssMode) {
1656 const isH = swiper.isHorizontal();
1657 if (speed === 0) {
1658 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
1659 } else {
1660 if (!swiper.support.smoothScroll) {
1661 animateCSSModeScroll({
1662 swiper,
1663 targetPosition: -newTranslate,
1664 side: isH ? 'left' : 'top'
1665 });
1666 return true;
1667 }
1668 wrapperEl.scrollTo({
1669 [isH ? 'left' : 'top']: -newTranslate,
1670 behavior: 'smooth'
1671 });
1672 }
1673 return true;
1674 }
1675 if (speed === 0) {
1676 swiper.setTransition(0);
1677 swiper.setTranslate(newTranslate);
1678 if (runCallbacks) {
1679 swiper.emit('beforeTransitionStart', speed, internal);
1680 swiper.emit('transitionEnd');
1681 }
1682 } else {
1683 swiper.setTransition(speed);
1684 swiper.setTranslate(newTranslate);
1685 if (runCallbacks) {
1686 swiper.emit('beforeTransitionStart', speed, internal);
1687 swiper.emit('transitionStart');
1688 }
1689 if (!swiper.animating) {
1690 swiper.animating = true;
1691 if (!swiper.onTranslateToWrapperTransitionEnd) {
1692 swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
1693 if (!swiper || swiper.destroyed) return;
1694 if (e.target !== this) return;
1695 swiper.wrapperEl.removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
1696 swiper.onTranslateToWrapperTransitionEnd = null;
1697 delete swiper.onTranslateToWrapperTransitionEnd;
1698 swiper.animating = false;
1699 if (runCallbacks) {
1700 swiper.emit('transitionEnd');
1701 }
1702 };
1703 }
1704 swiper.wrapperEl.addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
1705 }
1706 }
1707 return true;
1708 }
1709
1710 var translate = {
1711 getTranslate: getSwiperTranslate,
1712 setTranslate,
1713 minTranslate,
1714 maxTranslate,
1715 translateTo
1716 };
1717
1718 function setTransition(duration, byController) {
1719 const swiper = this;
1720 if (!swiper.params.cssMode) {
1721 swiper.wrapperEl.style.transitionDuration = `${duration}ms`;
1722 swiper.wrapperEl.style.transitionDelay = duration === 0 ? `0ms` : '';
1723 }
1724 swiper.emit('setTransition', duration, byController);
1725 }
1726
1727 function transitionEmit(_ref) {
1728 let {
1729 swiper,
1730 runCallbacks,
1731 direction,
1732 step
1733 } = _ref;
1734 const {
1735 activeIndex,
1736 previousIndex
1737 } = swiper;
1738 let dir = direction;
1739 if (!dir) {
1740 if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset';
1741 }
1742 swiper.emit(`transition${step}`);
1743 if (runCallbacks && activeIndex !== previousIndex) {
1744 if (dir === 'reset') {
1745 swiper.emit(`slideResetTransition${step}`);
1746 return;
1747 }
1748 swiper.emit(`slideChangeTransition${step}`);
1749 if (dir === 'next') {
1750 swiper.emit(`slideNextTransition${step}`);
1751 } else {
1752 swiper.emit(`slidePrevTransition${step}`);
1753 }
1754 }
1755 }
1756
1757 function transitionStart(runCallbacks, direction) {
1758 if (runCallbacks === void 0) {
1759 runCallbacks = true;
1760 }
1761 const swiper = this;
1762 const {
1763 params
1764 } = swiper;
1765 if (params.cssMode) return;
1766 if (params.autoHeight) {
1767 swiper.updateAutoHeight();
1768 }
1769 transitionEmit({
1770 swiper,
1771 runCallbacks,
1772 direction,
1773 step: 'Start'
1774 });
1775 }
1776
1777 function transitionEnd(runCallbacks, direction) {
1778 if (runCallbacks === void 0) {
1779 runCallbacks = true;
1780 }
1781 const swiper = this;
1782 const {
1783 params
1784 } = swiper;
1785 swiper.animating = false;
1786 if (params.cssMode) return;
1787 swiper.setTransition(0);
1788 transitionEmit({
1789 swiper,
1790 runCallbacks,
1791 direction,
1792 step: 'End'
1793 });
1794 }
1795
1796 var transition = {
1797 setTransition,
1798 transitionStart,
1799 transitionEnd
1800 };
1801
1802 function slideTo(index, speed, runCallbacks, internal, initial) {
1803 if (index === void 0) {
1804 index = 0;
1805 }
1806 if (runCallbacks === void 0) {
1807 runCallbacks = true;
1808 }
1809 if (typeof index === 'string') {
1810 index = parseInt(index, 10);
1811 }
1812 const swiper = this;
1813 let slideIndex = index;
1814 if (slideIndex < 0) slideIndex = 0;
1815 const {
1816 params,
1817 snapGrid,
1818 slidesGrid,
1819 previousIndex,
1820 activeIndex,
1821 rtlTranslate: rtl,
1822 wrapperEl,
1823 enabled
1824 } = swiper;
1825 if (!enabled && !internal && !initial || swiper.destroyed || swiper.animating && params.preventInteractionOnTransition) {
1826 return false;
1827 }
1828 if (typeof speed === 'undefined') {
1829 speed = swiper.params.speed;
1830 }
1831 const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
1832 let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
1833 if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
1834 const translate = -snapGrid[snapIndex];
1835 // Normalize slideIndex
1836 if (params.normalizeSlideIndex) {
1837 for (let i = 0; i < slidesGrid.length; i += 1) {
1838 const normalizedTranslate = -Math.floor(translate * 100);
1839 const normalizedGrid = Math.floor(slidesGrid[i] * 100);
1840 const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
1841 if (typeof slidesGrid[i + 1] !== 'undefined') {
1842 if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) {
1843 slideIndex = i;
1844 } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
1845 slideIndex = i + 1;
1846 }
1847 } else if (normalizedTranslate >= normalizedGrid) {
1848 slideIndex = i;
1849 }
1850 }
1851 }
1852 // Directions locks
1853 if (swiper.initialized && slideIndex !== activeIndex) {
1854 if (!swiper.allowSlideNext && (rtl ? translate > swiper.translate && translate > swiper.minTranslate() : translate < swiper.translate && translate < swiper.minTranslate())) {
1855 return false;
1856 }
1857 if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
1858 if ((activeIndex || 0) !== slideIndex) {
1859 return false;
1860 }
1861 }
1862 }
1863 if (slideIndex !== (previousIndex || 0) && runCallbacks) {
1864 swiper.emit('beforeSlideChangeStart');
1865 }
1866
1867 // Update progress
1868 swiper.updateProgress(translate);
1869 let direction;
1870 if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset';
1871
1872 // initial virtual
1873 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
1874 const isInitialVirtual = isVirtual && initial;
1875 // Update Index
1876 if (!isInitialVirtual && (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate)) {
1877 swiper.updateActiveIndex(slideIndex);
1878 // Update Height
1879 if (params.autoHeight) {
1880 swiper.updateAutoHeight();
1881 }
1882 swiper.updateSlidesClasses();
1883 if (params.effect !== 'slide') {
1884 swiper.setTranslate(translate);
1885 }
1886 if (direction !== 'reset') {
1887 swiper.transitionStart(runCallbacks, direction);
1888 swiper.transitionEnd(runCallbacks, direction);
1889 }
1890 return false;
1891 }
1892 if (params.cssMode) {
1893 const isH = swiper.isHorizontal();
1894 const t = rtl ? translate : -translate;
1895 if (speed === 0) {
1896 if (isVirtual) {
1897 swiper.wrapperEl.style.scrollSnapType = 'none';
1898 swiper._immediateVirtual = true;
1899 }
1900 if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) {
1901 swiper._cssModeVirtualInitialSet = true;
1902 requestAnimationFrame(() => {
1903 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1904 });
1905 } else {
1906 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1907 }
1908 if (isVirtual) {
1909 requestAnimationFrame(() => {
1910 swiper.wrapperEl.style.scrollSnapType = '';
1911 swiper._immediateVirtual = false;
1912 });
1913 }
1914 } else {
1915 if (!swiper.support.smoothScroll) {
1916 animateCSSModeScroll({
1917 swiper,
1918 targetPosition: t,
1919 side: isH ? 'left' : 'top'
1920 });
1921 return true;
1922 }
1923 wrapperEl.scrollTo({
1924 [isH ? 'left' : 'top']: t,
1925 behavior: 'smooth'
1926 });
1927 }
1928 return true;
1929 }
1930 swiper.setTransition(speed);
1931 swiper.setTranslate(translate);
1932 swiper.updateActiveIndex(slideIndex);
1933 swiper.updateSlidesClasses();
1934 swiper.emit('beforeTransitionStart', speed, internal);
1935 swiper.transitionStart(runCallbacks, direction);
1936 if (speed === 0) {
1937 swiper.transitionEnd(runCallbacks, direction);
1938 } else if (!swiper.animating) {
1939 swiper.animating = true;
1940 if (!swiper.onSlideToWrapperTransitionEnd) {
1941 swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
1942 if (!swiper || swiper.destroyed) return;
1943 if (e.target !== this) return;
1944 swiper.wrapperEl.removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
1945 swiper.onSlideToWrapperTransitionEnd = null;
1946 delete swiper.onSlideToWrapperTransitionEnd;
1947 swiper.transitionEnd(runCallbacks, direction);
1948 };
1949 }
1950 swiper.wrapperEl.addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
1951 }
1952 return true;
1953 }
1954
1955 function slideToLoop(index, speed, runCallbacks, internal) {
1956 if (index === void 0) {
1957 index = 0;
1958 }
1959 if (runCallbacks === void 0) {
1960 runCallbacks = true;
1961 }
1962 if (typeof index === 'string') {
1963 const indexAsNumber = parseInt(index, 10);
1964 index = indexAsNumber;
1965 }
1966 const swiper = this;
1967 if (swiper.destroyed) return;
1968 if (typeof speed === 'undefined') {
1969 speed = swiper.params.speed;
1970 }
1971 const gridEnabled = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
1972 let newIndex = index;
1973 if (swiper.params.loop) {
1974 if (swiper.virtual && swiper.params.virtual.enabled) {
1975 // eslint-disable-next-line
1976 newIndex = newIndex + swiper.virtual.slidesBefore;
1977 } else {
1978 let targetSlideIndex;
1979 if (gridEnabled) {
1980 const slideIndex = newIndex * swiper.params.grid.rows;
1981 targetSlideIndex = swiper.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex)[0].column;
1982 } else {
1983 targetSlideIndex = swiper.getSlideIndexByData(newIndex);
1984 }
1985 const cols = gridEnabled ? Math.ceil(swiper.slides.length / swiper.params.grid.rows) : swiper.slides.length;
1986 const {
1987 centeredSlides
1988 } = swiper.params;
1989 let slidesPerView = swiper.params.slidesPerView;
1990 if (slidesPerView === 'auto') {
1991 slidesPerView = swiper.slidesPerViewDynamic();
1992 } else {
1993 slidesPerView = Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
1994 if (centeredSlides && slidesPerView % 2 === 0) {
1995 slidesPerView = slidesPerView + 1;
1996 }
1997 }
1998 let needLoopFix = cols - targetSlideIndex < slidesPerView;
1999 if (centeredSlides) {
2000 needLoopFix = needLoopFix || targetSlideIndex < Math.ceil(slidesPerView / 2);
2001 }
2002 if (internal && centeredSlides && swiper.params.slidesPerView !== 'auto' && !gridEnabled) {
2003 needLoopFix = false;
2004 }
2005 if (needLoopFix) {
2006 const direction = centeredSlides ? targetSlideIndex < swiper.activeIndex ? 'prev' : 'next' : targetSlideIndex - swiper.activeIndex - 1 < swiper.params.slidesPerView ? 'next' : 'prev';
2007 swiper.loopFix({
2008 direction,
2009 slideTo: true,
2010 activeSlideIndex: direction === 'next' ? targetSlideIndex + 1 : targetSlideIndex - cols + 1,
2011 slideRealIndex: direction === 'next' ? swiper.realIndex : undefined
2012 });
2013 }
2014 if (gridEnabled) {
2015 const slideIndex = newIndex * swiper.params.grid.rows;
2016 newIndex = swiper.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex)[0].column;
2017 } else {
2018 newIndex = swiper.getSlideIndexByData(newIndex);
2019 }
2020 }
2021 }
2022 requestAnimationFrame(() => {
2023 swiper.slideTo(newIndex, speed, runCallbacks, internal);
2024 });
2025 return swiper;
2026 }
2027
2028 /* eslint no-unused-vars: "off" */
2029 function slideNext(speed, runCallbacks, internal) {
2030 if (runCallbacks === void 0) {
2031 runCallbacks = true;
2032 }
2033 const swiper = this;
2034 const {
2035 enabled,
2036 params,
2037 animating
2038 } = swiper;
2039 if (!enabled || swiper.destroyed) return swiper;
2040 if (typeof speed === 'undefined') {
2041 speed = swiper.params.speed;
2042 }
2043 let perGroup = params.slidesPerGroup;
2044 if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
2045 perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
2046 }
2047 const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
2048 const isVirtual = swiper.virtual && params.virtual.enabled;
2049 if (params.loop) {
2050 if (animating && !isVirtual && params.loopPreventsSliding) return false;
2051 swiper.loopFix({
2052 direction: 'next'
2053 });
2054 // eslint-disable-next-line
2055 swiper._clientLeft = swiper.wrapperEl.clientLeft;
2056 if (swiper.activeIndex === swiper.slides.length - 1 && params.cssMode) {
2057 requestAnimationFrame(() => {
2058 swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
2059 });
2060 return true;
2061 }
2062 }
2063 if (params.rewind && swiper.isEnd) {
2064 return swiper.slideTo(0, speed, runCallbacks, internal);
2065 }
2066 return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
2067 }
2068
2069 /* eslint no-unused-vars: "off" */
2070 function slidePrev(speed, runCallbacks, internal) {
2071 if (runCallbacks === void 0) {
2072 runCallbacks = true;
2073 }
2074 const swiper = this;
2075 const {
2076 params,
2077 snapGrid,
2078 slidesGrid,
2079 rtlTranslate,
2080 enabled,
2081 animating
2082 } = swiper;
2083 if (!enabled || swiper.destroyed) return swiper;
2084 if (typeof speed === 'undefined') {
2085 speed = swiper.params.speed;
2086 }
2087 const isVirtual = swiper.virtual && params.virtual.enabled;
2088 if (params.loop) {
2089 if (animating && !isVirtual && params.loopPreventsSliding) return false;
2090 swiper.loopFix({
2091 direction: 'prev'
2092 });
2093 // eslint-disable-next-line
2094 swiper._clientLeft = swiper.wrapperEl.clientLeft;
2095 }
2096 const translate = rtlTranslate ? swiper.translate : -swiper.translate;
2097 function normalize(val) {
2098 if (val < 0) return -Math.floor(Math.abs(val));
2099 return Math.floor(val);
2100 }
2101 const normalizedTranslate = normalize(translate);
2102 const normalizedSnapGrid = snapGrid.map(val => normalize(val));
2103 let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
2104 if (typeof prevSnap === 'undefined' && params.cssMode) {
2105 let prevSnapIndex;
2106 snapGrid.forEach((snap, snapIndex) => {
2107 if (normalizedTranslate >= snap) {
2108 // prevSnap = snap;
2109 prevSnapIndex = snapIndex;
2110 }
2111 });
2112 if (typeof prevSnapIndex !== 'undefined') {
2113 prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
2114 }
2115 }
2116 let prevIndex = 0;
2117 if (typeof prevSnap !== 'undefined') {
2118 prevIndex = slidesGrid.indexOf(prevSnap);
2119 if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
2120 if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
2121 prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1;
2122 prevIndex = Math.max(prevIndex, 0);
2123 }
2124 }
2125 if (params.rewind && swiper.isBeginning) {
2126 const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
2127 return swiper.slideTo(lastIndex, speed, runCallbacks, internal);
2128 } else if (params.loop && swiper.activeIndex === 0 && params.cssMode) {
2129 requestAnimationFrame(() => {
2130 swiper.slideTo(prevIndex, speed, runCallbacks, internal);
2131 });
2132 return true;
2133 }
2134 return swiper.slideTo(prevIndex, speed, runCallbacks, internal);
2135 }
2136
2137 /* eslint no-unused-vars: "off" */
2138 function slideReset(speed, runCallbacks, internal) {
2139 if (runCallbacks === void 0) {
2140 runCallbacks = true;
2141 }
2142 const swiper = this;
2143 if (swiper.destroyed) return;
2144 if (typeof speed === 'undefined') {
2145 speed = swiper.params.speed;
2146 }
2147 return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
2148 }
2149
2150 /* eslint no-unused-vars: "off" */
2151 function slideToClosest(speed, runCallbacks, internal, threshold) {
2152 if (runCallbacks === void 0) {
2153 runCallbacks = true;
2154 }
2155 if (threshold === void 0) {
2156 threshold = 0.5;
2157 }
2158 const swiper = this;
2159 if (swiper.destroyed) return;
2160 if (typeof speed === 'undefined') {
2161 speed = swiper.params.speed;
2162 }
2163 let index = swiper.activeIndex;
2164 const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
2165 const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
2166 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
2167 if (translate >= swiper.snapGrid[snapIndex]) {
2168 // The current translate is on or after the current snap index, so the choice
2169 // is between the current index and the one after it.
2170 const currentSnap = swiper.snapGrid[snapIndex];
2171 const nextSnap = swiper.snapGrid[snapIndex + 1];
2172 if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {
2173 index += swiper.params.slidesPerGroup;
2174 }
2175 } else {
2176 // The current translate is before the current snap index, so the choice
2177 // is between the current index and the one before it.
2178 const prevSnap = swiper.snapGrid[snapIndex - 1];
2179 const currentSnap = swiper.snapGrid[snapIndex];
2180 if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) {
2181 index -= swiper.params.slidesPerGroup;
2182 }
2183 }
2184 index = Math.max(index, 0);
2185 index = Math.min(index, swiper.slidesGrid.length - 1);
2186 return swiper.slideTo(index, speed, runCallbacks, internal);
2187 }
2188
2189 function slideToClickedSlide() {
2190 const swiper = this;
2191 if (swiper.destroyed) return;
2192 const {
2193 params,
2194 slidesEl
2195 } = swiper;
2196 const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
2197 let slideToIndex = swiper.clickedIndex;
2198 let realIndex;
2199 const slideSelector = swiper.isElement ? `swiper-slide` : `.${params.slideClass}`;
2200 if (params.loop) {
2201 if (swiper.animating) return;
2202 realIndex = parseInt(swiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
2203 if (params.centeredSlides) {
2204 if (slideToIndex < swiper.loopedSlides - slidesPerView / 2 || slideToIndex > swiper.slides.length - swiper.loopedSlides + slidesPerView / 2) {
2205 swiper.loopFix();
2206 slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
2207 nextTick(() => {
2208 swiper.slideTo(slideToIndex);
2209 });
2210 } else {
2211 swiper.slideTo(slideToIndex);
2212 }
2213 } else if (slideToIndex > swiper.slides.length - slidesPerView) {
2214 swiper.loopFix();
2215 slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
2216 nextTick(() => {
2217 swiper.slideTo(slideToIndex);
2218 });
2219 } else {
2220 swiper.slideTo(slideToIndex);
2221 }
2222 } else {
2223 swiper.slideTo(slideToIndex);
2224 }
2225 }
2226
2227 var slide = {
2228 slideTo,
2229 slideToLoop,
2230 slideNext,
2231 slidePrev,
2232 slideReset,
2233 slideToClosest,
2234 slideToClickedSlide
2235 };
2236
2237 function loopCreate(slideRealIndex) {
2238 const swiper = this;
2239 const {
2240 params,
2241 slidesEl
2242 } = swiper;
2243 if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
2244 const initSlides = () => {
2245 const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
2246 slides.forEach((el, index) => {
2247 el.setAttribute('data-swiper-slide-index', index);
2248 });
2249 };
2250 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
2251 const slidesPerGroup = params.slidesPerGroup * (gridEnabled ? params.grid.rows : 1);
2252 const shouldFillGroup = swiper.slides.length % slidesPerGroup !== 0;
2253 const shouldFillGrid = gridEnabled && swiper.slides.length % params.grid.rows !== 0;
2254 const addBlankSlides = amountOfSlides => {
2255 for (let i = 0; i < amountOfSlides; i += 1) {
2256 const slideEl = swiper.isElement ? createElement('swiper-slide', [params.slideBlankClass]) : createElement('div', [params.slideClass, params.slideBlankClass]);
2257 swiper.slidesEl.append(slideEl);
2258 }
2259 };
2260 if (shouldFillGroup) {
2261 if (params.loopAddBlankSlides) {
2262 const slidesToAdd = slidesPerGroup - swiper.slides.length % slidesPerGroup;
2263 addBlankSlides(slidesToAdd);
2264 swiper.recalcSlides();
2265 swiper.updateSlides();
2266 } else {
2267 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)');
2268 }
2269 initSlides();
2270 } else if (shouldFillGrid) {
2271 if (params.loopAddBlankSlides) {
2272 const slidesToAdd = params.grid.rows - swiper.slides.length % params.grid.rows;
2273 addBlankSlides(slidesToAdd);
2274 swiper.recalcSlides();
2275 swiper.updateSlides();
2276 } else {
2277 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)');
2278 }
2279 initSlides();
2280 } else {
2281 initSlides();
2282 }
2283 swiper.loopFix({
2284 slideRealIndex,
2285 direction: params.centeredSlides ? undefined : 'next'
2286 });
2287 }
2288
2289 function loopFix(_temp) {
2290 let {
2291 slideRealIndex,
2292 slideTo = true,
2293 direction,
2294 setTranslate,
2295 activeSlideIndex,
2296 byController,
2297 byMousewheel
2298 } = _temp === void 0 ? {} : _temp;
2299 const swiper = this;
2300 if (!swiper.params.loop) return;
2301 swiper.emit('beforeLoopFix');
2302 const {
2303 slides,
2304 allowSlidePrev,
2305 allowSlideNext,
2306 slidesEl,
2307 params
2308 } = swiper;
2309 const {
2310 centeredSlides
2311 } = params;
2312 swiper.allowSlidePrev = true;
2313 swiper.allowSlideNext = true;
2314 if (swiper.virtual && params.virtual.enabled) {
2315 if (slideTo) {
2316 if (!params.centeredSlides && swiper.snapIndex === 0) {
2317 swiper.slideTo(swiper.virtual.slides.length, 0, false, true);
2318 } else if (params.centeredSlides && swiper.snapIndex < params.slidesPerView) {
2319 swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true);
2320 } else if (swiper.snapIndex === swiper.snapGrid.length - 1) {
2321 swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true);
2322 }
2323 }
2324 swiper.allowSlidePrev = allowSlidePrev;
2325 swiper.allowSlideNext = allowSlideNext;
2326 swiper.emit('loopFix');
2327 return;
2328 }
2329 let slidesPerView = params.slidesPerView;
2330 if (slidesPerView === 'auto') {
2331 slidesPerView = swiper.slidesPerViewDynamic();
2332 } else {
2333 slidesPerView = Math.ceil(parseFloat(params.slidesPerView, 10));
2334 if (centeredSlides && slidesPerView % 2 === 0) {
2335 slidesPerView = slidesPerView + 1;
2336 }
2337 }
2338 const slidesPerGroup = params.slidesPerGroupAuto ? slidesPerView : params.slidesPerGroup;
2339 let loopedSlides = slidesPerGroup;
2340 if (loopedSlides % slidesPerGroup !== 0) {
2341 loopedSlides += slidesPerGroup - loopedSlides % slidesPerGroup;
2342 }
2343 loopedSlides += params.loopAdditionalSlides;
2344 swiper.loopedSlides = loopedSlides;
2345 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
2346 if (slides.length < slidesPerView + loopedSlides) {
2347 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');
2348 } else if (gridEnabled && params.grid.fill === 'row') {
2349 showWarning('Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`');
2350 }
2351 const prependSlidesIndexes = [];
2352 const appendSlidesIndexes = [];
2353 let activeIndex = swiper.activeIndex;
2354 if (typeof activeSlideIndex === 'undefined') {
2355 activeSlideIndex = swiper.getSlideIndex(slides.filter(el => el.classList.contains(params.slideActiveClass))[0]);
2356 } else {
2357 activeIndex = activeSlideIndex;
2358 }
2359 const isNext = direction === 'next' || !direction;
2360 const isPrev = direction === 'prev' || !direction;
2361 let slidesPrepended = 0;
2362 let slidesAppended = 0;
2363 const cols = gridEnabled ? Math.ceil(slides.length / params.grid.rows) : slides.length;
2364 const activeColIndex = gridEnabled ? slides[activeSlideIndex].column : activeSlideIndex;
2365 const activeColIndexWithShift = activeColIndex + (centeredSlides && typeof setTranslate === 'undefined' ? -slidesPerView / 2 + 0.5 : 0);
2366 // prepend last slides before start
2367 if (activeColIndexWithShift < loopedSlides) {
2368 slidesPrepended = Math.max(loopedSlides - activeColIndexWithShift, slidesPerGroup);
2369 for (let i = 0; i < loopedSlides - activeColIndexWithShift; i += 1) {
2370 const index = i - Math.floor(i / cols) * cols;
2371 if (gridEnabled) {
2372 const colIndexToPrepend = cols - index - 1;
2373 for (let i = slides.length - 1; i >= 0; i -= 1) {
2374 if (slides[i].column === colIndexToPrepend) prependSlidesIndexes.push(i);
2375 }
2376 // slides.forEach((slide, slideIndex) => {
2377 // if (slide.column === colIndexToPrepend) prependSlidesIndexes.push(slideIndex);
2378 // });
2379 } else {
2380 prependSlidesIndexes.push(cols - index - 1);
2381 }
2382 }
2383 } else if (activeColIndexWithShift + slidesPerView > cols - loopedSlides) {
2384 slidesAppended = Math.max(activeColIndexWithShift - (cols - loopedSlides * 2), slidesPerGroup);
2385 for (let i = 0; i < slidesAppended; i += 1) {
2386 const index = i - Math.floor(i / cols) * cols;
2387 if (gridEnabled) {
2388 slides.forEach((slide, slideIndex) => {
2389 if (slide.column === index) appendSlidesIndexes.push(slideIndex);
2390 });
2391 } else {
2392 appendSlidesIndexes.push(index);
2393 }
2394 }
2395 }
2396 swiper.__preventObserver__ = true;
2397 requestAnimationFrame(() => {
2398 swiper.__preventObserver__ = false;
2399 });
2400 if (isPrev) {
2401 prependSlidesIndexes.forEach(index => {
2402 slides[index].swiperLoopMoveDOM = true;
2403 slidesEl.prepend(slides[index]);
2404 slides[index].swiperLoopMoveDOM = false;
2405 });
2406 }
2407 if (isNext) {
2408 appendSlidesIndexes.forEach(index => {
2409 slides[index].swiperLoopMoveDOM = true;
2410 slidesEl.append(slides[index]);
2411 slides[index].swiperLoopMoveDOM = false;
2412 });
2413 }
2414 swiper.recalcSlides();
2415 if (params.slidesPerView === 'auto') {
2416 swiper.updateSlides();
2417 } else if (gridEnabled && (prependSlidesIndexes.length > 0 && isPrev || appendSlidesIndexes.length > 0 && isNext)) {
2418 swiper.slides.forEach((slide, slideIndex) => {
2419 swiper.grid.updateSlide(slideIndex, slide, swiper.slides);
2420 });
2421 }
2422 if (params.watchSlidesProgress) {
2423 swiper.updateSlidesOffset();
2424 }
2425 if (slideTo) {
2426 if (prependSlidesIndexes.length > 0 && isPrev) {
2427 if (typeof slideRealIndex === 'undefined') {
2428 const currentSlideTranslate = swiper.slidesGrid[activeIndex];
2429 const newSlideTranslate = swiper.slidesGrid[activeIndex + slidesPrepended];
2430 const diff = newSlideTranslate - currentSlideTranslate;
2431 if (byMousewheel) {
2432 swiper.setTranslate(swiper.translate - diff);
2433 } else {
2434 swiper.slideTo(activeIndex + Math.ceil(slidesPrepended), 0, false, true);
2435 if (setTranslate) {
2436 swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
2437 swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
2438 }
2439 }
2440 } else {
2441 if (setTranslate) {
2442 const shift = gridEnabled ? prependSlidesIndexes.length / params.grid.rows : prependSlidesIndexes.length;
2443 swiper.slideTo(swiper.activeIndex + shift, 0, false, true);
2444 swiper.touchEventsData.currentTranslate = swiper.translate;
2445 }
2446 }
2447 } else if (appendSlidesIndexes.length > 0 && isNext) {
2448 if (typeof slideRealIndex === 'undefined') {
2449 const currentSlideTranslate = swiper.slidesGrid[activeIndex];
2450 const newSlideTranslate = swiper.slidesGrid[activeIndex - slidesAppended];
2451 const diff = newSlideTranslate - currentSlideTranslate;
2452 if (byMousewheel) {
2453 swiper.setTranslate(swiper.translate - diff);
2454 } else {
2455 swiper.slideTo(activeIndex - slidesAppended, 0, false, true);
2456 if (setTranslate) {
2457 swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
2458 swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
2459 }
2460 }
2461 } else {
2462 const shift = gridEnabled ? appendSlidesIndexes.length / params.grid.rows : appendSlidesIndexes.length;
2463 swiper.slideTo(swiper.activeIndex - shift, 0, false, true);
2464 }
2465 }
2466 }
2467 swiper.allowSlidePrev = allowSlidePrev;
2468 swiper.allowSlideNext = allowSlideNext;
2469 if (swiper.controller && swiper.controller.control && !byController) {
2470 const loopParams = {
2471 slideRealIndex,
2472 direction,
2473 setTranslate,
2474 activeSlideIndex,
2475 byController: true
2476 };
2477 if (Array.isArray(swiper.controller.control)) {
2478 swiper.controller.control.forEach(c => {
2479 if (!c.destroyed && c.params.loop) c.loopFix({
2480 ...loopParams,
2481 slideTo: c.params.slidesPerView === params.slidesPerView ? slideTo : false
2482 });
2483 });
2484 } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) {
2485 swiper.controller.control.loopFix({
2486 ...loopParams,
2487 slideTo: swiper.controller.control.params.slidesPerView === params.slidesPerView ? slideTo : false
2488 });
2489 }
2490 }
2491 swiper.emit('loopFix');
2492 }
2493
2494 function loopDestroy() {
2495 const swiper = this;
2496 const {
2497 params,
2498 slidesEl
2499 } = swiper;
2500 if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
2501 swiper.recalcSlides();
2502 const newSlidesOrder = [];
2503 swiper.slides.forEach(slideEl => {
2504 const index = typeof slideEl.swiperSlideIndex === 'undefined' ? slideEl.getAttribute('data-swiper-slide-index') * 1 : slideEl.swiperSlideIndex;
2505 newSlidesOrder[index] = slideEl;
2506 });
2507 swiper.slides.forEach(slideEl => {
2508 slideEl.removeAttribute('data-swiper-slide-index');
2509 });
2510 newSlidesOrder.forEach(slideEl => {
2511 slidesEl.append(slideEl);
2512 });
2513 swiper.recalcSlides();
2514 swiper.slideTo(swiper.realIndex, 0);
2515 }
2516
2517 var loop = {
2518 loopCreate,
2519 loopFix,
2520 loopDestroy
2521 };
2522
2523 function setGrabCursor(moving) {
2524 const swiper = this;
2525 if (!swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return;
2526 const el = swiper.params.touchEventsTarget === 'container' ? swiper.el : swiper.wrapperEl;
2527 if (swiper.isElement) {
2528 swiper.__preventObserver__ = true;
2529 }
2530 el.style.cursor = 'move';
2531 el.style.cursor = moving ? 'grabbing' : 'grab';
2532 if (swiper.isElement) {
2533 requestAnimationFrame(() => {
2534 swiper.__preventObserver__ = false;
2535 });
2536 }
2537 }
2538
2539 function unsetGrabCursor() {
2540 const swiper = this;
2541 if (swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {
2542 return;
2543 }
2544 if (swiper.isElement) {
2545 swiper.__preventObserver__ = true;
2546 }
2547 swiper[swiper.params.touchEventsTarget === 'container' ? 'el' : 'wrapperEl'].style.cursor = '';
2548 if (swiper.isElement) {
2549 requestAnimationFrame(() => {
2550 swiper.__preventObserver__ = false;
2551 });
2552 }
2553 }
2554
2555 var grabCursor = {
2556 setGrabCursor,
2557 unsetGrabCursor
2558 };
2559
2560 // Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
2561 function closestElement(selector, base) {
2562 if (base === void 0) {
2563 base = this;
2564 }
2565 function __closestFrom(el) {
2566 if (!el || el === getDocument() || el === getWindow()) return null;
2567 if (el.assignedSlot) el = el.assignedSlot;
2568 const found = el.closest(selector);
2569 if (!found && !el.getRootNode) {
2570 return null;
2571 }
2572 return found || __closestFrom(el.getRootNode().host);
2573 }
2574 return __closestFrom(base);
2575 }
2576 function preventEdgeSwipe(swiper, event, startX) {
2577 const window = getWindow();
2578 const {
2579 params
2580 } = swiper;
2581 const edgeSwipeDetection = params.edgeSwipeDetection;
2582 const edgeSwipeThreshold = params.edgeSwipeThreshold;
2583 if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {
2584 if (edgeSwipeDetection === 'prevent') {
2585 event.preventDefault();
2586 return true;
2587 }
2588 return false;
2589 }
2590 return true;
2591 }
2592 function onTouchStart(event) {
2593 const swiper = this;
2594 const document = getDocument();
2595 let e = event;
2596 if (e.originalEvent) e = e.originalEvent;
2597 const data = swiper.touchEventsData;
2598 if (e.type === 'pointerdown') {
2599 if (data.pointerId !== null && data.pointerId !== e.pointerId) {
2600 return;
2601 }
2602 data.pointerId = e.pointerId;
2603 } else if (e.type === 'touchstart' && e.targetTouches.length === 1) {
2604 data.touchId = e.targetTouches[0].identifier;
2605 }
2606 if (e.type === 'touchstart') {
2607 // don't proceed touch event
2608 preventEdgeSwipe(swiper, e, e.targetTouches[0].pageX);
2609 return;
2610 }
2611 const {
2612 params,
2613 touches,
2614 enabled
2615 } = swiper;
2616 if (!enabled) return;
2617 if (!params.simulateTouch && e.pointerType === 'mouse') return;
2618 if (swiper.animating && params.preventInteractionOnTransition) {
2619 return;
2620 }
2621 if (!swiper.animating && params.cssMode && params.loop) {
2622 swiper.loopFix();
2623 }
2624 let targetEl = e.target;
2625 if (params.touchEventsTarget === 'wrapper') {
2626 if (!elementIsChildOf(targetEl, swiper.wrapperEl)) return;
2627 }
2628 if ('which' in e && e.which === 3) return;
2629 if ('button' in e && e.button > 0) return;
2630 if (data.isTouched && data.isMoved) return;
2631
2632 // change target el for shadow root component
2633 const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
2634 // eslint-disable-next-line
2635 const eventPath = e.composedPath ? e.composedPath() : e.path;
2636 if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) {
2637 targetEl = eventPath[0];
2638 }
2639 const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
2640 const isTargetShadow = !!(e.target && e.target.shadowRoot);
2641
2642 // use closestElement for shadow root element to get the actual closest for nested shadow root element
2643 if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))) {
2644 swiper.allowClick = true;
2645 return;
2646 }
2647 if (params.swipeHandler) {
2648 if (!targetEl.closest(params.swipeHandler)) return;
2649 }
2650 touches.currentX = e.pageX;
2651 touches.currentY = e.pageY;
2652 const startX = touches.currentX;
2653 const startY = touches.currentY;
2654
2655 // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
2656
2657 if (!preventEdgeSwipe(swiper, e, startX)) {
2658 return;
2659 }
2660 Object.assign(data, {
2661 isTouched: true,
2662 isMoved: false,
2663 allowTouchCallbacks: true,
2664 isScrolling: undefined,
2665 startMoving: undefined
2666 });
2667 touches.startX = startX;
2668 touches.startY = startY;
2669 data.touchStartTime = now();
2670 swiper.allowClick = true;
2671 swiper.updateSize();
2672 swiper.swipeDirection = undefined;
2673 if (params.threshold > 0) data.allowThresholdMove = false;
2674 let preventDefault = true;
2675 if (targetEl.matches(data.focusableElements)) {
2676 preventDefault = false;
2677 if (targetEl.nodeName === 'SELECT') {
2678 data.isTouched = false;
2679 }
2680 }
2681 if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== targetEl && (e.pointerType === 'mouse' || e.pointerType !== 'mouse' && !targetEl.matches(data.focusableElements))) {
2682 document.activeElement.blur();
2683 }
2684 const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
2685 if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) {
2686 e.preventDefault();
2687 }
2688 if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {
2689 swiper.freeMode.onTouchStart();
2690 }
2691 swiper.emit('touchStart', e);
2692 }
2693
2694 function onTouchMove(event) {
2695 const document = getDocument();
2696 const swiper = this;
2697 const data = swiper.touchEventsData;
2698 const {
2699 params,
2700 touches,
2701 rtlTranslate: rtl,
2702 enabled
2703 } = swiper;
2704 if (!enabled) return;
2705 if (!params.simulateTouch && event.pointerType === 'mouse') return;
2706 let e = event;
2707 if (e.originalEvent) e = e.originalEvent;
2708 if (e.type === 'pointermove') {
2709 if (data.touchId !== null) return; // return from pointer if we use touch
2710 const id = e.pointerId;
2711 if (id !== data.pointerId) return;
2712 }
2713 let targetTouch;
2714 if (e.type === 'touchmove') {
2715 targetTouch = [...e.changedTouches].filter(t => t.identifier === data.touchId)[0];
2716 if (!targetTouch || targetTouch.identifier !== data.touchId) return;
2717 } else {
2718 targetTouch = e;
2719 }
2720 if (!data.isTouched) {
2721 if (data.startMoving && data.isScrolling) {
2722 swiper.emit('touchMoveOpposite', e);
2723 }
2724 return;
2725 }
2726 const pageX = targetTouch.pageX;
2727 const pageY = targetTouch.pageY;
2728 if (e.preventedByNestedSwiper) {
2729 touches.startX = pageX;
2730 touches.startY = pageY;
2731 return;
2732 }
2733 if (!swiper.allowTouchMove) {
2734 if (!e.target.matches(data.focusableElements)) {
2735 swiper.allowClick = false;
2736 }
2737 if (data.isTouched) {
2738 Object.assign(touches, {
2739 startX: pageX,
2740 startY: pageY,
2741 currentX: pageX,
2742 currentY: pageY
2743 });
2744 data.touchStartTime = now();
2745 }
2746 return;
2747 }
2748 if (params.touchReleaseOnEdges && !params.loop) {
2749 if (swiper.isVertical()) {
2750 // Vertical
2751 if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {
2752 data.isTouched = false;
2753 data.isMoved = false;
2754 return;
2755 }
2756 } else if (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate()) {
2757 return;
2758 }
2759 }
2760 if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== e.target && e.pointerType !== 'mouse') {
2761 document.activeElement.blur();
2762 }
2763 if (document.activeElement) {
2764 if (e.target === document.activeElement && e.target.matches(data.focusableElements)) {
2765 data.isMoved = true;
2766 swiper.allowClick = false;
2767 return;
2768 }
2769 }
2770 if (data.allowTouchCallbacks) {
2771 swiper.emit('touchMove', e);
2772 }
2773 touches.previousX = touches.currentX;
2774 touches.previousY = touches.currentY;
2775 touches.currentX = pageX;
2776 touches.currentY = pageY;
2777 const diffX = touches.currentX - touches.startX;
2778 const diffY = touches.currentY - touches.startY;
2779 if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return;
2780 if (typeof data.isScrolling === 'undefined') {
2781 let touchAngle;
2782 if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) {
2783 data.isScrolling = false;
2784 } else {
2785 // eslint-disable-next-line
2786 if (diffX * diffX + diffY * diffY >= 25) {
2787 touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
2788 data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle;
2789 }
2790 }
2791 }
2792 if (data.isScrolling) {
2793 swiper.emit('touchMoveOpposite', e);
2794 }
2795 if (typeof data.startMoving === 'undefined') {
2796 if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
2797 data.startMoving = true;
2798 }
2799 }
2800 if (data.isScrolling || e.type === 'touchmove' && data.preventTouchMoveFromPointerMove) {
2801 data.isTouched = false;
2802 return;
2803 }
2804 if (!data.startMoving) {
2805 return;
2806 }
2807 swiper.allowClick = false;
2808 if (!params.cssMode && e.cancelable) {
2809 e.preventDefault();
2810 }
2811 if (params.touchMoveStopPropagation && !params.nested) {
2812 e.stopPropagation();
2813 }
2814 let diff = swiper.isHorizontal() ? diffX : diffY;
2815 let touchesDiff = swiper.isHorizontal() ? touches.currentX - touches.previousX : touches.currentY - touches.previousY;
2816 if (params.oneWayMovement) {
2817 diff = Math.abs(diff) * (rtl ? 1 : -1);
2818 touchesDiff = Math.abs(touchesDiff) * (rtl ? 1 : -1);
2819 }
2820 touches.diff = diff;
2821 diff *= params.touchRatio;
2822 if (rtl) {
2823 diff = -diff;
2824 touchesDiff = -touchesDiff;
2825 }
2826 const prevTouchesDirection = swiper.touchesDirection;
2827 swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
2828 swiper.touchesDirection = touchesDiff > 0 ? 'prev' : 'next';
2829 const isLoop = swiper.params.loop && !params.cssMode;
2830 const allowLoopFix = swiper.touchesDirection === 'next' && swiper.allowSlideNext || swiper.touchesDirection === 'prev' && swiper.allowSlidePrev;
2831 if (!data.isMoved) {
2832 if (isLoop && allowLoopFix) {
2833 swiper.loopFix({
2834 direction: swiper.swipeDirection
2835 });
2836 }
2837 data.startTranslate = swiper.getTranslate();
2838 swiper.setTransition(0);
2839 if (swiper.animating) {
2840 const evt = new window.CustomEvent('transitionend', {
2841 bubbles: true,
2842 cancelable: true,
2843 detail: {
2844 bySwiperTouchMove: true
2845 }
2846 });
2847 swiper.wrapperEl.dispatchEvent(evt);
2848 }
2849 data.allowMomentumBounce = false;
2850 // Grab Cursor
2851 if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
2852 swiper.setGrabCursor(true);
2853 }
2854 swiper.emit('sliderFirstMove', e);
2855 }
2856 let loopFixed;
2857 new Date().getTime();
2858 if (data.isMoved && data.allowThresholdMove && prevTouchesDirection !== swiper.touchesDirection && isLoop && allowLoopFix && Math.abs(diff) >= 1) {
2859 Object.assign(touches, {
2860 startX: pageX,
2861 startY: pageY,
2862 currentX: pageX,
2863 currentY: pageY,
2864 startTranslate: data.currentTranslate
2865 });
2866 data.loopSwapReset = true;
2867 data.startTranslate = data.currentTranslate;
2868 return;
2869 }
2870 swiper.emit('sliderMove', e);
2871 data.isMoved = true;
2872 data.currentTranslate = diff + data.startTranslate;
2873 let disableParentSwiper = true;
2874 let resistanceRatio = params.resistanceRatio;
2875 if (params.touchReleaseOnEdges) {
2876 resistanceRatio = 0;
2877 }
2878 if (diff > 0) {
2879 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())) {
2880 swiper.loopFix({
2881 direction: 'prev',
2882 setTranslate: true,
2883 activeSlideIndex: 0
2884 });
2885 }
2886 if (data.currentTranslate > swiper.minTranslate()) {
2887 disableParentSwiper = false;
2888 if (params.resistance) {
2889 data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio;
2890 }
2891 }
2892 } else if (diff < 0) {
2893 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())) {
2894 swiper.loopFix({
2895 direction: 'next',
2896 setTranslate: true,
2897 activeSlideIndex: swiper.slides.length - (params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10)))
2898 });
2899 }
2900 if (data.currentTranslate < swiper.maxTranslate()) {
2901 disableParentSwiper = false;
2902 if (params.resistance) {
2903 data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio;
2904 }
2905 }
2906 }
2907 if (disableParentSwiper) {
2908 e.preventedByNestedSwiper = true;
2909 }
2910
2911 // Directions locks
2912 if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
2913 data.currentTranslate = data.startTranslate;
2914 }
2915 if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
2916 data.currentTranslate = data.startTranslate;
2917 }
2918 if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
2919 data.currentTranslate = data.startTranslate;
2920 }
2921
2922 // Threshold
2923 if (params.threshold > 0) {
2924 if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
2925 if (!data.allowThresholdMove) {
2926 data.allowThresholdMove = true;
2927 touches.startX = touches.currentX;
2928 touches.startY = touches.currentY;
2929 data.currentTranslate = data.startTranslate;
2930 touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;
2931 return;
2932 }
2933 } else {
2934 data.currentTranslate = data.startTranslate;
2935 return;
2936 }
2937 }
2938 if (!params.followFinger || params.cssMode) return;
2939
2940 // Update active index in free mode
2941 if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {
2942 swiper.updateActiveIndex();
2943 swiper.updateSlidesClasses();
2944 }
2945 if (params.freeMode && params.freeMode.enabled && swiper.freeMode) {
2946 swiper.freeMode.onTouchMove();
2947 }
2948 // Update progress
2949 swiper.updateProgress(data.currentTranslate);
2950 // Update translate
2951 swiper.setTranslate(data.currentTranslate);
2952 }
2953
2954 function onTouchEnd(event) {
2955 const swiper = this;
2956 const data = swiper.touchEventsData;
2957 let e = event;
2958 if (e.originalEvent) e = e.originalEvent;
2959 let targetTouch;
2960 const isTouchEvent = e.type === 'touchend' || e.type === 'touchcancel';
2961 if (!isTouchEvent) {
2962 if (data.touchId !== null) return; // return from pointer if we use touch
2963 if (e.pointerId !== data.pointerId) return;
2964 targetTouch = e;
2965 } else {
2966 targetTouch = [...e.changedTouches].filter(t => t.identifier === data.touchId)[0];
2967 if (!targetTouch || targetTouch.identifier !== data.touchId) return;
2968 }
2969 if (['pointercancel', 'pointerout', 'pointerleave', 'contextmenu'].includes(e.type)) {
2970 const proceed = ['pointercancel', 'contextmenu'].includes(e.type) && (swiper.browser.isSafari || swiper.browser.isWebView);
2971 if (!proceed) {
2972 return;
2973 }
2974 }
2975 data.pointerId = null;
2976 data.touchId = null;
2977 const {
2978 params,
2979 touches,
2980 rtlTranslate: rtl,
2981 slidesGrid,
2982 enabled
2983 } = swiper;
2984 if (!enabled) return;
2985 if (!params.simulateTouch && e.pointerType === 'mouse') return;
2986 if (data.allowTouchCallbacks) {
2987 swiper.emit('touchEnd', e);
2988 }
2989 data.allowTouchCallbacks = false;
2990 if (!data.isTouched) {
2991 if (data.isMoved && params.grabCursor) {
2992 swiper.setGrabCursor(false);
2993 }
2994 data.isMoved = false;
2995 data.startMoving = false;
2996 return;
2997 }
2998
2999 // Return Grab Cursor
3000 if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
3001 swiper.setGrabCursor(false);
3002 }
3003
3004 // Time diff
3005 const touchEndTime = now();
3006 const timeDiff = touchEndTime - data.touchStartTime;
3007
3008 // Tap, doubleTap, Click
3009 if (swiper.allowClick) {
3010 const pathTree = e.path || e.composedPath && e.composedPath();
3011 swiper.updateClickedSlide(pathTree && pathTree[0] || e.target, pathTree);
3012 swiper.emit('tap click', e);
3013 if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {
3014 swiper.emit('doubleTap doubleClick', e);
3015 }
3016 }
3017 data.lastClickTime = now();
3018 nextTick(() => {
3019 if (!swiper.destroyed) swiper.allowClick = true;
3020 });
3021 if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 && !data.loopSwapReset || data.currentTranslate === data.startTranslate && !data.loopSwapReset) {
3022 data.isTouched = false;
3023 data.isMoved = false;
3024 data.startMoving = false;
3025 return;
3026 }
3027 data.isTouched = false;
3028 data.isMoved = false;
3029 data.startMoving = false;
3030 let currentPos;
3031 if (params.followFinger) {
3032 currentPos = rtl ? swiper.translate : -swiper.translate;
3033 } else {
3034 currentPos = -data.currentTranslate;
3035 }
3036 if (params.cssMode) {
3037 return;
3038 }
3039 if (params.freeMode && params.freeMode.enabled) {
3040 swiper.freeMode.onTouchEnd({
3041 currentPos
3042 });
3043 return;
3044 }
3045
3046 // Find current slide
3047 const swipeToLast = currentPos >= -swiper.maxTranslate() && !swiper.params.loop;
3048 let stopIndex = 0;
3049 let groupSize = swiper.slidesSizesGrid[0];
3050 for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {
3051 const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
3052 if (typeof slidesGrid[i + increment] !== 'undefined') {
3053 if (swipeToLast || currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {
3054 stopIndex = i;
3055 groupSize = slidesGrid[i + increment] - slidesGrid[i];
3056 }
3057 } else if (swipeToLast || currentPos >= slidesGrid[i]) {
3058 stopIndex = i;
3059 groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
3060 }
3061 }
3062 let rewindFirstIndex = null;
3063 let rewindLastIndex = null;
3064 if (params.rewind) {
3065 if (swiper.isBeginning) {
3066 rewindLastIndex = params.virtual && params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
3067 } else if (swiper.isEnd) {
3068 rewindFirstIndex = 0;
3069 }
3070 }
3071 // Find current slide size
3072 const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
3073 const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
3074 if (timeDiff > params.longSwipesMs) {
3075 // Long touches
3076 if (!params.longSwipes) {
3077 swiper.slideTo(swiper.activeIndex);
3078 return;
3079 }
3080 if (swiper.swipeDirection === 'next') {
3081 if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);else swiper.slideTo(stopIndex);
3082 }
3083 if (swiper.swipeDirection === 'prev') {
3084 if (ratio > 1 - params.longSwipesRatio) {
3085 swiper.slideTo(stopIndex + increment);
3086 } else if (rewindLastIndex !== null && ratio < 0 && Math.abs(ratio) > params.longSwipesRatio) {
3087 swiper.slideTo(rewindLastIndex);
3088 } else {
3089 swiper.slideTo(stopIndex);
3090 }
3091 }
3092 } else {
3093 // Short swipes
3094 if (!params.shortSwipes) {
3095 swiper.slideTo(swiper.activeIndex);
3096 return;
3097 }
3098 const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);
3099 if (!isNavButtonTarget) {
3100 if (swiper.swipeDirection === 'next') {
3101 swiper.slideTo(rewindFirstIndex !== null ? rewindFirstIndex : stopIndex + increment);
3102 }
3103 if (swiper.swipeDirection === 'prev') {
3104 swiper.slideTo(rewindLastIndex !== null ? rewindLastIndex : stopIndex);
3105 }
3106 } else if (e.target === swiper.navigation.nextEl) {
3107 swiper.slideTo(stopIndex + increment);
3108 } else {
3109 swiper.slideTo(stopIndex);
3110 }
3111 }
3112 }
3113
3114 function onResize() {
3115 const swiper = this;
3116 const {
3117 params,
3118 el
3119 } = swiper;
3120 if (el && el.offsetWidth === 0) return;
3121
3122 // Breakpoints
3123 if (params.breakpoints) {
3124 swiper.setBreakpoint();
3125 }
3126
3127 // Save locks
3128 const {
3129 allowSlideNext,
3130 allowSlidePrev,
3131 snapGrid
3132 } = swiper;
3133 const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
3134
3135 // Disable locks on resize
3136 swiper.allowSlideNext = true;
3137 swiper.allowSlidePrev = true;
3138 swiper.updateSize();
3139 swiper.updateSlides();
3140 swiper.updateSlidesClasses();
3141 const isVirtualLoop = isVirtual && params.loop;
3142 if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides && !isVirtualLoop) {
3143 swiper.slideTo(swiper.slides.length - 1, 0, false, true);
3144 } else {
3145 if (swiper.params.loop && !isVirtual) {
3146 swiper.slideToLoop(swiper.realIndex, 0, false, true);
3147 } else {
3148 swiper.slideTo(swiper.activeIndex, 0, false, true);
3149 }
3150 }
3151 if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
3152 clearTimeout(swiper.autoplay.resizeTimeout);
3153 swiper.autoplay.resizeTimeout = setTimeout(() => {
3154 if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
3155 swiper.autoplay.resume();
3156 }
3157 }, 500);
3158 }
3159 // Return locks after resize
3160 swiper.allowSlidePrev = allowSlidePrev;
3161 swiper.allowSlideNext = allowSlideNext;
3162 if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
3163 swiper.checkOverflow();
3164 }
3165 }
3166
3167 function onClick(e) {
3168 const swiper = this;
3169 if (!swiper.enabled) return;
3170 if (!swiper.allowClick) {
3171 if (swiper.params.preventClicks) e.preventDefault();
3172 if (swiper.params.preventClicksPropagation && swiper.animating) {
3173 e.stopPropagation();
3174 e.stopImmediatePropagation();
3175 }
3176 }
3177 }
3178
3179 function onScroll() {
3180 const swiper = this;
3181 const {
3182 wrapperEl,
3183 rtlTranslate,
3184 enabled
3185 } = swiper;
3186 if (!enabled) return;
3187 swiper.previousTranslate = swiper.translate;
3188 if (swiper.isHorizontal()) {
3189 swiper.translate = -wrapperEl.scrollLeft;
3190 } else {
3191 swiper.translate = -wrapperEl.scrollTop;
3192 }
3193 // eslint-disable-next-line
3194 if (swiper.translate === 0) swiper.translate = 0;
3195 swiper.updateActiveIndex();
3196 swiper.updateSlidesClasses();
3197 let newProgress;
3198 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
3199 if (translatesDiff === 0) {
3200 newProgress = 0;
3201 } else {
3202 newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;
3203 }
3204 if (newProgress !== swiper.progress) {
3205 swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
3206 }
3207 swiper.emit('setTranslate', swiper.translate, false);
3208 }
3209
3210 function onLoad(e) {
3211 const swiper = this;
3212 processLazyPreloader(swiper, e.target);
3213 if (swiper.params.cssMode || swiper.params.slidesPerView !== 'auto' && !swiper.params.autoHeight) {
3214 return;
3215 }
3216 swiper.update();
3217 }
3218
3219 function onDocumentTouchStart() {
3220 const swiper = this;
3221 if (swiper.documentTouchHandlerProceeded) return;
3222 swiper.documentTouchHandlerProceeded = true;
3223 if (swiper.params.touchReleaseOnEdges) {
3224 swiper.el.style.touchAction = 'auto';
3225 }
3226 }
3227
3228 const events = (swiper, method) => {
3229 const document = getDocument();
3230 const {
3231 params,
3232 el,
3233 wrapperEl,
3234 device
3235 } = swiper;
3236 const capture = !!params.nested;
3237 const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
3238 const swiperMethod = method;
3239 if (!el || typeof el === 'string') return;
3240
3241 // Touch Events
3242 document[domMethod]('touchstart', swiper.onDocumentTouchStart, {
3243 passive: false,
3244 capture
3245 });
3246 el[domMethod]('touchstart', swiper.onTouchStart, {
3247 passive: false
3248 });
3249 el[domMethod]('pointerdown', swiper.onTouchStart, {
3250 passive: false
3251 });
3252 document[domMethod]('touchmove', swiper.onTouchMove, {
3253 passive: false,
3254 capture
3255 });
3256 document[domMethod]('pointermove', swiper.onTouchMove, {
3257 passive: false,
3258 capture
3259 });
3260 document[domMethod]('touchend', swiper.onTouchEnd, {
3261 passive: true
3262 });
3263 document[domMethod]('pointerup', swiper.onTouchEnd, {
3264 passive: true
3265 });
3266 document[domMethod]('pointercancel', swiper.onTouchEnd, {
3267 passive: true
3268 });
3269 document[domMethod]('touchcancel', swiper.onTouchEnd, {
3270 passive: true
3271 });
3272 document[domMethod]('pointerout', swiper.onTouchEnd, {
3273 passive: true
3274 });
3275 document[domMethod]('pointerleave', swiper.onTouchEnd, {
3276 passive: true
3277 });
3278 document[domMethod]('contextmenu', swiper.onTouchEnd, {
3279 passive: true
3280 });
3281
3282 // Prevent Links Clicks
3283 if (params.preventClicks || params.preventClicksPropagation) {
3284 el[domMethod]('click', swiper.onClick, true);
3285 }
3286 if (params.cssMode) {
3287 wrapperEl[domMethod]('scroll', swiper.onScroll);
3288 }
3289
3290 // Resize handler
3291 if (params.updateOnWindowResize) {
3292 swiper[swiperMethod](device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize, true);
3293 } else {
3294 swiper[swiperMethod]('observerUpdate', onResize, true);
3295 }
3296
3297 // Images loader
3298 el[domMethod]('load', swiper.onLoad, {
3299 capture: true
3300 });
3301 };
3302 function attachEvents() {
3303 const swiper = this;
3304 const {
3305 params
3306 } = swiper;
3307 swiper.onTouchStart = onTouchStart.bind(swiper);
3308 swiper.onTouchMove = onTouchMove.bind(swiper);
3309 swiper.onTouchEnd = onTouchEnd.bind(swiper);
3310 swiper.onDocumentTouchStart = onDocumentTouchStart.bind(swiper);
3311 if (params.cssMode) {
3312 swiper.onScroll = onScroll.bind(swiper);
3313 }
3314 swiper.onClick = onClick.bind(swiper);
3315 swiper.onLoad = onLoad.bind(swiper);
3316 events(swiper, 'on');
3317 }
3318 function detachEvents() {
3319 const swiper = this;
3320 events(swiper, 'off');
3321 }
3322 var events$1 = {
3323 attachEvents,
3324 detachEvents
3325 };
3326
3327 const isGridEnabled = (swiper, params) => {
3328 return swiper.grid && params.grid && params.grid.rows > 1;
3329 };
3330 function setBreakpoint() {
3331 const swiper = this;
3332 const {
3333 realIndex,
3334 initialized,
3335 params,
3336 el
3337 } = swiper;
3338 const breakpoints = params.breakpoints;
3339 if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return;
3340
3341 // Get breakpoint for window width and update parameters
3342 const breakpoint = swiper.getBreakpoint(breakpoints, swiper.params.breakpointsBase, swiper.el);
3343 if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;
3344 const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
3345 const breakpointParams = breakpointOnlyParams || swiper.originalParams;
3346 const wasMultiRow = isGridEnabled(swiper, params);
3347 const isMultiRow = isGridEnabled(swiper, breakpointParams);
3348 const wasGrabCursor = swiper.params.grabCursor;
3349 const isGrabCursor = breakpointParams.grabCursor;
3350 const wasEnabled = params.enabled;
3351 if (wasMultiRow && !isMultiRow) {
3352 el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
3353 swiper.emitContainerClasses();
3354 } else if (!wasMultiRow && isMultiRow) {
3355 el.classList.add(`${params.containerModifierClass}grid`);
3356 if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') {
3357 el.classList.add(`${params.containerModifierClass}grid-column`);
3358 }
3359 swiper.emitContainerClasses();
3360 }
3361 if (wasGrabCursor && !isGrabCursor) {
3362 swiper.unsetGrabCursor();
3363 } else if (!wasGrabCursor && isGrabCursor) {
3364 swiper.setGrabCursor();
3365 }
3366
3367 // Toggle navigation, pagination, scrollbar
3368 ['navigation', 'pagination', 'scrollbar'].forEach(prop => {
3369 if (typeof breakpointParams[prop] === 'undefined') return;
3370 const wasModuleEnabled = params[prop] && params[prop].enabled;
3371 const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
3372 if (wasModuleEnabled && !isModuleEnabled) {
3373 swiper[prop].disable();
3374 }
3375 if (!wasModuleEnabled && isModuleEnabled) {
3376 swiper[prop].enable();
3377 }
3378 });
3379 const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
3380 const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
3381 const wasLoop = params.loop;
3382 if (directionChanged && initialized) {
3383 swiper.changeDirection();
3384 }
3385 extend(swiper.params, breakpointParams);
3386 const isEnabled = swiper.params.enabled;
3387 const hasLoop = swiper.params.loop;
3388 Object.assign(swiper, {
3389 allowTouchMove: swiper.params.allowTouchMove,
3390 allowSlideNext: swiper.params.allowSlideNext,
3391 allowSlidePrev: swiper.params.allowSlidePrev
3392 });
3393 if (wasEnabled && !isEnabled) {
3394 swiper.disable();
3395 } else if (!wasEnabled && isEnabled) {
3396 swiper.enable();
3397 }
3398 swiper.currentBreakpoint = breakpoint;
3399 swiper.emit('_beforeBreakpoint', breakpointParams);
3400 if (initialized) {
3401 if (needsReLoop) {
3402 swiper.loopDestroy();
3403 swiper.loopCreate(realIndex);
3404 swiper.updateSlides();
3405 } else if (!wasLoop && hasLoop) {
3406 swiper.loopCreate(realIndex);
3407 swiper.updateSlides();
3408 } else if (wasLoop && !hasLoop) {
3409 swiper.loopDestroy();
3410 }
3411 }
3412 swiper.emit('breakpoint', breakpointParams);
3413 }
3414
3415 function getBreakpoint(breakpoints, base, containerEl) {
3416 if (base === void 0) {
3417 base = 'window';
3418 }
3419 if (!breakpoints || base === 'container' && !containerEl) return undefined;
3420 let breakpoint = false;
3421 const window = getWindow();
3422 const currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight;
3423 const points = Object.keys(breakpoints).map(point => {
3424 if (typeof point === 'string' && point.indexOf('@') === 0) {
3425 const minRatio = parseFloat(point.substr(1));
3426 const value = currentHeight * minRatio;
3427 return {
3428 value,
3429 point
3430 };
3431 }
3432 return {
3433 value: point,
3434 point
3435 };
3436 });
3437 points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10));
3438 for (let i = 0; i < points.length; i += 1) {
3439 const {
3440 point,
3441 value
3442 } = points[i];
3443 if (base === 'window') {
3444 if (window.matchMedia(`(min-width: ${value}px)`).matches) {
3445 breakpoint = point;
3446 }
3447 } else if (value <= containerEl.clientWidth) {
3448 breakpoint = point;
3449 }
3450 }
3451 return breakpoint || 'max';
3452 }
3453
3454 var breakpoints = {
3455 setBreakpoint,
3456 getBreakpoint
3457 };
3458
3459 function prepareClasses(entries, prefix) {
3460 const resultClasses = [];
3461 entries.forEach(item => {
3462 if (typeof item === 'object') {
3463 Object.keys(item).forEach(classNames => {
3464 if (item[classNames]) {
3465 resultClasses.push(prefix + classNames);
3466 }
3467 });
3468 } else if (typeof item === 'string') {
3469 resultClasses.push(prefix + item);
3470 }
3471 });
3472 return resultClasses;
3473 }
3474 function addClasses() {
3475 const swiper = this;
3476 const {
3477 classNames,
3478 params,
3479 rtl,
3480 el,
3481 device
3482 } = swiper;
3483 // prettier-ignore
3484 const suffixes = prepareClasses(['initialized', params.direction, {
3485 'free-mode': swiper.params.freeMode && params.freeMode.enabled
3486 }, {
3487 'autoheight': params.autoHeight
3488 }, {
3489 'rtl': rtl
3490 }, {
3491 'grid': params.grid && params.grid.rows > 1
3492 }, {
3493 'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
3494 }, {
3495 'android': device.android
3496 }, {
3497 'ios': device.ios
3498 }, {
3499 'css-mode': params.cssMode
3500 }, {
3501 'centered': params.cssMode && params.centeredSlides
3502 }, {
3503 'watch-progress': params.watchSlidesProgress
3504 }], params.containerModifierClass);
3505 classNames.push(...suffixes);
3506 el.classList.add(...classNames);
3507 swiper.emitContainerClasses();
3508 }
3509
3510 function removeClasses() {
3511 const swiper = this;
3512 const {
3513 el,
3514 classNames
3515 } = swiper;
3516 if (!el || typeof el === 'string') return;
3517 el.classList.remove(...classNames);
3518 swiper.emitContainerClasses();
3519 }
3520
3521 var classes = {
3522 addClasses,
3523 removeClasses
3524 };
3525
3526 function checkOverflow() {
3527 const swiper = this;
3528 const {
3529 isLocked: wasLocked,
3530 params
3531 } = swiper;
3532 const {
3533 slidesOffsetBefore
3534 } = params;
3535 if (slidesOffsetBefore) {
3536 const lastSlideIndex = swiper.slides.length - 1;
3537 const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] + slidesOffsetBefore * 2;
3538 swiper.isLocked = swiper.size > lastSlideRightEdge;
3539 } else {
3540 swiper.isLocked = swiper.snapGrid.length === 1;
3541 }
3542 if (params.allowSlideNext === true) {
3543 swiper.allowSlideNext = !swiper.isLocked;
3544 }
3545 if (params.allowSlidePrev === true) {
3546 swiper.allowSlidePrev = !swiper.isLocked;
3547 }
3548 if (wasLocked && wasLocked !== swiper.isLocked) {
3549 swiper.isEnd = false;
3550 }
3551 if (wasLocked !== swiper.isLocked) {
3552 swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
3553 }
3554 }
3555 var checkOverflow$1 = {
3556 checkOverflow
3557 };
3558
3559 var defaults = {
3560 init: true,
3561 direction: 'horizontal',
3562 oneWayMovement: false,
3563 swiperElementNodeName: 'SWIPER-CONTAINER',
3564 touchEventsTarget: 'wrapper',
3565 initialSlide: 0,
3566 speed: 300,
3567 cssMode: false,
3568 updateOnWindowResize: true,
3569 resizeObserver: true,
3570 nested: false,
3571 createElements: false,
3572 eventsPrefix: 'swiper',
3573 enabled: true,
3574 focusableElements: 'input, select, option, textarea, button, video, label',
3575 // Overrides
3576 width: null,
3577 height: null,
3578 //
3579 preventInteractionOnTransition: false,
3580 // ssr
3581 userAgent: null,
3582 url: null,
3583 // To support iOS's swipe-to-go-back gesture (when being used in-app).
3584 edgeSwipeDetection: false,
3585 edgeSwipeThreshold: 20,
3586 // Autoheight
3587 autoHeight: false,
3588 // Set wrapper width
3589 setWrapperSize: false,
3590 // Virtual Translate
3591 virtualTranslate: false,
3592 // Effects
3593 effect: 'slide',
3594 // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
3595
3596 // Breakpoints
3597 breakpoints: undefined,
3598 breakpointsBase: 'window',
3599 // Slides grid
3600 spaceBetween: 0,
3601 slidesPerView: 1,
3602 slidesPerGroup: 1,
3603 slidesPerGroupSkip: 0,
3604 slidesPerGroupAuto: false,
3605 centeredSlides: false,
3606 centeredSlidesBounds: false,
3607 slidesOffsetBefore: 0,
3608 // in px
3609 slidesOffsetAfter: 0,
3610 // in px
3611 normalizeSlideIndex: true,
3612 centerInsufficientSlides: false,
3613 // Disable swiper and hide navigation when container not overflow
3614 watchOverflow: true,
3615 // Round length
3616 roundLengths: false,
3617 // Touches
3618 touchRatio: 1,
3619 touchAngle: 45,
3620 simulateTouch: true,
3621 shortSwipes: true,
3622 longSwipes: true,
3623 longSwipesRatio: 0.5,
3624 longSwipesMs: 300,
3625 followFinger: true,
3626 allowTouchMove: true,
3627 threshold: 5,
3628 touchMoveStopPropagation: false,
3629 touchStartPreventDefault: true,
3630 touchStartForcePreventDefault: false,
3631 touchReleaseOnEdges: false,
3632 // Unique Navigation Elements
3633 uniqueNavElements: true,
3634 // Resistance
3635 resistance: true,
3636 resistanceRatio: 0.85,
3637 // Progress
3638 watchSlidesProgress: false,
3639 // Cursor
3640 grabCursor: false,
3641 // Clicks
3642 preventClicks: true,
3643 preventClicksPropagation: true,
3644 slideToClickedSlide: false,
3645 // loop
3646 loop: false,
3647 loopAddBlankSlides: true,
3648 loopAdditionalSlides: 0,
3649 loopPreventsSliding: true,
3650 // rewind
3651 rewind: false,
3652 // Swiping/no swiping
3653 allowSlidePrev: true,
3654 allowSlideNext: true,
3655 swipeHandler: null,
3656 // '.swipe-handler',
3657 noSwiping: true,
3658 noSwipingClass: 'swiper-no-swiping',
3659 noSwipingSelector: null,
3660 // Passive Listeners
3661 passiveListeners: true,
3662 maxBackfaceHiddenSlides: 10,
3663 // NS
3664 containerModifierClass: 'swiper-',
3665 // NEW
3666 slideClass: 'swiper-slide',
3667 slideBlankClass: 'swiper-slide-blank',
3668 slideActiveClass: 'swiper-slide-active',
3669 slideVisibleClass: 'swiper-slide-visible',
3670 slideFullyVisibleClass: 'swiper-slide-fully-visible',
3671 slideNextClass: 'swiper-slide-next',
3672 slidePrevClass: 'swiper-slide-prev',
3673 wrapperClass: 'swiper-wrapper',
3674 lazyPreloaderClass: 'swiper-lazy-preloader',
3675 lazyPreloadPrevNext: 0,
3676 // Callbacks
3677 runCallbacksOnInit: true,
3678 // Internals
3679 _emitClasses: false
3680 };
3681
3682 function moduleExtendParams(params, allModulesParams) {
3683 return function extendParams(obj) {
3684 if (obj === void 0) {
3685 obj = {};
3686 }
3687 const moduleParamName = Object.keys(obj)[0];
3688 const moduleParams = obj[moduleParamName];
3689 if (typeof moduleParams !== 'object' || moduleParams === null) {
3690 extend(allModulesParams, obj);
3691 return;
3692 }
3693 if (params[moduleParamName] === true) {
3694 params[moduleParamName] = {
3695 enabled: true
3696 };
3697 }
3698 if (moduleParamName === 'navigation' && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].prevEl && !params[moduleParamName].nextEl) {
3699 params[moduleParamName].auto = true;
3700 }
3701 if (['pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].el) {
3702 params[moduleParamName].auto = true;
3703 }
3704 if (!(moduleParamName in params && 'enabled' in moduleParams)) {
3705 extend(allModulesParams, obj);
3706 return;
3707 }
3708 if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {
3709 params[moduleParamName].enabled = true;
3710 }
3711 if (!params[moduleParamName]) params[moduleParamName] = {
3712 enabled: false
3713 };
3714 extend(allModulesParams, obj);
3715 };
3716 }
3717
3718 /* eslint no-param-reassign: "off" */
3719 const prototypes = {
3720 eventsEmitter,
3721 update,
3722 translate,
3723 transition,
3724 slide,
3725 loop,
3726 grabCursor,
3727 events: events$1,
3728 breakpoints,
3729 checkOverflow: checkOverflow$1,
3730 classes
3731 };
3732 const extendedDefaults = {};
3733 class Swiper {
3734 constructor() {
3735 let el;
3736 let params;
3737 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
3738 args[_key] = arguments[_key];
3739 }
3740 if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') {
3741 params = args[0];
3742 } else {
3743 [el, params] = args;
3744 }
3745 if (!params) params = {};
3746 params = extend({}, params);
3747 if (el && !params.el) params.el = el;
3748 const document = getDocument();
3749 if (params.el && typeof params.el === 'string' && document.querySelectorAll(params.el).length > 1) {
3750 const swipers = [];
3751 document.querySelectorAll(params.el).forEach(containerEl => {
3752 const newParams = extend({}, params, {
3753 el: containerEl
3754 });
3755 swipers.push(new Swiper(newParams));
3756 });
3757 // eslint-disable-next-line no-constructor-return
3758 return swipers;
3759 }
3760
3761 // Swiper Instance
3762 const swiper = this;
3763 swiper.__swiper__ = true;
3764 swiper.support = getSupport();
3765 swiper.device = getDevice({
3766 userAgent: params.userAgent
3767 });
3768 swiper.browser = getBrowser();
3769 swiper.eventsListeners = {};
3770 swiper.eventsAnyListeners = [];
3771 swiper.modules = [...swiper.__modules__];
3772 if (params.modules && Array.isArray(params.modules)) {
3773 swiper.modules.push(...params.modules);
3774 }
3775 const allModulesParams = {};
3776 swiper.modules.forEach(mod => {
3777 mod({
3778 params,
3779 swiper,
3780 extendParams: moduleExtendParams(params, allModulesParams),
3781 on: swiper.on.bind(swiper),
3782 once: swiper.once.bind(swiper),
3783 off: swiper.off.bind(swiper),
3784 emit: swiper.emit.bind(swiper)
3785 });
3786 });
3787
3788 // Extend defaults with modules params
3789 const swiperParams = extend({}, defaults, allModulesParams);
3790
3791 // Extend defaults with passed params
3792 swiper.params = extend({}, swiperParams, extendedDefaults, params);
3793 swiper.originalParams = extend({}, swiper.params);
3794 swiper.passedParams = extend({}, params);
3795
3796 // add event listeners
3797 if (swiper.params && swiper.params.on) {
3798 Object.keys(swiper.params.on).forEach(eventName => {
3799 swiper.on(eventName, swiper.params.on[eventName]);
3800 });
3801 }
3802 if (swiper.params && swiper.params.onAny) {
3803 swiper.onAny(swiper.params.onAny);
3804 }
3805
3806 // Extend Swiper
3807 Object.assign(swiper, {
3808 enabled: swiper.params.enabled,
3809 el,
3810 // Classes
3811 classNames: [],
3812 // Slides
3813 slides: [],
3814 slidesGrid: [],
3815 snapGrid: [],
3816 slidesSizesGrid: [],
3817 // isDirection
3818 isHorizontal() {
3819 return swiper.params.direction === 'horizontal';
3820 },
3821 isVertical() {
3822 return swiper.params.direction === 'vertical';
3823 },
3824 // Indexes
3825 activeIndex: 0,
3826 realIndex: 0,
3827 //
3828 isBeginning: true,
3829 isEnd: false,
3830 // Props
3831 translate: 0,
3832 previousTranslate: 0,
3833 progress: 0,
3834 velocity: 0,
3835 animating: false,
3836 cssOverflowAdjustment() {
3837 // Returns 0 unless `translate` is > 2**23
3838 // Should be subtracted from css values to prevent overflow
3839 return Math.trunc(this.translate / 2 ** 23) * 2 ** 23;
3840 },
3841 // Locks
3842 allowSlideNext: swiper.params.allowSlideNext,
3843 allowSlidePrev: swiper.params.allowSlidePrev,
3844 // Touch Events
3845 touchEventsData: {
3846 isTouched: undefined,
3847 isMoved: undefined,
3848 allowTouchCallbacks: undefined,
3849 touchStartTime: undefined,
3850 isScrolling: undefined,
3851 currentTranslate: undefined,
3852 startTranslate: undefined,
3853 allowThresholdMove: undefined,
3854 // Form elements to match
3855 focusableElements: swiper.params.focusableElements,
3856 // Last click time
3857 lastClickTime: 0,
3858 clickTimeout: undefined,
3859 // Velocities
3860 velocities: [],
3861 allowMomentumBounce: undefined,
3862 startMoving: undefined,
3863 pointerId: null,
3864 touchId: null
3865 },
3866 // Clicks
3867 allowClick: true,
3868 // Touches
3869 allowTouchMove: swiper.params.allowTouchMove,
3870 touches: {
3871 startX: 0,
3872 startY: 0,
3873 currentX: 0,
3874 currentY: 0,
3875 diff: 0
3876 },
3877 // Images
3878 imagesToLoad: [],
3879 imagesLoaded: 0
3880 });
3881 swiper.emit('_swiper');
3882
3883 // Init
3884 if (swiper.params.init) {
3885 swiper.init();
3886 }
3887
3888 // Return app instance
3889 // eslint-disable-next-line no-constructor-return
3890 return swiper;
3891 }
3892 getDirectionLabel(property) {
3893 if (this.isHorizontal()) {
3894 return property;
3895 }
3896 // prettier-ignore
3897 return {
3898 'width': 'height',
3899 'margin-top': 'margin-left',
3900 'margin-bottom ': 'margin-right',
3901 'margin-left': 'margin-top',
3902 'margin-right': 'margin-bottom',
3903 'padding-left': 'padding-top',
3904 'padding-right': 'padding-bottom',
3905 'marginRight': 'marginBottom'
3906 }[property];
3907 }
3908 getSlideIndex(slideEl) {
3909 const {
3910 slidesEl,
3911 params
3912 } = this;
3913 const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
3914 const firstSlideIndex = elementIndex(slides[0]);
3915 return elementIndex(slideEl) - firstSlideIndex;
3916 }
3917 getSlideIndexByData(index) {
3918 return this.getSlideIndex(this.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === index)[0]);
3919 }
3920 recalcSlides() {
3921 const swiper = this;
3922 const {
3923 slidesEl,
3924 params
3925 } = swiper;
3926 swiper.slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
3927 }
3928 enable() {
3929 const swiper = this;
3930 if (swiper.enabled) return;
3931 swiper.enabled = true;
3932 if (swiper.params.grabCursor) {
3933 swiper.setGrabCursor();
3934 }
3935 swiper.emit('enable');
3936 }
3937 disable() {
3938 const swiper = this;
3939 if (!swiper.enabled) return;
3940 swiper.enabled = false;
3941 if (swiper.params.grabCursor) {
3942 swiper.unsetGrabCursor();
3943 }
3944 swiper.emit('disable');
3945 }
3946 setProgress(progress, speed) {
3947 const swiper = this;
3948 progress = Math.min(Math.max(progress, 0), 1);
3949 const min = swiper.minTranslate();
3950 const max = swiper.maxTranslate();
3951 const current = (max - min) * progress + min;
3952 swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
3953 swiper.updateActiveIndex();
3954 swiper.updateSlidesClasses();
3955 }
3956 emitContainerClasses() {
3957 const swiper = this;
3958 if (!swiper.params._emitClasses || !swiper.el) return;
3959 const cls = swiper.el.className.split(' ').filter(className => {
3960 return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;
3961 });
3962 swiper.emit('_containerClasses', cls.join(' '));
3963 }
3964 getSlideClasses(slideEl) {
3965 const swiper = this;
3966 if (swiper.destroyed) return '';
3967 return slideEl.className.split(' ').filter(className => {
3968 return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;
3969 }).join(' ');
3970 }
3971 emitSlidesClasses() {
3972 const swiper = this;
3973 if (!swiper.params._emitClasses || !swiper.el) return;
3974 const updates = [];
3975 swiper.slides.forEach(slideEl => {
3976 const classNames = swiper.getSlideClasses(slideEl);
3977 updates.push({
3978 slideEl,
3979 classNames
3980 });
3981 swiper.emit('_slideClass', slideEl, classNames);
3982 });
3983 swiper.emit('_slideClasses', updates);
3984 }
3985 slidesPerViewDynamic(view, exact) {
3986 if (view === void 0) {
3987 view = 'current';
3988 }
3989 if (exact === void 0) {
3990 exact = false;
3991 }
3992 const swiper = this;
3993 const {
3994 params,
3995 slides,
3996 slidesGrid,
3997 slidesSizesGrid,
3998 size: swiperSize,
3999 activeIndex
4000 } = swiper;
4001 let spv = 1;
4002 if (typeof params.slidesPerView === 'number') return params.slidesPerView;
4003 if (params.centeredSlides) {
4004 let slideSize = slides[activeIndex] ? Math.ceil(slides[activeIndex].swiperSlideSize) : 0;
4005 let breakLoop;
4006 for (let i = activeIndex + 1; i < slides.length; i += 1) {
4007 if (slides[i] && !breakLoop) {
4008 slideSize += Math.ceil(slides[i].swiperSlideSize);
4009 spv += 1;
4010 if (slideSize > swiperSize) breakLoop = true;
4011 }
4012 }
4013 for (let i = activeIndex - 1; i >= 0; i -= 1) {
4014 if (slides[i] && !breakLoop) {
4015 slideSize += slides[i].swiperSlideSize;
4016 spv += 1;
4017 if (slideSize > swiperSize) breakLoop = true;
4018 }
4019 }
4020 } else {
4021 // eslint-disable-next-line
4022 if (view === 'current') {
4023 for (let i = activeIndex + 1; i < slides.length; i += 1) {
4024 const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
4025 if (slideInView) {
4026 spv += 1;
4027 }
4028 }
4029 } else {
4030 // previous
4031 for (let i = activeIndex - 1; i >= 0; i -= 1) {
4032 const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
4033 if (slideInView) {
4034 spv += 1;
4035 }
4036 }
4037 }
4038 }
4039 return spv;
4040 }
4041 update() {
4042 const swiper = this;
4043 if (!swiper || swiper.destroyed) return;
4044 const {
4045 snapGrid,
4046 params
4047 } = swiper;
4048 // Breakpoints
4049 if (params.breakpoints) {
4050 swiper.setBreakpoint();
4051 }
4052 [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach(imageEl => {
4053 if (imageEl.complete) {
4054 processLazyPreloader(swiper, imageEl);
4055 }
4056 });
4057 swiper.updateSize();
4058 swiper.updateSlides();
4059 swiper.updateProgress();
4060 swiper.updateSlidesClasses();
4061 function setTranslate() {
4062 const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
4063 const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
4064 swiper.setTranslate(newTranslate);
4065 swiper.updateActiveIndex();
4066 swiper.updateSlidesClasses();
4067 }
4068 let translated;
4069 if (params.freeMode && params.freeMode.enabled && !params.cssMode) {
4070 setTranslate();
4071 if (params.autoHeight) {
4072 swiper.updateAutoHeight();
4073 }
4074 } else {
4075 if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
4076 const slides = swiper.virtual && params.virtual.enabled ? swiper.virtual.slides : swiper.slides;
4077 translated = swiper.slideTo(slides.length - 1, 0, false, true);
4078 } else {
4079 translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
4080 }
4081 if (!translated) {
4082 setTranslate();
4083 }
4084 }
4085 if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
4086 swiper.checkOverflow();
4087 }
4088 swiper.emit('update');
4089 }
4090 changeDirection(newDirection, needUpdate) {
4091 if (needUpdate === void 0) {
4092 needUpdate = true;
4093 }
4094 const swiper = this;
4095 const currentDirection = swiper.params.direction;
4096 if (!newDirection) {
4097 // eslint-disable-next-line
4098 newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
4099 }
4100 if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
4101 return swiper;
4102 }
4103 swiper.el.classList.remove(`${swiper.params.containerModifierClass}${currentDirection}`);
4104 swiper.el.classList.add(`${swiper.params.containerModifierClass}${newDirection}`);
4105 swiper.emitContainerClasses();
4106 swiper.params.direction = newDirection;
4107 swiper.slides.forEach(slideEl => {
4108 if (newDirection === 'vertical') {
4109 slideEl.style.width = '';
4110 } else {
4111 slideEl.style.height = '';
4112 }
4113 });
4114 swiper.emit('changeDirection');
4115 if (needUpdate) swiper.update();
4116 return swiper;
4117 }
4118 changeLanguageDirection(direction) {
4119 const swiper = this;
4120 if (swiper.rtl && direction === 'rtl' || !swiper.rtl && direction === 'ltr') return;
4121 swiper.rtl = direction === 'rtl';
4122 swiper.rtlTranslate = swiper.params.direction === 'horizontal' && swiper.rtl;
4123 if (swiper.rtl) {
4124 swiper.el.classList.add(`${swiper.params.containerModifierClass}rtl`);
4125 swiper.el.dir = 'rtl';
4126 } else {
4127 swiper.el.classList.remove(`${swiper.params.containerModifierClass}rtl`);
4128 swiper.el.dir = 'ltr';
4129 }
4130 swiper.update();
4131 }
4132 mount(element) {
4133 const swiper = this;
4134 if (swiper.mounted) return true;
4135
4136 // Find el
4137 let el = element || swiper.params.el;
4138 if (typeof el === 'string') {
4139 el = document.querySelector(el);
4140 }
4141 if (!el) {
4142 return false;
4143 }
4144 el.swiper = swiper;
4145 if (el.parentNode && el.parentNode.host && el.parentNode.host.nodeName === swiper.params.swiperElementNodeName.toUpperCase()) {
4146 swiper.isElement = true;
4147 }
4148 const getWrapperSelector = () => {
4149 return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`;
4150 };
4151 const getWrapper = () => {
4152 if (el && el.shadowRoot && el.shadowRoot.querySelector) {
4153 const res = el.shadowRoot.querySelector(getWrapperSelector());
4154 // Children needs to return slot items
4155 return res;
4156 }
4157 return elementChildren(el, getWrapperSelector())[0];
4158 };
4159 // Find Wrapper
4160 let wrapperEl = getWrapper();
4161 if (!wrapperEl && swiper.params.createElements) {
4162 wrapperEl = createElement('div', swiper.params.wrapperClass);
4163 el.append(wrapperEl);
4164 elementChildren(el, `.${swiper.params.slideClass}`).forEach(slideEl => {
4165 wrapperEl.append(slideEl);
4166 });
4167 }
4168 Object.assign(swiper, {
4169 el,
4170 wrapperEl,
4171 slidesEl: swiper.isElement && !el.parentNode.host.slideSlots ? el.parentNode.host : wrapperEl,
4172 hostEl: swiper.isElement ? el.parentNode.host : el,
4173 mounted: true,
4174 // RTL
4175 rtl: el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl',
4176 rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl'),
4177 wrongRTL: elementStyle(wrapperEl, 'display') === '-webkit-box'
4178 });
4179 return true;
4180 }
4181 init(el) {
4182 const swiper = this;
4183 if (swiper.initialized) return swiper;
4184 const mounted = swiper.mount(el);
4185 if (mounted === false) return swiper;
4186 swiper.emit('beforeInit');
4187
4188 // Set breakpoint
4189 if (swiper.params.breakpoints) {
4190 swiper.setBreakpoint();
4191 }
4192
4193 // Add Classes
4194 swiper.addClasses();
4195
4196 // Update size
4197 swiper.updateSize();
4198
4199 // Update slides
4200 swiper.updateSlides();
4201 if (swiper.params.watchOverflow) {
4202 swiper.checkOverflow();
4203 }
4204
4205 // Set Grab Cursor
4206 if (swiper.params.grabCursor && swiper.enabled) {
4207 swiper.setGrabCursor();
4208 }
4209
4210 // Slide To Initial Slide
4211 if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
4212 swiper.slideTo(swiper.params.initialSlide + swiper.virtual.slidesBefore, 0, swiper.params.runCallbacksOnInit, false, true);
4213 } else {
4214 swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
4215 }
4216
4217 // Create loop
4218 if (swiper.params.loop) {
4219 swiper.loopCreate();
4220 }
4221
4222 // Attach events
4223 swiper.attachEvents();
4224 const lazyElements = [...swiper.el.querySelectorAll('[loading="lazy"]')];
4225 if (swiper.isElement) {
4226 lazyElements.push(...swiper.hostEl.querySelectorAll('[loading="lazy"]'));
4227 }
4228 lazyElements.forEach(imageEl => {
4229 if (imageEl.complete) {
4230 processLazyPreloader(swiper, imageEl);
4231 } else {
4232 imageEl.addEventListener('load', e => {
4233 processLazyPreloader(swiper, e.target);
4234 });
4235 }
4236 });
4237 preload(swiper);
4238
4239 // Init Flag
4240 swiper.initialized = true;
4241 preload(swiper);
4242
4243 // Emit
4244 swiper.emit('init');
4245 swiper.emit('afterInit');
4246 return swiper;
4247 }
4248 destroy(deleteInstance, cleanStyles) {
4249 if (deleteInstance === void 0) {
4250 deleteInstance = true;
4251 }
4252 if (cleanStyles === void 0) {
4253 cleanStyles = true;
4254 }
4255 const swiper = this;
4256 const {
4257 params,
4258 el,
4259 wrapperEl,
4260 slides
4261 } = swiper;
4262 if (typeof swiper.params === 'undefined' || swiper.destroyed) {
4263 return null;
4264 }
4265 swiper.emit('beforeDestroy');
4266
4267 // Init Flag
4268 swiper.initialized = false;
4269
4270 // Detach events
4271 swiper.detachEvents();
4272
4273 // Destroy loop
4274 if (params.loop) {
4275 swiper.loopDestroy();
4276 }
4277
4278 // Cleanup styles
4279 if (cleanStyles) {
4280 swiper.removeClasses();
4281 if (el && typeof el !== 'string') {
4282 el.removeAttribute('style');
4283 }
4284 if (wrapperEl) {
4285 wrapperEl.removeAttribute('style');
4286 }
4287 if (slides && slides.length) {
4288 slides.forEach(slideEl => {
4289 slideEl.classList.remove(params.slideVisibleClass, params.slideFullyVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
4290 slideEl.removeAttribute('style');
4291 slideEl.removeAttribute('data-swiper-slide-index');
4292 });
4293 }
4294 }
4295 swiper.emit('destroy');
4296
4297 // Detach emitter events
4298 Object.keys(swiper.eventsListeners).forEach(eventName => {
4299 swiper.off(eventName);
4300 });
4301 if (deleteInstance !== false) {
4302 if (swiper.el && typeof swiper.el !== 'string') {
4303 swiper.el.swiper = null;
4304 }
4305 deleteProps(swiper);
4306 }
4307 swiper.destroyed = true;
4308 return null;
4309 }
4310 static extendDefaults(newDefaults) {
4311 extend(extendedDefaults, newDefaults);
4312 }
4313 static get extendedDefaults() {
4314 return extendedDefaults;
4315 }
4316 static get defaults() {
4317 return defaults;
4318 }
4319 static installModule(mod) {
4320 if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];
4321 const modules = Swiper.prototype.__modules__;
4322 if (typeof mod === 'function' && modules.indexOf(mod) < 0) {
4323 modules.push(mod);
4324 }
4325 }
4326 static use(module) {
4327 if (Array.isArray(module)) {
4328 module.forEach(m => Swiper.installModule(m));
4329 return Swiper;
4330 }
4331 Swiper.installModule(module);
4332 return Swiper;
4333 }
4334 }
4335 Object.keys(prototypes).forEach(prototypeGroup => {
4336 Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => {
4337 Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
4338 });
4339 });
4340 Swiper.use([Resize, Observer]);
4341
4342 return Swiper;
4343
4344})();