@gem-sdk/swiper 0.0.14 → 0.0.15-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/swiper-element.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Swiper Custom Element 0.0.14
2
+ * Swiper Custom Element 0.0.15-dev.1
3
3
  * Gem SDK - Swiper, Customized of swiper
4
4
  * https://swiperjs.com
5
5
  *
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * Released under the MIT License
9
9
  *
10
- * Released on: March 18, 2026
10
+ * Released on: March 20, 2026
11
11
  */
12
12
 
13
13
  (function () {
@@ -841,9 +841,6 @@
841
841
 
842
842
  function updateSlides() {
843
843
  const swiper = this;
844
- function getDirectionPropertyValue(node, label) {
845
- return parseFloat(node.getPropertyValue(swiper.getDirectionLabel(label)) || 0);
846
- }
847
844
  const params = swiper.params;
848
845
  const {
849
846
  wrapperEl,
@@ -852,10 +849,8 @@
852
849
  rtlTranslate: rtl,
853
850
  wrongRTL
854
851
  } = swiper;
855
- const isVirtual = swiper.virtual && params.virtual.enabled;
856
- const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
857
852
  const slides = elementChildren(slidesEl, `.${swiper.params.slideClass}, swiper-slide`);
858
- const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
853
+ const slidesLength = slides.length;
859
854
  let snapGrid = [];
860
855
  const slidesGrid = [];
861
856
  const slidesSizesGrid = [];
@@ -873,15 +868,15 @@
873
868
  let slidePosition = -offsetBefore;
874
869
  let prevSlideSize = 0;
875
870
  let index = 0;
876
- if (typeof swiperSize === 'undefined') {
877
- return;
878
- }
871
+ if (typeof swiperSize === 'undefined') return;
879
872
  if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
880
873
  spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
881
874
  } else if (typeof spaceBetween === 'string') {
882
875
  spaceBetween = parseFloat(spaceBetween);
883
876
  }
884
- swiper.virtualSize = -spaceBetween;
877
+
878
+ // core-lite: compute total slides size without optional modules
879
+ swiper.slidesTotalSize = -spaceBetween;
885
880
 
886
881
  // reset margins
887
882
  slides.forEach(slideEl => {
@@ -899,49 +894,34 @@
899
894
  setCSSProperty(wrapperEl, '--swiper-centered-offset-before', '');
900
895
  setCSSProperty(wrapperEl, '--swiper-centered-offset-after', '');
901
896
  }
902
- const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
903
- if (gridEnabled) {
904
- swiper.grid.initSlides(slides);
905
- } else if (swiper.grid) {
906
- swiper.grid.unsetSlides();
907
- }
908
897
 
909
898
  // Calc slides
910
899
  let slideSize;
911
- const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => {
912
- return typeof params.breakpoints[key].slidesPerView !== 'undefined';
913
- }).length > 0;
900
+ const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => typeof params.breakpoints[key].slidesPerView !== 'undefined').length > 0;
914
901
  for (let i = 0; i < slidesLength; i += 1) {
915
902
  slideSize = 0;
916
903
  let slide;
917
904
  if (slides[i]) slide = slides[i];
918
- if (gridEnabled) {
919
- swiper.grid.updateSlide(i, slide, slides);
920
- }
921
905
  if (slides[i] && elementStyle(slide, 'display') === 'none') continue; // eslint-disable-line
922
906
 
923
907
  if (params.slidesPerView === 'auto') {
924
- if (shouldResetSlideSize) {
908
+ if (shouldResetSlideSize && slides[i]) {
925
909
  slides[i].style[swiper.getDirectionLabel('width')] = ``;
926
910
  }
927
911
  const slideStyles = getComputedStyle(slide);
928
912
  const currentTransform = slide.style.transform;
929
913
  const currentWebKitTransform = slide.style.webkitTransform;
930
- if (currentTransform) {
931
- slide.style.transform = 'none';
932
- }
933
- if (currentWebKitTransform) {
934
- slide.style.webkitTransform = 'none';
935
- }
914
+ if (currentTransform) slide.style.transform = 'none';
915
+ if (currentWebKitTransform) slide.style.webkitTransform = 'none';
936
916
  if (params.roundLengths) {
937
917
  slideSize = swiper.isHorizontal() ? elementOuterSize(slide, 'width', true) : elementOuterSize(slide, 'height', true);
938
918
  } else {
939
919
  // eslint-disable-next-line
940
- const width = getDirectionPropertyValue(slideStyles, 'width');
941
- const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
942
- const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
943
- const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
944
- const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
920
+ const width = parseFloat(slideStyles.getPropertyValue('width')) || slide.offsetWidth;
921
+ const paddingLeft = parseFloat(slideStyles.getPropertyValue('padding-left')) || 0;
922
+ const paddingRight = parseFloat(slideStyles.getPropertyValue('padding-right')) || 0;
923
+ const marginLeft = parseFloat(slideStyles.getPropertyValue('margin-left')) || 0;
924
+ const marginRight = parseFloat(slideStyles.getPropertyValue('margin-right')) || 0;
945
925
  const boxSizing = slideStyles.getPropertyValue('box-sizing');
946
926
  if (boxSizing && boxSizing === 'border-box') {
947
927
  slideSize = width + marginLeft + marginRight;
@@ -953,12 +933,8 @@
953
933
  slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);
954
934
  }
955
935
  }
956
- if (currentTransform) {
957
- slide.style.transform = currentTransform;
958
- }
959
- if (currentWebKitTransform) {
960
- slide.style.webkitTransform = currentWebKitTransform;
961
- }
936
+ if (currentTransform) slide.style.transform = currentTransform;
937
+ if (currentWebKitTransform) slide.style.webkitTransform = currentWebKitTransform;
962
938
  if (params.roundLengths) slideSize = Math.floor(slideSize);
963
939
  } else {
964
940
  slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
@@ -967,13 +943,13 @@
967
943
  slides[i].style[swiper.getDirectionLabel('width')] = `${slideSize}px`;
968
944
  }
969
945
  }
970
- if (slides[i]) {
971
- slides[i].swiperSlideSize = slideSize;
972
- }
946
+ if (slides[i]) slides[i].swiperSlideSize = slideSize;
973
947
  slidesSizesGrid.push(slideSize);
974
948
  if (params.centeredSlides) {
975
949
  slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
976
- if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
950
+ if (prevSlideSize === 0 && i !== 0) {
951
+ slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
952
+ }
977
953
  if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
978
954
  if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
979
955
  if (params.roundLengths) slidePosition = Math.floor(slidePosition);
@@ -981,55 +957,37 @@
981
957
  slidesGrid.push(slidePosition);
982
958
  } else {
983
959
  if (params.roundLengths) slidePosition = Math.floor(slidePosition);
984
- if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);
960
+ if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) {
961
+ snapGrid.push(slidePosition);
962
+ }
985
963
  slidesGrid.push(slidePosition);
986
964
  slidePosition = slidePosition + slideSize + spaceBetween;
987
965
  }
988
- swiper.virtualSize += slideSize + spaceBetween;
966
+ swiper.slidesTotalSize += slideSize + spaceBetween;
989
967
  prevSlideSize = slideSize;
990
968
  index += 1;
991
969
  }
992
- swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
993
- if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
994
- wrapperEl.style.width = `${swiper.virtualSize + spaceBetween}px`;
970
+ swiper.slidesTotalSize = Math.max(swiper.slidesTotalSize, swiperSize) + offsetAfter;
971
+ if (rtl && wrongRTL && params.effect === 'slide') {
972
+ wrapperEl.style.width = `${swiper.slidesTotalSize + spaceBetween}px`;
995
973
  }
996
974
  if (params.setWrapperSize) {
997
- wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
998
- }
999
- if (gridEnabled) {
1000
- swiper.grid.updateWrapperSize(slideSize, snapGrid);
975
+ wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.slidesTotalSize + spaceBetween}px`;
1001
976
  }
1002
977
 
1003
- // Remove last grid elements depending on width
978
+ // Remove last snap points depending on width (non-centered)
1004
979
  if (!params.centeredSlides) {
1005
980
  const newSlidesGrid = [];
1006
981
  for (let i = 0; i < snapGrid.length; i += 1) {
1007
982
  let slidesGridItem = snapGrid[i];
1008
983
  if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
1009
- if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
984
+ if (snapGrid[i] <= swiper.slidesTotalSize - swiperSize) {
1010
985
  newSlidesGrid.push(slidesGridItem);
1011
986
  }
1012
987
  }
1013
988
  snapGrid = newSlidesGrid;
1014
- if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
1015
- snapGrid.push(swiper.virtualSize - swiperSize);
1016
- }
1017
- }
1018
- if (isVirtual && params.loop) {
1019
- const size = slidesSizesGrid[0] + spaceBetween;
1020
- if (params.slidesPerGroup > 1) {
1021
- const groups = Math.ceil((swiper.virtual.slidesBefore + swiper.virtual.slidesAfter) / params.slidesPerGroup);
1022
- const groupSize = size * params.slidesPerGroup;
1023
- for (let i = 0; i < groups; i += 1) {
1024
- snapGrid.push(snapGrid[snapGrid.length - 1] + groupSize);
1025
- }
1026
- }
1027
- for (let i = 0; i < swiper.virtual.slidesBefore + swiper.virtual.slidesAfter; i += 1) {
1028
- if (params.slidesPerGroup === 1) {
1029
- snapGrid.push(snapGrid[snapGrid.length - 1] + size);
1030
- }
1031
- slidesGrid.push(slidesGrid[slidesGrid.length - 1] + size);
1032
- swiper.virtualSize += size;
989
+ if (Math.floor(swiper.slidesTotalSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
990
+ snapGrid.push(swiper.slidesTotalSize - swiperSize);
1033
991
  }
1034
992
  }
1035
993
  if (snapGrid.length === 0) snapGrid = [0];
@@ -1037,9 +995,7 @@
1037
995
  const key = swiper.isHorizontal() && rtl ? 'marginLeft' : swiper.getDirectionLabel('marginRight');
1038
996
  slides.filter((_, slideIndex) => {
1039
997
  if (!params.cssMode || params.loop) return true;
1040
- if (slideIndex === slides.length - 1) {
1041
- return false;
1042
- }
998
+ if (slideIndex === slides.length - 1) return false;
1043
999
  return true;
1044
1000
  }).forEach(slideEl => {
1045
1001
  slideEl.style[key] = `${spaceBetween}px`;
@@ -1089,7 +1045,9 @@
1089
1045
  swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);
1090
1046
  swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);
1091
1047
  }
1092
- if (slidesLength !== previousSlidesLength) {
1048
+
1049
+ // Emit changes
1050
+ if (slidesLength !== (previousSlidesGridLength ? slides.length : slides.length)) {
1093
1051
  swiper.emit('slidesLengthChange');
1094
1052
  }
1095
1053
  if (snapGrid.length !== previousSnapGridLength) {
@@ -1103,7 +1061,7 @@
1103
1061
  swiper.updateSlidesOffset();
1104
1062
  }
1105
1063
  swiper.emit('slidesUpdated');
1106
- if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) {
1064
+ if (!params.cssMode && params.effect === 'slide') {
1107
1065
  const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`;
