From 65ee3767931fb449430cf8e7f2ddfa4f941f6155 Mon Sep 17 00:00:00 2001
From: Jesus Vista
Date: Wed, 23 Apr 2025 20:50:25 +0800
Subject: [PATCH 1/2] Enhance carousel functionality with new thumbnail options
and validation
- Added `thumbnailFitMode` and `thumbnailAlignment` options to control thumbnail display.
- Implemented validation for carousel options to ensure correct usage.
- Updated example configuration to demonstrate new thumbnail features.
- Enhanced CSS for thumbnail effects and improved filename display on hover.
---
README.md | 35 ++++++++++++++--
dist/js-carousel.min.css | 2 +-
dist/js-carousel.min.js | 2 +-
examples/index.html | 5 ++-
src/css/carousel.css | 29 +++++++++++--
src/css/controls.css | 6 ++-
src/js/carousel.js | 16 +++++++
src/js/constants/index.js | 1 +
src/js/constants/thumbnails.contants.js | 14 +++++++
src/js/utils/index.js | 1 +
src/js/utils/validation.utils.js | 56 +++++++++++++++++++++++++
11 files changed, 154 insertions(+), 13 deletions(-)
create mode 100644 src/js/constants/thumbnails.contants.js
create mode 100644 src/js/utils/validation.utils.js
diff --git a/README.md b/README.md
index b0edec0..982119a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,3 @@
-
JS carousel | Cloudimage (DMO)
@@ -12,11 +11,9 @@
src="https://scaleflex.cloudimg.io/v7/plugins/js-carousel/carousel_exemple.png">
-
-
### Introduction:
-Meet `js-carousel` by Scaleflex—a minimal, no-nonsense JavaScript carousel plugin that does *exactly* what you need it to do: load fast, look slick, and play nice with performance. Designed with zero dependencies and a featherlight footprint, this carousel is tailor-made for developers and performance-obsessed teams who don’t want to trade speed for style. Whether you're running a headless CMS or optimizing for that last Lighthouse point, `js-carousel` by Scaleflex is the go-to solution.
+Meet `js-carousel` by Scaleflex—a minimal, no-nonsense JavaScript carousel plugin that does _exactly_ what you need it to do: load fast, look slick, and play nice with performance. Designed with zero dependencies and a featherlight footprint, this carousel is tailor-made for developers and performance-obsessed teams who don’t want to trade speed for style. Whether you're running a headless CMS or optimizing for that last Lighthouse point, `js-carousel` by Scaleflex is the go-to solution.
`js-carousel` by Scaleflex does not bundle in more features than you'll ever use, it focuses on doing one thing exceptionally well: delivering a fast, responsive, and ultra-smooth image slider & zoomer experience with minimal setup. It’s the smart choice for frontend engineers who value UX as much as DX. Simple to integrate, easy to customize, and built for scale.
@@ -173,6 +170,34 @@ carousel.init()
}
```
+### `thumbnailFitMode` (string)
+
+- **Default**: `'crop-fit'`
+- **Options**: `'crop-fit'`, `'fit'`
+- **Description**: Controls how thumbnail images are fitted within their containers
+- **Example**:
+
+```javascript
+{
+ thumbnailFitMode: 'fit' // Makes thumbnails fit within their container without cropping
+}
+```
+
+### `thumbnailAlignment` (string)
+
+- **Default**: `'space-evenly'`
+- **Options**: `'left'`, `'center'`, `'right'`, `'space-evenly'`, `'space-between'`
+- **Description**: Controls the horizontal alignment of thumbnails in the thumbnail container
+- **Example**:
+
+```javascript
+{
+ thumbnailAlignment: 'space-between' // Distributes thumbnails with equal space between them
+}
+```
+
+Let me verify this by checking the constants file for thumbnail alignment.
+
## Complete Example
Here's an example showing all options with their default values:
@@ -191,6 +216,8 @@ const carousel = new CloudImageCarousel('#my-carousel', {
showControls: true,
showBullets: false,
transitionEffect: 'fade',
+ thumbnailFitMode: 'crop-fit',
+ thumbnailAlignment: 'space-evenly',
images: ['path/to/image1.jpg', 'path/to/image2.jpg', 'path/to/image3.jpg'],
})
diff --git a/dist/js-carousel.min.css b/dist/js-carousel.min.css
index 3efb3fd..ccfddb2 100644
--- a/dist/js-carousel.min.css
+++ b/dist/js-carousel.min.css
@@ -1 +1 @@
-.ci-carousel{border-radius:16px;box-shadow:0 8px 43px rgba(0,0,0,.09);margin:0 auto;max-width:1200px}.ci-carousel,.ci-carousel-main{background:#efefef;overflow:hidden;position:relative;width:100%}.ci-carousel-main{aspect-ratio:16/9;touch-action:pan-y pinch-zoom}.ci-carousel-images-container{height:100%;position:relative;touch-action:pan-y pinch-zoom;-webkit-user-select:none;user-select:none;width:100%}.ci-carousel-image-wrapper,.ci-carousel-images{height:100%;left:0;position:absolute;top:0;width:100%}.ci-carousel-image-wrapper{filter:blur(8px);opacity:0;overflow:hidden;transform-origin:center center;transition:opacity .5s cubic-bezier(.16,1,.3,1);visibility:hidden;will-change:transform}.ci-carousel-image-wrapper.active{filter:blur(0);opacity:1;transition:opacity .5s cubic-bezier(.16,1,.3,1),transform 0s;visibility:visible}.ci-carousel-image-wrapper img{height:100%;object-fit:contain;pointer-events:none;user-select:none;width:100%}.ci-carousel-image-wrapper.zoomed{cursor:grab}.ci-carousel-image-wrapper.zoomed:active{cursor:grabbing}.ci-carousel-bullets{background:#fff;display:flex;gap:15px;justify-content:center;padding:12px 16px}.ci-carousel-bullet{background:rgba(0,0,0,.15);border:none;border-radius:50%;cursor:pointer;height:8px;padding:0;transition:all .4s cubic-bezier(.16,1,.3,1);width:8px}.ci-carousel-bullet.active{background:#1a1a1a;transform:scale(1.3)}.ci-carousel-thumbnails{background:#fff;display:flex;gap:16px;overflow-x:auto;padding:24px;scrollbar-width:none;-ms-overflow-style:none}.ci-carousel-thumbnail{border-radius:12px;cursor:pointer;height:66px;opacity:.7;overflow:hidden;position:relative;transition:all .4s cubic-bezier(.16,1,.3,1);width:88px}.ci-carousel-thumbnail:hover{opacity:.9;transform:translateY(-2px)}.ci-carousel-thumbnail.active{box-shadow:0 0 0 2px #000;opacity:1;transform:translateY(-2px)}.ci-carousel-thumbnail img{height:100%;object-fit:cover;width:100%}.ci-carousel-filename{background:linear-gradient(0deg,rgba(0,0,0,.75),transparent);bottom:0;color:#fff;font-size:13px;font-weight:500;left:0;letter-spacing:.3px;opacity:0;padding:24px 20px 16px;position:absolute;text-align:center;transform:translateY(8px);transition:all .4s cubic-bezier(.16,1,.3,1);width:100%}.ci-carousel-image-wrapper:hover .ci-carousel-filename{opacity:1;transform:translateY(0)}.ci-carousel.is-fullscreen{background:rgba(0,0,0,.95);border-radius:0;color:#fff;height:100vh;left:0;margin:0;max-width:none;position:fixed;top:0;width:100vw;z-index:9999}.ci-carousel.is-fullscreen .ci-carousel-main{background:transparent;height:100vh}.ci-carousel.is-fullscreen .ci-carousel-bullets{background:hsla(0,0%,100%,.1)}.ci-carousel.is-fullscreen .ci-carousel-btn{color:#1a1a1a}.ci-carousel.is-fullscreen .ci-carousel-btn:hover{background:hsla(0,0%,100%,.1)}.ci-carousel.is-fullscreen .ci-carousel-bullet{background:hsla(0,0%,100%,.3)}.ci-carousel.is-fullscreen .ci-carousel-bullet.active{background:#fff}.ci-carousel.is-fullscreen .ci-carousel-controls{backdrop-filter:blur(8px);background:rgba(0,0,0,.5);position:absolute}.slide{display:block!important;opacity:0;transform:translateX(5%);transition:all .7s cubic-bezier(.16,1,.3,1)}.slide.active{opacity:1;transform:translateX(0)}.slide.prev{opacity:0;transform:translateX(-5%)}.fade{display:block!important;opacity:0;transition:opacity .7s cubic-bezier(.16,1,.3,1)}.fade.active{opacity:1}.ci-carousel-has-controls .ci-carousel-bottom-container{position:relative}.ci-carousel-controls{align-items:center;border-radius:20px;box-sizing:border-box;display:flex;justify-content:space-between;left:0;opacity:0;padding:30px;position:absolute;top:-100px;transition:opacity .5s ease-in-out;width:280px;width:100%;z-index:10}.ci-carousel-controls.controls-visible{opacity:1}.ci-carousel-btn{align-items:center;background:hsla(0,0%,100%,.95);border:none;border-radius:50%;color:#1a1a1a;cursor:pointer;display:flex;font-size:18px;height:44px;justify-content:center;transition:all .3s cubic-bezier(.16,1,.3,1);width:44px}.ci-carousel-btn:hover{background:#fff;box-shadow:0 4px 12px rgba(0,0,0,.15)}.ci-carousel-btn:focus{box-shadow:0 0 0 3px rgba(66,153,225,.6);outline:none}.ci-carousel-btn:active{transform:scale(.96) translateY(0)}@media (hover:hover){.ci-carousel:hover .ci-carousel-controls{opacity:1}}@media (max-width:1024px){.ci-carousel-btn{height:40px;width:40px}}@media (max-width:768px){.ci-carousel-controls{border-radius:0;box-shadow:none;box-sizing:border-box;opacity:0;padding:16px;position:absolute;top:-55px;transition:opacity .3s ease-in-out;width:100%}.ci-carousel-controls.controls-visible{opacity:1}.ci-carousel-btn{height:30px;min-height:30px;min-width:30px;padding:10px;width:30px}.ci-carousel-thumbnails{background:#fafafa;border-top:1px solid rgba(0,0,0,.1);padding:16px}.ci-carousel-has-thumbnails .ci-carousel-thumbnails{padding-top:8px}.ci-carousel.fullscreen .ci-carousel-controls{background:rgba(0,0,0,.75);bottom:0;right:0}.ci-carousel.fullscreen .ci-carousel-thumbnails{background:rgba(0,0,0,.75);border-top:1px solid hsla(0,0%,100%,.1)}}@media (max-width:480px){.ci-carousel-controls{padding:12px}.ci-carousel-thumbnails{gap:8px;padding:12px}.ci-carousel-thumbnail{height:48px;width:64px}}@media screen and (max-height:500px){.ci-carousel-main{height:100vh}.ci-carousel-controls{position:absolute;top:-100px;width:100%}}
\ No newline at end of file
+.ci-carousel{border-radius:16px;box-shadow:0 8px 43px rgba(0,0,0,.09);margin:0 auto;max-width:1200px}.ci-carousel,.ci-carousel-main{background:#efefef;overflow:hidden;position:relative;width:100%}.ci-carousel-main{aspect-ratio:16/9;touch-action:pan-y pinch-zoom}.ci-carousel-images-container{height:100%;position:relative;touch-action:pan-y pinch-zoom;-webkit-user-select:none;user-select:none;width:100%}.ci-carousel-image-wrapper,.ci-carousel-images{height:100%;left:0;position:absolute;top:0;width:100%}.ci-carousel-image-wrapper{filter:blur(8px);opacity:0;overflow:hidden;transform-origin:center center;transition:opacity .5s cubic-bezier(.16,1,.3,1);visibility:hidden;will-change:transform}.ci-carousel-image-wrapper.active{filter:blur(0);opacity:1;transition:opacity .5s cubic-bezier(.16,1,.3,1),transform 0s;visibility:visible}.ci-carousel-image-wrapper img{height:100%;object-fit:contain;pointer-events:none;user-select:none;width:100%}.ci-carousel-image-wrapper.zoomed{cursor:grab}.ci-carousel-image-wrapper.zoomed:active{cursor:grabbing}.ci-carousel-bullets{background:#fff;display:flex;gap:15px;justify-content:center;padding:12px 16px}.ci-carousel-bullet{background:rgba(0,0,0,.15);border:none;border-radius:50%;cursor:pointer;height:8px;padding:0;transition:all .4s cubic-bezier(.16,1,.3,1);width:8px}.ci-carousel-bullet.active{background:#1a1a1a;transform:scale(1.3)}.ci-carousel-thumbnails{background:#fff;display:flex;gap:16px;overflow-x:auto;padding:24px;scrollbar-width:none;-ms-overflow-style:none}.ci-carousel-thumbnail{border-radius:12px;cursor:pointer;height:66px;opacity:.7;overflow:hidden;position:relative;transition:all .4s cubic-bezier(.16,1,.3,1);width:88px}.ci-carousel-thumbnail:hover{box-shadow:0 0 0 2px #000;opacity:.9;transform:translateY(-2px)}.ci-carousel-thumbnail.active{animation:fadeBoxShadow 5s ease-out forwards;box-shadow:0 0 0 2px #000;opacity:1;transform:translateY(-2px)}@keyframes fadeBoxShadow{0%{box-shadow:0 0 0 2px #000}to{box-shadow:0 0 0 0 transparent}}.ci-carousel-thumbnail img{height:100%;width:100%}.ci-carousel-filename{background:linear-gradient(0deg,rgba(0,0,0,.75),transparent);bottom:0;box-sizing:border-box;color:#fff;font-size:13px;font-weight:500;left:0;letter-spacing:.3px;opacity:0;padding:24px 20px 16px;position:absolute;text-align:center;transform:translateY(8px);transition:all .5s ease-in-out;width:100%}.ci-carousel-has-filenames .ci-carousel-filename{opacity:1;transform:translateY(0)}.ci-carousel.is-fullscreen{background:rgba(0,0,0,.95);border-radius:0;color:#fff;height:100vh;left:0;margin:0;max-width:none;position:fixed;top:0;width:100vw;z-index:9999}.ci-carousel.is-fullscreen .ci-carousel-main{background:transparent;height:100vh}.ci-carousel.is-fullscreen .ci-carousel-bullets{background:hsla(0,0%,100%,.1)}.ci-carousel.is-fullscreen .ci-carousel-btn{color:#1a1a1a}.ci-carousel.is-fullscreen .ci-carousel-btn:hover{background:hsla(0,0%,100%,.1)}.ci-carousel.is-fullscreen .ci-carousel-bullet{background:hsla(0,0%,100%,.3)}.ci-carousel.is-fullscreen .ci-carousel-bullet.active{background:#fff}.ci-carousel.is-fullscreen .ci-carousel-controls{backdrop-filter:blur(8px);background:rgba(0,0,0,.5);position:absolute}.ci-carousel.is-fullscreen.ci-carousel-has-filenames .ci-carousel-filename{font-size:20px}.ci-carousel.is-fullscreen.ci-carousel-has-filenames:hover .ci-carousel-filename{bottom:100px;font-size:20px;opacity:1}.slide{display:block!important;opacity:0;transform:translateX(5%);transition:all .7s cubic-bezier(.16,1,.3,1)}.slide.active{opacity:1;transform:translateX(0)}.slide.prev{opacity:0;transform:translateX(-5%)}.fade{display:block!important;opacity:0;transition:opacity .7s cubic-bezier(.16,1,.3,1)}.fade.active{opacity:1}.ci-carousel-has-controls .ci-carousel-bottom-container{position:relative}.ci-carousel-has-filenames .ci-carousel-controls{top:-110px}.ci-carousel-controls{align-items:center;box-sizing:border-box;display:flex;justify-content:space-between;left:0;opacity:0;padding:30px;position:absolute;top:-100px;transition:opacity .5s ease-in-out;width:100%;z-index:10}.ci-carousel-controls.controls-visible{opacity:1}.ci-carousel-btn{align-items:center;background:hsla(0,0%,100%,.95);border:none;border-radius:50%;color:#1a1a1a;cursor:pointer;display:flex;font-size:18px;height:44px;justify-content:center;transition:all .3s cubic-bezier(.16,1,.3,1);width:44px}.ci-carousel-btn:hover{background:#fff;box-shadow:0 4px 12px rgba(0,0,0,.15)}.ci-carousel-btn:focus{box-shadow:0 0 0 3px rgba(66,153,225,.6);outline:none}.ci-carousel-btn:active{transform:scale(.96) translateY(0)}@media (hover:hover){.ci-carousel:hover .ci-carousel-controls{opacity:1}}@media (max-width:1024px){.ci-carousel-btn{height:40px;width:40px}}@media (max-width:768px){.ci-carousel-controls{border-radius:0;box-shadow:none;box-sizing:border-box;opacity:0;padding:16px;position:absolute;top:-55px;transition:opacity .3s ease-in-out;width:100%}.ci-carousel-controls.controls-visible{opacity:1}.ci-carousel-btn{height:30px;min-height:30px;min-width:30px;padding:10px;width:30px}.ci-carousel-thumbnails{background:#fafafa;border-top:1px solid rgba(0,0,0,.1);padding:16px}.ci-carousel-has-thumbnails .ci-carousel-thumbnails{padding-top:8px}.ci-carousel.fullscreen .ci-carousel-controls{background:rgba(0,0,0,.75);bottom:0;right:0}.ci-carousel.fullscreen .ci-carousel-thumbnails{background:rgba(0,0,0,.75);border-top:1px solid hsla(0,0%,100%,.1)}}@media (max-width:480px){.ci-carousel-controls{padding:12px}.ci-carousel-thumbnails{gap:8px;padding:12px}.ci-carousel-thumbnail{height:48px;width:64px}}@media screen and (max-height:500px){.ci-carousel-main{height:100vh}.ci-carousel-controls{position:absolute;top:-100px;width:100%}}
\ No newline at end of file
diff --git a/dist/js-carousel.min.js b/dist/js-carousel.min.js
index 4b44054..7975a7f 100644
--- a/dist/js-carousel.min.js
+++ b/dist/js-carousel.min.js
@@ -3,4 +3,4 @@
* http://hammerjs.github.io/
*
* Copyright (c) 2016 Jorik Tangelder;
- * Licensed under the MIT license */!function(o,r,s,a){"use strict";var l,c=["","webkit","Moz","MS","ms","o"],u=r.createElement("div"),h=Math.round,p=Math.abs,d=Date.now;function f(t,e,n){return setTimeout(C(t,n),e)}function m(t,e,n){return!!Array.isArray(t)&&(v(t,n[e],n),!0)}function v(t,e,n){var i;if(t)if(t.forEach)t.forEach(e,n);else if(t.length!==a)for(i=0;i\s*\(/gm,"{anonymous}()@"):"Unknown Stack Trace",r=o.console&&(o.console.warn||o.console.log);return r&&r.call(o.console,i,n),t.apply(this,arguments)}}l="function"!=typeof Object.assign?function(t){if(t===a||null===t)throw new TypeError("Cannot convert undefined or null to object");for(var e=Object(t),n=1;n-1}function P(t){return t.trim().split(/\s+/g)}function L(t,e,n){if(t.indexOf&&!n)return t.indexOf(e);for(var i=0;in[e]})):i.sort()),i}function A(t,e){for(var n,i,o=e[0].toUpperCase()+e.slice(1),r=0;r1&&!n.firstMultiple?n.firstMultiple=V(e):1===o&&(n.firstMultiple=!1);var r=n.firstInput,s=n.firstMultiple,l=s?s.center:r.center,c=e.center=B(i);e.timeStamp=d(),e.deltaTime=e.timeStamp-r.timeStamp,e.angle=K(l,c),e.distance=G(l,c),function(t,e){var n=e.center,i=t.offsetDelta||{},o=t.prevDelta||{},r=t.prevInput||{};1!==e.eventType&&4!==r.eventType||(o=t.prevDelta={x:r.deltaX||0,y:r.deltaY||0},i=t.offsetDelta={x:n.x,y:n.y});e.deltaX=o.x+(n.x-i.x),e.deltaY=o.y+(n.y-i.y)}(n,e),e.offsetDirection=U(e.deltaX,e.deltaY);var u=Z(e.deltaTime,e.deltaX,e.deltaY);e.overallVelocityX=u.x,e.overallVelocityY=u.y,e.overallVelocity=p(u.x)>p(u.y)?u.x:u.y,e.scale=s?(h=s.pointers,f=i,G(f[0],f[1],Y)/G(h[0],h[1],Y)):1,e.rotation=s?function(t,e){return K(e[1],e[0],Y)+K(t[1],t[0],Y)}(s.pointers,i):0,e.maxPointers=n.prevInput?e.pointers.length>n.prevInput.maxPointers?e.pointers.length:n.prevInput.maxPointers:e.pointers.length,function(t,e){var n,i,o,r,s=t.lastInterval||e,l=e.timeStamp-s.timeStamp;if(8!=e.eventType&&(l>25||s.velocity===a)){var c=e.deltaX-s.deltaX,u=e.deltaY-s.deltaY,h=Z(l,c,u);i=h.x,o=h.y,n=p(h.x)>p(h.y)?h.x:h.y,r=U(c,u),t.lastInterval=e}else n=s.velocity,i=s.velocityX,o=s.velocityY,r=s.direction;e.velocity=n,e.velocityX=i,e.velocityY=o,e.direction=r}(n,e);var h,f;var m=t.element;I(e.srcEvent.target,m)&&(m=e.srcEvent.target);e.target=m}(t,n),t.emit("hammer.input",n),t.recognize(n),t.session.prevInput=n}function V(t){for(var e=[],n=0;n=p(e)?t<0?2:4:e<0?8:16}function G(t,e,n){n||(n=X);var i=e[n[0]]-t[n[0]],o=e[n[1]]-t[n[1]];return Math.sqrt(i*i+o*o)}function K(t,e,n){n||(n=X);var i=e[n[0]]-t[n[0]],o=e[n[1]]-t[n[1]];return 180*Math.atan2(o,i)/Math.PI}q.prototype={handler:function(){},init:function(){this.evEl&&S(this.element,this.evEl,this.domHandler),this.evTarget&&S(this.target,this.evTarget,this.domHandler),this.evWin&&S(F(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&z(this.element,this.evEl,this.domHandler),this.evTarget&&z(this.target,this.evTarget,this.domHandler),this.evWin&&z(F(this.element),this.evWin,this.domHandler)}};var $={mousedown:1,mousemove:2,mouseup:4},J="mousedown",Q="mousemove mouseup";function tt(){this.evEl=J,this.evWin=Q,this.pressed=!1,q.apply(this,arguments)}w(tt,q,{handler:function(t){var e=$[t.type];1&e&&0===t.button&&(this.pressed=!0),2&e&&1!==t.which&&(e=4),this.pressed&&(4&e&&(this.pressed=!1),this.callback(this.manager,e,{pointers:[t],changedPointers:[t],pointerType:_,srcEvent:t}))}});var et={pointerdown:1,pointermove:2,pointerup:4,pointercancel:8,pointerout:8},nt={2:N,3:"pen",4:_,5:"kinect"},it="pointerdown",ot="pointermove pointerup pointercancel";function rt(){this.evEl=it,this.evWin=ot,q.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}o.MSPointerEvent&&!o.PointerEvent&&(it="MSPointerDown",ot="MSPointerMove MSPointerUp MSPointerCancel"),w(rt,q,{handler:function(t){var e=this.store,n=!1,i=t.type.toLowerCase().replace("ms",""),o=et[i],r=nt[t.pointerType]||t.pointerType,s=r==N,a=L(e,t.pointerId,"pointerId");1&o&&(0===t.button||s)?a<0&&(e.push(t),a=e.length-1):12&o&&(n=!0),a<0||(e[a]=t,this.callback(this.manager,o,{pointers:e,changedPointers:[t],pointerType:r,srcEvent:t}),n&&e.splice(a,1))}});var st={touchstart:1,touchmove:2,touchend:4,touchcancel:8};function at(){this.evTarget="touchstart",this.evWin="touchstart touchmove touchend touchcancel",this.started=!1,q.apply(this,arguments)}function lt(t,e){var n=k(t.touches),i=k(t.changedTouches);return 12&e&&(n=O(n.concat(i),"identifier",!0)),[n,i]}w(at,q,{handler:function(t){var e=st[t.type];if(1===e&&(this.started=!0),this.started){var n=lt.call(this,t,e);12&e&&n[0].length-n[1].length==0&&(this.started=!1),this.callback(this.manager,e,{pointers:n[0],changedPointers:n[1],pointerType:N,srcEvent:t})}}});var ct={touchstart:1,touchmove:2,touchend:4,touchcancel:8},ut="touchstart touchmove touchend touchcancel";function ht(){this.evTarget=ut,this.targetIds={},q.apply(this,arguments)}function pt(t,e){var n=k(t.touches),i=this.targetIds;if(3&e&&1===n.length)return i[n[0].identifier]=!0,[n,n];var o,r,s=k(t.changedTouches),a=[],l=this.target;if(r=n.filter((function(t){return I(t.target,l)})),1===e)for(o=0;o-1&&i.splice(t,1)}),2500)}}function vt(t){for(var e=t.srcEvent.clientX,n=t.srcEvent.clientY,i=0;i-1&&this.requireFail.splice(e,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(t){return!!this.simultaneous[t.id]},emit:function(t){var e=this,n=this.state;function i(n){e.manager.emit(n,t)}n<8&&i(e.options.event+Lt(n)),i(e.options.event),t.additionalEvent&&i(t.additionalEvent),n>=8&&i(e.options.event+Lt(n))},tryEmit:function(t){if(this.canEmit())return this.emit(t);this.state=xt},canEmit:function(){for(var t=0;te.threshold&&o&e.direction},attrTest:function(t){return At.prototype.attrTest.call(this,t)&&(2&this.state||!(2&this.state)&&this.directionTest(t))},emit:function(t){this.pX=t.deltaX,this.pY=t.deltaY;var e=kt(t.direction);e&&(t.additionalEvent=this.options.event+e),this._super.emit.call(this,t)}}),w(Ft,At,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[Et]},attrTest:function(t){return this._super.attrTest.call(this,t)&&(Math.abs(t.scale-1)>this.options.threshold||2&this.state)},emit:function(t){if(1!==t.scale){var e=t.scale<1?"in":"out";t.additionalEvent=this.options.event+e}this._super.emit.call(this,t)}}),w(Dt,Pt,{defaults:{event:"press",pointers:1,time:251,threshold:9},getTouchAction:function(){return[wt]},process:function(t){var e=this.options,n=t.pointers.length===e.pointers,i=t.distancee.time;if(this._input=t,!i||!n||12&t.eventType&&!o)this.reset();else if(1&t.eventType)this.reset(),this._timer=f((function(){this.state=8,this.tryEmit()}),e.time,this);else if(4&t.eventType)return 8;return xt},reset:function(){clearTimeout(this._timer)},emit:function(t){8===this.state&&(t&&4&t.eventType?this.manager.emit(this.options.event+"up",t):(this._input.timeStamp=d(),this.manager.emit(this.options.event,this._input)))}}),w(jt,At,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[Et]},attrTest:function(t){return this._super.attrTest.call(this,t)&&(Math.abs(t.rotation)>this.options.threshold||2&this.state)}}),w(Ht,At,{defaults:{event:"swipe",threshold:10,velocity:.3,direction:30,pointers:1},getTouchAction:function(){return Mt.prototype.getTouchAction.call(this)},attrTest:function(t){var e,n=this.options.direction;return 30&n?e=t.overallVelocity:6&n?e=t.overallVelocityX:n&R&&(e=t.overallVelocityY),this._super.attrTest.call(this,t)&&n&t.offsetDirection&&t.distance>this.options.threshold&&t.maxPointers==this.options.pointers&&p(e)>this.options.velocity&&4&t.eventType},emit:function(t){var e=kt(t.offsetDirection);e&&this.manager.emit(this.options.event+e,t),this.manager.emit(this.options.event,t)}}),w(Nt,Pt,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:9,posThreshold:10},getTouchAction:function(){return[Ct]},process:function(t){var e=this.options,n=t.pointers.length===e.pointers,i=t.distance{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var i in e)n.o(e,i)&&!n.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var i={};return(()=>{"use strict";n.d(i,{default:()=>mt});const t=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],e=(()=>{if("undefined"==typeof document)return!1;const e=t[0],n={};for(const i of t){const t=i?.[1];if(t in document){for(const[t,o]of i.entries())n[e[t]]=o;return n}}return!1})(),o={change:e.fullscreenchange,error:e.fullscreenerror};let r={request:(t=document.documentElement,n)=>new Promise(((i,o)=>{const s=()=>{r.off("change",s),i()};r.on("change",s);const a=t[e.requestFullscreen](n);a instanceof Promise&&a.then(s).catch(o)})),exit:()=>new Promise(((t,n)=>{if(!r.isFullscreen)return void t();const i=()=>{r.off("change",i),t()};r.on("change",i);const o=document[e.exitFullscreen]();o instanceof Promise&&o.then(i).catch(n)})),toggle:(t,e)=>r.isFullscreen?r.exit():r.request(t,e),onchange(t){r.on("change",t)},onerror(t){r.on("error",t)},on(t,e){const n=o[t];n&&document.addEventListener(n,e,!1)},off(t,e){const n=o[t];n&&document.removeEventListener(n,e,!1)},raw:e};Object.defineProperties(r,{isFullscreen:{get:()=>Boolean(document[e.fullscreenElement])},element:{enumerable:!0,get:()=>document[e.fullscreenElement]??void 0},isEnabled:{enumerable:!0,get:()=>Boolean(document[e.fullscreenEnabled])}}),e||(r={isEnabled:!1});const s=r;var a="ci-carousel-image",l="ci-carousel-bullet",c="ci-carousel-fullscreen",u="controls-visible",h="active",p="click",d="wheel",f="keydown",m='',v='',g='',y='',b="slide",w="fade",C="ArrowLeft",E="ArrowRight",T="Escape",S=function(t,e,n,i){var o=document.createElement("button");return o.classList.add("ci-carousel-btn",t),o.setAttribute("aria-label",n),o.innerHTML=e,o.addEventListener(p,i),o};function z(t){return z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},z(t)}function I(t,e){for(var n=0;n1}},{key:"enableSwipe",value:function(){!this.enabled&&this.hammer&&(this.hammer.get("swipe").set({enable:!0}),this.enabled=!0)}},{key:"disableSwipe",value:function(){this.enabled&&this.hammer&&(this.hammer.get("swipe").set({enable:!1}),this.enabled=!1)}},{key:"destroy",value:function(){var t;null!==(t=this.zoomPanControls)&&void 0!==t&&t.panzoomInstance&&this.zoomListener&&(this.zoomPanControls.panzoomInstance.off("zoom",this.zoomListener),this.zoomListener=null),this.hammer&&(this.hammer.destroy(),this.hammer=null),this.carousel=null,this.imagesContainer=null,this.zoomPanControls=null}}],e&&A(t.prototype,e),n&&A(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,e,n}(),D=function(){return D=Object.assign||function(t){for(var e,n=1,i=arguments.length;n-1&&t.splice(n,1),t.push(e)}function $(t){for(var e,n=(t=t.slice(0)).pop();e=t.pop();)n={clientX:(e.clientX-n.clientX)/2+n.clientX,clientY:(e.clientY-n.clientY)/2+n.clientY};return n}function J(t){if(t.length<2)return 0;var e=t[0],n=t[1];return Math.sqrt(Math.pow(Math.abs(n.clientX-e.clientX),2)+Math.pow(Math.abs(n.clientY-e.clientY),2))}function Q(t,e){return 1===t.nodeType&&" ".concat(function(t){return(t.getAttribute("class")||"").trim()}(t)," ").indexOf(" ".concat(e," "))>-1}"undefined"!=typeof window&&("function"==typeof window.PointerEvent?B={down:"pointerdown",move:"pointermove",up:"pointerup pointerleave pointercancel"}:"function"==typeof window.TouchEvent&&(B={down:"touchstart",move:"touchmove",up:"touchend touchcancel"}));var tt=/^http:[\w\.\/]+svg$/;var et={animate:!1,canvas:!1,cursor:"move",disablePan:!1,disableZoom:!1,disableXAxis:!1,disableYAxis:!1,duration:200,easing:"ease-in-out",exclude:[],excludeClass:"panzoom-exclude",handleStartEvent:function(t){t.preventDefault(),t.stopPropagation()},maxScale:4,minScale:.125,overflow:"hidden",panOnlyWhenZoomed:!1,pinchAndPan:!1,relative:!1,setTransform:function(t,e,n){var i=e.x,o=e.y,r=e.scale,s=e.isSVG;if(W(t,"transform","scale(".concat(r,") translate(").concat(i,"px, ").concat(o,"px)")),s&&H){var a=window.getComputedStyle(t).getPropertyValue("transform");t.setAttribute("transform",a)}},startX:0,startY:0,startScale:1,step:.3,touchAction:"none"};function nt(t,e){if(!t)throw new Error("Panzoom requires an element as an argument");if(1!==t.nodeType)throw new Error("Panzoom requires an element with a nodeType of 1");if(!function(t){for(var e=t;e&&e.parentNode;){if(e.parentNode===document)return!0;e=e.parentNode instanceof ShadowRoot?e.parentNode.host:e.parentNode}return!1}(t))throw new Error("Panzoom should be called on elements that have been attached to the DOM");e=D(D({},et),e);var n=function(t){return tt.test(t.namespaceURI)&&"svg"!==t.nodeName.toLowerCase()}(t),i=t.parentNode;i.style.overflow=e.overflow,i.style.userSelect="none",i.style.touchAction=e.touchAction,(e.canvas?i:t).style.cursor=e.cursor,t.style.userSelect="none",t.style.touchAction=e.touchAction,W(t,"transformOrigin","string"==typeof e.origin?e.origin:n?"0 0":"50% 50%");var o,r,s,a,l,c,u=0,h=0,p=1,d=!1;function f(e,n,i){if(!i.silent){var o=new CustomEvent(e,{detail:n});t.dispatchEvent(o)}}function m(e,i,o){var r={x:u,y:h,scale:p,isSVG:n,originalEvent:o};return requestAnimationFrame((function(){"boolean"==typeof i.animate&&(i.animate?function(t,e){var n=X("transform");W(t,"transition","".concat(n," ").concat(e.duration,"ms ").concat(e.easing))}(t,i):W(t,"transition","none")),i.setTransform(t,r,i),f(e,r,i),f("panzoomchange",r,i)})),r}function v(n,i,o,r){var s=D(D({},e),r),a={x:u,y:h,opts:s};if(!s.force&&(s.disablePan||s.panOnlyWhenZoomed&&p===s.startScale))return a;if(n=parseFloat(n),i=parseFloat(i),s.disableXAxis||(a.x=(s.relative?u:0)+n),s.disableYAxis||(a.y=(s.relative?h:0)+i),s.contain){var l=V(t),c=l.elem.width/p,d=l.elem.height/p,f=c*o,m=d*o,v=(f-c)/2,g=(m-d)/2;if("inside"===s.contain){var y=(-l.elem.margin.left-l.parent.padding.left+v)/o,b=(l.parent.width-f-l.parent.padding.left-l.elem.margin.left-l.parent.border.left-l.parent.border.right+v)/o;a.x=Math.max(Math.min(a.x,b),y);var w=(-l.elem.margin.top-l.parent.padding.top+g)/o,C=(l.parent.height-m-l.parent.padding.top-l.elem.margin.top-l.parent.border.top-l.parent.border.bottom+g)/o;a.y=Math.max(Math.min(a.y,C),w)}else if("outside"===s.contain){y=(-(f-l.parent.width)-l.parent.padding.left-l.parent.border.left-l.parent.border.right+v)/o,b=(v-l.parent.padding.left)/o;a.x=Math.max(Math.min(a.x,b),y);w=(-(m-l.parent.height)-l.parent.padding.top-l.parent.border.top-l.parent.border.bottom+g)/o,C=(g-l.parent.padding.top)/o;a.y=Math.max(Math.min(a.y,C),w)}}return s.roundPixels&&(a.x=Math.round(a.x),a.y=Math.round(a.y)),a}function g(n,i){var o=D(D({},e),i),r={scale:p,opts:o};if(!o.force&&o.disableZoom)return r;var s=e.minScale,a=e.maxScale;if(o.contain){var l=V(t),c=l.elem.width/p,u=l.elem.height/p;if(c>1&&u>1){var h=(l.parent.width-l.parent.border.left-l.parent.border.right)/c,d=(l.parent.height-l.parent.border.top-l.parent.border.bottom)/u;"inside"===e.contain?a=Math.min(a,h,d):"outside"===e.contain&&(s=Math.max(s,h,d))}}return r.scale=Math.min(Math.max(n,s),a),r}function y(t,e,i,o){var r=v(t,e,p,i);return u!==r.x||h!==r.y?(u=r.x,h=r.y,m("panzoompan",r.opts,o)):{x:u,y:h,scale:p,isSVG:n,originalEvent:o}}function b(t,e,n){var i=g(t,e),o=i.opts;if(o.force||!o.disableZoom){t=i.scale;var r=u,s=h;if(o.focal){var a=o.focal;r=(a.x/t-a.x/p+u*t)/t,s=(a.y/t-a.y/p+h*t)/t}var l=v(r,s,t,{relative:!1,force:!0});return u=l.x,h=l.y,p=t,m("panzoomzoom",o,n)}}function w(t,n){var i=D(D(D({},e),{animate:!0}),n);return b(p*Math.exp((t?1:-1)*i.step),i)}function C(e,i,o,r){var s=V(t),a=s.parent.width-s.parent.padding.left-s.parent.padding.right-s.parent.border.left-s.parent.border.right,l=s.parent.height-s.parent.padding.top-s.parent.padding.bottom-s.parent.border.top-s.parent.border.bottom,c=i.clientX-s.parent.left-s.parent.padding.left-s.parent.border.left-s.elem.margin.left,u=i.clientY-s.parent.top-s.parent.padding.top-s.parent.border.top-s.elem.margin.top;n||(c-=s.elem.width/p/2,u-=s.elem.height/p/2);var h={x:c/a*(a*e),y:u/l*(l*e)};return b(e,D(D({},o),{animate:!1,focal:h}),r)}b(e.startScale,{animate:!1,force:!0}),setTimeout((function(){y(e.startX,e.startY,{animate:!1,force:!0})}));var E=[];function T(t){if(!function(t,e){for(var n=t;null!=n;n=n.parentNode)if(Q(n,e.excludeClass)||e.exclude.indexOf(n)>-1)return!0;return!1}(t.target,e)){K(E,t),d=!0,e.handleStartEvent(t),o=u,r=h,f("panzoomstart",{x:u,y:h,scale:p,isSVG:n,originalEvent:t},e);var i=$(E);s=i.clientX,a=i.clientY,l=p,c=J(E)}}function S(t){if(d&&void 0!==o&&void 0!==r&&void 0!==s&&void 0!==a){K(E,t);var n=$(E),i=E.length>1,u=p;if(i)0===c&&(c=J(E)),C(u=g((J(E)-c)*e.step/80+l).scale,n,{animate:!1},t);i&&!e.pinchAndPan||y(o+(n.clientX-s)/u,r+(n.clientY-a)/u,{animate:!1},t)}}function z(t){1===E.length&&f("panzoomend",{x:u,y:h,scale:p,isSVG:n,originalEvent:t},e),function(t,e){if(e.touches)for(;t.length;)t.pop();else{var n=G(t,e);n>-1&&t.splice(n,1)}}(E,t),d&&(d=!1,o=r=s=a=void 0)}var I=!1;function x(){I||(I=!0,Z("down",e.canvas?i:t,T),Z("move",document,S,{passive:!0}),Z("up",document,z,{passive:!0}))}return e.noBind||x(),{bind:x,destroy:function(){I=!1,U("down",e.canvas?i:t,T),U("move",document,S),U("up",document,z)},eventNames:B,getPan:function(){return{x:u,y:h}},getScale:function(){return p},getOptions:function(){return function(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}(e)},handleDown:T,handleMove:S,handleUp:z,pan:y,reset:function(t){var n=D(D(D({},e),{animate:!0,force:!0}),t);p=g(n.startScale,n).scale;var i=v(n.startX,n.startY,p,n);return u=i.x,h=i.y,m("panzoomreset",n)},resetStyle:function(){i.style.overflow="",i.style.userSelect="",i.style.touchAction="",i.style.cursor="",t.style.cursor="",t.style.userSelect="",t.style.touchAction="",W(t,"transformOrigin","")},setOptions:function(n){for(var o in void 0===n&&(n={}),n)n.hasOwnProperty(o)&&(e[o]=n[o]);(n.hasOwnProperty("cursor")||n.hasOwnProperty("canvas"))&&(i.style.cursor=t.style.cursor="",(e.canvas?i:t).style.cursor=e.cursor),n.hasOwnProperty("overflow")&&(i.style.overflow=n.overflow),n.hasOwnProperty("touchAction")&&(i.style.touchAction=n.touchAction,t.style.touchAction=n.touchAction)},setStyle:function(e,n){return W(t,e,n)},zoom:b,zoomIn:function(t){return w(!0,t)},zoomOut:function(t){return w(!1,t)},zoomToPoint:C,zoomWithWheel:function(t,n){t.preventDefault();var i=D(D(D({},e),n),{animate:!1}),o=(0===t.deltaY&&t.deltaX?t.deltaX:t.deltaY)<0?1:-1;return C(g(p*Math.exp(o*i.step/3),i).scale,t,i,t)}}}nt.defaultOptions=et;function it(t){return it="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},it(t)}function ot(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function rt(t){for(var e=1;e1?"move":"zoom-in"}},n.addEventListener(d,this.currentHandlers.wheel),n.addEventListener("pointerdown",this.currentHandlers.pointerdown),document.addEventListener("pointermove",this.currentHandlers.pointermove),document.addEventListener("pointerup",this.currentHandlers.pointerup),t.addEventListener("panzoomchange",this.currentHandlers.panzoomchange)}}},{key:"handleWheel",value:function(t){this.panzoomInstance||this.initializeVisibleImage(),this.debouncedWheel(t)}},{key:"getCurrentWrapper",value:function(){return this.imagesContainer.children[this.carousel.currentIndex]}},{key:"zoomIn",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.panzoomInstance||this.initializeVisibleImage(),this.panzoomInstance&&this.panzoomInstance.zoomIn(rt({animate:!0},t))}},{key:"zoomOut",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.panzoomInstance&&this.panzoomInstance.zoomOut(rt({animate:!0},t))}},{key:"resetZoom",value:function(){this.panzoomInstance&&(this.panzoomInstance.reset({animate:!0}),this.cleanupCurrentPanzoom())}},{key:"cleanupCurrentPanzoom",value:function(){if(this.panzoomInstance&&this.currentElement){var t=this.currentElement.parentElement;this.currentElement&&t&&this.currentHandlers&&(t.removeEventListener(d,this.currentHandlers.wheel),t.removeEventListener("pointerdown",this.currentHandlers.pointerdown),document.removeEventListener("pointermove",this.currentHandlers.pointermove),document.removeEventListener("pointerup",this.currentHandlers.pointerup),this.currentElement.removeEventListener("panzoomchange",this.currentHandlers.panzoomchange)),this.panzoomInstance.destroy(),this.panzoomInstance=null,this.currentElement=null,this.currentHandlers=null}}},{key:"destroy",value:function(){this.cleanupCurrentPanzoom(),this.imagesContainer.removeEventListener(d,this.handleWheel)}}],e&&at(t.prototype,e),n&&at(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,e,n}();function ut(t){return ut="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},ut(t)}function ht(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function pt(t,e){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:{};if(function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),dt(this,"mainView",void 0),dt(this,"imagesContainer",void 0),dt(this,"thumbnailsContainer",void 0),dt(this,"controlsContainer",void 0),dt(this,"bulletsContainer",void 0),!e)throw new Error("Container parameter is required");if(this.container="string"==typeof e?document.querySelector(e):e,!(this.container&&this.container instanceof HTMLElement))throw new Error("Invalid container: ".concat("string"==typeof e?'Element "'.concat(e,'" not found'):"Container must be a valid HTML element"));this.options=function(t){for(var e=1;e=this.images.length&&(t=this.options.cycle?0:this.images.length-1);var e=this.currentIndex;this.currentIndex=t,this.options.autoplay&&this.resetAutoplay(),this.updateSlide(e)}},{key:"updateSlide",value:function(t){var e=this.imagesContainer.children,n=e[t],i=e[this.currentIndex];if(n.classList.remove(h),i.classList.remove(h),(this.options.transitionEffect===b||this.options.transitionEffect===w)&&i.classList.add(h),this.options.showThumbnails){var o=this.thumbnailsContainer.children;o[t].classList.remove(h),o[this.currentIndex].classList.add(h)}if(this.options.showBullets){var r=this.bulletsContainer.children;r[t].classList.remove(h),r[this.currentIndex].classList.add(h)}this.zoomPanControls&&(this.zoomPanControls.resetZoom(),this.zoomPanControls.initializeVisibleImage())}},{key:"next",value:function(){this.goToSlide(this.currentIndex+1)}},{key:"prev",value:function(){this.goToSlide(this.currentIndex-1)}},{key:"zoomIn",value:function(){this.zoomPanControls&&this.zoomPanControls.zoomIn({animate:!0})}},{key:"zoomOut",value:function(){this.zoomPanControls&&this.zoomPanControls.zoomOut({animate:!0})}},{key:"resetZoom",value:function(){this.zoomPanControls&&this.zoomPanControls.resetZoom()}},{key:"toggleFullscreen",value:function(){var t=this;s.isEnabled&&(s.toggle(this.container),s.on("change",(function(){t.isFullscreen=s.isFullscreen,document.querySelector(".".concat(c)).innerHTML=t.isFullscreen?y:g,t.container.classList.toggle("is-fullscreen",t.isFullscreen)})))}},{key:"startAutoplay",value:function(){var t=this;this.autoplayInterval=setInterval((function(){t.next()}),this.options.autoplayInterval)}},{key:"stopAutoplay",value:function(){this.autoplayInterval&&clearInterval(this.autoplayInterval)}},{key:"resetAutoplay",value:function(){this.stopAutoplay(),this.startAutoplay()}},{key:"destroy",value:function(){var t,e;this.autoplayInterval&&clearInterval(this.autoplayInterval),this.observer&&this.observer.disconnect(),this.thumbnailClickHandler&&(null===(t=this.thumbnailsContainer)||void 0===t||t.removeEventListener(p,this.thumbnailClickHandler)),this.bulletClickHandler&&(null===(e=this.bulletsContainer)||void 0===e||e.removeEventListener(p,this.bulletClickHandler)),this.zoomPanControls&&this.zoomPanControls.destroy(),this.controls&&this.controls.destroy(),s.isEnabled&&s.off("change"),this.swipeControls&&this.swipeControls.destroy(),this.images=[],this.container=null,this.mainView=null,this.imagesContainer=null,this.thumbnailsContainer=null,this.controlsContainer=null,this.bulletsContainer=null}}],e&&pt(t.prototype,e),n&&pt(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,e,n}()})(),i=i.default})()));
\ No newline at end of file
+ * Licensed under the MIT license */!function(o,r,s,a){"use strict";var l,c=["","webkit","Moz","MS","ms","o"],u=r.createElement("div"),h=Math.round,p=Math.abs,d=Date.now;function f(t,e,n){return setTimeout(E(t,n),e)}function m(t,e,n){return!!Array.isArray(t)&&(v(t,n[e],n),!0)}function v(t,e,n){var i;if(t)if(t.forEach)t.forEach(e,n);else if(t.length!==a)for(i=0;i\s*\(/gm,"{anonymous}()@"):"Unknown Stack Trace",r=o.console&&(o.console.warn||o.console.log);return r&&r.call(o.console,i,n),t.apply(this,arguments)}}l="function"!=typeof Object.assign?function(t){if(t===a||null===t)throw new TypeError("Cannot convert undefined or null to object");for(var e=Object(t),n=1;n-1}function x(t){return t.trim().split(/\s+/g)}function L(t,e,n){if(t.indexOf&&!n)return t.indexOf(e);for(var i=0;in[e]})):i.sort()),i}function A(t,e){for(var n,i,o=e[0].toUpperCase()+e.slice(1),r=0;r1&&!n.firstMultiple?n.firstMultiple=q(e):1===o&&(n.firstMultiple=!1);var r=n.firstInput,s=n.firstMultiple,l=s?s.center:r.center,c=e.center=B(i);e.timeStamp=d(),e.deltaTime=e.timeStamp-r.timeStamp,e.angle=K(l,c),e.distance=G(l,c),function(t,e){var n=e.center,i=t.offsetDelta||{},o=t.prevDelta||{},r=t.prevInput||{};1!==e.eventType&&4!==r.eventType||(o=t.prevDelta={x:r.deltaX||0,y:r.deltaY||0},i=t.offsetDelta={x:n.x,y:n.y});e.deltaX=o.x+(n.x-i.x),e.deltaY=o.y+(n.y-i.y)}(n,e),e.offsetDirection=U(e.deltaX,e.deltaY);var u=Z(e.deltaTime,e.deltaX,e.deltaY);e.overallVelocityX=u.x,e.overallVelocityY=u.y,e.overallVelocity=p(u.x)>p(u.y)?u.x:u.y,e.scale=s?(h=s.pointers,f=i,G(f[0],f[1],X)/G(h[0],h[1],X)):1,e.rotation=s?function(t,e){return K(e[1],e[0],X)+K(t[1],t[0],X)}(s.pointers,i):0,e.maxPointers=n.prevInput?e.pointers.length>n.prevInput.maxPointers?e.pointers.length:n.prevInput.maxPointers:e.pointers.length,function(t,e){var n,i,o,r,s=t.lastInterval||e,l=e.timeStamp-s.timeStamp;if(8!=e.eventType&&(l>25||s.velocity===a)){var c=e.deltaX-s.deltaX,u=e.deltaY-s.deltaY,h=Z(l,c,u);i=h.x,o=h.y,n=p(h.x)>p(h.y)?h.x:h.y,r=U(c,u),t.lastInterval=e}else n=s.velocity,i=s.velocityX,o=s.velocityY,r=s.direction;e.velocity=n,e.velocityX=i,e.velocityY=o,e.direction=r}(n,e);var h,f;var m=t.element;z(e.srcEvent.target,m)&&(m=e.srcEvent.target);e.target=m}(t,n),t.emit("hammer.input",n),t.recognize(n),t.session.prevInput=n}function q(t){for(var e=[],n=0;n=p(e)?t<0?2:4:e<0?8:16}function G(t,e,n){n||(n=Y);var i=e[n[0]]-t[n[0]],o=e[n[1]]-t[n[1]];return Math.sqrt(i*i+o*o)}function K(t,e,n){n||(n=Y);var i=e[n[0]]-t[n[0]],o=e[n[1]]-t[n[1]];return 180*Math.atan2(o,i)/Math.PI}V.prototype={handler:function(){},init:function(){this.evEl&&S(this.element,this.evEl,this.domHandler),this.evTarget&&S(this.target,this.evTarget,this.domHandler),this.evWin&&S(F(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&I(this.element,this.evEl,this.domHandler),this.evTarget&&I(this.target,this.evTarget,this.domHandler),this.evWin&&I(F(this.element),this.evWin,this.domHandler)}};var $={mousedown:1,mousemove:2,mouseup:4},J="mousedown",Q="mousemove mouseup";function tt(){this.evEl=J,this.evWin=Q,this.pressed=!1,V.apply(this,arguments)}w(tt,V,{handler:function(t){var e=$[t.type];1&e&&0===t.button&&(this.pressed=!0),2&e&&1!==t.which&&(e=4),this.pressed&&(4&e&&(this.pressed=!1),this.callback(this.manager,e,{pointers:[t],changedPointers:[t],pointerType:_,srcEvent:t}))}});var et={pointerdown:1,pointermove:2,pointerup:4,pointercancel:8,pointerout:8},nt={2:N,3:"pen",4:_,5:"kinect"},it="pointerdown",ot="pointermove pointerup pointercancel";function rt(){this.evEl=it,this.evWin=ot,V.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}o.MSPointerEvent&&!o.PointerEvent&&(it="MSPointerDown",ot="MSPointerMove MSPointerUp MSPointerCancel"),w(rt,V,{handler:function(t){var e=this.store,n=!1,i=t.type.toLowerCase().replace("ms",""),o=et[i],r=nt[t.pointerType]||t.pointerType,s=r==N,a=L(e,t.pointerId,"pointerId");1&o&&(0===t.button||s)?a<0&&(e.push(t),a=e.length-1):12&o&&(n=!0),a<0||(e[a]=t,this.callback(this.manager,o,{pointers:e,changedPointers:[t],pointerType:r,srcEvent:t}),n&&e.splice(a,1))}});var st={touchstart:1,touchmove:2,touchend:4,touchcancel:8};function at(){this.evTarget="touchstart",this.evWin="touchstart touchmove touchend touchcancel",this.started=!1,V.apply(this,arguments)}function lt(t,e){var n=O(t.touches),i=O(t.changedTouches);return 12&e&&(n=k(n.concat(i),"identifier",!0)),[n,i]}w(at,V,{handler:function(t){var e=st[t.type];if(1===e&&(this.started=!0),this.started){var n=lt.call(this,t,e);12&e&&n[0].length-n[1].length==0&&(this.started=!1),this.callback(this.manager,e,{pointers:n[0],changedPointers:n[1],pointerType:N,srcEvent:t})}}});var ct={touchstart:1,touchmove:2,touchend:4,touchcancel:8},ut="touchstart touchmove touchend touchcancel";function ht(){this.evTarget=ut,this.targetIds={},V.apply(this,arguments)}function pt(t,e){var n=O(t.touches),i=this.targetIds;if(3&e&&1===n.length)return i[n[0].identifier]=!0,[n,n];var o,r,s=O(t.changedTouches),a=[],l=this.target;if(r=n.filter((function(t){return z(t.target,l)})),1===e)for(o=0;o-1&&i.splice(t,1)}),2500)}}function vt(t){for(var e=t.srcEvent.clientX,n=t.srcEvent.clientY,i=0;i-1&&this.requireFail.splice(e,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(t){return!!this.simultaneous[t.id]},emit:function(t){var e=this,n=this.state;function i(n){e.manager.emit(n,t)}n<8&&i(e.options.event+Lt(n)),i(e.options.event),t.additionalEvent&&i(t.additionalEvent),n>=8&&i(e.options.event+Lt(n))},tryEmit:function(t){if(this.canEmit())return this.emit(t);this.state=Pt},canEmit:function(){for(var t=0;te.threshold&&o&e.direction},attrTest:function(t){return At.prototype.attrTest.call(this,t)&&(2&this.state||!(2&this.state)&&this.directionTest(t))},emit:function(t){this.pX=t.deltaX,this.pY=t.deltaY;var e=Ot(t.direction);e&&(t.additionalEvent=this.options.event+e),this._super.emit.call(this,t)}}),w(Ft,At,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[Ct]},attrTest:function(t){return this._super.attrTest.call(this,t)&&(Math.abs(t.scale-1)>this.options.threshold||2&this.state)},emit:function(t){if(1!==t.scale){var e=t.scale<1?"in":"out";t.additionalEvent=this.options.event+e}this._super.emit.call(this,t)}}),w(jt,xt,{defaults:{event:"press",pointers:1,time:251,threshold:9},getTouchAction:function(){return[wt]},process:function(t){var e=this.options,n=t.pointers.length===e.pointers,i=t.distancee.time;if(this._input=t,!i||!n||12&t.eventType&&!o)this.reset();else if(1&t.eventType)this.reset(),this._timer=f((function(){this.state=8,this.tryEmit()}),e.time,this);else if(4&t.eventType)return 8;return Pt},reset:function(){clearTimeout(this._timer)},emit:function(t){8===this.state&&(t&&4&t.eventType?this.manager.emit(this.options.event+"up",t):(this._input.timeStamp=d(),this.manager.emit(this.options.event,this._input)))}}),w(Dt,At,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[Ct]},attrTest:function(t){return this._super.attrTest.call(this,t)&&(Math.abs(t.rotation)>this.options.threshold||2&this.state)}}),w(Ht,At,{defaults:{event:"swipe",threshold:10,velocity:.3,direction:30,pointers:1},getTouchAction:function(){return Mt.prototype.getTouchAction.call(this)},attrTest:function(t){var e,n=this.options.direction;return 30&n?e=t.overallVelocity:6&n?e=t.overallVelocityX:n&R&&(e=t.overallVelocityY),this._super.attrTest.call(this,t)&&n&t.offsetDirection&&t.distance>this.options.threshold&&t.maxPointers==this.options.pointers&&p(e)>this.options.velocity&&4&t.eventType},emit:function(t){var e=Ot(t.offsetDirection);e&&this.manager.emit(this.options.event+e,t),this.manager.emit(this.options.event,t)}}),w(Nt,xt,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:9,posThreshold:10},getTouchAction:function(){return[Et]},process:function(t){var e=this.options,n=t.pointers.length===e.pointers,i=t.distance{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var i in e)n.o(e,i)&&!n.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var i={};return(()=>{"use strict";n.d(i,{default:()=>vt});const t=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],e=(()=>{if("undefined"==typeof document)return!1;const e=t[0],n={};for(const i of t){const t=i?.[1];if(t in document){for(const[t,o]of i.entries())n[e[t]]=o;return n}}return!1})(),o={change:e.fullscreenchange,error:e.fullscreenerror};let r={request:(t=document.documentElement,n)=>new Promise(((i,o)=>{const s=()=>{r.off("change",s),i()};r.on("change",s);const a=t[e.requestFullscreen](n);a instanceof Promise&&a.then(s).catch(o)})),exit:()=>new Promise(((t,n)=>{if(!r.isFullscreen)return void t();const i=()=>{r.off("change",i),t()};r.on("change",i);const o=document[e.exitFullscreen]();o instanceof Promise&&o.then(i).catch(n)})),toggle:(t,e)=>r.isFullscreen?r.exit():r.request(t,e),onchange(t){r.on("change",t)},onerror(t){r.on("error",t)},on(t,e){const n=o[t];n&&document.addEventListener(n,e,!1)},off(t,e){const n=o[t];n&&document.removeEventListener(n,e,!1)},raw:e};Object.defineProperties(r,{isFullscreen:{get:()=>Boolean(document[e.fullscreenElement])},element:{enumerable:!0,get:()=>document[e.fullscreenElement]??void 0},isEnabled:{enumerable:!0,get:()=>Boolean(document[e.fullscreenEnabled])}}),e||(r={isEnabled:!1});const s=r;var a="ci-carousel-image",l="ci-carousel-bullet",c="ci-carousel-fullscreen",u="controls-visible",h="active",p="click",d="wheel",f="keydown",m='',v='',g='',y='',b={CROP_FIT:"crop-fit",FIT:"fit"},w={LEFT:"left",CENTER:"center",RIGHT:"right",SPACE_EVENLY:"space-evenly",SPACE_BETWEEN:"space-between"},E={SLIDE:"slide",FADE:"fade"},C="ArrowLeft",T="ArrowRight",S="Escape",I=function(t,e,n,i){var o=document.createElement("button");return o.classList.add("ci-carousel-btn",t),o.setAttribute("aria-label",n),o.innerHTML=e,o.addEventListener(p,i),o};function z(t){return z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},z(t)}function P(t,e){for(var n=0;n1}},{key:"enableSwipe",value:function(){!this.enabled&&this.hammer&&(this.hammer.get("swipe").set({enable:!0}),this.enabled=!0)}},{key:"disableSwipe",value:function(){this.enabled&&this.hammer&&(this.hammer.get("swipe").set({enable:!1}),this.enabled=!1)}},{key:"destroy",value:function(){var t;null!==(t=this.zoomPanControls)&&void 0!==t&&t.panzoomInstance&&this.zoomListener&&(this.zoomPanControls.panzoomInstance.off("zoom",this.zoomListener),this.zoomListener=null),this.hammer&&(this.hammer.destroy(),this.hammer=null),this.carousel=null,this.imagesContainer=null,this.zoomPanControls=null}}],e&&M(t.prototype,e),n&&M(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,e,n}(),D=function(){return D=Object.assign||function(t){for(var e,n=1,i=arguments.length;n-1&&t.splice(n,1),t.push(e)}function J(t){for(var e,n=(t=t.slice(0)).pop();e=t.pop();)n={clientX:(e.clientX-n.clientX)/2+n.clientX,clientY:(e.clientY-n.clientY)/2+n.clientY};return n}function Q(t){if(t.length<2)return 0;var e=t[0],n=t[1];return Math.sqrt(Math.pow(Math.abs(n.clientX-e.clientX),2)+Math.pow(Math.abs(n.clientY-e.clientY),2))}function tt(t,e){return 1===t.nodeType&&" ".concat(function(t){return(t.getAttribute("class")||"").trim()}(t)," ").indexOf(" ".concat(e," "))>-1}"undefined"!=typeof window&&("function"==typeof window.PointerEvent?Z={down:"pointerdown",move:"pointermove",up:"pointerup pointerleave pointercancel"}:"function"==typeof window.TouchEvent&&(Z={down:"touchstart",move:"touchmove",up:"touchend touchcancel"}));var et=/^http:[\w\.\/]+svg$/;var nt={animate:!1,canvas:!1,cursor:"move",disablePan:!1,disableZoom:!1,disableXAxis:!1,disableYAxis:!1,duration:200,easing:"ease-in-out",exclude:[],excludeClass:"panzoom-exclude",handleStartEvent:function(t){t.preventDefault(),t.stopPropagation()},maxScale:4,minScale:.125,overflow:"hidden",panOnlyWhenZoomed:!1,pinchAndPan:!1,relative:!1,setTransform:function(t,e,n){var i=e.x,o=e.y,r=e.scale,s=e.isSVG;if(q(t,"transform","scale(".concat(r,") translate(").concat(i,"px, ").concat(o,"px)")),s&&N){var a=window.getComputedStyle(t).getPropertyValue("transform");t.setAttribute("transform",a)}},startX:0,startY:0,startScale:1,step:.3,touchAction:"none"};function it(t,e){if(!t)throw new Error("Panzoom requires an element as an argument");if(1!==t.nodeType)throw new Error("Panzoom requires an element with a nodeType of 1");if(!function(t){for(var e=t;e&&e.parentNode;){if(e.parentNode===document)return!0;e=e.parentNode instanceof ShadowRoot?e.parentNode.host:e.parentNode}return!1}(t))throw new Error("Panzoom should be called on elements that have been attached to the DOM");e=D(D({},nt),e);var n=function(t){return et.test(t.namespaceURI)&&"svg"!==t.nodeName.toLowerCase()}(t),i=t.parentNode;i.style.overflow=e.overflow,i.style.userSelect="none",i.style.touchAction=e.touchAction,(e.canvas?i:t).style.cursor=e.cursor,t.style.userSelect="none",t.style.touchAction=e.touchAction,q(t,"transformOrigin","string"==typeof e.origin?e.origin:n?"0 0":"50% 50%");var o,r,s,a,l,c,u=0,h=0,p=1,d=!1;function f(e,n,i){if(!i.silent){var o=new CustomEvent(e,{detail:n});t.dispatchEvent(o)}}function m(e,i,o){var r={x:u,y:h,scale:p,isSVG:n,originalEvent:o};return requestAnimationFrame((function(){"boolean"==typeof i.animate&&(i.animate?function(t,e){var n=X("transform");q(t,"transition","".concat(n," ").concat(e.duration,"ms ").concat(e.easing))}(t,i):q(t,"transition","none")),i.setTransform(t,r,i),f(e,r,i),f("panzoomchange",r,i)})),r}function v(n,i,o,r){var s=D(D({},e),r),a={x:u,y:h,opts:s};if(!s.force&&(s.disablePan||s.panOnlyWhenZoomed&&p===s.startScale))return a;if(n=parseFloat(n),i=parseFloat(i),s.disableXAxis||(a.x=(s.relative?u:0)+n),s.disableYAxis||(a.y=(s.relative?h:0)+i),s.contain){var l=B(t),c=l.elem.width/p,d=l.elem.height/p,f=c*o,m=d*o,v=(f-c)/2,g=(m-d)/2;if("inside"===s.contain){var y=(-l.elem.margin.left-l.parent.padding.left+v)/o,b=(l.parent.width-f-l.parent.padding.left-l.elem.margin.left-l.parent.border.left-l.parent.border.right+v)/o;a.x=Math.max(Math.min(a.x,b),y);var w=(-l.elem.margin.top-l.parent.padding.top+g)/o,E=(l.parent.height-m-l.parent.padding.top-l.elem.margin.top-l.parent.border.top-l.parent.border.bottom+g)/o;a.y=Math.max(Math.min(a.y,E),w)}else if("outside"===s.contain){y=(-(f-l.parent.width)-l.parent.padding.left-l.parent.border.left-l.parent.border.right+v)/o,b=(v-l.parent.padding.left)/o;a.x=Math.max(Math.min(a.x,b),y);w=(-(m-l.parent.height)-l.parent.padding.top-l.parent.border.top-l.parent.border.bottom+g)/o,E=(g-l.parent.padding.top)/o;a.y=Math.max(Math.min(a.y,E),w)}}return s.roundPixels&&(a.x=Math.round(a.x),a.y=Math.round(a.y)),a}function g(n,i){var o=D(D({},e),i),r={scale:p,opts:o};if(!o.force&&o.disableZoom)return r;var s=e.minScale,a=e.maxScale;if(o.contain){var l=B(t),c=l.elem.width/p,u=l.elem.height/p;if(c>1&&u>1){var h=(l.parent.width-l.parent.border.left-l.parent.border.right)/c,d=(l.parent.height-l.parent.border.top-l.parent.border.bottom)/u;"inside"===e.contain?a=Math.min(a,h,d):"outside"===e.contain&&(s=Math.max(s,h,d))}}return r.scale=Math.min(Math.max(n,s),a),r}function y(t,e,i,o){var r=v(t,e,p,i);return u!==r.x||h!==r.y?(u=r.x,h=r.y,m("panzoompan",r.opts,o)):{x:u,y:h,scale:p,isSVG:n,originalEvent:o}}function b(t,e,n){var i=g(t,e),o=i.opts;if(o.force||!o.disableZoom){t=i.scale;var r=u,s=h;if(o.focal){var a=o.focal;r=(a.x/t-a.x/p+u*t)/t,s=(a.y/t-a.y/p+h*t)/t}var l=v(r,s,t,{relative:!1,force:!0});return u=l.x,h=l.y,p=t,m("panzoomzoom",o,n)}}function w(t,n){var i=D(D(D({},e),{animate:!0}),n);return b(p*Math.exp((t?1:-1)*i.step),i)}function E(e,i,o,r){var s=B(t),a=s.parent.width-s.parent.padding.left-s.parent.padding.right-s.parent.border.left-s.parent.border.right,l=s.parent.height-s.parent.padding.top-s.parent.padding.bottom-s.parent.border.top-s.parent.border.bottom,c=i.clientX-s.parent.left-s.parent.padding.left-s.parent.border.left-s.elem.margin.left,u=i.clientY-s.parent.top-s.parent.padding.top-s.parent.border.top-s.elem.margin.top;n||(c-=s.elem.width/p/2,u-=s.elem.height/p/2);var h={x:c/a*(a*e),y:u/l*(l*e)};return b(e,D(D({},o),{animate:!1,focal:h}),r)}b(e.startScale,{animate:!1,force:!0}),setTimeout((function(){y(e.startX,e.startY,{animate:!1,force:!0})}));var C=[];function T(t){if(!function(t,e){for(var n=t;null!=n;n=n.parentNode)if(tt(n,e.excludeClass)||e.exclude.indexOf(n)>-1)return!0;return!1}(t.target,e)){$(C,t),d=!0,e.handleStartEvent(t),o=u,r=h,f("panzoomstart",{x:u,y:h,scale:p,isSVG:n,originalEvent:t},e);var i=J(C);s=i.clientX,a=i.clientY,l=p,c=Q(C)}}function S(t){if(d&&void 0!==o&&void 0!==r&&void 0!==s&&void 0!==a){$(C,t);var n=J(C),i=C.length>1,u=p;if(i)0===c&&(c=Q(C)),E(u=g((Q(C)-c)*e.step/80+l).scale,n,{animate:!1},t);i&&!e.pinchAndPan||y(o+(n.clientX-s)/u,r+(n.clientY-a)/u,{animate:!1},t)}}function I(t){1===C.length&&f("panzoomend",{x:u,y:h,scale:p,isSVG:n,originalEvent:t},e),function(t,e){if(e.touches)for(;t.length;)t.pop();else{var n=K(t,e);n>-1&&t.splice(n,1)}}(C,t),d&&(d=!1,o=r=s=a=void 0)}var z=!1;function P(){z||(z=!0,U("down",e.canvas?i:t,T),U("move",document,S,{passive:!0}),U("up",document,I,{passive:!0}))}return e.noBind||P(),{bind:P,destroy:function(){z=!1,G("down",e.canvas?i:t,T),G("move",document,S),G("up",document,I)},eventNames:Z,getPan:function(){return{x:u,y:h}},getScale:function(){return p},getOptions:function(){return function(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}(e)},handleDown:T,handleMove:S,handleUp:I,pan:y,reset:function(t){var n=D(D(D({},e),{animate:!0,force:!0}),t);p=g(n.startScale,n).scale;var i=v(n.startX,n.startY,p,n);return u=i.x,h=i.y,m("panzoomreset",n)},resetStyle:function(){i.style.overflow="",i.style.userSelect="",i.style.touchAction="",i.style.cursor="",t.style.cursor="",t.style.userSelect="",t.style.touchAction="",q(t,"transformOrigin","")},setOptions:function(n){for(var o in void 0===n&&(n={}),n)n.hasOwnProperty(o)&&(e[o]=n[o]);(n.hasOwnProperty("cursor")||n.hasOwnProperty("canvas"))&&(i.style.cursor=t.style.cursor="",(e.canvas?i:t).style.cursor=e.cursor),n.hasOwnProperty("overflow")&&(i.style.overflow=n.overflow),n.hasOwnProperty("touchAction")&&(i.style.touchAction=n.touchAction,t.style.touchAction=n.touchAction)},setStyle:function(e,n){return q(t,e,n)},zoom:b,zoomIn:function(t){return w(!0,t)},zoomOut:function(t){return w(!1,t)},zoomToPoint:E,zoomWithWheel:function(t,n){t.preventDefault();var i=D(D(D({},e),n),{animate:!1}),o=(0===t.deltaY&&t.deltaX?t.deltaX:t.deltaY)<0?1:-1;return E(g(p*Math.exp(o*i.step/3),i).scale,t,i,t)}}}it.defaultOptions=nt;function ot(t){return ot="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},ot(t)}function rt(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function st(t){for(var e=1;e1?"move":"zoom-in"}},n.addEventListener(d,this.currentHandlers.wheel),n.addEventListener("pointerdown",this.currentHandlers.pointerdown),document.addEventListener("pointermove",this.currentHandlers.pointermove),document.addEventListener("pointerup",this.currentHandlers.pointerup),t.addEventListener("panzoomchange",this.currentHandlers.panzoomchange)}}},{key:"handleWheel",value:function(t){this.panzoomInstance||this.initializeVisibleImage(),this.debouncedWheel(t)}},{key:"getCurrentWrapper",value:function(){return this.imagesContainer.children[this.carousel.currentIndex]}},{key:"zoomIn",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.panzoomInstance||this.initializeVisibleImage(),this.panzoomInstance&&this.panzoomInstance.zoomIn(st({animate:!0},t))}},{key:"zoomOut",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.panzoomInstance&&this.panzoomInstance.zoomOut(st({animate:!0},t))}},{key:"resetZoom",value:function(){this.panzoomInstance&&(this.panzoomInstance.reset({animate:!0}),this.cleanupCurrentPanzoom())}},{key:"cleanupCurrentPanzoom",value:function(){if(this.panzoomInstance&&this.currentElement){var t=this.currentElement.parentElement;this.currentElement&&t&&this.currentHandlers&&(t.removeEventListener(d,this.currentHandlers.wheel),t.removeEventListener("pointerdown",this.currentHandlers.pointerdown),document.removeEventListener("pointermove",this.currentHandlers.pointermove),document.removeEventListener("pointerup",this.currentHandlers.pointerup),this.currentElement.removeEventListener("panzoomchange",this.currentHandlers.panzoomchange)),this.panzoomInstance.destroy(),this.panzoomInstance=null,this.currentElement=null,this.currentHandlers=null}}},{key:"destroy",value:function(){this.cleanupCurrentPanzoom(),this.imagesContainer.removeEventListener(d,this.handleWheel)}}],e&<(t.prototype,e),n&<(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,e,n}();function ht(t){return ht="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},ht(t)}function pt(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function dt(t,e){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:{};if(function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),ft(this,"mainView",void 0),ft(this,"imagesContainer",void 0),ft(this,"thumbnailsContainer",void 0),ft(this,"controlsContainer",void 0),ft(this,"bulletsContainer",void 0),!e)throw new Error("Container parameter is required");if(this.container="string"==typeof e?document.querySelector(e):e,!(this.container&&this.container instanceof HTMLElement))throw new Error("Invalid container: ".concat("string"==typeof e?'Element "'.concat(e,'" not found'):"Container must be a valid HTML element"));!function(t){if(void 0!==t.images){if(!Array.isArray(t.images))throw new Error("images option must be an array of strings");if(!t.images.every((function(t){return"string"==typeof t})))throw new Error("All elements in images array must be strings")}if(["autoplay","cycle","showFilenames","showThumbnails","showBullets","showControls"].forEach((function(e){if(void 0!==t[e]&&"boolean"!=typeof t[e])throw new Error("".concat(e," option must be a boolean"))})),void 0!==t.autoplayInterval&&("number"!=typeof t.autoplayInterval||t.autoplayInterval<0))throw new Error("autoplayInterval option must be a positive number");if(void 0!==t.transitionEffect&&!Object.values(E).includes(t.transitionEffect))throw new Error("transitionEffect must be one of: ".concat(Object.values(E).join(", ")));if(void 0!==t.thumbnailFitMode&&!Object.values(b).includes(t.thumbnailFitMode))throw new Error("thumbnailFitMode must be one of: ".concat(Object.values(b).join(", ")));if(void 0!==t.thumbnailAlignment&&!Object.values(w).includes(t.thumbnailAlignment))throw new Error("thumbnailAlignment must be one of: ".concat(Object.values(w).join(", ")))}(n),this.options=function(t){for(var e=1;e=this.images.length&&(t=this.options.cycle?0:this.images.length-1);var e=this.currentIndex;this.currentIndex=t,this.options.autoplay&&this.resetAutoplay(),this.updateSlide(e)}},{key:"updateSlide",value:function(t){var e=this.imagesContainer.children,n=e[t],i=e[this.currentIndex];if(n.classList.remove(h),i.classList.remove(h),(this.options.transitionEffect===E.SLIDE||this.options.transitionEffect===E.FADE)&&i.classList.add(h),this.options.showThumbnails){var o=this.thumbnailsContainer.children;o[t].classList.remove(h),o[this.currentIndex].classList.add(h)}if(this.options.showBullets){var r=this.bulletsContainer.children;r[t].classList.remove(h),r[this.currentIndex].classList.add(h)}this.zoomPanControls&&(this.zoomPanControls.resetZoom(),this.zoomPanControls.initializeVisibleImage())}},{key:"next",value:function(){this.goToSlide(this.currentIndex+1)}},{key:"prev",value:function(){this.goToSlide(this.currentIndex-1)}},{key:"zoomIn",value:function(){this.zoomPanControls&&this.zoomPanControls.zoomIn({animate:!0})}},{key:"zoomOut",value:function(){this.zoomPanControls&&this.zoomPanControls.zoomOut({animate:!0})}},{key:"resetZoom",value:function(){this.zoomPanControls&&this.zoomPanControls.resetZoom()}},{key:"toggleFullscreen",value:function(){var t=this;s.isEnabled&&(s.toggle(this.container),s.on("change",(function(){t.isFullscreen=s.isFullscreen,document.querySelector(".".concat(c)).innerHTML=t.isFullscreen?y:g,t.container.classList.toggle("is-fullscreen",t.isFullscreen)})))}},{key:"startAutoplay",value:function(){var t=this;this.autoplayInterval=setInterval((function(){t.next()}),this.options.autoplayInterval)}},{key:"stopAutoplay",value:function(){this.autoplayInterval&&clearInterval(this.autoplayInterval)}},{key:"resetAutoplay",value:function(){this.stopAutoplay(),this.startAutoplay()}},{key:"destroy",value:function(){var t,e;this.autoplayInterval&&clearInterval(this.autoplayInterval),this.observer&&this.observer.disconnect(),this.thumbnailClickHandler&&(null===(t=this.thumbnailsContainer)||void 0===t||t.removeEventListener(p,this.thumbnailClickHandler)),this.bulletClickHandler&&(null===(e=this.bulletsContainer)||void 0===e||e.removeEventListener(p,this.bulletClickHandler)),this.zoomPanControls&&this.zoomPanControls.destroy(),this.controls&&this.controls.destroy(),s.isEnabled&&s.off("change"),this.swipeControls&&this.swipeControls.destroy(),this.images=[],this.container=null,this.mainView=null,this.imagesContainer=null,this.thumbnailsContainer=null,this.controlsContainer=null,this.bulletsContainer=null}}],e&&dt(t.prototype,e),n&&dt(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,e,n}()})(),i=i.default})()));
\ No newline at end of file
diff --git a/examples/index.html b/examples/index.html
index 733fa7b..5e05b90 100644
--- a/examples/index.html
+++ b/examples/index.html
@@ -15,11 +15,13 @@
autoplay: false,
autoplayInterval: 3000,
cycle: true,
- showFilenames: false,
+ showFilenames: true,
showThumbnails: true,
showControls: true,
showBullets: false,
transitionEffect: 'slide',
+ thumbnailFitMode: 'fit',
+ thumbnailAlignment: 'center',
images: [
'https://demo.cloudimg.io/v7/https://samples.scaleflex.com/hotel.jpg',
'https://demo.cloudimg.io/v7/https://samples.scaleflex.com/birds.jpg',
@@ -35,6 +37,7 @@
'https://demo.cloudimg.io/v7/https://samples.scaleflex.com/Image02.jpg',
'https://demo.cloudimg.io/v7/https://samples.scaleflex.com/Image04.jpg',
'https://demo.cloudimg.io/v7/https://samples.scaleflex.com/plate1.jpg',
+ 'https://assets.scaleflex.com/Corporate+Branding/VXP+logo/VXP+logo+BLACK.png',
],
})
diff --git a/src/css/carousel.css b/src/css/carousel.css
index 83a05e0..fda3712 100644
--- a/src/css/carousel.css
+++ b/src/css/carousel.css
@@ -125,18 +125,28 @@
.ci-carousel-thumbnail:hover {
opacity: 0.9;
transform: translateY(-2px);
+ box-shadow: 0 0 0 2px #000000;
}
.ci-carousel-thumbnail.active {
opacity: 1;
box-shadow: 0 0 0 2px #000000;
transform: translateY(-2px);
+ animation: fadeBoxShadow 5s ease-out forwards;
+}
+
+@keyframes fadeBoxShadow {
+ 0% {
+ box-shadow: 0 0 0 2px #000000;
+ }
+ 100% {
+ box-shadow: 0 0 0 0 transparent;
+ }
}
.ci-carousel-thumbnail img {
width: 100%;
height: 100%;
- object-fit: cover;
}
/* Minimal Filename Display */
@@ -152,12 +162,13 @@
font-size: 13px;
font-weight: 500;
letter-spacing: 0.3px;
- opacity: 0;
transform: translateY(8px);
- transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
+ opacity: 0;
+ transition: all 0.5s ease-in-out;
+ box-sizing: border-box;
}
-.ci-carousel-image-wrapper:hover .ci-carousel-filename {
+.ci-carousel-has-filenames .ci-carousel-filename {
opacity: 1;
transform: translateY(0);
}
@@ -207,3 +218,13 @@
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(8px);
}
+
+.ci-carousel.is-fullscreen.ci-carousel-has-filenames .ci-carousel-filename {
+ font-size: 20px;
+}
+
+.ci-carousel.is-fullscreen.ci-carousel-has-filenames:hover .ci-carousel-filename {
+ opacity: 1;
+ font-size: 20px;
+ bottom: 100px;
+}
diff --git a/src/css/controls.css b/src/css/controls.css
index fa34868..e8aa699 100644
--- a/src/css/controls.css
+++ b/src/css/controls.css
@@ -4,13 +4,15 @@
position: relative;
}
+.ci-carousel-has-filenames .ci-carousel-controls {
+ top: -110px;
+}
+
.ci-carousel-controls {
align-items: center;
display: flex;
justify-content: space-between;
- width: 280px;
z-index: 10;
- border-radius: 20px;
width: 100%;
padding: 30px;
box-sizing: border-box;
diff --git a/src/js/carousel.js b/src/js/carousel.js
index a240e47..7ffab90 100644
--- a/src/js/carousel.js
+++ b/src/js/carousel.js
@@ -15,11 +15,13 @@ import {
} from './constants/classes.constants'
import { CLICK_EVENT } from './constants/events.constants'
import { ICONS } from './constants/icons.contants'
+import { THUMBNAIL_ALIGNMENT, THUMBNAIL_FIT_MODE } from './constants/thumbnails.contants'
import { TRANSITION_EFFECTS } from './constants/transition.constants'
import { CarouselControls } from './controls/controls'
import { SwipeControls } from './controls/swipe.controls'
import { ZoomPanControls } from './controls/zoom-pan.controls'
import { getFilenameWithoutExtension } from './utils/image.utils'
+import { validateOptions } from './utils/validation.utils'
class CloudImageCarousel {
/**
@@ -42,6 +44,9 @@ class CloudImageCarousel {
)
}
+ // Validate options before setting them
+ validateOptions(options)
+
this.options = {
images: options.images || [],
autoplay: options.autoplay || false,
@@ -52,6 +57,8 @@ class CloudImageCarousel {
showBullets: options.showBullets || false,
showControls: options.showControls || true,
transitionEffect: options.transitionEffect || TRANSITION_EFFECTS.FADE, // slide, fade
+ thumbnailFitMode: options.thumbnailFitMode || THUMBNAIL_FIT_MODE.CROP_FIT, // fit, crop-fit
+ thumbnailAlignment: options.thumbnailAlignment || THUMBNAIL_ALIGNMENT.SPACE_EVENLY, // left, center, right, space-evenly
...options,
}
@@ -150,6 +157,11 @@ class CloudImageCarousel {
this.bottomContainer.appendChild(this.bulletsContainer)
}
+ // Bullets container
+ if (this.options.showFilenames) {
+ this.container.classList.add('ci-carousel-has-filenames')
+ }
+
// Add containers to main view
this.mainView.appendChild(this.imagesContainer)
this.container.appendChild(this.mainView)
@@ -282,6 +294,9 @@ class CloudImageCarousel {
// Create a document fragment for better performance
const fragment = document.createDocumentFragment()
+ // Set the alignment for the thumbnails container
+ this.thumbnailsContainer.style.justifyContent = this.options.thumbnailAlignment
+
this.images.forEach((img, index) => {
const thumb = document.createElement('div')
thumb.classList.add('ci-carousel-thumbnail')
@@ -292,6 +307,7 @@ class CloudImageCarousel {
const thumbImg = new Image()
thumbImg.src = img.src
+ thumbImg.style.objectFit = this.options.thumbnailFitMode === THUMBNAIL_FIT_MODE.CROP_FIT ? 'cover' : 'contain'
thumb.appendChild(thumbImg)
fragment.appendChild(thumb)
})
diff --git a/src/js/constants/index.js b/src/js/constants/index.js
index 2423300..fec1b90 100644
--- a/src/js/constants/index.js
+++ b/src/js/constants/index.js
@@ -2,3 +2,4 @@ export * from './events.constants'
export * from './controls.constants'
export * from './transition.constants'
export * from './icons.contants'
+export * from './thumbnails.contants'
diff --git a/src/js/constants/thumbnails.contants.js b/src/js/constants/thumbnails.contants.js
new file mode 100644
index 0000000..8ac09b7
--- /dev/null
+++ b/src/js/constants/thumbnails.contants.js
@@ -0,0 +1,14 @@
+const THUMBNAIL_FIT_MODE = {
+ CROP_FIT: 'crop-fit',
+ FIT: 'fit',
+}
+
+const THUMBNAIL_ALIGNMENT = {
+ LEFT: 'left',
+ CENTER: 'center',
+ RIGHT: 'right',
+ SPACE_EVENLY: 'space-evenly',
+ SPACE_BETWEEN: 'space-between',
+}
+
+export { THUMBNAIL_FIT_MODE, THUMBNAIL_ALIGNMENT }
diff --git a/src/js/utils/index.js b/src/js/utils/index.js
index fcd8791..4429fac 100644
--- a/src/js/utils/index.js
+++ b/src/js/utils/index.js
@@ -1,3 +1,4 @@
export * from './image.utils.js'
export * from './throttling.utils.js'
export * from './dom.utils.js'
+export * from './validation.utils.js'
diff --git a/src/js/utils/validation.utils.js b/src/js/utils/validation.utils.js
new file mode 100644
index 0000000..c41f87d
--- /dev/null
+++ b/src/js/utils/validation.utils.js
@@ -0,0 +1,56 @@
+import { THUMBNAIL_ALIGNMENT, THUMBNAIL_FIT_MODE } from '../constants/thumbnails.contants'
+import { TRANSITION_EFFECTS } from '../constants/transition.constants'
+
+/**
+ * Validates the options passed to the carousel
+ * @param {Object} options - The options to validate
+ * @throws {Error} If any option is invalid
+ * @private
+ */
+export const validateOptions = (options) => {
+ // Validate images array
+ if (options.images !== undefined) {
+ if (!Array.isArray(options.images)) {
+ throw new Error('images option must be an array of strings')
+ }
+ if (!options.images.every((img) => typeof img === 'string')) {
+ throw new Error('All elements in images array must be strings')
+ }
+ }
+
+ // Validate boolean options
+ const booleanOptions = ['autoplay', 'cycle', 'showFilenames', 'showThumbnails', 'showBullets', 'showControls']
+ booleanOptions.forEach((option) => {
+ if (options[option] !== undefined && typeof options[option] !== 'boolean') {
+ throw new Error(`${option} option must be a boolean`)
+ }
+ })
+
+ // Validate autoplayInterval
+ if (options.autoplayInterval !== undefined) {
+ if (typeof options.autoplayInterval !== 'number' || options.autoplayInterval < 0) {
+ throw new Error('autoplayInterval option must be a positive number')
+ }
+ }
+
+ // Validate transitionEffect
+ if (options.transitionEffect !== undefined) {
+ if (!Object.values(TRANSITION_EFFECTS).includes(options.transitionEffect)) {
+ throw new Error(`transitionEffect must be one of: ${Object.values(TRANSITION_EFFECTS).join(', ')}`)
+ }
+ }
+
+ // Validate thumbnailFitMode
+ if (options.thumbnailFitMode !== undefined) {
+ if (!Object.values(THUMBNAIL_FIT_MODE).includes(options.thumbnailFitMode)) {
+ throw new Error(`thumbnailFitMode must be one of: ${Object.values(THUMBNAIL_FIT_MODE).join(', ')}`)
+ }
+ }
+
+ // Validate thumbnailAlignment
+ if (options.thumbnailAlignment !== undefined) {
+ if (!Object.values(THUMBNAIL_ALIGNMENT).includes(options.thumbnailAlignment)) {
+ throw new Error(`thumbnailAlignment must be one of: ${Object.values(THUMBNAIL_ALIGNMENT).join(', ')}`)
+ }
+ }
+}
From c47eb4b869239f4c327acd2c035703b6662795a7 Mon Sep 17 00:00:00 2001
From: Jesus Vista
Date: Mon, 28 Apr 2025 18:11:08 +0800
Subject: [PATCH 2/2] update read me, remove unnecessary comment
---
README.md | 2 --
1 file changed, 2 deletions(-)
diff --git a/README.md b/README.md
index 982119a..e2ededd 100644
--- a/README.md
+++ b/README.md
@@ -196,8 +196,6 @@ carousel.init()
}
```
-Let me verify this by checking the constants file for thumbnail alignment.
-
## Complete Example
Here's an example showing all options with their default values: