{"version":3,"file":"index.mjs","sources":["../../node_modules/lucide-react/dist/esm/icons/arrow-left.js","../../node_modules/lucide-react/dist/esm/icons/arrow-right.js","../../node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js","../../node_modules/embla-carousel/esm/embla-carousel.esm.js","../../node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js","../../src/components/ui/carousel/carousel.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.479.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"path\", { d: \"m12 19-7-7 7-7\", key: \"1l729n\" }],\n  [\"path\", { d: \"M19 12H5\", key: \"x3x0zl\" }]\n];\nconst ArrowLeft = createLucideIcon(\"ArrowLeft\", __iconNode);\n\nexport { __iconNode, ArrowLeft as default };\n//# sourceMappingURL=arrow-left.js.map\n","/**\n * @license lucide-react v0.479.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n  [\"path\", { d: \"m12 5 7 7-7 7\", key: \"xquz4c\" }]\n];\nconst ArrowRight = createLucideIcon(\"ArrowRight\", __iconNode);\n\nexport { __iconNode, ArrowRight as default };\n//# sourceMappingURL=arrow-right.js.map\n","function isObject(subject) {\n  return Object.prototype.toString.call(subject) === '[object Object]';\n}\nfunction isRecord(subject) {\n  return isObject(subject) || Array.isArray(subject);\n}\nfunction canUseDOM() {\n  return !!(typeof window !== 'undefined' && window.document && window.document.createElement);\n}\nfunction areOptionsEqual(optionsA, optionsB) {\n  const optionsAKeys = Object.keys(optionsA);\n  const optionsBKeys = Object.keys(optionsB);\n  if (optionsAKeys.length !== optionsBKeys.length) return false;\n  const breakpointsA = JSON.stringify(Object.keys(optionsA.breakpoints || {}));\n  const breakpointsB = JSON.stringify(Object.keys(optionsB.breakpoints || {}));\n  if (breakpointsA !== breakpointsB) return false;\n  return optionsAKeys.every(key => {\n    const valueA = optionsA[key];\n    const valueB = optionsB[key];\n    if (typeof valueA === 'function') return `${valueA}` === `${valueB}`;\n    if (!isRecord(valueA) || !isRecord(valueB)) return valueA === valueB;\n    return areOptionsEqual(valueA, valueB);\n  });\n}\nfunction sortAndMapPluginToOptions(plugins) {\n  return plugins.concat().sort((a, b) => a.name > b.name ? 1 : -1).map(plugin => plugin.options);\n}\nfunction arePluginsEqual(pluginsA, pluginsB) {\n  if (pluginsA.length !== pluginsB.length) return false;\n  const optionsA = sortAndMapPluginToOptions(pluginsA);\n  const optionsB = sortAndMapPluginToOptions(pluginsB);\n  return optionsA.every((optionA, index) => {\n    const optionB = optionsB[index];\n    return areOptionsEqual(optionA, optionB);\n  });\n}\n\nexport { areOptionsEqual, arePluginsEqual, canUseDOM, sortAndMapPluginToOptions };\n//# sourceMappingURL=embla-carousel-reactive-utils.esm.js.map\n","function isNumber(subject) {\n  return typeof subject === 'number';\n}\nfunction isString(subject) {\n  return typeof subject === 'string';\n}\nfunction isBoolean(subject) {\n  return typeof subject === 'boolean';\n}\nfunction isObject(subject) {\n  return Object.prototype.toString.call(subject) === '[object Object]';\n}\nfunction mathAbs(n) {\n  return Math.abs(n);\n}\nfunction mathSign(n) {\n  return Math.sign(n);\n}\nfunction deltaAbs(valueB, valueA) {\n  return mathAbs(valueB - valueA);\n}\nfunction factorAbs(valueB, valueA) {\n  if (valueB === 0 || valueA === 0) return 0;\n  if (mathAbs(valueB) <= mathAbs(valueA)) return 0;\n  const diff = deltaAbs(mathAbs(valueB), mathAbs(valueA));\n  return mathAbs(diff / valueB);\n}\nfunction roundToTwoDecimals(num) {\n  return Math.round(num * 100) / 100;\n}\nfunction arrayKeys(array) {\n  return objectKeys(array).map(Number);\n}\nfunction arrayLast(array) {\n  return array[arrayLastIndex(array)];\n}\nfunction arrayLastIndex(array) {\n  return Math.max(0, array.length - 1);\n}\nfunction arrayIsLastIndex(array, index) {\n  return index === arrayLastIndex(array);\n}\nfunction arrayFromNumber(n, startAt = 0) {\n  return Array.from(Array(n), (_, i) => startAt + i);\n}\nfunction objectKeys(object) {\n  return Object.keys(object);\n}\nfunction objectsMergeDeep(objectA, objectB) {\n  return [objectA, objectB].reduce((mergedObjects, currentObject) => {\n    objectKeys(currentObject).forEach(key => {\n      const valueA = mergedObjects[key];\n      const valueB = currentObject[key];\n      const areObjects = isObject(valueA) && isObject(valueB);\n      mergedObjects[key] = areObjects ? objectsMergeDeep(valueA, valueB) : valueB;\n    });\n    return mergedObjects;\n  }, {});\n}\nfunction isMouseEvent(evt, ownerWindow) {\n  return typeof ownerWindow.MouseEvent !== 'undefined' && evt instanceof ownerWindow.MouseEvent;\n}\n\nfunction Alignment(align, viewSize) {\n  const predefined = {\n    start,\n    center,\n    end\n  };\n  function start() {\n    return 0;\n  }\n  function center(n) {\n    return end(n) / 2;\n  }\n  function end(n) {\n    return viewSize - n;\n  }\n  function measure(n, index) {\n    if (isString(align)) return predefined[align](n);\n    return align(viewSize, n, index);\n  }\n  const self = {\n    measure\n  };\n  return self;\n}\n\nfunction EventStore() {\n  let listeners = [];\n  function add(node, type, handler, options = {\n    passive: true\n  }) {\n    let removeListener;\n    if ('addEventListener' in node) {\n      node.addEventListener(type, handler, options);\n      removeListener = () => node.removeEventListener(type, handler, options);\n    } else {\n      const legacyMediaQueryList = node;\n      legacyMediaQueryList.addListener(handler);\n      removeListener = () => legacyMediaQueryList.removeListener(handler);\n    }\n    listeners.push(removeListener);\n    return self;\n  }\n  function clear() {\n    listeners = listeners.filter(remove => remove());\n  }\n  const self = {\n    add,\n    clear\n  };\n  return self;\n}\n\nfunction Animations(ownerDocument, ownerWindow, update, render) {\n  const documentVisibleHandler = EventStore();\n  const fixedTimeStep = 1000 / 60;\n  let lastTimeStamp = null;\n  let accumulatedTime = 0;\n  let animationId = 0;\n  function init() {\n    documentVisibleHandler.add(ownerDocument, 'visibilitychange', () => {\n      if (ownerDocument.hidden) reset();\n    });\n  }\n  function destroy() {\n    stop();\n    documentVisibleHandler.clear();\n  }\n  function animate(timeStamp) {\n    if (!animationId) return;\n    if (!lastTimeStamp) {\n      lastTimeStamp = timeStamp;\n      update();\n      update();\n    }\n    const timeElapsed = timeStamp - lastTimeStamp;\n    lastTimeStamp = timeStamp;\n    accumulatedTime += timeElapsed;\n    while (accumulatedTime >= fixedTimeStep) {\n      update();\n      accumulatedTime -= fixedTimeStep;\n    }\n    const alpha = accumulatedTime / fixedTimeStep;\n    render(alpha);\n    if (animationId) {\n      animationId = ownerWindow.requestAnimationFrame(animate);\n    }\n  }\n  function start() {\n    if (animationId) return;\n    animationId = ownerWindow.requestAnimationFrame(animate);\n  }\n  function stop() {\n    ownerWindow.cancelAnimationFrame(animationId);\n    lastTimeStamp = null;\n    accumulatedTime = 0;\n    animationId = 0;\n  }\n  function reset() {\n    lastTimeStamp = null;\n    accumulatedTime = 0;\n  }\n  const self = {\n    init,\n    destroy,\n    start,\n    stop,\n    update,\n    render\n  };\n  return self;\n}\n\nfunction Axis(axis, contentDirection) {\n  const isRightToLeft = contentDirection === 'rtl';\n  const isVertical = axis === 'y';\n  const scroll = isVertical ? 'y' : 'x';\n  const cross = isVertical ? 'x' : 'y';\n  const sign = !isVertical && isRightToLeft ? -1 : 1;\n  const startEdge = getStartEdge();\n  const endEdge = getEndEdge();\n  function measureSize(nodeRect) {\n    const {\n      height,\n      width\n    } = nodeRect;\n    return isVertical ? height : width;\n  }\n  function getStartEdge() {\n    if (isVertical) return 'top';\n    return isRightToLeft ? 'right' : 'left';\n  }\n  function getEndEdge() {\n    if (isVertical) return 'bottom';\n    return isRightToLeft ? 'left' : 'right';\n  }\n  function direction(n) {\n    return n * sign;\n  }\n  const self = {\n    scroll,\n    cross,\n    startEdge,\n    endEdge,\n    measureSize,\n    direction\n  };\n  return self;\n}\n\nfunction Limit(min = 0, max = 0) {\n  const length = mathAbs(min - max);\n  function reachedMin(n) {\n    return n < min;\n  }\n  function reachedMax(n) {\n    return n > max;\n  }\n  function reachedAny(n) {\n    return reachedMin(n) || reachedMax(n);\n  }\n  function constrain(n) {\n    if (!reachedAny(n)) return n;\n    return reachedMin(n) ? min : max;\n  }\n  function removeOffset(n) {\n    if (!length) return n;\n    return n - length * Math.ceil((n - max) / length);\n  }\n  const self = {\n    length,\n    max,\n    min,\n    constrain,\n    reachedAny,\n    reachedMax,\n    reachedMin,\n    removeOffset\n  };\n  return self;\n}\n\nfunction Counter(max, start, loop) {\n  const {\n    constrain\n  } = Limit(0, max);\n  const loopEnd = max + 1;\n  let counter = withinLimit(start);\n  function withinLimit(n) {\n    return !loop ? constrain(n) : mathAbs((loopEnd + n) % loopEnd);\n  }\n  function get() {\n    return counter;\n  }\n  function set(n) {\n    counter = withinLimit(n);\n    return self;\n  }\n  function add(n) {\n    return clone().set(get() + n);\n  }\n  function clone() {\n    return Counter(max, get(), loop);\n  }\n  const self = {\n    get,\n    set,\n    add,\n    clone\n  };\n  return self;\n}\n\nfunction DragHandler(axis, rootNode, ownerDocument, ownerWindow, target, dragTracker, location, animation, scrollTo, scrollBody, scrollTarget, index, eventHandler, percentOfView, dragFree, dragThreshold, skipSnaps, baseFriction, watchDrag) {\n  const {\n    cross: crossAxis,\n    direction\n  } = axis;\n  const focusNodes = ['INPUT', 'SELECT', 'TEXTAREA'];\n  const nonPassiveEvent = {\n    passive: false\n  };\n  const initEvents = EventStore();\n  const dragEvents = EventStore();\n  const goToNextThreshold = Limit(50, 225).constrain(percentOfView.measure(20));\n  const snapForceBoost = {\n    mouse: 300,\n    touch: 400\n  };\n  const freeForceBoost = {\n    mouse: 500,\n    touch: 600\n  };\n  const baseSpeed = dragFree ? 43 : 25;\n  let isMoving = false;\n  let startScroll = 0;\n  let startCross = 0;\n  let pointerIsDown = false;\n  let preventScroll = false;\n  let preventClick = false;\n  let isMouse = false;\n  function init(emblaApi) {\n    if (!watchDrag) return;\n    function downIfAllowed(evt) {\n      if (isBoolean(watchDrag) || watchDrag(emblaApi, evt)) down(evt);\n    }\n    const node = rootNode;\n    initEvents.add(node, 'dragstart', evt => evt.preventDefault(), nonPassiveEvent).add(node, 'touchmove', () => undefined, nonPassiveEvent).add(node, 'touchend', () => undefined).add(node, 'touchstart', downIfAllowed).add(node, 'mousedown', downIfAllowed).add(node, 'touchcancel', up).add(node, 'contextmenu', up).add(node, 'click', click, true);\n  }\n  function destroy() {\n    initEvents.clear();\n    dragEvents.clear();\n  }\n  function addDragEvents() {\n    const node = isMouse ? ownerDocument : rootNode;\n    dragEvents.add(node, 'touchmove', move, nonPassiveEvent).add(node, 'touchend', up).add(node, 'mousemove', move, nonPassiveEvent).add(node, 'mouseup', up);\n  }\n  function isFocusNode(node) {\n    const nodeName = node.nodeName || '';\n    return focusNodes.includes(nodeName);\n  }\n  function forceBoost() {\n    const boost = dragFree ? freeForceBoost : snapForceBoost;\n    const type = isMouse ? 'mouse' : 'touch';\n    return boost[type];\n  }\n  function allowedForce(force, targetChanged) {\n    const next = index.add(mathSign(force) * -1);\n    const baseForce = scrollTarget.byDistance(force, !dragFree).distance;\n    if (dragFree || mathAbs(force) < goToNextThreshold) return baseForce;\n    if (skipSnaps && targetChanged) return baseForce * 0.5;\n    return scrollTarget.byIndex(next.get(), 0).distance;\n  }\n  function down(evt) {\n    const isMouseEvt = isMouseEvent(evt, ownerWindow);\n    isMouse = isMouseEvt;\n    preventClick = dragFree && isMouseEvt && !evt.buttons && isMoving;\n    isMoving = deltaAbs(target.get(), location.get()) >= 2;\n    if (isMouseEvt && evt.button !== 0) return;\n    if (isFocusNode(evt.target)) return;\n    pointerIsDown = true;\n    dragTracker.pointerDown(evt);\n    scrollBody.useFriction(0).useDuration(0);\n    target.set(location);\n    addDragEvents();\n    startScroll = dragTracker.readPoint(evt);\n    startCross = dragTracker.readPoint(evt, crossAxis);\n    eventHandler.emit('pointerDown');\n  }\n  function move(evt) {\n    const isTouchEvt = !isMouseEvent(evt, ownerWindow);\n    if (isTouchEvt && evt.touches.length >= 2) return up(evt);\n    const lastScroll = dragTracker.readPoint(evt);\n    const lastCross = dragTracker.readPoint(evt, crossAxis);\n    const diffScroll = deltaAbs(lastScroll, startScroll);\n    const diffCross = deltaAbs(lastCross, startCross);\n    if (!preventScroll && !isMouse) {\n      if (!evt.cancelable) return up(evt);\n      preventScroll = diffScroll > diffCross;\n      if (!preventScroll) return up(evt);\n    }\n    const diff = dragTracker.pointerMove(evt);\n    if (diffScroll > dragThreshold) preventClick = true;\n    scrollBody.useFriction(0.3).useDuration(0.75);\n    animation.start();\n    target.add(direction(diff));\n    evt.preventDefault();\n  }\n  function up(evt) {\n    const currentLocation = scrollTarget.byDistance(0, false);\n    const targetChanged = currentLocation.index !== index.get();\n    const rawForce = dragTracker.pointerUp(evt) * forceBoost();\n    const force = allowedForce(direction(rawForce), targetChanged);\n    const forceFactor = factorAbs(rawForce, force);\n    const speed = baseSpeed - 10 * forceFactor;\n    const friction = baseFriction + forceFactor / 50;\n    preventScroll = false;\n    pointerIsDown = false;\n    dragEvents.clear();\n    scrollBody.useDuration(speed).useFriction(friction);\n    scrollTo.distance(force, !dragFree);\n    isMouse = false;\n    eventHandler.emit('pointerUp');\n  }\n  function click(evt) {\n    if (preventClick) {\n      evt.stopPropagation();\n      evt.preventDefault();\n      preventClick = false;\n    }\n  }\n  function pointerDown() {\n    return pointerIsDown;\n  }\n  const self = {\n    init,\n    destroy,\n    pointerDown\n  };\n  return self;\n}\n\nfunction DragTracker(axis, ownerWindow) {\n  const logInterval = 170;\n  let startEvent;\n  let lastEvent;\n  function readTime(evt) {\n    return evt.timeStamp;\n  }\n  function readPoint(evt, evtAxis) {\n    const property = evtAxis || axis.scroll;\n    const coord = `client${property === 'x' ? 'X' : 'Y'}`;\n    return (isMouseEvent(evt, ownerWindow) ? evt : evt.touches[0])[coord];\n  }\n  function pointerDown(evt) {\n    startEvent = evt;\n    lastEvent = evt;\n    return readPoint(evt);\n  }\n  function pointerMove(evt) {\n    const diff = readPoint(evt) - readPoint(lastEvent);\n    const expired = readTime(evt) - readTime(startEvent) > logInterval;\n    lastEvent = evt;\n    if (expired) startEvent = evt;\n    return diff;\n  }\n  function pointerUp(evt) {\n    if (!startEvent || !lastEvent) return 0;\n    const diffDrag = readPoint(lastEvent) - readPoint(startEvent);\n    const diffTime = readTime(evt) - readTime(startEvent);\n    const expired = readTime(evt) - readTime(lastEvent) > logInterval;\n    const force = diffDrag / diffTime;\n    const isFlick = diffTime && !expired && mathAbs(force) > 0.1;\n    return isFlick ? force : 0;\n  }\n  const self = {\n    pointerDown,\n    pointerMove,\n    pointerUp,\n    readPoint\n  };\n  return self;\n}\n\nfunction NodeRects() {\n  function measure(node) {\n    const {\n      offsetTop,\n      offsetLeft,\n      offsetWidth,\n      offsetHeight\n    } = node;\n    const offset = {\n      top: offsetTop,\n      right: offsetLeft + offsetWidth,\n      bottom: offsetTop + offsetHeight,\n      left: offsetLeft,\n      width: offsetWidth,\n      height: offsetHeight\n    };\n    return offset;\n  }\n  const self = {\n    measure\n  };\n  return self;\n}\n\nfunction PercentOfView(viewSize) {\n  function measure(n) {\n    return viewSize * (n / 100);\n  }\n  const self = {\n    measure\n  };\n  return self;\n}\n\nfunction ResizeHandler(container, eventHandler, ownerWindow, slides, axis, watchResize, nodeRects) {\n  const observeNodes = [container].concat(slides);\n  let resizeObserver;\n  let containerSize;\n  let slideSizes = [];\n  let destroyed = false;\n  function readSize(node) {\n    return axis.measureSize(nodeRects.measure(node));\n  }\n  function init(emblaApi) {\n    if (!watchResize) return;\n    containerSize = readSize(container);\n    slideSizes = slides.map(readSize);\n    function defaultCallback(entries) {\n      for (const entry of entries) {\n        if (destroyed) return;\n        const isContainer = entry.target === container;\n        const slideIndex = slides.indexOf(entry.target);\n        const lastSize = isContainer ? containerSize : slideSizes[slideIndex];\n        const newSize = readSize(isContainer ? container : slides[slideIndex]);\n        const diffSize = mathAbs(newSize - lastSize);\n        if (diffSize >= 0.5) {\n          emblaApi.reInit();\n          eventHandler.emit('resize');\n          break;\n        }\n      }\n    }\n    resizeObserver = new ResizeObserver(entries => {\n      if (isBoolean(watchResize) || watchResize(emblaApi, entries)) {\n        defaultCallback(entries);\n      }\n    });\n    ownerWindow.requestAnimationFrame(() => {\n      observeNodes.forEach(node => resizeObserver.observe(node));\n    });\n  }\n  function destroy() {\n    destroyed = true;\n    if (resizeObserver) resizeObserver.disconnect();\n  }\n  const self = {\n    init,\n    destroy\n  };\n  return self;\n}\n\nfunction ScrollBody(location, offsetLocation, previousLocation, target, baseDuration, baseFriction) {\n  let scrollVelocity = 0;\n  let scrollDirection = 0;\n  let scrollDuration = baseDuration;\n  let scrollFriction = baseFriction;\n  let rawLocation = location.get();\n  let rawLocationPrevious = 0;\n  function seek() {\n    const displacement = target.get() - location.get();\n    const isInstant = !scrollDuration;\n    let scrollDistance = 0;\n    if (isInstant) {\n      scrollVelocity = 0;\n      previousLocation.set(target);\n      location.set(target);\n      scrollDistance = displacement;\n    } else {\n      previousLocation.set(location);\n      scrollVelocity += displacement / scrollDuration;\n      scrollVelocity *= scrollFriction;\n      rawLocation += scrollVelocity;\n      location.add(scrollVelocity);\n      scrollDistance = rawLocation - rawLocationPrevious;\n    }\n    scrollDirection = mathSign(scrollDistance);\n    rawLocationPrevious = rawLocation;\n    return self;\n  }\n  function settled() {\n    const diff = target.get() - offsetLocation.get();\n    return mathAbs(diff) < 0.001;\n  }\n  function duration() {\n    return scrollDuration;\n  }\n  function direction() {\n    return scrollDirection;\n  }\n  function velocity() {\n    return scrollVelocity;\n  }\n  function useBaseDuration() {\n    return useDuration(baseDuration);\n  }\n  function useBaseFriction() {\n    return useFriction(baseFriction);\n  }\n  function useDuration(n) {\n    scrollDuration = n;\n    return self;\n  }\n  function useFriction(n) {\n    scrollFriction = n;\n    return self;\n  }\n  const self = {\n    direction,\n    duration,\n    velocity,\n    seek,\n    settled,\n    useBaseFriction,\n    useBaseDuration,\n    useFriction,\n    useDuration\n  };\n  return self;\n}\n\nfunction ScrollBounds(limit, location, target, scrollBody, percentOfView) {\n  const pullBackThreshold = percentOfView.measure(10);\n  const edgeOffsetTolerance = percentOfView.measure(50);\n  const frictionLimit = Limit(0.1, 0.99);\n  let disabled = false;\n  function shouldConstrain() {\n    if (disabled) return false;\n    if (!limit.reachedAny(target.get())) return false;\n    if (!limit.reachedAny(location.get())) return false;\n    return true;\n  }\n  function constrain(pointerDown) {\n    if (!shouldConstrain()) return;\n    const edge = limit.reachedMin(location.get()) ? 'min' : 'max';\n    const diffToEdge = mathAbs(limit[edge] - location.get());\n    const diffToTarget = target.get() - location.get();\n    const friction = frictionLimit.constrain(diffToEdge / edgeOffsetTolerance);\n    target.subtract(diffToTarget * friction);\n    if (!pointerDown && mathAbs(diffToTarget) < pullBackThreshold) {\n      target.set(limit.constrain(target.get()));\n      scrollBody.useDuration(25).useBaseFriction();\n    }\n  }\n  function toggleActive(active) {\n    disabled = !active;\n  }\n  const self = {\n    shouldConstrain,\n    constrain,\n    toggleActive\n  };\n  return self;\n}\n\nfunction ScrollContain(viewSize, contentSize, snapsAligned, containScroll, pixelTolerance) {\n  const scrollBounds = Limit(-contentSize + viewSize, 0);\n  const snapsBounded = measureBounded();\n  const scrollContainLimit = findScrollContainLimit();\n  const snapsContained = measureContained();\n  function usePixelTolerance(bound, snap) {\n    return deltaAbs(bound, snap) <= 1;\n  }\n  function findScrollContainLimit() {\n    const startSnap = snapsBounded[0];\n    const endSnap = arrayLast(snapsBounded);\n    const min = snapsBounded.lastIndexOf(startSnap);\n    const max = snapsBounded.indexOf(endSnap) + 1;\n    return Limit(min, max);\n  }\n  function measureBounded() {\n    return snapsAligned.map((snapAligned, index) => {\n      const {\n        min,\n        max\n      } = scrollBounds;\n      const snap = scrollBounds.constrain(snapAligned);\n      const isFirst = !index;\n      const isLast = arrayIsLastIndex(snapsAligned, index);\n      if (isFirst) return max;\n      if (isLast) return min;\n      if (usePixelTolerance(min, snap)) return min;\n      if (usePixelTolerance(max, snap)) return max;\n      return snap;\n    }).map(scrollBound => parseFloat(scrollBound.toFixed(3)));\n  }\n  function measureContained() {\n    if (contentSize <= viewSize + pixelTolerance) return [scrollBounds.max];\n    if (containScroll === 'keepSnaps') return snapsBounded;\n    const {\n      min,\n      max\n    } = scrollContainLimit;\n    return snapsBounded.slice(min, max);\n  }\n  const self = {\n    snapsContained,\n    scrollContainLimit\n  };\n  return self;\n}\n\nfunction ScrollLimit(contentSize, scrollSnaps, loop) {\n  const max = scrollSnaps[0];\n  const min = loop ? max - contentSize : arrayLast(scrollSnaps);\n  const limit = Limit(min, max);\n  const self = {\n    limit\n  };\n  return self;\n}\n\nfunction ScrollLooper(contentSize, limit, location, vectors) {\n  const jointSafety = 0.1;\n  const min = limit.min + jointSafety;\n  const max = limit.max + jointSafety;\n  const {\n    reachedMin,\n    reachedMax\n  } = Limit(min, max);\n  function shouldLoop(direction) {\n    if (direction === 1) return reachedMax(location.get());\n    if (direction === -1) return reachedMin(location.get());\n    return false;\n  }\n  function loop(direction) {\n    if (!shouldLoop(direction)) return;\n    const loopDistance = contentSize * (direction * -1);\n    vectors.forEach(v => v.add(loopDistance));\n  }\n  const self = {\n    loop\n  };\n  return self;\n}\n\nfunction ScrollProgress(limit) {\n  const {\n    max,\n    length\n  } = limit;\n  function get(n) {\n    const currentLocation = n - max;\n    return length ? currentLocation / -length : 0;\n  }\n  const self = {\n    get\n  };\n  return self;\n}\n\nfunction ScrollSnaps(axis, alignment, containerRect, slideRects, slidesToScroll) {\n  const {\n    startEdge,\n    endEdge\n  } = axis;\n  const {\n    groupSlides\n  } = slidesToScroll;\n  const alignments = measureSizes().map(alignment.measure);\n  const snaps = measureUnaligned();\n  const snapsAligned = measureAligned();\n  function measureSizes() {\n    return groupSlides(slideRects).map(rects => arrayLast(rects)[endEdge] - rects[0][startEdge]).map(mathAbs);\n  }\n  function measureUnaligned() {\n    return slideRects.map(rect => containerRect[startEdge] - rect[startEdge]).map(snap => -mathAbs(snap));\n  }\n  function measureAligned() {\n    return groupSlides(snaps).map(g => g[0]).map((snap, index) => snap + alignments[index]);\n  }\n  const self = {\n    snaps,\n    snapsAligned\n  };\n  return self;\n}\n\nfunction SlideRegistry(containSnaps, containScroll, scrollSnaps, scrollContainLimit, slidesToScroll, slideIndexes) {\n  const {\n    groupSlides\n  } = slidesToScroll;\n  const {\n    min,\n    max\n  } = scrollContainLimit;\n  const slideRegistry = createSlideRegistry();\n  function createSlideRegistry() {\n    const groupedSlideIndexes = groupSlides(slideIndexes);\n    const doNotContain = !containSnaps || containScroll === 'keepSnaps';\n    if (scrollSnaps.length === 1) return [slideIndexes];\n    if (doNotContain) return groupedSlideIndexes;\n    return groupedSlideIndexes.slice(min, max).map((group, index, groups) => {\n      const isFirst = !index;\n      const isLast = arrayIsLastIndex(groups, index);\n      if (isFirst) {\n        const range = arrayLast(groups[0]) + 1;\n        return arrayFromNumber(range);\n      }\n      if (isLast) {\n        const range = arrayLastIndex(slideIndexes) - arrayLast(groups)[0] + 1;\n        return arrayFromNumber(range, arrayLast(groups)[0]);\n      }\n      return group;\n    });\n  }\n  const self = {\n    slideRegistry\n  };\n  return self;\n}\n\nfunction ScrollTarget(loop, scrollSnaps, contentSize, limit, targetVector) {\n  const {\n    reachedAny,\n    removeOffset,\n    constrain\n  } = limit;\n  function minDistance(distances) {\n    return distances.concat().sort((a, b) => mathAbs(a) - mathAbs(b))[0];\n  }\n  function findTargetSnap(target) {\n    const distance = loop ? removeOffset(target) : constrain(target);\n    const ascDiffsToSnaps = scrollSnaps.map((snap, index) => ({\n      diff: shortcut(snap - distance, 0),\n      index\n    })).sort((d1, d2) => mathAbs(d1.diff) - mathAbs(d2.diff));\n    const {\n      index\n    } = ascDiffsToSnaps[0];\n    return {\n      index,\n      distance\n    };\n  }\n  function shortcut(target, direction) {\n    const targets = [target, target + contentSize, target - contentSize];\n    if (!loop) return target;\n    if (!direction) return minDistance(targets);\n    const matchingTargets = targets.filter(t => mathSign(t) === direction);\n    if (matchingTargets.length) return minDistance(matchingTargets);\n    return arrayLast(targets) - contentSize;\n  }\n  function byIndex(index, direction) {\n    const diffToSnap = scrollSnaps[index] - targetVector.get();\n    const distance = shortcut(diffToSnap, direction);\n    return {\n      index,\n      distance\n    };\n  }\n  function byDistance(distance, snap) {\n    const target = targetVector.get() + distance;\n    const {\n      index,\n      distance: targetSnapDistance\n    } = findTargetSnap(target);\n    const reachedBound = !loop && reachedAny(target);\n    if (!snap || reachedBound) return {\n      index,\n      distance\n    };\n    const diffToSnap = scrollSnaps[index] - targetSnapDistance;\n    const snapDistance = distance + shortcut(diffToSnap, 0);\n    return {\n      index,\n      distance: snapDistance\n    };\n  }\n  const self = {\n    byDistance,\n    byIndex,\n    shortcut\n  };\n  return self;\n}\n\nfunction ScrollTo(animation, indexCurrent, indexPrevious, scrollBody, scrollTarget, targetVector, eventHandler) {\n  function scrollTo(target) {\n    const distanceDiff = target.distance;\n    const indexDiff = target.index !== indexCurrent.get();\n    targetVector.add(distanceDiff);\n    if (distanceDiff) {\n      if (scrollBody.duration()) {\n        animation.start();\n      } else {\n        animation.update();\n        animation.render(1);\n        animation.update();\n      }\n    }\n    if (indexDiff) {\n      indexPrevious.set(indexCurrent.get());\n      indexCurrent.set(target.index);\n      eventHandler.emit('select');\n    }\n  }\n  function distance(n, snap) {\n    const target = scrollTarget.byDistance(n, snap);\n    scrollTo(target);\n  }\n  function index(n, direction) {\n    const targetIndex = indexCurrent.clone().set(n);\n    const target = scrollTarget.byIndex(targetIndex.get(), direction);\n    scrollTo(target);\n  }\n  const self = {\n    distance,\n    index\n  };\n  return self;\n}\n\nfunction SlideFocus(root, slides, slideRegistry, scrollTo, scrollBody, eventStore, eventHandler, watchFocus) {\n  const focusListenerOptions = {\n    passive: true,\n    capture: true\n  };\n  let lastTabPressTime = 0;\n  function init(emblaApi) {\n    if (!watchFocus) return;\n    function defaultCallback(index) {\n      const nowTime = new Date().getTime();\n      const diffTime = nowTime - lastTabPressTime;\n      if (diffTime > 10) return;\n      eventHandler.emit('slideFocusStart');\n      root.scrollLeft = 0;\n      const group = slideRegistry.findIndex(group => group.includes(index));\n      if (!isNumber(group)) return;\n      scrollBody.useDuration(0);\n      scrollTo.index(group, 0);\n      eventHandler.emit('slideFocus');\n    }\n    eventStore.add(document, 'keydown', registerTabPress, false);\n    slides.forEach((slide, slideIndex) => {\n      eventStore.add(slide, 'focus', evt => {\n        if (isBoolean(watchFocus) || watchFocus(emblaApi, evt)) {\n          defaultCallback(slideIndex);\n        }\n      }, focusListenerOptions);\n    });\n  }\n  function registerTabPress(event) {\n    if (event.code === 'Tab') lastTabPressTime = new Date().getTime();\n  }\n  const self = {\n    init\n  };\n  return self;\n}\n\nfunction Vector1D(initialValue) {\n  let value = initialValue;\n  function get() {\n    return value;\n  }\n  function set(n) {\n    value = normalizeInput(n);\n  }\n  function add(n) {\n    value += normalizeInput(n);\n  }\n  function subtract(n) {\n    value -= normalizeInput(n);\n  }\n  function normalizeInput(n) {\n    return isNumber(n) ? n : n.get();\n  }\n  const self = {\n    get,\n    set,\n    add,\n    subtract\n  };\n  return self;\n}\n\nfunction Translate(axis, container) {\n  const translate = axis.scroll === 'x' ? x : y;\n  const containerStyle = container.style;\n  let previousTarget = null;\n  let disabled = false;\n  function x(n) {\n    return `translate3d(${n}px,0px,0px)`;\n  }\n  function y(n) {\n    return `translate3d(0px,${n}px,0px)`;\n  }\n  function to(target) {\n    if (disabled) return;\n    const newTarget = roundToTwoDecimals(axis.direction(target));\n    if (newTarget === previousTarget) return;\n    containerStyle.transform = translate(newTarget);\n    previousTarget = newTarget;\n  }\n  function toggleActive(active) {\n    disabled = !active;\n  }\n  function clear() {\n    if (disabled) return;\n    containerStyle.transform = '';\n    if (!container.getAttribute('style')) container.removeAttribute('style');\n  }\n  const self = {\n    clear,\n    to,\n    toggleActive\n  };\n  return self;\n}\n\nfunction SlideLooper(axis, viewSize, contentSize, slideSizes, slideSizesWithGaps, snaps, scrollSnaps, location, slides) {\n  const roundingSafety = 0.5;\n  const ascItems = arrayKeys(slideSizesWithGaps);\n  const descItems = arrayKeys(slideSizesWithGaps).reverse();\n  const loopPoints = startPoints().concat(endPoints());\n  function removeSlideSizes(indexes, from) {\n    return indexes.reduce((a, i) => {\n      return a - slideSizesWithGaps[i];\n    }, from);\n  }\n  function slidesInGap(indexes, gap) {\n    return indexes.reduce((a, i) => {\n      const remainingGap = removeSlideSizes(a, gap);\n      return remainingGap > 0 ? a.concat([i]) : a;\n    }, []);\n  }\n  function findSlideBounds(offset) {\n    return snaps.map((snap, index) => ({\n      start: snap - slideSizes[index] + roundingSafety + offset,\n      end: snap + viewSize - roundingSafety + offset\n    }));\n  }\n  function findLoopPoints(indexes, offset, isEndEdge) {\n    const slideBounds = findSlideBounds(offset);\n    return indexes.map(index => {\n      const initial = isEndEdge ? 0 : -contentSize;\n      const altered = isEndEdge ? contentSize : 0;\n      const boundEdge = isEndEdge ? 'end' : 'start';\n      const loopPoint = slideBounds[index][boundEdge];\n      return {\n        index,\n        loopPoint,\n        slideLocation: Vector1D(-1),\n        translate: Translate(axis, slides[index]),\n        target: () => location.get() > loopPoint ? initial : altered\n      };\n    });\n  }\n  function startPoints() {\n    const gap = scrollSnaps[0];\n    const indexes = slidesInGap(descItems, gap);\n    return findLoopPoints(indexes, contentSize, false);\n  }\n  function endPoints() {\n    const gap = viewSize - scrollSnaps[0] - 1;\n    const indexes = slidesInGap(ascItems, gap);\n    return findLoopPoints(indexes, -contentSize, true);\n  }\n  function canLoop() {\n    return loopPoints.every(({\n      index\n    }) => {\n      const otherIndexes = ascItems.filter(i => i !== index);\n      return removeSlideSizes(otherIndexes, viewSize) <= 0.1;\n    });\n  }\n  function loop() {\n    loopPoints.forEach(loopPoint => {\n      const {\n        target,\n        translate,\n        slideLocation\n      } = loopPoint;\n      const shiftLocation = target();\n      if (shiftLocation === slideLocation.get()) return;\n      translate.to(shiftLocation);\n      slideLocation.set(shiftLocation);\n    });\n  }\n  function clear() {\n    loopPoints.forEach(loopPoint => loopPoint.translate.clear());\n  }\n  const self = {\n    canLoop,\n    clear,\n    loop,\n    loopPoints\n  };\n  return self;\n}\n\nfunction SlidesHandler(container, eventHandler, watchSlides) {\n  let mutationObserver;\n  let destroyed = false;\n  function init(emblaApi) {\n    if (!watchSlides) return;\n    function defaultCallback(mutations) {\n      for (const mutation of mutations) {\n        if (mutation.type === 'childList') {\n          emblaApi.reInit();\n          eventHandler.emit('slidesChanged');\n          break;\n        }\n      }\n    }\n    mutationObserver = new MutationObserver(mutations => {\n      if (destroyed) return;\n      if (isBoolean(watchSlides) || watchSlides(emblaApi, mutations)) {\n        defaultCallback(mutations);\n      }\n    });\n    mutationObserver.observe(container, {\n      childList: true\n    });\n  }\n  function destroy() {\n    if (mutationObserver) mutationObserver.disconnect();\n    destroyed = true;\n  }\n  const self = {\n    init,\n    destroy\n  };\n  return self;\n}\n\nfunction SlidesInView(container, slides, eventHandler, threshold) {\n  const intersectionEntryMap = {};\n  let inViewCache = null;\n  let notInViewCache = null;\n  let intersectionObserver;\n  let destroyed = false;\n  function init() {\n    intersectionObserver = new IntersectionObserver(entries => {\n      if (destroyed) return;\n      entries.forEach(entry => {\n        const index = slides.indexOf(entry.target);\n        intersectionEntryMap[index] = entry;\n      });\n      inViewCache = null;\n      notInViewCache = null;\n      eventHandler.emit('slidesInView');\n    }, {\n      root: container.parentElement,\n      threshold\n    });\n    slides.forEach(slide => intersectionObserver.observe(slide));\n  }\n  function destroy() {\n    if (intersectionObserver) intersectionObserver.disconnect();\n    destroyed = true;\n  }\n  function createInViewList(inView) {\n    return objectKeys(intersectionEntryMap).reduce((list, slideIndex) => {\n      const index = parseInt(slideIndex);\n      const {\n        isIntersecting\n      } = intersectionEntryMap[index];\n      const inViewMatch = inView && isIntersecting;\n      const notInViewMatch = !inView && !isIntersecting;\n      if (inViewMatch || notInViewMatch) list.push(index);\n      return list;\n    }, []);\n  }\n  function get(inView = true) {\n    if (inView && inViewCache) return inViewCache;\n    if (!inView && notInViewCache) return notInViewCache;\n    const slideIndexes = createInViewList(inView);\n    if (inView) inViewCache = slideIndexes;\n    if (!inView) notInViewCache = slideIndexes;\n    return slideIndexes;\n  }\n  const self = {\n    init,\n    destroy,\n    get\n  };\n  return self;\n}\n\nfunction SlideSizes(axis, containerRect, slideRects, slides, readEdgeGap, ownerWindow) {\n  const {\n    measureSize,\n    startEdge,\n    endEdge\n  } = axis;\n  const withEdgeGap = slideRects[0] && readEdgeGap;\n  const startGap = measureStartGap();\n  const endGap = measureEndGap();\n  const slideSizes = slideRects.map(measureSize);\n  const slideSizesWithGaps = measureWithGaps();\n  function measureStartGap() {\n    if (!withEdgeGap) return 0;\n    const slideRect = slideRects[0];\n    return mathAbs(containerRect[startEdge] - slideRect[startEdge]);\n  }\n  function measureEndGap() {\n    if (!withEdgeGap) return 0;\n    const style = ownerWindow.getComputedStyle(arrayLast(slides));\n    return parseFloat(style.getPropertyValue(`margin-${endEdge}`));\n  }\n  function measureWithGaps() {\n    return slideRects.map((rect, index, rects) => {\n      const isFirst = !index;\n      const isLast = arrayIsLastIndex(rects, index);\n      if (isFirst) return slideSizes[index] + startGap;\n      if (isLast) return slideSizes[index] + endGap;\n      return rects[index + 1][startEdge] - rect[startEdge];\n    }).map(mathAbs);\n  }\n  const self = {\n    slideSizes,\n    slideSizesWithGaps,\n    startGap,\n    endGap\n  };\n  return self;\n}\n\nfunction SlidesToScroll(axis, viewSize, slidesToScroll, loop, containerRect, slideRects, startGap, endGap, pixelTolerance) {\n  const {\n    startEdge,\n    endEdge,\n    direction\n  } = axis;\n  const groupByNumber = isNumber(slidesToScroll);\n  function byNumber(array, groupSize) {\n    return arrayKeys(array).filter(i => i % groupSize === 0).map(i => array.slice(i, i + groupSize));\n  }\n  function bySize(array) {\n    if (!array.length) return [];\n    return arrayKeys(array).reduce((groups, rectB, index) => {\n      const rectA = arrayLast(groups) || 0;\n      const isFirst = rectA === 0;\n      const isLast = rectB === arrayLastIndex(array);\n      const edgeA = containerRect[startEdge] - slideRects[rectA][startEdge];\n      const edgeB = containerRect[startEdge] - slideRects[rectB][endEdge];\n      const gapA = !loop && isFirst ? direction(startGap) : 0;\n      const gapB = !loop && isLast ? direction(endGap) : 0;\n      const chunkSize = mathAbs(edgeB - gapB - (edgeA + gapA));\n      if (index && chunkSize > viewSize + pixelTolerance) groups.push(rectB);\n      if (isLast) groups.push(array.length);\n      return groups;\n    }, []).map((currentSize, index, groups) => {\n      const previousSize = Math.max(groups[index - 1] || 0);\n      return array.slice(previousSize, currentSize);\n    });\n  }\n  function groupSlides(array) {\n    return groupByNumber ? byNumber(array, slidesToScroll) : bySize(array);\n  }\n  const self = {\n    groupSlides\n  };\n  return self;\n}\n\nfunction Engine(root, container, slides, ownerDocument, ownerWindow, options, eventHandler) {\n  // Options\n  const {\n    align,\n    axis: scrollAxis,\n    direction,\n    startIndex,\n    loop,\n    duration,\n    dragFree,\n    dragThreshold,\n    inViewThreshold,\n    slidesToScroll: groupSlides,\n    skipSnaps,\n    containScroll,\n    watchResize,\n    watchSlides,\n    watchDrag,\n    watchFocus\n  } = options;\n  // Measurements\n  const pixelTolerance = 2;\n  const nodeRects = NodeRects();\n  const containerRect = nodeRects.measure(container);\n  const slideRects = slides.map(nodeRects.measure);\n  const axis = Axis(scrollAxis, direction);\n  const viewSize = axis.measureSize(containerRect);\n  const percentOfView = PercentOfView(viewSize);\n  const alignment = Alignment(align, viewSize);\n  const containSnaps = !loop && !!containScroll;\n  const readEdgeGap = loop || !!containScroll;\n  const {\n    slideSizes,\n    slideSizesWithGaps,\n    startGap,\n    endGap\n  } = SlideSizes(axis, containerRect, slideRects, slides, readEdgeGap, ownerWindow);\n  const slidesToScroll = SlidesToScroll(axis, viewSize, groupSlides, loop, containerRect, slideRects, startGap, endGap, pixelTolerance);\n  const {\n    snaps,\n    snapsAligned\n  } = ScrollSnaps(axis, alignment, containerRect, slideRects, slidesToScroll);\n  const contentSize = -arrayLast(snaps) + arrayLast(slideSizesWithGaps);\n  const {\n    snapsContained,\n    scrollContainLimit\n  } = ScrollContain(viewSize, contentSize, snapsAligned, containScroll, pixelTolerance);\n  const scrollSnaps = containSnaps ? snapsContained : snapsAligned;\n  const {\n    limit\n  } = ScrollLimit(contentSize, scrollSnaps, loop);\n  // Indexes\n  const index = Counter(arrayLastIndex(scrollSnaps), startIndex, loop);\n  const indexPrevious = index.clone();\n  const slideIndexes = arrayKeys(slides);\n  // Animation\n  const update = ({\n    dragHandler,\n    scrollBody,\n    scrollBounds,\n    options: {\n      loop\n    }\n  }) => {\n    if (!loop) scrollBounds.constrain(dragHandler.pointerDown());\n    scrollBody.seek();\n  };\n  const render = ({\n    scrollBody,\n    translate,\n    location,\n    offsetLocation,\n    previousLocation,\n    scrollLooper,\n    slideLooper,\n    dragHandler,\n    animation,\n    eventHandler,\n    scrollBounds,\n    options: {\n      loop\n    }\n  }, alpha) => {\n    const shouldSettle = scrollBody.settled();\n    const withinBounds = !scrollBounds.shouldConstrain();\n    const hasSettled = loop ? shouldSettle : shouldSettle && withinBounds;\n    const hasSettledAndIdle = hasSettled && !dragHandler.pointerDown();\n    if (hasSettledAndIdle) animation.stop();\n    const interpolatedLocation = location.get() * alpha + previousLocation.get() * (1 - alpha);\n    offsetLocation.set(interpolatedLocation);\n    if (loop) {\n      scrollLooper.loop(scrollBody.direction());\n      slideLooper.loop();\n    }\n    translate.to(offsetLocation.get());\n    if (hasSettledAndIdle) eventHandler.emit('settle');\n    if (!hasSettled) eventHandler.emit('scroll');\n  };\n  const animation = Animations(ownerDocument, ownerWindow, () => update(engine), alpha => render(engine, alpha));\n  // Shared\n  const friction = 0.68;\n  const startLocation = scrollSnaps[index.get()];\n  const location = Vector1D(startLocation);\n  const previousLocation = Vector1D(startLocation);\n  const offsetLocation = Vector1D(startLocation);\n  const target = Vector1D(startLocation);\n  const scrollBody = ScrollBody(location, offsetLocation, previousLocation, target, duration, friction);\n  const scrollTarget = ScrollTarget(loop, scrollSnaps, contentSize, limit, target);\n  const scrollTo = ScrollTo(animation, index, indexPrevious, scrollBody, scrollTarget, target, eventHandler);\n  const scrollProgress = ScrollProgress(limit);\n  const eventStore = EventStore();\n  const slidesInView = SlidesInView(container, slides, eventHandler, inViewThreshold);\n  const {\n    slideRegistry\n  } = SlideRegistry(containSnaps, containScroll, scrollSnaps, scrollContainLimit, slidesToScroll, slideIndexes);\n  const slideFocus = SlideFocus(root, slides, slideRegistry, scrollTo, scrollBody, eventStore, eventHandler, watchFocus);\n  // Engine\n  const engine = {\n    ownerDocument,\n    ownerWindow,\n    eventHandler,\n    containerRect,\n    slideRects,\n    animation,\n    axis,\n    dragHandler: DragHandler(axis, root, ownerDocument, ownerWindow, target, DragTracker(axis, ownerWindow), location, animation, scrollTo, scrollBody, scrollTarget, index, eventHandler, percentOfView, dragFree, dragThreshold, skipSnaps, friction, watchDrag),\n    eventStore,\n    percentOfView,\n    index,\n    indexPrevious,\n    limit,\n    location,\n    offsetLocation,\n    previousLocation,\n    options,\n    resizeHandler: ResizeHandler(container, eventHandler, ownerWindow, slides, axis, watchResize, nodeRects),\n    scrollBody,\n    scrollBounds: ScrollBounds(limit, offsetLocation, target, scrollBody, percentOfView),\n    scrollLooper: ScrollLooper(contentSize, limit, offsetLocation, [location, offsetLocation, previousLocation, target]),\n    scrollProgress,\n    scrollSnapList: scrollSnaps.map(scrollProgress.get),\n    scrollSnaps,\n    scrollTarget,\n    scrollTo,\n    slideLooper: SlideLooper(axis, viewSize, contentSize, slideSizes, slideSizesWithGaps, snaps, scrollSnaps, offsetLocation, slides),\n    slideFocus,\n    slidesHandler: SlidesHandler(container, eventHandler, watchSlides),\n    slidesInView,\n    slideIndexes,\n    slideRegistry,\n    slidesToScroll,\n    target,\n    translate: Translate(axis, container)\n  };\n  return engine;\n}\n\nfunction EventHandler() {\n  let listeners = {};\n  let api;\n  function init(emblaApi) {\n    api = emblaApi;\n  }\n  function getListeners(evt) {\n    return listeners[evt] || [];\n  }\n  function emit(evt) {\n    getListeners(evt).forEach(e => e(api, evt));\n    return self;\n  }\n  function on(evt, cb) {\n    listeners[evt] = getListeners(evt).concat([cb]);\n    return self;\n  }\n  function off(evt, cb) {\n    listeners[evt] = getListeners(evt).filter(e => e !== cb);\n    return self;\n  }\n  function clear() {\n    listeners = {};\n  }\n  const self = {\n    init,\n    emit,\n    off,\n    on,\n    clear\n  };\n  return self;\n}\n\nconst defaultOptions = {\n  align: 'center',\n  axis: 'x',\n  container: null,\n  slides: null,\n  containScroll: 'trimSnaps',\n  direction: 'ltr',\n  slidesToScroll: 1,\n  inViewThreshold: 0,\n  breakpoints: {},\n  dragFree: false,\n  dragThreshold: 10,\n  loop: false,\n  skipSnaps: false,\n  duration: 25,\n  startIndex: 0,\n  active: true,\n  watchDrag: true,\n  watchResize: true,\n  watchSlides: true,\n  watchFocus: true\n};\n\nfunction OptionsHandler(ownerWindow) {\n  function mergeOptions(optionsA, optionsB) {\n    return objectsMergeDeep(optionsA, optionsB || {});\n  }\n  function optionsAtMedia(options) {\n    const optionsAtMedia = options.breakpoints || {};\n    const matchedMediaOptions = objectKeys(optionsAtMedia).filter(media => ownerWindow.matchMedia(media).matches).map(media => optionsAtMedia[media]).reduce((a, mediaOption) => mergeOptions(a, mediaOption), {});\n    return mergeOptions(options, matchedMediaOptions);\n  }\n  function optionsMediaQueries(optionsList) {\n    return optionsList.map(options => objectKeys(options.breakpoints || {})).reduce((acc, mediaQueries) => acc.concat(mediaQueries), []).map(ownerWindow.matchMedia);\n  }\n  const self = {\n    mergeOptions,\n    optionsAtMedia,\n    optionsMediaQueries\n  };\n  return self;\n}\n\nfunction PluginsHandler(optionsHandler) {\n  let activePlugins = [];\n  function init(emblaApi, plugins) {\n    activePlugins = plugins.filter(({\n      options\n    }) => optionsHandler.optionsAtMedia(options).active !== false);\n    activePlugins.forEach(plugin => plugin.init(emblaApi, optionsHandler));\n    return plugins.reduce((map, plugin) => Object.assign(map, {\n      [plugin.name]: plugin\n    }), {});\n  }\n  function destroy() {\n    activePlugins = activePlugins.filter(plugin => plugin.destroy());\n  }\n  const self = {\n    init,\n    destroy\n  };\n  return self;\n}\n\nfunction EmblaCarousel(root, userOptions, userPlugins) {\n  const ownerDocument = root.ownerDocument;\n  const ownerWindow = ownerDocument.defaultView;\n  const optionsHandler = OptionsHandler(ownerWindow);\n  const pluginsHandler = PluginsHandler(optionsHandler);\n  const mediaHandlers = EventStore();\n  const eventHandler = EventHandler();\n  const {\n    mergeOptions,\n    optionsAtMedia,\n    optionsMediaQueries\n  } = optionsHandler;\n  const {\n    on,\n    off,\n    emit\n  } = eventHandler;\n  const reInit = reActivate;\n  let destroyed = false;\n  let engine;\n  let optionsBase = mergeOptions(defaultOptions, EmblaCarousel.globalOptions);\n  let options = mergeOptions(optionsBase);\n  let pluginList = [];\n  let pluginApis;\n  let container;\n  let slides;\n  function storeElements() {\n    const {\n      container: userContainer,\n      slides: userSlides\n    } = options;\n    const customContainer = isString(userContainer) ? root.querySelector(userContainer) : userContainer;\n    container = customContainer || root.children[0];\n    const customSlides = isString(userSlides) ? container.querySelectorAll(userSlides) : userSlides;\n    slides = [].slice.call(customSlides || container.children);\n  }\n  function createEngine(options) {\n    const engine = Engine(root, container, slides, ownerDocument, ownerWindow, options, eventHandler);\n    if (options.loop && !engine.slideLooper.canLoop()) {\n      const optionsWithoutLoop = Object.assign({}, options, {\n        loop: false\n      });\n      return createEngine(optionsWithoutLoop);\n    }\n    return engine;\n  }\n  function activate(withOptions, withPlugins) {\n    if (destroyed) return;\n    optionsBase = mergeOptions(optionsBase, withOptions);\n    options = optionsAtMedia(optionsBase);\n    pluginList = withPlugins || pluginList;\n    storeElements();\n    engine = createEngine(options);\n    optionsMediaQueries([optionsBase, ...pluginList.map(({\n      options\n    }) => options)]).forEach(query => mediaHandlers.add(query, 'change', reActivate));\n    if (!options.active) return;\n    engine.translate.to(engine.location.get());\n    engine.animation.init();\n    engine.slidesInView.init();\n    engine.slideFocus.init(self);\n    engine.eventHandler.init(self);\n    engine.resizeHandler.init(self);\n    engine.slidesHandler.init(self);\n    if (engine.options.loop) engine.slideLooper.loop();\n    if (container.offsetParent && slides.length) engine.dragHandler.init(self);\n    pluginApis = pluginsHandler.init(self, pluginList);\n  }\n  function reActivate(withOptions, withPlugins) {\n    const startIndex = selectedScrollSnap();\n    deActivate();\n    activate(mergeOptions({\n      startIndex\n    }, withOptions), withPlugins);\n    eventHandler.emit('reInit');\n  }\n  function deActivate() {\n    engine.dragHandler.destroy();\n    engine.eventStore.clear();\n    engine.translate.clear();\n    engine.slideLooper.clear();\n    engine.resizeHandler.destroy();\n    engine.slidesHandler.destroy();\n    engine.slidesInView.destroy();\n    engine.animation.destroy();\n    pluginsHandler.destroy();\n    mediaHandlers.clear();\n  }\n  function destroy() {\n    if (destroyed) return;\n    destroyed = true;\n    mediaHandlers.clear();\n    deActivate();\n    eventHandler.emit('destroy');\n    eventHandler.clear();\n  }\n  function scrollTo(index, jump, direction) {\n    if (!options.active || destroyed) return;\n    engine.scrollBody.useBaseFriction().useDuration(jump === true ? 0 : options.duration);\n    engine.scrollTo.index(index, direction || 0);\n  }\n  function scrollNext(jump) {\n    const next = engine.index.add(1).get();\n    scrollTo(next, jump, -1);\n  }\n  function scrollPrev(jump) {\n    const prev = engine.index.add(-1).get();\n    scrollTo(prev, jump, 1);\n  }\n  function canScrollNext() {\n    const next = engine.index.add(1).get();\n    return next !== selectedScrollSnap();\n  }\n  function canScrollPrev() {\n    const prev = engine.index.add(-1).get();\n    return prev !== selectedScrollSnap();\n  }\n  function scrollSnapList() {\n    return engine.scrollSnapList;\n  }\n  function scrollProgress() {\n    return engine.scrollProgress.get(engine.offsetLocation.get());\n  }\n  function selectedScrollSnap() {\n    return engine.index.get();\n  }\n  function previousScrollSnap() {\n    return engine.indexPrevious.get();\n  }\n  function slidesInView() {\n    return engine.slidesInView.get();\n  }\n  function slidesNotInView() {\n    return engine.slidesInView.get(false);\n  }\n  function plugins() {\n    return pluginApis;\n  }\n  function internalEngine() {\n    return engine;\n  }\n  function rootNode() {\n    return root;\n  }\n  function containerNode() {\n    return container;\n  }\n  function slideNodes() {\n    return slides;\n  }\n  const self = {\n    canScrollNext,\n    canScrollPrev,\n    containerNode,\n    internalEngine,\n    destroy,\n    off,\n    on,\n    emit,\n    plugins,\n    previousScrollSnap,\n    reInit,\n    rootNode,\n    scrollNext,\n    scrollPrev,\n    scrollProgress,\n    scrollSnapList,\n    scrollTo,\n    selectedScrollSnap,\n    slideNodes,\n    slidesInView,\n    slidesNotInView\n  };\n  activate(userOptions, userPlugins);\n  setTimeout(() => eventHandler.emit('init'), 0);\n  return self;\n}\nEmblaCarousel.globalOptions = undefined;\n\nexport { EmblaCarousel as default };\n//# sourceMappingURL=embla-carousel.esm.js.map\n","import { useRef, useState, useCallback, useEffect } from 'react';\nimport { areOptionsEqual, arePluginsEqual, canUseDOM } from 'embla-carousel-reactive-utils';\nimport EmblaCarousel from 'embla-carousel';\n\nfunction useEmblaCarousel(options = {}, plugins = []) {\n  const storedOptions = useRef(options);\n  const storedPlugins = useRef(plugins);\n  const [emblaApi, setEmblaApi] = useState();\n  const [viewport, setViewport] = useState();\n  const reInit = useCallback(() => {\n    if (emblaApi) emblaApi.reInit(storedOptions.current, storedPlugins.current);\n  }, [emblaApi]);\n  useEffect(() => {\n    if (areOptionsEqual(storedOptions.current, options)) return;\n    storedOptions.current = options;\n    reInit();\n  }, [options, reInit]);\n  useEffect(() => {\n    if (arePluginsEqual(storedPlugins.current, plugins)) return;\n    storedPlugins.current = plugins;\n    reInit();\n  }, [plugins, reInit]);\n  useEffect(() => {\n    if (canUseDOM() && viewport) {\n      EmblaCarousel.globalOptions = useEmblaCarousel.globalOptions;\n      const newEmblaApi = EmblaCarousel(viewport, storedOptions.current, storedPlugins.current);\n      setEmblaApi(newEmblaApi);\n      return () => newEmblaApi.destroy();\n    } else {\n      setEmblaApi(undefined);\n    }\n  }, [viewport, setEmblaApi]);\n  return [setViewport, emblaApi];\n}\nuseEmblaCarousel.globalOptions = undefined;\n\nexport { useEmblaCarousel as default };\n//# sourceMappingURL=embla-carousel-react.esm.js.map\n","\"use client\";\n\nimport useEmblaCarousel, { type UseEmblaCarouselType } from \"embla-carousel-react\";\nimport { ArrowLeft, ArrowRight } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\n\ntype CarouselApi = UseEmblaCarouselType[1];\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\ntype CarouselOptions = UseCarouselParameters[0];\ntype CarouselPlugin = UseCarouselParameters[1];\n\ntype CarouselProps = {\n\topts?: CarouselOptions;\n\tplugins?: CarouselPlugin;\n\torientation?: \"horizontal\" | \"vertical\";\n\tsetApi?: (api: CarouselApi) => void;\n};\n\ntype CarouselContextProps = {\n\tcarouselRef: ReturnType<typeof useEmblaCarousel>[0];\n\tapi: ReturnType<typeof useEmblaCarousel>[1];\n\tscrollPrev: () => void;\n\tscrollNext: () => void;\n\tcanScrollPrev: boolean;\n\tcanScrollNext: boolean;\n} & CarouselProps;\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null);\n\nfunction useCarousel() {\n\tconst context = React.useContext(CarouselContext);\n\n\tif (!context) {\n\t\tthrow new Error(\"useCarousel must be used within a <Carousel />\");\n\t}\n\n\treturn context;\n}\n\nfunction Carousel({\n\torientation = \"horizontal\",\n\topts,\n\tsetApi,\n\tplugins,\n\tclassName,\n\tchildren,\n\t...props\n}: React.ComponentProps<\"div\"> & CarouselProps) {\n\tconst [carouselRef, api] = useEmblaCarousel(\n\t\t{\n\t\t\t...opts,\n\t\t\taxis: orientation === \"horizontal\" ? \"x\" : \"y\",\n\t\t},\n\t\tplugins,\n\t);\n\tconst [canScrollPrev, setCanScrollPrev] = React.useState(false);\n\tconst [canScrollNext, setCanScrollNext] = React.useState(false);\n\n\tconst onSelect = React.useCallback((api: CarouselApi) => {\n\t\tif (!api) return;\n\t\tsetCanScrollPrev(api.canScrollPrev());\n\t\tsetCanScrollNext(api.canScrollNext());\n\t}, []);\n\n\tconst scrollPrev = React.useCallback(() => {\n\t\tapi?.scrollPrev();\n\t}, [api]);\n\n\tconst scrollNext = React.useCallback(() => {\n\t\tapi?.scrollNext();\n\t}, [api]);\n\n\tconst handleKeyDown = React.useCallback(\n\t\t(event: React.KeyboardEvent<HTMLDivElement>) => {\n\t\t\tif (event.key === \"ArrowLeft\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tscrollPrev();\n\t\t\t} else if (event.key === \"ArrowRight\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tscrollNext();\n\t\t\t}\n\t\t},\n\t\t[scrollPrev, scrollNext],\n\t);\n\n\tReact.useEffect(() => {\n\t\tif (!api || !setApi) return;\n\t\tsetApi(api);\n\t}, [api, setApi]);\n\n\tReact.useEffect(() => {\n\t\tif (!api) return;\n\t\tonSelect(api);\n\t\tapi.on(\"reInit\", onSelect);\n\t\tapi.on(\"select\", onSelect);\n\n\t\treturn () => {\n\t\t\tapi?.off(\"select\", onSelect);\n\t\t};\n\t}, [api, onSelect]);\n\n\treturn (\n\t\t<CarouselContext.Provider\n\t\t\tvalue={{\n\t\t\t\tcarouselRef,\n\t\t\t\tapi: api,\n\t\t\t\topts,\n\t\t\t\torientation: orientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\n\t\t\t\tscrollPrev,\n\t\t\t\tscrollNext,\n\t\t\t\tcanScrollPrev,\n\t\t\t\tcanScrollNext,\n\t\t\t}}\n\t\t>\n\t\t\t{/** biome-ignore lint/a11y/useAriaPropsSupportedByRole: <roledescription> */}\n\t\t\t<div\n\t\t\t\tonKeyDownCapture={handleKeyDown}\n\t\t\t\tclassName={cn(\"relative\", className)}\n\t\t\t\taria-roledescription=\"carousel\"\n\t\t\t\tdata-slot=\"carousel\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</CarouselContext.Provider>\n\t);\n}\n\nfunction CarouselContent({ className, ...props }: React.ComponentProps<\"div\">) {\n\tconst { carouselRef, orientation } = useCarousel();\n\n\treturn (\n\t\t<div ref={carouselRef} className=\"overflow-hidden\" data-slot=\"carousel-content\">\n\t\t\t<div\n\t\t\t\tclassName={cn(\"flex\", orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\nfunction CarouselItem({ className, ...props }: React.ComponentProps<\"div\">) {\n\tconst { orientation } = useCarousel();\n\n\treturn (\n\t\t// biome-ignore lint/a11y/useSemanticElements: <group>\n\t\t<div\n\t\t\trole=\"group\"\n\t\t\taria-roledescription=\"slide\"\n\t\t\tdata-slot=\"carousel-item\"\n\t\t\tclassName={cn(\n\t\t\t\t\"min-w-0 shrink-0 grow-0 basis-full\",\n\t\t\t\torientation === \"horizontal\" ? \"pl-4\" : \"pt-4\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction CarouselPrevious({\n\tclassName,\n\tvariant = \"outline\",\n\tsize = \"icon\",\n\t...props\n}: React.ComponentProps<typeof Button>) {\n\tconst { orientation, scrollPrev, canScrollPrev } = useCarousel();\n\n\treturn (\n\t\t<Button\n\t\t\tdata-slot=\"carousel-previous\"\n\t\t\tvariant={variant}\n\t\t\tsize={size}\n\t\t\tclassName={cn(\n\t\t\t\t\"absolute size-8 rounded-full\",\n\t\t\t\torientation === \"horizontal\"\n\t\t\t\t\t? \"top-1/2 -left-12 -translate-y-1/2\"\n\t\t\t\t\t: \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tdisabled={!canScrollPrev}\n\t\t\tonClick={scrollPrev}\n\t\t\t{...props}\n\t\t>\n\t\t\t<ArrowLeft />\n\t\t\t<span className=\"sr-only\">Previous slide</span>\n\t\t</Button>\n\t);\n}\n\nfunction CarouselNext({\n\tclassName,\n\tvariant = \"outline\",\n\tsize = \"icon\",\n\t...props\n}: React.ComponentProps<typeof Button>) {\n\tconst { orientation, scrollNext, canScrollNext } = useCarousel();\n\n\treturn (\n\t\t<Button\n\t\t\tdata-slot=\"carousel-next\"\n\t\t\tvariant={variant}\n\t\t\tsize={size}\n\t\t\tclassName={cn(\n\t\t\t\t\"absolute size-8 rounded-full\",\n\t\t\t\torientation === \"horizontal\"\n\t\t\t\t\t? \"top-1/2 -right-12 -translate-y-1/2\"\n\t\t\t\t\t: \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tdisabled={!canScrollNext}\n\t\t\tonClick={scrollNext}\n\t\t\t{...props}\n\t\t>\n\t\t\t<ArrowRight />\n\t\t\t<span className=\"sr-only\">Next slide</span>\n\t\t</Button>\n\t);\n}\n\nexport {\n\ttype CarouselApi,\n\tCarousel,\n\tCarouselContent,\n\tCarouselItem,\n\tCarouselPrevious,\n\tCarouselNext,\n};\n"],"names":["__iconNode","isObject","subject","Object","prototype","toString","call","isRecord","Array","isArray","canUseDOM","window","document","createElement","areOptionsEqual","optionsA","optionsB","optionsAKeys","keys","optionsBKeys","length","breakpointsA","JSON","stringify","breakpoints","breakpointsB","every","key","valueA","valueB","sortAndMapPluginToOptions","plugins","concat","sort","a","b","name","map","plugin","options","arePluginsEqual","pluginsA","pluginsB","optionA","index","optionB","isNumber","isString","isBoolean","mathAbs","n","Math","abs","mathSign","sign","deltaAbs","factorAbs","diff","roundToTwoDecimals","num","round","arrayKeys","array","objectKeys","Number","arrayLast","arrayLastIndex","max","arrayIsLastIndex","arrayFromNumber","startAt","from","_","i","object","objectsMergeDeep","objectA","objectB","reduce","mergedObjects","currentObject","forEach","areObjects","isMouseEvent","evt","ownerWindow","MouseEvent","useEmblaCarousel","storedOptions","useRef","storedPlugins","emblaApi","setEmblaApi","useState","viewport","setViewport","reInit","useCallback","current","useEffect","EmblaCarousel","globalOptions","newEmblaApi","destroy","undefined","CarouselContext","React","createContext","useCarousel","context","useContext","Error","Carousel","orientation","opts","setApi","className","children","props","carouselRef","api","axis","canScrollPrev","setCanScrollPrev","canScrollNext","setCanScrollNext","onSelect","scrollPrev","scrollNext","handleKeyDown","event","preventDefault","on","off","Provider","value","div","onKeyDownCapture","cn","aria-roledescription","data-slot","CarouselContent","ref","CarouselItem","role","CarouselPrevious","variant","size","Button","disabled","onClick","ArrowLeft","span","CarouselNext","ArrowRight"],"mappings":"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E,OAAOA,WAAW,CAACC,UAAU,KAAK,WAAW,IAC7CF,GAAG,YAAYC,WAAW,CAACC,UAAU;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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","x_google_ignoreList":[0,1,2,3,4]}