1108
1066
  const hasClassBackfaceClassAdded = swiper.el.classList.contains(backFaceHiddenClass);
1109
1067
  if (slidesLength <= params.maxBackfaceHiddenSlides) {
@@ -1117,20 +1075,13 @@
1117
1075
  function updateAutoHeight(speed) {
1118
1076
  const swiper = this;
1119
1077
  const activeSlides = [];
1120
- const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
1121
- let newHeight = 0;
1122
- let i;
1123
1078
  if (typeof speed === 'number') {
1124
1079
  swiper.setTransition(speed);
1125
1080
  } else if (speed === true) {
1126
1081
  swiper.setTransition(swiper.params.speed);
1127
1082
  }
1128
- const getSlideByIndex = index => {
1129
- if (isVirtual) {
1130
- return swiper.slides[swiper.getSlideIndexByData(index)];
1131
- }
1132
- return swiper.slides[index];
1133
- };
1083
+ const getSlideByIndex = index => swiper.slides[index];
1084
+
1134
1085
  // Find slides currently in view
1135
1086
  if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
1136
1087
  if (swiper.params.centeredSlides) {
@@ -1138,9 +1089,9 @@
1138
1089
  activeSlides.push(slide);
1139
1090
  });
1140
1091
  } else {
1141
- for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
1092
+ for (let i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
1142
1093
  const index = swiper.activeIndex + i;
1143
- if (index > swiper.slides.length && !isVirtual) break;
1094
+ if (index > swiper.slides.length) break;
1144
1095
  activeSlides.push(getSlideByIndex(index));
1145
1096
  }
1146
1097
  }
@@ -1149,14 +1100,13 @@
1149
1100
  }
1150
1101
 
1151
1102
  // Find new height from highest slide in view
1152
- for (i = 0; i < activeSlides.length; i += 1) {
1103
+ let newHeight = 0;
1104
+ for (let i = 0; i < activeSlides.length; i += 1) {
1153
1105
  if (typeof activeSlides[i] !== 'undefined') {
1154
1106
  const height = activeSlides[i].offsetHeight;
1155
1107
  newHeight = height > newHeight ? height : newHeight;
1156
1108
  }
1157
1109
  }
1158
-
1159
- // Update Height
1160
1110
  if (newHeight || newHeight === 0) swiper.wrapperEl.style.height = `${newHeight}px`;
1161
1111
  }
1162
1112
 
@@ -1301,46 +1251,16 @@
1301
1251
  slidesEl,
1302
1252
  activeIndex
1303
1253
  } = swiper;
1304
- const isVirtual = swiper.virtual && params.virtual.enabled;
1305
- const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
1306
- const getFilteredSlide = selector => {
1307
- return elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0];
1308
- };
1309
- let activeSlide;
1310
- let prevSlide;
1254
+ const getNextSlide = slideEl => elementNextAll(slideEl, `.${params.slideClass}, swiper-slide`)[0];
1255
+ const getPrevSlide = slideEl => elementPrevAll(slideEl, `.${params.slideClass}, swiper-slide`)[0];
1256
+ const activeSlide = slides[activeIndex];
1311
1257
  let nextSlide;
1312
- if (isVirtual) {
1313
- if (params.loop) {
1314
- let slideIndex = activeIndex - swiper.virtual.slidesBefore;
1315
- if (slideIndex < 0) slideIndex = swiper.virtual.slides.length + slideIndex;
1316
- if (slideIndex >= swiper.virtual.slides.length) slideIndex -= swiper.virtual.slides.length;
1317
- activeSlide = getFilteredSlide(`[data-swiper-slide-index="${slideIndex}"]`);
1318
- } else {
1319
- activeSlide = getFilteredSlide(`[data-swiper-slide-index="${activeIndex}"]`);
1320
- }
1321
- } else {
1322
- if (gridEnabled) {
1323
- activeSlide = slides.find(slideEl => slideEl.column === activeIndex);
1324
- nextSlide = slides.find(slideEl => slideEl.column === activeIndex + 1);
1325
- prevSlide = slides.find(slideEl => slideEl.column === activeIndex - 1);
1326
- } else {
1327
- activeSlide = slides[activeIndex];
1328
- }
1329
- }
1258
+ let prevSlide;
1330
1259
  if (activeSlide) {
1331
- if (!gridEnabled) {
1332
- // Next Slide
1333
- nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
1334
- if (params.loop && !nextSlide) {
1335
- nextSlide = slides[0];
1336
- }
1337
-
1338
- // Prev Slide
1339
- prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
1340
- if (params.loop && !prevSlide === 0) {
1341
- prevSlide = slides[slides.length - 1];
1342
- }
1343
- }
1260
+ nextSlide = getNextSlide(activeSlide);
1261
+ prevSlide = getPrevSlide(activeSlide);
1262
+ if (params.loop && !nextSlide) nextSlide = slides[0];
1263
+ if (params.loop && !prevSlide) prevSlide = slides[slides.length - 1];
1344
1264
  }
1345
1265
  slides.forEach(slideEl => {
1346
1266
  toggleSlideClasses(slideEl, slideEl === activeSlide, params.slideActiveClass);
@@ -1431,7 +1351,6 @@
1431
1351
  activeIndex = i;
1432
1352
  }
1433
1353
  }
1434
- // Normalize slideIndex
1435
1354
  if (params.normalizeSlideIndex) {
1436
1355
  if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
1437
1356
  }
@@ -1449,16 +1368,6 @@
1449
1368
  } = swiper;
1450
1369
  let activeIndex = newActiveIndex;
1451
1370
  let snapIndex;
1452
- const getVirtualRealIndex = aIndex => {
1453
- let realIndex = aIndex - swiper.virtual.slidesBefore;
1454
- if (realIndex < 0) {
1455
- realIndex = swiper.virtual.slides.length + realIndex;
1456
- }
1457
- if (realIndex >= swiper.virtual.slides.length) {
1458
- realIndex -= swiper.virtual.slides.length;
1459
- }
1460
- return realIndex;
1461
- };
1462
1371
  if (typeof activeIndex === 'undefined') {
1463
1372
  activeIndex = getActiveIndexByTranslate(swiper);
1464
1373
  }
@@ -1476,32 +1385,12 @@
1476
1385
  }
1477
1386
  return;
1478
1387
  }
