UNPKG

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