1479
- if (activeIndex === previousIndex && swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
1480
- swiper.realIndex = getVirtualRealIndex(activeIndex);
1481
- return;
1482
- }
1483
- const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
1484
-
1485
- // Get real index
1486
- let realIndex;
1487
- if (swiper.virtual && params.virtual.enabled && params.loop) {
1488
- realIndex = getVirtualRealIndex(activeIndex);
1489
- } else if (gridEnabled) {
1490
- const firstSlideInColumn = swiper.slides.find(slideEl => slideEl.column === activeIndex);
1491
- let activeSlideIndex = parseInt(firstSlideInColumn.getAttribute('data-swiper-slide-index'), 10);
1492
- if (Number.isNaN(activeSlideIndex)) {
1493
- activeSlideIndex = Math.max(swiper.slides.indexOf(firstSlideInColumn), 0);
1494
- }
1495
- realIndex = Math.floor(activeSlideIndex / params.grid.rows);
1496
- } else if (swiper.slides[activeIndex]) {
1388
+ let realIndex = activeIndex;
1389
+ if (swiper.slides[activeIndex]) {
1497
1390
  const slideIndex = swiper.slides[activeIndex].getAttribute('data-swiper-slide-index');
1498
1391
  if (slideIndex) {
1499
1392
  realIndex = parseInt(slideIndex, 10);
1500
- } else {
1501
- realIndex = activeIndex;
1502
1393
  }
1503
- } else {
1504
- realIndex = activeIndex;
1505
1394
  }
1506
1395
  Object.assign(swiper, {
1507
1396
  previousSnapIndex,
@@ -1548,11 +1437,7 @@
1548
1437
  }
1549
1438
  if (slide && slideFound) {
1550
1439
  swiper.clickedSlide = slide;
1551
- if (swiper.virtual && swiper.params.virtual.enabled) {
1552
- swiper.clickedIndex = parseInt(slide.getAttribute('data-swiper-slide-index'), 10);
1553
- } else {
1554
- swiper.clickedIndex = slideIndex;
1555
- }
1440
+ swiper.clickedIndex = slideIndex;
1556
1441
  } else {
1557
1442
  swiper.clickedSlide = undefined;
1558
1443
  swiper.clickedIndex = undefined;
@@ -1586,9 +1471,6 @@
1586
1471
  translate,
1587
1472
  wrapperEl
1588
1473
  } = swiper;
1589
- if (params.virtualTranslate) {
1590
- return rtl ? -translate : translate;
1591
- }
1592
1474
  if (params.cssMode) {
1593
1475
  return translate;
1594
1476
  }
@@ -1622,7 +1504,7 @@
1622
1504
  swiper.translate = swiper.isHorizontal() ? x : y;
1623
1505
  if (params.cssMode) {
1624
1506
  wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
1625
- } else if (!params.virtualTranslate) {
1507
+ } else {
1626
1508
  if (swiper.isHorizontal()) {
1627
1509
  x -= swiper.cssOverflowAdjustment();
1628
1510
  } else {
@@ -1859,7 +1741,6 @@
1859
1741
  let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
1860
1742
  if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
1861
1743
  const translate = -snapGrid[snapIndex];
1862
- // Normalize slideIndex
1863
1744
  if (params.normalizeSlideIndex) {
1864
1745
  for (let i = 0; i < slidesGrid.length; i += 1) {
1865
1746
  const normalizedTranslate = -Math.floor(translate * 100);
@@ -1876,33 +1757,24 @@
1876
1757
  }
1877
1758
  }
1878
1759
  }
1760
+
1879
1761
  // Directions locks
1880
1762
  if (swiper.initialized && slideIndex !== activeIndex) {
1881
1763
  if (!swiper.allowSlideNext && (rtl ? translate > swiper.translate && translate > swiper.minTranslate() : translate < swiper.translate && translate < swiper.minTranslate())) {
1882
1764
  return false;
1883
1765
  }
1884
1766
  if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
1885
- if ((activeIndex || 0) !== slideIndex) {
1886
- return false;
1887
- }
1767
+ if ((activeIndex || 0) !== slideIndex) return false;
1888
1768
  }
1889
1769
  }
1890
1770
  if (slideIndex !== (previousIndex || 0) && runCallbacks) {
1891
1771
  swiper.emit('beforeSlideChangeStart');
1892
1772
  }
1893
-
1894
- // Update progress
1895
1773
  swiper.updateProgress(translate);
1896
1774
  let direction;
1897
1775
  if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset';
1898
-
1899
- // initial virtual
1900
- const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
1901
- const isInitialVirtual = isVirtual && initial;
1902
- // Update Index
1903
- if (!isInitialVirtual && (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate)) {
1776
+ if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {
1904
1777
  swiper.updateActiveIndex(slideIndex);
1905
- // Update Height
1906
1778
  if (params.autoHeight) {
1907
1779
  swiper.updateAutoHeight();
1908
1780
  }
@@ -1920,24 +1792,7 @@
1920
1792
  const isH = swiper.isHorizontal();
1921
1793
  const t = rtl ? translate : -translate;
1922
1794
  if (speed === 0) {
1923
- if (isVirtual) {
1924
- swiper.wrapperEl.style.scrollSnapType = 'none';
1925
- swiper._immediateVirtual = true;
1926
- }
1927
- if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) {
1928
- swiper._cssModeVirtualInitialSet = true;
1929
- requestAnimationFrame(() => {
1930
- wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1931
- });
1932
- } else {
1933
- wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1934
- }
1935
- if (isVirtual) {
1936
- requestAnimationFrame(() => {
1937
- swiper.wrapperEl.style.scrollSnapType = '';
1938
- swiper._immediateVirtual = false;
1939
- });
1940
- }
1795
+ wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1941
1796
  } else {
1942
1797
  if (!swiper.support.smoothScroll) {
1943
1798
  animateCSSModeScroll({
@@ -1955,10 +1810,7 @@
1955
1810
  return true;
1956
1811
  }
1957
1812
  const browser = getBrowser();
1958
- const isSafari = browser.isSafari;
1959
- if (isVirtual && !initial && isSafari && swiper.isElement) {
1960
- swiper.virtual.update(false, false, slideIndex);
1961
- }
1813
+ browser.isSafari;
1962
1814
  swiper.setTransition(speed);
1963
1815
  swiper.setTranslate(translate);
1964
1816
  swiper.updateActiveIndex(slideIndex);
@@ -2129,8 +1981,6 @@
2129
1981
  if (swiper.params?.isSneakPeekCenter && slides.length > 1 && swiper.activeIndex === 0) {
2130
1982
  const gap = Math.abs(swiper.snapGrid[1] - swiper.snapGrid[0]);
2131
1983
  const swiperTranslate = JSON.parse(JSON.stringify(swiper.snapGrid[1]));
2132
-
2133
- // Move last item to first position only if active slide is the first slide
2134
1984
  const lastSlide = slides[slides.length - 1];
2135
1985
  lastSlide.swiperLoopMoveDOM = true;
2136
1986
  swiper.slidesEl.prepend(lastSlide);
@@ -2165,11 +2015,8 @@
2165
2015
  perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
2166
2016
  }
2167
2017
  const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
2168
- const isVirtual = swiper.virtual && params.virtual.enabled;
2169
2018
  if (params.loop) {
2170
- if (animating && !isVirtual && params.loopPreventsSliding) return false;
2171
-
2172
- // Kiểm tra xem loop có bị disable không
2019
+ if (animating && params.loopPreventsSliding) return false;
2173
2020
  const currentSlidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10));
2174
2021
  if (swiper.slides.length >= currentSlidesPerView) {
2175
2022
  swiper.loopFix({
@@ -2195,8 +2042,7 @@
2195
2042
  const lastSnapGridIndex = swiper.snapGrid.length - 1;
2196
2043
  const gap = Math.abs(swiper.snapGrid[lastSnapGridIndex] - swiper.snapGrid[lastSnapGridIndex - 1]);
2197
2044
  const swiperTranslate = structuredClone(swiper.snapGrid[lastSnapGridIndex - 1]);
2198
-
2199
- // Move first item to last position only if active slide is the last slide
2045
+ if (!swiper.params.loop) return;
2200
2046
  const firstSlide = slides[0];
2201
2047
  firstSlide.swiperLoopMoveDOM = true;
2202
2048
  swiper.slidesEl.append(firstSlide);
@@ -2221,17 +2067,14 @@
2221
2067
  params,
2222
2068
  snapGrid,
2223
2069
  slidesGrid,
2224
- rtlTranslate,
2225
- enabled,
2226
- animating
2070
+ rtlTranslate: rtlTranslate,
2071
+ enabled
2227
2072
  } = swiper;
2228
2073
  if (!enabled || swiper.destroyed) return swiper;
2229
2074
  if (typeof speed === 'undefined') {
2230
2075
  speed = swiper.params.speed;
2231
2076
  }
2232
- swiper.virtual && params.virtual.enabled;
2233
2077
  if (params.loop) {
2234
- // Kiểm tra xem loop có bị disable không
2235
2078
  const currentSlidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10));
2236
2079
  if (swiper.slides.length >= currentSlidesPerView) {
2237
2080
  swiper.loopFix({
@@ -2248,18 +2091,16 @@
2248
2091
  }
2249
2092
  const normalizedTranslate = normalize(translate);
2250
2093
  const normalizedSnapGrid = snapGrid.map(val => normalize(val));
2251
- const isFreeMode = params.freeMode && params.freeMode.enabled;
2252
2094
  let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
2253
- if (typeof prevSnap === 'undefined' && (params.cssMode || isFreeMode)) {
2095
+ if (typeof prevSnap === 'undefined' && params.cssMode) {
2254
2096
  let prevSnapIndex;
2255
2097
  snapGrid.forEach((snap, snapIndex) => {
2256
2098
  if (normalizedTranslate >= snap) {
2257
- // prevSnap = snap;
2258
2099
  prevSnapIndex = snapIndex;
2259
2100
  }
2260
2101
  });
2261
2102
  if (typeof prevSnapIndex !== 'undefined') {
2262
- prevSnap = isFreeMode ? snapGrid[prevSnapIndex] : snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
2103
+ prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
2263
2104
  }
2264
2105
  }
2265
2106
  let prevIndex = 0;
@@ -2272,7 +2113,7 @@
2272
2113
  }
2273
2114
  }
2274
2115
  if (params.rewind && swiper.isBeginning) {
2275
- const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
2116
+ const lastIndex = swiper.slides.length - 1;
2276
2117
  return swiper.slideTo(lastIndex, speed, runCallbacks, internal);
2277
2118
  } else if (params.loop && swiper.activeIndex === 0 && params.cssMode) {
2278
2119
  requestAnimationFrame(() => {
@@ -2286,8 +2127,7 @@
2286
2127
  if (swiper.params?.isSneakPeekCenter && slides.length > 1 && swiper.activeIndex === 0) {
2287
2128
  const gap = Math.abs(swiper.snapGrid[1] - swiper.snapGrid[0]);
2288
2129
  const swiperTranslate = JSON.parse(JSON.stringify(swiper.snapGrid[1]));
2289
-
2290
- // Move last item to first position only if active slide is the first slide
2130
+ if (!swiper.params.loop) return;
2291
2131
  const lastSlide = slides[slides.length - 1];
2292
2132
  lastSlide.swiperLoopMoveDOM = true;
2293
2133
  swiper.slidesEl.prepend(lastSlide);
@@ -2363,20 +2203,19 @@
2363
2203
  slidesEl
2364
2204
  } = swiper;
2365
2205
  const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
2366
- let slideToIndex = swiper.getSlideIndexWhenGrid(swiper.clickedIndex);
2206
+ const slideToIndex = swiper.clickedIndex;
2367
2207
  let realIndex;
2368
2208
  const slideSelector = swiper.isElement ? `swiper-slide` : `.${params.slideClass}`;
2369
- const isGrid = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
2370
2209
  if (params.loop) {
2371
2210
  if (swiper.animating) return;
2372
2211
  realIndex = parseInt(swiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
2373
2212
  if (params.centeredSlides) {
2374
2213
  swiper.slideToLoop(realIndex);
2375
- } else if (slideToIndex > (isGrid ? (swiper.slides.length - slidesPerView) / 2 - (swiper.params.grid.rows - 1) : swiper.slides.length - slidesPerView)) {
2214
+ } else if (slideToIndex > swiper.slides.length - slidesPerView) {
2376
2215
  swiper.loopFix();
2377
- slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
2216
+ const clickedEl = elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0];
2378
2217
  nextTick(() => {
2379
- swiper.slideTo(slideToIndex);
2218
+ if (clickedEl) swiper.slideTo(swiper.getSlideIndex(clickedEl));
2380
2219
  });
2381
2220
  } else {
2382
2221
  swiper.slideTo(slideToIndex);
@@ -2403,7 +2242,7 @@
2403
2242
  params,
2404
2243
  slidesEl
2405
2244
  } = swiper;
2406
- if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
2245
+ if (!params.loop) return;
2407
2246
  const initSlides = () => {
2408
2247
  const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
2409
2248
  slides.forEach((el, index) => {
@@ -2412,21 +2251,17 @@
2412
2251
  };
2413
2252
  const clearBlankSlides = () => {
2414
2253
  const slides = elementChildren(slidesEl, `.${params.slideBlankClass}`);
2415
- slides.forEach(el => {
2416
- el.remove();
2417
- });
2254
+ slides.forEach(el => el.remove());
2418
2255
  if (slides.length > 0) {
2419
2256
  swiper.recalcSlides();
2420
2257
  swiper.updateSlides();
2421
2258
  }
2422
2259
  };
2423
- const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
2424
- if (params.loopAddBlankSlides && (params.slidesPerGroup > 1 || gridEnabled)) {
2260
+ if (params.loopAddBlankSlides && params.slidesPerGroup > 1) {
2425
2261
  clearBlankSlides();
2426
2262
  }
2427
- const slidesPerGroup = params.slidesPerGroup * (gridEnabled ? params.grid.rows : 1);
2263
+ const slidesPerGroup = params.slidesPerGroup;
2428
2264
  const shouldFillGroup = swiper.slides.length % slidesPerGroup !== 0;
2429
- const shouldFillGrid = gridEnabled && swiper.slides.length % params.grid.rows !== 0;
2430
2265
  const addBlankSlides = amountOfSlides => {
2431
2266
  for (let i = 0; i < amountOfSlides; i += 1) {
2432
2267
  const slideEl = swiper.isElement ? createElement('swiper-slide', [params.slideBlankClass]) : createElement('div', [params.slideClass, params.slideBlankClass]);
@@ -2443,16 +2278,6 @@
2443
2278
  showWarning('Swiper Loop Warning: The number of slides is not even to slidesPerGroup, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
2444
2279
  }
2445
2280
  initSlides();
2446
- } else if (shouldFillGrid) {
2447
- if (params.loopAddBlankSlides) {
2448
- const slidesToAdd = params.grid.rows - swiper.slides.length % params.grid.rows;
2449
- addBlankSlides(slidesToAdd);
2450
- swiper.recalcSlides();
2451
- swiper.updateSlides();
2452
- } else {
2453
- showWarning('Swiper Loop Warning: The number of slides is not even to grid.rows, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
2454
- }
2455
- initSlides();
2456
2281
  } else {
2457
2282
  initSlides();
2458
2283
  }
@@ -2471,13 +2296,12 @@
2471
2296
  setTranslate,
2472
2297
  activeSlideIndex,
2473
2298
  initial,
2474
- byController,
2475
2299
  byMousewheel
2476
2300
  } = _temp === void 0 ? {} : _temp;
2477
2301
  const swiper = this;
2478
2302
  if (!swiper.params.loop) return;
2479
2303
 
2480
- // Disable loop mode nếu số slides ít hơn slidesPerView
2304
+ // Disable loop mode if number of slides is smaller than slidesPerView
2481
2305
  const currentSlidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
2482
2306
  if (swiper.slides.length < currentSlidesPerView) {
2483
2307
  console.warn('Swiper: Loop mode disabled - slides.length < slidesPerView');
@@ -2497,21 +2321,6 @@
2497
2321
  } = params;
2498
2322
  swiper.allowSlidePrev = true;
2499
2323
  swiper.allowSlideNext = true;
2500
- if (swiper.virtual && params.virtual.enabled) {
2501
- if (slideTo) {
2502
- if (!params.centeredSlides && swiper.snapIndex === 0) {
2503
- swiper.slideTo(swiper.virtual.slides.length, 0, false, true);
2504
- } else if (params.centeredSlides && swiper.snapIndex < params.slidesPerView) {
2505
- swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true);
2506
- } else if (swiper.snapIndex === swiper.snapGrid.length - 1) {
2507
- swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true);
2508
- }
2509
- }
2510
- swiper.allowSlidePrev = allowSlidePrev;
2511
- swiper.allowSlideNext = allowSlideNext;
2512
- swiper.emit('loopFix');
2513
- return;
2514
- }
2515
2324
  let slidesPerView = params.slidesPerView;
2516
2325
  if (slidesPerView === 'auto') {
2517
2326
  slidesPerView = swiper.slidesPerViewDynamic();
@@ -2521,22 +2330,19 @@
2521
2330
  slidesPerView = slidesPerView + 1;
2522
2331
  }
2523
2332
  }
2524
- const slidesPerGroup = params.slidesPerGroupAuto ? slidesPerView : params.slidesPerGroup;
2333
+ const slidesPerGroup = params.slidesPerGroup;
2525
2334
  let loopedSlides = centeredSlides ? Math.max(slidesPerGroup, Math.ceil(slidesPerView / 2)) : slidesPerGroup;
2526
2335
  if (loopedSlides % slidesPerGroup !== 0) {
2527
2336
  loopedSlides += slidesPerGroup - loopedSlides % slidesPerGroup;
2528
2337
  }
2529
2338
  loopedSlides += params.loopAdditionalSlides;
2530
2339
  swiper.loopedSlides = loopedSlides;
2531
- const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
2532
- if (slides.length < slidesPerView + loopedSlides || swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
2340
+ if (slides.length < slidesPerView + loopedSlides) {
2533
2341
  showWarning('Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled or not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters');
2534
- } else if (gridEnabled && params.grid.fill === 'row') {
2535
- showWarning('Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`');
2536
2342
  }
2537
2343
  const prependSlidesIndexes = [];
2538
2344
  const appendSlidesIndexes = [];
2539
- const cols = gridEnabled ? Math.ceil(slides.length / params.grid.rows) : slides.length;
2345
+ const cols = slides.length;
2540
2346
  const isInitialOverflow = initial && cols - initialSlide < slidesPerView && !centeredSlides;
2541
2347
  let activeIndex = isInitialOverflow ? initialSlide : swiper.activeIndex;
2542
2348
  if (typeof activeSlideIndex === 'undefined') {
@@ -2548,24 +2354,15 @@
2548
2354
  const isPrev = direction === 'prev' || !direction;
2549
2355
  let slidesPrepended = 0;
2550
2356
  let slidesAppended = 0;
2551
- const activeColIndex = gridEnabled ? slides[activeSlideIndex].column : activeSlideIndex;
2357
+ const activeColIndex = activeSlideIndex;
2552
2358
  const activeColIndexWithShift = activeColIndex + (centeredSlides && typeof setTranslate === 'undefined' ? -slidesPerView / 2 + 0.5 : 0);
2359
+
2553
2360
  // prepend last slides before start
2554
2361
  if (activeColIndexWithShift < loopedSlides) {
2555
2362
  slidesPrepended = Math.max(loopedSlides - activeColIndexWithShift, slidesPerGroup);
2556
2363
  for (let i = 0; i < loopedSlides - activeColIndexWithShift; i += 1) {
2557
2364
  const index = i - Math.floor(i / cols) * cols;
2558
- if (gridEnabled) {
2559
- const colIndexToPrepend = cols - index - 1;
2560
- for (let i = slides.length - 1; i >= 0; i -= 1) {
2561
- if (slides[i].column === colIndexToPrepend) prependSlidesIndexes.push(i);
2562
- }
2563
- // slides.forEach((slide, slideIndex) => {
2564
- // if (slide.column === colIndexToPrepend) prependSlidesIndexes.push(slideIndex);
2565
- // });
2566
- } else {
2567
- prependSlidesIndexes.push(cols - index - 1);
2568
- }
2365
+ prependSlidesIndexes.push(cols - index - 1);
2569
2366
  }
2570
2367
  } else if (activeColIndexWithShift + slidesPerView > cols - loopedSlides) {
2571
2368
  slidesAppended = Math.max(activeColIndexWithShift - (cols - loopedSlides * 2), slidesPerGroup);
@@ -2574,27 +2371,13 @@
2574
2371
  }
2575
2372
  for (let i = 0; i < slidesAppended; i += 1) {
2576
2373
  const index = i - Math.floor(i / cols) * cols;
2577
- if (gridEnabled) {
2578
- slides.forEach((slide, slideIndex) => {
2579
- if (slide.column === index) appendSlidesIndexes.push(slideIndex);
2580
- });
2581
- } else {
2582
- appendSlidesIndexes.push(index);
2583
- }
2374
+ appendSlidesIndexes.push(index);
2584
2375
  }
2585
2376
  }
2586
2377
  swiper.__preventObserver__ = true;
2587
2378
  requestAnimationFrame(() => {
2588
2379
  swiper.__preventObserver__ = false;
2589
2380
  });
2590
- if (swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
2591
- if (appendSlidesIndexes.includes(activeSlideIndex)) {
2592
- appendSlidesIndexes.splice(appendSlidesIndexes.indexOf(activeSlideIndex), 1);
2593
- }
2594
- if (prependSlidesIndexes.includes(activeSlideIndex)) {
2595
- prependSlidesIndexes.splice(prependSlidesIndexes.indexOf(activeSlideIndex), 1);
2596
- }
2597
- }
2598
2381
  if (isPrev) {
2599
2382
  prependSlidesIndexes.forEach(index => {
2600
2383
  slides[index].swiperLoopMoveDOM = true;
@@ -2612,10 +2395,6 @@
2612
2395
  swiper.recalcSlides();
2613
2396
  if (params.slidesPerView === 'auto') {
2614
2397
  swiper.updateSlides();
2615
- } else if (gridEnabled && (prependSlidesIndexes.length > 0 && isPrev || appendSlidesIndexes.length > 0 && isNext)) {
2616
- swiper.slides.forEach((slide, slideIndex) => {
2617
- swiper.grid.updateSlide(slideIndex, slide, swiper.slides);
2618
- });
2619
2398
  }
2620
2399
  if (params.watchSlidesProgress) {
2621
2400
  swiper.updateSlidesOffset();
@@ -2635,12 +2414,10 @@
2635
2414
  swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
2636
2415
  }
2637
2416
  }
2638
- } else {
2639
- if (setTranslate) {
2640
- const shift = gridEnabled ? prependSlidesIndexes.length / params.grid.rows : prependSlidesIndexes.length;
2641
- swiper.slideTo(swiper.activeIndex + shift, 0, false, true);
2642
- swiper.touchEventsData.currentTranslate = swiper.translate;
2643
- }
2417
+ } else if (setTranslate) {
2418
+ const shift = prependSlidesIndexes.length;
2419
+ swiper.slideTo(swiper.activeIndex + shift, 0, false, true);
2420
+ swiper.touchEventsData.currentTranslate = swiper.translate;
2644
2421
  }
2645
2422
  } else if (appendSlidesIndexes.length > 0 && isNext) {
2646
2423
  if (typeof slideRealIndex === 'undefined') {
@@ -2656,36 +2433,14 @@
2656
2433
  swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
2657
2434
  }
2658
2435
  }
2659
- } else {
2660
- const shift = gridEnabled ? appendSlidesIndexes.length / params.grid.rows : appendSlidesIndexes.length;
2436
+ } else if (setTranslate) {
2437
+ const shift = appendSlidesIndexes.length;
2661
2438
  swiper.slideTo(swiper.activeIndex - shift, 0, false, true);
2662
2439
  }
2663
2440
  }
2664
2441
  }
2665
2442
  swiper.allowSlidePrev = allowSlidePrev;
2666
2443
  swiper.allowSlideNext = allowSlideNext;
2667
- if (swiper.controller && swiper.controller.control && !byController) {
2668
- const loopParams = {
2669
- slideRealIndex,
2670
- direction,
2671
- setTranslate,
2672
- activeSlideIndex,
2673
- byController: true
2674
- };
2675
- if (Array.isArray(swiper.controller.control)) {
2676
- swiper.controller.control.forEach(c => {
2677
- if (!c.destroyed && c.params.loop) c.loopFix({
2678
- ...loopParams,
2679
- slideTo: c.params.slidesPerView === params.slidesPerView ? slideTo : false
2680
- });
2681
- });
2682
- } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) {
2683
- swiper.controller.control.loopFix({
2684
- ...loopParams,
2685
- slideTo: swiper.controller.control.params.slidesPerView === params.slidesPerView ? slideTo : false
2686
- });
2687
- }
2688
- }
2689
2444
  swiper.emit('loopFix');
2690
2445
  }
2691
2446
 
@@ -2702,7 +2457,7 @@
2702
2457
  const swiper = this;
2703
2458
  if (!swiper.params.loop) return;
2704
2459
 
2705
- // Disable loop mode nếu số slides ít hơn slidesPerView
2460
+ // Disable loop mode if number of slides is smaller than slidesPerView
2706
2461
  const currentSlidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
2707
2462
  if (swiper.slides.length < currentSlidesPerView) {
2708
2463
  console.warn('Swiper: Loop mode disabled - slides.length < slidesPerView');
@@ -2741,7 +2496,7 @@
2741
2496
  }
2742
2497
  loopedSlides += params.loopAdditionalSlides;
2743
2498
  swiper.loopedSlides = loopedSlides;
2744
- if (slides.length < slidesPerView + loopedSlides || swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
2499
+ if (slides.length < slidesPerView + loopedSlides) {
2745
2500
  showWarning('Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled or not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters');
2746
2501
  }
2747
2502
  const isNext = direction === 'next' || !direction;
@@ -2767,20 +2522,16 @@
2767
2522
  activeSlideIndex = swiper.getSlideIndex(slides.find(el => el.classList.contains(params.slideActiveClass)));
2768
2523
  }
2769
2524
 
2770
- // Tạo DocumentFragment để chứa các slide clone
2525
+ // DocumentFragment to hold slide clones
2771
2526
  const cloneFragment = document.createDocumentFragment();
2772
2527
 
2773
- // Clone các slide theo numberOfSlidesNeedClone (đã đảo ngược) và thêm vào fragment
2528
+ // Clone slides according to numberOfSlidesNeedClone and append to fragment
2774
2529
  (isNext ? numberOfSlidesNeedClone : numberOfSlidesNeedClone.reverse()).forEach(index => {
2775
2530
  if (slides[index]) {
2776
2531
  const originalSlide = slides[index];
2777
2532
  const clonedSlide = originalSlide.cloneNode(true);
2778
-
2779
- // Đánh dấu slide clone
2780
2533
  clonedSlide.setAttribute('data-swiper-clone', 'true');
2781
2534
  clonedSlide.classList.add('swiper-slide-clone');
2782
-
2783
- // Thêm clone vào fragment
2784
2535
  cloneFragment.appendChild(clonedSlide);
2785
2536
  }
2786
2537
  });
@@ -2801,32 +2552,28 @@
2801
2552
  });
2802
2553
  }
2803
2554
 
2804
- // Sắp xếp cloneFragment theo data-swiper-slide-index tăng dần
2555
+ // Sort cloned slides by data-swiper-slide-index
2805
2556
  const clonedSlides = Array.from(cloneFragment.children);
2806
2557
  clonedSlides.sort((a, b) => {
2807
2558
  const indexA = parseInt(a.getAttribute('data-swiper-slide-index')) || 0;
2808
2559
  const indexB = parseInt(b.getAttribute('data-swiper-slide-index')) || 0;
2809
2560
  return indexA - indexB;
2810
2561
  });
2811
-
2812
- // Xóa tất cả children cũ và thêm lại theo thứ tự đã sắp xếp
2813
2562
  cloneFragment.innerHTML = '';
2814
2563
  clonedSlides.forEach(slide => {
2815
2564
  cloneFragment.appendChild(slide);
2816
2565
  });
2817
2566
 
2818
- // Thêm fragment vào vị trí phù hợp
2567
+ // Place fragment into the right position
2819
2568
  if (isPrev) {
2820
- // Nếu là prev, thêm fragment vào cuối slidesEl
2821
2569
  slidesEl.appendChild(cloneFragment);
2822
2570
  } else if (isNext) {
2823
- // Nếu là next, thêm fragment vào đầu slidesEl
2824
2571
  slidesEl.insertBefore(cloneFragment, slidesEl.firstChild);
2825
2572
  }
2826
2573
  swiper.recalcSlides();
2827
2574
  swiper.updateSlides();
2828
2575
 
2829
- // Tìm slide data-swiper-slide-index tương ứng
2576
+ // Find old active slide index after recalculation
2830
2577
  let oldActiveIndex = null;
2831
2578
  for (let i = 0; i < slidesEl.children.length; i++) {
2832
2579
  const child = slidesEl.children[i];
@@ -2839,7 +2586,7 @@
2839
2586
  swiper.slideTo(oldActiveIndex, 0);
2840
2587
  }
2841
2588
 
2842
- // Tìm vị trí slide sau khi remove clone để set lại translate tạo hiệu ứng animate
2589
+ // Update translate after removing clones for animation
2843
2590
  const skip = Math.min(swiper.params.slidesPerGroupSkip, newIndex);
2844
2591
  let snapIndex = skip + Math.floor((newIndex - skip) / swiper.params.slidesPerGroup);
2845
2592
  if (snapIndex >= swiper.snapGrid.length) snapIndex = swiper.snapGrid.length - 1;
@@ -2865,7 +2612,8 @@
2865
2612
  }
2866
2613
  swiper.setTranslate(updateTranslate);
2867
2614
  }
2868
- // Remove slide clone ra khỏi slidesEl sau khi slideTo hoàn thành
2615
+
2616
+ // Remove clones
2869
2617
  const cloneSlides = slidesEl.querySelectorAll('[data-swiper-clone="true"]');
2870
2618
  cloneSlides.forEach(cloneSlide => {
2871
2619
  if (cloneSlide.parentNode) {
@@ -2895,7 +2643,7 @@
2895
2643
  params,
2896
2644
  slidesEl
2897
2645
  } = swiper;
2898
- if (!params.loop || !slidesEl || swiper.virtual && swiper.params.virtual.enabled) return;
2646
+ if (!params.loop || !slidesEl) return;
2899
2647
  swiper.recalcSlides();
2900
2648
  const newSlidesOrder = [];
2901
2649
  swiper.slides.forEach(slideEl => {
@@ -2956,7 +2704,6 @@
2956
2704
  unsetGrabCursor
2957
2705
  };
2958
2706
 
2959
- // Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
2960
2707
  function closestElement(selector, base) {
2961
2708
  if (base === void 0) {
2962
2709
  base = this;
@@ -2965,9 +2712,7 @@
2965
2712
  if (!el || el === getDocument() || el === getWindow()) return null;
2966
2713
  if (el.assignedSlot) el = el.assignedSlot;
2967
2714
  const found = el.closest(selector);
2968
- if (!found && !el.getRootNode) {
2969
- return null;
2970
- }
2715
+ if (!found && !el.getRootNode) return null;
2971
2716
  return found || __closestFrom(el.getRootNode().host);
2972
2717
  }
2973
2718
  return __closestFrom(base);
@@ -2995,9 +2740,7 @@
2995
2740
  if (e.originalEvent) e = e.originalEvent;
2996
2741
  const data = swiper.touchEventsData;
2997
2742
  if (e.type === 'pointerdown') {
2998
- if (data.pointerId !== null && data.pointerId !== e.pointerId) {
2999
- return;
3000
- }
2743
+ if (data.pointerId !== null && data.pointerId !== e.pointerId) return;
3001
2744
  data.pointerId = e.pointerId;
3002
2745
  } else if (e.type === 'touchstart' && e.targetTouches.length === 1) {
3003
2746
  data.touchId = e.targetTouches[0].identifier;
@@ -3014,9 +2757,7 @@
3014
2757
  } = swiper;
3015
2758
  if (!enabled) return;
3016
2759
  if (!params.simulateTouch && e.pointerType === 'mouse') return;
3017
- if (swiper.animating && params.preventInteractionOnTransition) {
3018
- return;
3019
- }
2760
+ if (swiper.animating && params.preventInteractionOnTransition) return;
3020
2761
  if (!swiper.animating && params.cssMode && params.loop) {
3021
2762
  swiper.loopFix();
3022
2763
  }
@@ -3027,8 +2768,6 @@
3027
2768
  if ('which' in e && e.which === 3) return;
3028
2769
  if ('button' in e && e.button > 0) return;
3029
2770
  if (data.isTouched && data.isMoved) return;
3030
-
3031
- // change target el for shadow root component
3032
2771
  const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
3033
2772
  // eslint-disable-next-line
3034
2773
  const eventPath = e.composedPath ? e.composedPath() : e.path;
@@ -3037,8 +2776,6 @@
3037
2776
  }
3038
2777
  const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
3039
2778
  const isTargetShadow = !!(e.target && e.target.shadowRoot);
3040
-
3041
- // use closestElement for shadow root element to get the actual closest for nested shadow root element
3042
2779
  if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))) {
3043
2780
  swiper.allowClick = true;
3044
2781
  return;
@@ -3050,12 +2787,7 @@
3050
2787
  touches.currentY = e.pageY;
3051
2788
  const startX = touches.currentX;
3052
2789
  const startY = touches.currentY;
3053
-
3054
- // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
3055
-
3056
- if (!preventEdgeSwipe(swiper, e, startX)) {
3057
- return;
3058
- }
2790
+ if (!preventEdgeSwipe(swiper, e, startX)) return;
3059
2791
  Object.assign(data, {
3060
2792
  isTouched: true,
3061
2793
  isMoved: false,
@@ -3084,9 +2816,6 @@
3084
2816
  if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) {
3085
2817
  e.preventDefault();
3086
2818
  }
3087
- if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {
3088
- swiper.freeMode.onTouchStart();
3089
- }
3090
2819
  swiper.emit('touchStart', e);
3091
2820
  }
3092
2821
 
@@ -3105,7 +2834,7 @@
3105
2834
  let e = event;
3106
2835
  if (e.originalEvent) e = e.originalEvent;
3107
2836
  if (e.type === 'pointermove') {
3108
- if (data.touchId !== null) return; // return from pointer if we use touch
2837
+ if (data.touchId !== null) return;
3109
2838
  const id = e.pointerId;
3110
2839
  if (id !== data.pointerId) return;
3111
2840
  }
@@ -3146,7 +2875,6 @@
3146
2875
  }
3147
2876
  if (params.touchReleaseOnEdges && !params.loop) {
3148
2877
  if (swiper.isVertical()) {
3149
- // Vertical
3150
2878
  if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {
3151
2879
  data.isTouched = false;
3152
2880
  data.isMoved = false;
@@ -3248,7 +2976,6 @@
3248
2976
  swiper.wrapperEl.dispatchEvent(evt);
3249
2977
  }
3250
2978
  data.allowMomentumBounce = false;
3251
- // Grab Cursor
3252
2979
  if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
3253
2980
  swiper.setGrabCursor(true);
3254
2981
  }
@@ -3319,8 +3046,6 @@
3319
3046
  if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
3320
3047
  data.currentTranslate = data.startTranslate;
3321
3048
  }
3322
-
3323
- // Threshold
3324
3049
  if (params.threshold > 0) {
3325
3050
  if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
3326
3051
  if (!data.allowThresholdMove) {
@@ -3338,17 +3063,12 @@
3338
3063
  }
3339
3064
  if (!params.followFinger || params.cssMode) return;
3340
3065
 
3341
- // Update active index in free mode
3342
- if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {
3066
+ // core-lite: no optional feature updates; only watchSlidesProgress
3067
+ if (params.watchSlidesProgress) {
3343
3068
  swiper.updateActiveIndex();
3344
3069
  swiper.updateSlidesClasses();
3345
3070
  }
3346
- if (params.freeMode && params.freeMode.enabled && swiper.freeMode) {
3347
- swiper.freeMode.onTouchMove();
3348
- }
3349
- // Update progress
3350
3071
  swiper.updateProgress(data.currentTranslate);
3351
- // Update translate
3352
3072
  swiper.setTranslate(data.currentTranslate);
3353
3073
  }
3354
3074
 
@@ -3360,7 +3080,7 @@
3360
3080
  let targetTouch;
3361
3081
  const isTouchEvent = e.type === 'touchend' || e.type === 'touchcancel';
3362
3082
  if (!isTouchEvent) {
3363
- if (data.touchId !== null) return; // return from pointer if we use touch
3083
+ if (data.touchId !== null) return;
3364
3084
  if (e.pointerId !== data.pointerId) return;
3365
3085
  targetTouch = e;
3366
3086
  } else {
@@ -3369,9 +3089,7 @@
3369
3089
  }
3370
3090
  if (['pointercancel', 'pointerout', 'pointerleave', 'contextmenu'].includes(e.type)) {
3371
3091
  const proceed = ['pointercancel', 'contextmenu'].includes(e.type) && (swiper.browser.isSafari || swiper.browser.isWebView);
3372
- if (!proceed) {
3373
- return;
3374
- }
3092
+ if (!proceed) return;
3375
3093
  }
3376
3094
  data.pointerId = null;
3377
3095
  data.touchId = null;
@@ -3389,9 +3107,7 @@
3389
3107
  }
3390
3108
  data.allowTouchCallbacks = false;
3391
3109
  if (!data.isTouched) {
3392
- if (data.isMoved && params.grabCursor) {
3393
- swiper.setGrabCursor(false);
3394
- }
3110
+ if (data.isMoved && params.grabCursor) swiper.setGrabCursor(false);
3395
3111
  data.isMoved = false;
3396
3112
  data.startMoving = false;
3397
3113
  return;
@@ -3401,8 +3117,6 @@
3401
3117
  if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
3402
3118
  swiper.setGrabCursor(false);
3403
3119
  }
3404
-
3405
- // Time diff
3406
3120
  const touchEndTime = now();
3407
3121
  const timeDiff = touchEndTime - data.touchStartTime;
3408
3122
 
@@ -3429,20 +3143,8 @@
3429
3143
  data.isMoved = false;
3430
3144
  data.startMoving = false;
3431
3145
  let currentPos;
3432
- if (params.followFinger) {
3433
- currentPos = rtl ? swiper.translate : -swiper.translate;
3434
- } else {
3435
- currentPos = -data.currentTranslate;
3436
- }
3437
- if (params.cssMode) {
3438
- return;
3439
- }
3440
- if (params.freeMode && params.freeMode.enabled) {
3441
- swiper.freeMode.onTouchEnd({
3442
- currentPos
3443
- });
3444
- return;
3445
- }
3146
+ if (params.followFinger) currentPos = rtl ? swiper.translate : -swiper.translate;else currentPos = -data.currentTranslate;
3147
+ if (params.cssMode) return;
3446
3148
 
3447
3149
  // Find current slide
3448
3150
  const swipeToLast = currentPos >= -swiper.maxTranslate() && !swiper.params.loop;
@@ -3464,22 +3166,22 @@
3464
3166
  let rewindLastIndex = null;
3465
3167
  if (params.rewind) {
3466
3168
  if (swiper.isBeginning) {
3467
- rewindLastIndex = params.virtual && params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
3169
+ rewindLastIndex = swiper.slides.length - 1;
3468
3170
  } else if (swiper.isEnd) {
3469
3171
  rewindFirstIndex = 0;
3470
3172
  }
3471
3173
  }
3472
- // Find current slide size
3473
3174
  const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
3474
3175
  const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
3475
3176
  if (timeDiff > params.longSwipesMs) {
3476
- // Long touches
3477
3177
  if (!params.longSwipes) {
3478
3178
  swiper.slideTo(swiper.activeIndex);
3479
3179
  return;
3480
3180
  }
3481
3181
  if (swiper.swipeDirection === 'next') {
3482
- if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);else swiper.slideTo(stopIndex);
3182
+ if (ratio >= params.longSwipesRatio) {
3183
+ swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);
3184
+ } else swiper.slideTo(stopIndex);
3483
3185
  }
3484
3186
  if (swiper.swipeDirection === 'prev') {
3485
3187
  if (ratio > 1 - params.longSwipesRatio) {
@@ -3531,7 +3233,6 @@
3531
3233
  allowSlidePrev,
3532
3234
  snapGrid
3533
3235
  } = swiper;
3534
- const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
3535
3236
 
3536
3237
  // Disable locks on resize
3537
3238
  swiper.allowSlideNext = true;
@@ -3539,15 +3240,12 @@
3539
3240
  swiper.updateSize();
3540
3241
  swiper.updateSlides();
3541
3242
  swiper.updateSlidesClasses();
3542
- const isVirtualLoop = isVirtual && params.loop;
3543
- if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides && !isVirtualLoop) {
3243
+ if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides) {
3544
3244
  swiper.slideTo(swiper.slides.length - 1, 0, false, true);
3245
+ } else if (swiper.params.loop) {
3246
+ swiper.slideToLoop(swiper.realIndex, 0, false, true);
3545
3247
  } else {
3546
- if (swiper.params.loop && !isVirtual) {
3547
- swiper.slideToLoop(swiper.realIndex, 0, false, true);
3548
- } else {
3549
- swiper.slideTo(swiper.activeIndex, 0, false, true);
3550
- }
3248
+ swiper.slideTo(swiper.activeIndex, 0, false, true);
3551
3249
  }
3552
3250
  if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
3553
3251
  clearTimeout(swiper.autoplay.resizeTimeout);
@@ -3557,10 +3255,11 @@
3557
3255
  }
3558
3256
  }, 500);
3559
3257
  }
3258
+
3560
3259
  // Return locks after resize
3561
3260
  swiper.allowSlidePrev = allowSlidePrev;
3562
3261
  swiper.allowSlideNext = allowSlideNext;
3563
- if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
3262
+ if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
3564
3263
  swiper.checkOverflow();
3565
3264
  }
3566
3265
  }
@@ -3614,6 +3313,10 @@
3614
3313
  if (swiper.params.cssMode || swiper.params.slidesPerView !== 'auto' && !swiper.params.autoHeight) {
3615
3314
  return;
3616
3315
  }
3316
+ const el = e?.target;
3317
+ // IMG, IFRAME, EMBED with width/height attributes don't change slide size — no need to call swiper.update()
3318
+ if (!el || !['IMG', 'IFRAME', 'EMBED'].includes(el.tagName)) return;
3319
+ if (el.hasAttribute('width') && el.hasAttribute('height')) return;
3617
3320
  swiper.update();
3618
3321
  }
3619
3322
 
@@ -3725,8 +3428,15 @@
3725
3428
  detachEvents
3726
3429
  };
3727
3430
 
3728
- const isGridEnabled = (swiper, params) => {
3729
- return swiper.grid && params.grid && params.grid.rows > 1;
3431
+ const toggleModule = (swiper, params, breakpointParams, prop) => {
3432
+ const wasModuleEnabled = params[prop] && params[prop].enabled;
3433
+ const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
3434
+ if (wasModuleEnabled && !isModuleEnabled) {
3435
+ swiper[prop].disable();
3436
+ }
3437
+ if (!wasModuleEnabled && isModuleEnabled) {
3438
+ swiper[prop].enable();
3439
+ }
3730
3440
  };
3731
3441
  function setBreakpoint() {
3732
3442
  const swiper = this;
@@ -3747,38 +3457,20 @@
3747
3457
  if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;
3748
3458
  const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
3749
3459
  const breakpointParams = breakpointOnlyParams || swiper.originalParams;
3750
- const wasMultiRow = isGridEnabled(swiper, params);
3751
- const isMultiRow = isGridEnabled(swiper, breakpointParams);
3752
3460
  const wasGrabCursor = swiper.params.grabCursor;
3753
3461
  const isGrabCursor = breakpointParams.grabCursor;
3754
3462
  const wasEnabled = params.enabled;
3755
- if (wasMultiRow && !isMultiRow) {
3756
- el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
3757
- swiper.emitContainerClasses();
3758
- } else if (!wasMultiRow && isMultiRow) {
3759
- el.classList.add(`${params.containerModifierClass}grid`);
3760
- if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') {
3761
- el.classList.add(`${params.containerModifierClass}grid-column`);
3762
- }
3763
- swiper.emitContainerClasses();
3764
- }
3765
3463
  if (wasGrabCursor && !isGrabCursor) {
3766
3464
  swiper.unsetGrabCursor();
3767
3465
  } else if (!wasGrabCursor && isGrabCursor) {
3768
3466
  swiper.setGrabCursor();
3769
3467
  }
3770
3468
 
3771
- // Toggle navigation, pagination, scrollbar
3772
- ['navigation', 'pagination', 'scrollbar'].forEach(prop => {
3469
+ // Core-lite: toggle navigation & pagination only.
3470
+ const modules = ['navigation', 'pagination'];
3471
+ modules.forEach(prop => {
3773
3472
  if (typeof breakpointParams[prop] === 'undefined') return;
3774
- const wasModuleEnabled = params[prop] && params[prop].enabled;
3775
- const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
3776
- if (wasModuleEnabled && !isModuleEnabled) {
3777
- swiper[prop].disable();
3778
- }
3779
- if (!wasModuleEnabled && isModuleEnabled) {
3780
- swiper[prop].enable();
3781
- }
3473
+ toggleModule(swiper, params, breakpointParams, prop);
3782
3474
  });
3783
3475
  const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
3784
3476
  const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
@@ -3860,7 +3552,7 @@
3860
3552
  getBreakpoint
3861
3553
  };
3862
3554
 
3863
- function prepareClasses(entries, prefix) {
3555
+ const prepareClasses = (entries, prefix) => {
3864
3556
  const resultClasses = [];
3865
3557
  entries.forEach(item => {
3866
3558
  if (typeof item === 'object') {
@@ -3874,7 +3566,7 @@
3874
3566
  }
3875
3567
  });
3876
3568
  return resultClasses;
3877
- }
3569
+ };
3878
3570
  function addClasses() {
3879
3571
  const swiper = this;
3880
3572
  const {
@@ -3884,17 +3576,12 @@
3884
3576
  el,
3885
3577
  device
3886
3578
  } = swiper;
3579
+ // core-lite: removed module-specific classes
3887
3580
  // prettier-ignore
3888
3581
  const suffixes = prepareClasses(['initialized', params.direction, {
3889
- 'free-mode': swiper.params.freeMode && params.freeMode.enabled
3890
- }, {
3891
3582
  'autoheight': params.autoHeight
3892
3583
  }, {
3893
3584
  'rtl': rtl
3894
- }, {
3895
- 'grid': params.grid && params.grid.rows > 1
3896
- }, {
3897
- 'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
3898
3585
  }, {
3899
3586
  'android': device.android
3900
3587
  }, {
@@ -3991,16 +3678,12 @@
3991
3678
  autoHeight: false,
3992
3679
  // Set wrapper width
3993
3680
  setWrapperSize: false,
3994
- // Virtual Translate
3995
- virtualTranslate: false,
3996
- // Effects
3681
+ // Effects (core-lite only supports `slide`)
3997
3682
  effect: 'slide',
3998
- // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
3999
-
4000
3683
  // Breakpoints
4001
3684
  breakpoints: undefined,
4002
3685
  breakpointsBase: 'window',
4003
- // Slides grid
3686
+ // Slides
4004
3687
  spaceBetween: 0,
4005
3688
  slidesPerView: 1,
4006
3689
  slidesPerGroup: 1,
@@ -4103,7 +3786,9 @@
4103
3786
  if (moduleParamName === 'navigation' && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].prevEl && !params[moduleParamName].nextEl) {
4104
3787
  params[moduleParamName].auto = true;
4105
3788
  }
4106
- if (['pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].el) {
3789
+
3790
+ // Core-lite: keep only pagination auto-init.
3791
+ if (moduleParamName === 'pagination' && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].el) {
4107
3792
  params[moduleParamName].auto = true;
4108
3793
  }
4109
3794
  if (!(moduleParamName in params && 'enabled' in moduleParams)) {
@@ -4229,7 +3914,6 @@
4229
3914
  // Indexes
4230
3915
  activeIndex: 0,
4231
3916
  realIndex: 0,
4232
- //
4233
3917
  isBeginning: true,
4234
3918
  isEnd: false,
4235
3919
  // Props
@@ -4256,12 +3940,9 @@
4256
3940
  currentTranslate: undefined,
4257
3941
  startTranslate: undefined,
4258
3942
  allowThresholdMove: undefined,
4259
- // Form elements to match
4260
3943
  focusableElements: swiper.params.focusableElements,
4261
- // Last click time
4262
3944
  lastClickTime: 0,
4263
3945
  clickTimeout: undefined,
4264
- // Velocities
4265
3946
  velocities: [],
4266
3947
  allowMomentumBounce: undefined,
4267
3948
  startMoving: undefined,
@@ -4290,7 +3971,6 @@
4290
3971
  swiper.init();
4291
3972
  }
4292
3973
 
4293
- // Return app instance
4294
3974
  // eslint-disable-next-line no-constructor-return
4295
3975
  return swiper;
4296
3976
  }
@@ -4322,16 +4002,6 @@
4322
4002
  getSlideIndexByData(index) {
4323
4003
  return this.getSlideIndex(this.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === index));
4324
4004
  }
4325
- getSlideIndexWhenGrid(index) {
4326
- if (this.grid && this.params.grid && this.params.grid.rows > 1) {
4327
- if (this.params.grid.fill === 'column') {
4328
- index = Math.floor(index / this.params.grid.rows);
4329
- } else if (this.params.grid.fill === 'row') {
4330
- index = index % Math.ceil(this.slides.length / this.params.grid.rows);
4331
- }
4332
- }
4333
- return index;
4334
- }
4335
4005
  recalcSlides() {
4336
4006
  const swiper = this;
4337
4007
  const {
@@ -4433,21 +4103,15 @@
4433
4103
  }
4434
4104
  }
4435
4105
  } else {
4436
- // eslint-disable-next-line
4437
4106
  if (view === 'current') {
4438
4107
  for (let i = activeIndex + 1; i < slides.length; i += 1) {
4439
4108
  const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
4440
- if (slideInView) {
4441
- spv += 1;
4442
- }
4109
+ if (slideInView) spv += 1;
4443
4110
  }
4444
4111
  } else {
4445
- // previous
4446
4112
  for (let i = activeIndex - 1; i >= 0; i -= 1) {
4447
4113
  const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
4448
- if (slideInView) {
4449
- spv += 1;
4450
- }
4114
+ if (slideInView) spv += 1;
4451
4115
  }
4452
4116
  }
4453
4117
  }
@@ -4460,14 +4124,11 @@
4460
4124
  snapGrid,
4461
4125
  params
4462
4126
  } = swiper;
4463
- // Breakpoints
4464
4127
  if (params.breakpoints) {
4465
4128
  swiper.setBreakpoint();
4466
4129
  }
4467
4130
  [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach(imageEl => {
4468
- if (imageEl.complete) {
4469
- processLazyPreloader(swiper, imageEl);
4470
- }
4131
+ if (imageEl.complete) processLazyPreloader(swiper, imageEl);
4471
4132
  });
4472
4133
  swiper.updateSize();
4473
4134
  swiper.updateSlides();
@@ -4481,22 +4142,12 @@
4481
4142
  swiper.updateSlidesClasses();
4482
4143
  }
4483
4144
  let translated;
4484
- if (params.freeMode && params.freeMode.enabled && !params.cssMode) {
4485
- setTranslate();
4486
- if (params.autoHeight) {
4487
- swiper.updateAutoHeight();
4488
- }
4145
+ if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
4146
+ translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);
4489
4147
  } else {
4490
- if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
4491
- const slides = swiper.virtual && params.virtual.enabled ? swiper.virtual.slides : swiper.slides;
4492
- translated = swiper.slideTo(slides.length - 1, 0, false, true);
4493
- } else {
4494
- translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
4495
- }
4496
- if (!translated) {
4497
- setTranslate();
4498
- }
4148
+ translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
4499
4149
  }
4150
+ if (!translated) setTranslate();
4500
4151
  if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
4501
4152
  swiper.checkOverflow();
4502
4153
  }
@@ -4509,7 +4160,6 @@
4509
4160
  const swiper = this;
4510
4161
  const currentDirection = swiper.params.direction;
4511
4162
  if (!newDirection) {
4512
- // eslint-disable-next-line
4513
4163
  newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
4514
4164
  }
4515
4165
  if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
@@ -4547,15 +4197,11 @@
4547
4197
  mount(element) {
4548
4198
  const swiper = this;
4549
4199
  if (swiper.mounted) return true;
4550
-
4551
- // Find el
4552
4200
  let el = element || swiper.params.el;
4553
4201
  if (typeof el === 'string') {
4554
4202
  el = document.querySelector(el);
4555
4203
  }
4556
- if (!el) {
4557
- return false;
4558
- }
4204
+ if (!el) return false;
4559
4205
  el.swiper = swiper;
4560
4206
  if (el.parentNode && el.parentNode.host && el.parentNode.host.nodeName === swiper.params.swiperElementNodeName.toUpperCase()) {
4561
4207
  swiper.isElement = true;
@@ -4566,12 +4212,10 @@
4566
4212
  const getWrapper = () => {
4567
4213
  if (el && el.shadowRoot && el.shadowRoot.querySelector) {
4568
4214
  const res = el.shadowRoot.querySelector(getWrapperSelector());
4569
- // Children needs to return slot items
4570
4215
  return res;
4571
4216
  }
4572
4217
  return elementChildren(el, getWrapperSelector())[0];
4573
4218
  };
4574
- // Find Wrapper
4575
4219
  let wrapperEl = getWrapper();
4576
4220
  if (!wrapperEl && swiper.params.createElements) {
4577
4221
  wrapperEl = createElement('div', swiper.params.wrapperClass);
@@ -4586,7 +4230,6 @@
4586
4230
  slidesEl: swiper.isElement && !el.parentNode.host.slideSlots ? el.parentNode.host : wrapperEl,
4587
4231
  hostEl: swiper.isElement ? el.parentNode.host : el,
4588
4232
  mounted: true,
4589
- // RTL
4590
4233
  rtl: el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl',
4591
4234
  rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl'),
4592
4235
  wrongRTL: elementStyle(wrapperEl, 'display') === '-webkit-box'
@@ -4606,7 +4249,6 @@
4606
4249
  const gap = Math.abs(swiper.snapGrid[1] - swiper.snapGrid[0]);
4607
4250
  const swiperTranslate = structuredClone(swiper.snapGrid[1]);
4608
4251
  if (isFirstSlide) {
4609
- // Move last item to first position when at first slide
4610
4252
  const lastSlide = slides.at(-1);
4611
4253
  lastSlide.swiperLoopMoveDOM = true;
4612
4254
  swiper.slidesEl.prepend(lastSlide);
@@ -4618,7 +4260,6 @@
4618
4260
  swiper.setTransition(speed);
4619
4261
  swiper.setTranslate(-swiperTranslate);
4620
4262
  } else if (isLastSlide) {
4621
- // Move first item to last position when at last slide
4622
4263
  const firstSlide = slides[0];
4623
4264
  firstSlide.swiperLoopMoveDOM = true;
4624
4265
  swiper.slidesEl.append(firstSlide);
@@ -4639,42 +4280,24 @@
4639
4280
  const mounted = swiper.mount(el);
4640
4281
  if (mounted === false) return swiper;
4641
4282
  swiper.emit('beforeInit');
4642
-
4643
- // Set breakpoint
4644
4283
  if (swiper.params.breakpoints) {
4645
4284
  swiper.setBreakpoint();
4646
4285
  }
4647
-
4648
- // Add Classes
4649
4286
  swiper.addClasses();
4650
-
4651
- // Update size
4652
4287
  swiper.updateSize();
4653
-
4654
- // Update slides
4655
4288
  swiper.updateSlides();
4656
4289
  if (swiper.params.watchOverflow) {
4657
4290
  swiper.checkOverflow();
4658
4291
  }
4659
-
4660
- // Set Grab Cursor
4661
4292
  if (swiper.params.grabCursor && swiper.enabled) {
4662
4293
  swiper.setGrabCursor();
4663
4294
  }
4664
4295
 
4665
- // Slide To Initial Slide
4666
- if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
4667
- swiper.slideTo(swiper.params.initialSlide + swiper.virtual.slidesBefore, 0, swiper.params.runCallbacksOnInit, false, true);
4668
- } else {
4669
- swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
4670
- }
4671
-
4672
- // Create loop
4296
+ // Slide to initial slide (core-lite: no optional feature initial offsets)
4297
+ swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
4673
4298
  if (swiper.params.loop) {
4674
4299
  swiper.loopCreate(undefined, true);
4675
4300
  }
4676
-
4677
- // Attach events
4678
4301
  swiper.attachEvents();
4679
4302
  const lazyElements = [...swiper.el.querySelectorAll('[loading="lazy"]')];
4680
4303
  if (swiper.isElement) {
@@ -4684,18 +4307,12 @@
4684
4307
  if (imageEl.complete) {
4685
4308
  processLazyPreloader(swiper, imageEl);
4686
4309
  } else {
4687
- imageEl.addEventListener('load', e => {
4688
- processLazyPreloader(swiper, e.target);
4689
- });
4310
+ imageEl.addEventListener('load', e => processLazyPreloader(swiper, e.target));
4690
4311
  }
4691
4312
  });
4692
4313
  preload(swiper);
4693
-
4694
- // Init Flag
4695
4314
  swiper.initialized = true;
4696
4315
  preload(swiper);
4697
-
4698
- // Emit
4699
4316
  swiper.emit('init');
4700
4317
  swiper.emit('afterInit');
4701
4318
  return swiper;
@@ -4718,27 +4335,15 @@
4718
4335
  return null;
4719
4336
  }
4720
4337
  swiper.emit('beforeDestroy');
4721
-
4722
- // Init Flag
4723
4338
  swiper.initialized = false;
4724
-
4725
- // Detach events
4726
4339
  swiper.detachEvents();
4727
-
4728
- // Destroy loop
4729
4340
  if (params.loop) {
4730
4341
  swiper.loopDestroy();
4731
4342
  }
4732
-
4733
- // Cleanup styles
4734
4343
  if (cleanStyles) {
4735
4344
  swiper.removeClasses();
4736
- if (el && typeof el !== 'string') {
4737
- el.removeAttribute('style');
4738
- }
4739
- if (wrapperEl) {
4740
- wrapperEl.removeAttribute('style');
4741
- }
4345
+ if (el && typeof el !== 'string') el.removeAttribute('style');
4346
+ if (wrapperEl) wrapperEl.removeAttribute('style');
4742
4347
  if (slides && slides.length) {
4743
4348
  slides.forEach(slideEl => {
4744
4349
  slideEl.classList.remove(params.slideVisibleClass, params.slideFullyVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
@@ -4748,8 +4353,6 @@
4748
4353
  }
4749
4354
  }
4750
4355
  swiper.emit('destroy');
4751
-
4752
- // Detach emitter events
4753
4356
  Object.keys(swiper.eventsListeners).forEach(eventName => {
4754
4357
  swiper.off(eventName);
4755
4358
  });
@@ -5120,7 +4723,7 @@
5120
4723
  }
5121
4724
 
5122
4725
  /**
5123
- * Swiper Custom Element 0.0.14
4726
+ * Swiper Custom Element 0.0.15-dev.1
5124
4727
  * Gem SDK - Swiper, Customized of swiper
5125
4728
  * https://swiperjs.com
5126
4729
  *
@@ -5128,7 +4731,7 @@
5128
4731
  *
5129
4732
  * Released under the MIT License
5130
4733
  *
5131
- * Released on: March 18, 2026
4734
+ * Released on: March 20, 2026
5132
4735
  */
5133
4736
 
5134
4737