var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/components/layout-and-navigation/Carousel.tsx
var Carousel_exports = {};
__export(Carousel_exports, {
  Carousel: () => Carousel
});
module.exports = __toCommonJS(Carousel_exports);
var import_react = require("react");
var import_clsx2 = __toESM(require("clsx"));
var import_lucide_react = require("lucide-react");

// src/util/array.ts
var defaultRangeOptions = {
  allowEmptyRange: false,
  stepSize: 1,
  exclusiveStart: false,
  exclusiveEnd: true
};
var range = (endOrRange, options) => {
  const { allowEmptyRange, stepSize, exclusiveStart, exclusiveEnd } = { ...defaultRangeOptions, ...options };
  let start = 0;
  let end;
  if (typeof endOrRange === "number") {
    end = endOrRange;
  } else {
    start = endOrRange[0];
    end = endOrRange[1];
  }
  if (!exclusiveEnd) {
    end -= 1;
  }
  if (exclusiveStart) {
    start += 1;
  }
  if (end - 1 < start) {
    if (!allowEmptyRange) {
      console.warn(`range: end (${end}) < start (${start}) should be allowed explicitly, set options.allowEmptyRange to true`);
    }
    return [];
  }
  return Array.from({ length: end - start }, (_, index) => index * stepSize + start);
};
var createLoopingListWithIndex = (list, startIndex = 0, length = 0, forwards = true) => {
  if (length < 0) {
    console.warn(`createLoopingList: length must be >= 0, given ${length}`);
  } else if (length === 0) {
    length = list.length;
  }
  const returnList = [];
  if (forwards) {
    for (let i = startIndex; returnList.length < length; i = (i + 1) % list.length) {
      returnList.push([i, list[i]]);
    }
  } else {
    for (let i = startIndex; returnList.length < length; i = i === 0 ? i = list.length - 1 : i - 1) {
      returnList.push([i, list[i]]);
    }
  }
  return returnList;
};

// src/util/math.ts
var clamp = (value, min = 0, max = 1) => {
  return Math.min(Math.max(value, min), max);
};

// src/util/easeFunctions.ts
var EaseFunctions = class _EaseFunctions {
  static cubicBezierGeneric(x1, y1, x2, y2) {
    const cx = 3 * x1;
    const bx = 3 * (x2 - x1) - cx;
    const ax = 1 - cx - bx;
    const cy = 3 * y1;
    const by = 3 * (y2 - y1) - cy;
    const ay = 1 - cy - by;
    const x = (t) => ((ax * t + bx) * t + cx) * t;
    const y = (t) => ((ay * t + by) * t + cy) * t;
    return {
      x,
      y
    };
  }
  static cubicBezier(x1, y1, x2, y2) {
    const { y } = _EaseFunctions.cubicBezierGeneric(x1, y1, x2, y2);
    return (t) => {
      t = clamp(t);
      return y(t);
    };
  }
  static easeInEaseOut(t) {
    return _EaseFunctions.cubicBezier(0.65, 0, 0.35, 1)(t);
  }
};

// src/util/loopingArray.ts
var LoopingArrayCalculator = class _LoopingArrayCalculator {
  constructor(length, isLooping = true, allowedOverScroll = 0.1) {
    if (allowedOverScroll < 0 || length < 1) {
      throw new Error("Invalid parameters: allowedOverScroll >= 0 and length >= 1 must be true");
    }
    this.length = length;
    this.isLooping = isLooping;
    this.allowedOverScroll = allowedOverScroll;
  }
  getCorrectedPosition(position) {
    if (!this.isLooping) {
      return Math.max(-this.allowedOverScroll, Math.min(this.allowedOverScroll + this.length - 1, position));
    }
    if (position >= this.length) {
      return position % this.length;
    }
    if (position < 0) {
      return this.length - Math.abs(position) % this.length;
    }
    return position;
  }
  static withoutOffset(position) {
    return position + _LoopingArrayCalculator.getOffset(position);
  }
  static getOffset(position) {
    return Math.round(position) - position;
  }
  /**
   * @return absolute distance forwards or Infinity when the target cannot be reached (only possible when not isLooping)
   */
  getDistanceDirectional(position, target, direction) {
    if (!this.isLooping && (position < -this.allowedOverScroll || position > this.allowedOverScroll + this.length - 1)) {
      throw new Error("Invalid parameters: position is out of bounds.");
    }
    const isForwardInvalid = direction === 1 && position > target;
    const isBackwardInvalid = direction === -1 && target < position;
    if (!this.isLooping && (isForwardInvalid || isBackwardInvalid)) {
      return Infinity;
    }
    if (direction === -1) {
      return this.getDistanceDirectional(target, position, 1);
    }
    position = this.getCorrectedPosition(position);
    target = this.getCorrectedPosition(target);
    let distance = (target - position) * direction;
    if (distance < 0) {
      distance = this.length - Math.abs(position) % this.length + target;
    }
    return distance;
  }
  getDistanceForward(position, target) {
    return this.getDistanceDirectional(position, target, 1);
  }
  getDistanceBackward(position, target) {
    return this.getDistanceDirectional(position, target, -1);
  }
  getDistance(position, target) {
    const forwardDistance = this.getDistanceForward(position, target);
    const backwardDistance = this.getDistanceBackward(position, target);
    return Math.min(forwardDistance, backwardDistance);
  }
  getBestDirection(position, target) {
    const forwardDistance = this.getDistanceForward(position, target);
    const backwardDistance = this.getDistanceBackward(position, target);
    return forwardDistance < backwardDistance ? 1 : -1;
  }
};

// src/components/user-action/Button.tsx
var import_clsx = __toESM(require("clsx"));
var import_jsx_runtime = require("react/jsx-runtime");
var ButtonColorUtil = {
  solid: ["primary", "secondary", "tertiary", "positive", "warning", "negative", "neutral"],
  text: ["primary", "negative", "neutral"],
  outline: ["primary"]
};
var IconButtonUtil = {
  icon: [...ButtonColorUtil.solid, "transparent"]
};
var paddingMapping = {
  small: "btn-sm",
  medium: "btn-md",
  large: "btn-lg"
};
var iconPaddingMapping = {
  tiny: "icon-btn-xs",
  small: "icon-btn-sm",
  medium: "icon-btn-md",
  large: "icon-btn-lg"
};
var ButtonUtil = {
  paddingMapping,
  iconPaddingMapping
};
var IconButton = ({
  children,
  disabled = false,
  color = "primary",
  size = "medium",
  onClick,
  className,
  ...restProps
}) => {
  const colorClasses = {
    primary: "bg-button-solid-primary-background text-button-solid-primary-text",
    secondary: "bg-button-solid-secondary-background text-button-solid-secondary-text",
    tertiary: "bg-button-solid-tertiary-background text-button-solid-tertiary-text",
    positive: "bg-button-solid-positive-background text-button-solid-positive-text",
    warning: "bg-button-solid-warning-background text-button-solid-warning-text",
    negative: "bg-button-solid-negative-background text-button-solid-negative-text",
    neutral: "bg-button-solid-neutral-background text-button-solid-neutral-text",
    transparent: "bg-transparent"
  }[color];
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    "button",
    {
      onClick: disabled ? void 0 : onClick,
      disabled: disabled || onClick === void 0,
      className: (0, import_clsx.default)(
        {
          "text-disabled-text bg-disabled-background cursor-not-allowed": disabled && color !== "transparent",
          "text-disabled-text cursor-not-allowed opacity-70": disabled && color === "transparent",
          "hover:bg-button-text-hover-background": !disabled && color === "transparent",
          [(0, import_clsx.default)(colorClasses, "hover:brightness-90")]: !disabled
        },
        ButtonUtil.iconPaddingMapping[size],
        className
      ),
      ...restProps,
      children
    }
  );
};

// src/components/layout-and-navigation/Carousel.tsx
var import_jsx_runtime2 = require("react/jsx-runtime");
var Carousel = ({
  children,
  animationTime = 200,
  isLooping = false,
  isAutoLooping = false,
  autoLoopingTimeOut = 5e3,
  autoLoopAnimationTime = 500,
  hintNext = false,
  arrows = false,
  dots = true,
  overScrollThreshold = 0.1,
  blurColor = "from-background",
  className = "",
  heightClassName = "h-96",
  widthClassName = "w-[70%] desktop:w-1/2"
}) => {
  if (isAutoLooping && !isLooping) {
    console.error("When isAutoLooping is true, isLooping should also be true");
    isLooping = true;
  }
  const [{
    currentPosition,
    dragState,
    animationState
  }, setCarouselInformation] = (0, import_react.useState)({
    currentPosition: 0
  });
  const animationId = (0, import_react.useRef)(void 0);
  const timeOut = (0, import_react.useRef)(void 0);
  autoLoopingTimeOut = Math.max(0, autoLoopingTimeOut);
  const length = children.length;
  const paddingItemCount = 3;
  const util = (0, import_react.useMemo)(() => new LoopingArrayCalculator(length, isLooping, overScrollThreshold), [length, isLooping, overScrollThreshold]);
  const currentIndex = util.getCorrectedPosition(LoopingArrayCalculator.withoutOffset(currentPosition));
  animationTime = Math.max(200, animationTime);
  autoLoopAnimationTime = Math.max(200, autoLoopAnimationTime);
  const getStyleOffset = (index) => {
    const baseOffset = -50 + (index - currentPosition) * 100;
    return `${baseOffset}%`;
  };
  const animation = (0, import_react.useCallback)((time) => {
    let keepAnimating = true;
    setCarouselInformation((state) => {
      const {
        animationState: animationState2,
        dragState: dragState2
      } = state;
      if (animationState2 === void 0 || dragState2 !== void 0) {
        keepAnimating = false;
        return state;
      }
      if (!animationState2.startTime || !animationState2.lastUpdateTime) {
        return {
          ...state,
          animationState: {
            ...animationState2,
            startTime: time,
            lastUpdateTime: time
          }
        };
      }
      const useAnimationTime = animationState2.isAutoLooping ? autoLoopAnimationTime : animationTime;
      const progress = clamp((time - animationState2.startTime) / useAnimationTime);
      const easedProgress = EaseFunctions.easeInEaseOut(progress);
      const distance = util.getDistanceDirectional(animationState2.startPosition, animationState2.targetPosition, animationState2.direction);
      const newPosition = util.getCorrectedPosition(easedProgress * distance * animationState2.direction + animationState2.startPosition);
      if (animationState2.targetPosition === newPosition || progress === 1) {
        keepAnimating = false;
        return {
          currentPosition: LoopingArrayCalculator.withoutOffset(newPosition),
          animationState: void 0
        };
      }
      return {
        currentPosition: newPosition,
        animationState: {
          ...animationState2,
          lastUpdateTime: time
        }
      };
    });
    if (keepAnimating) {
      animationId.current = requestAnimationFrame((time1) => animation(time1));
    }
  }, [animationTime, autoLoopAnimationTime, util]);
  (0, import_react.useEffect)(() => {
    if (animationState) {
      animationId.current = requestAnimationFrame(animation);
    }
    return () => {
      if (animationId.current) {
        cancelAnimationFrame(animationId.current);
        animationId.current = 0;
      }
    };
  }, [animationState]);
  const startAutoLoop = () => setCarouselInformation((prevState) => ({
    ...prevState,
    dragState: prevState.dragState,
    animationState: prevState.animationState || prevState.dragState ? prevState.animationState : {
      startPosition: currentPosition,
      targetPosition: (currentPosition + 1) % length,
      direction: 1,
      // always move forward
      isAutoLooping: true
    }
  }));
  (0, import_react.useEffect)(() => {
    if (!animationId.current && !animationState && !dragState && !timeOut.current) {
      if (autoLoopingTimeOut > 0) {
        timeOut.current = setTimeout(() => {
          startAutoLoop();
          timeOut.current = void 0;
        }, autoLoopingTimeOut);
      } else {
        startAutoLoop();
      }
    }
  }, [animationState, dragState, animationId.current, timeOut.current]);
  const startAnimation = (targetPosition) => {
    if (targetPosition === void 0) {
      targetPosition = LoopingArrayCalculator.withoutOffset(currentPosition);
    }
    if (targetPosition === currentPosition) {
      return;
    }
    const direction = util.getBestDirection(currentPosition, targetPosition);
    clearTimeout(timeOut.current);
    timeOut.current = void 0;
    if (animationId.current) {
      cancelAnimationFrame(animationId.current);
      animationId.current = void 0;
    }
    setCarouselInformation((prevState) => ({
      ...prevState,
      dragState: void 0,
      animationState: {
        targetPosition,
        direction,
        startPosition: currentPosition,
        isAutoLooping: false
      },
      timeOut: void 0
    }));
  };
  const canGoLeft = () => {
    return isLooping || currentPosition !== 0;
  };
  const canGoRight = () => {
    return isLooping || currentPosition !== length - 1;
  };
  const left = () => {
    if (canGoLeft()) {
      startAnimation(currentPosition === 0 ? length - 1 : LoopingArrayCalculator.withoutOffset(currentPosition - 1));
    }
  };
  const right = () => {
    if (canGoRight()) {
      startAnimation(LoopingArrayCalculator.withoutOffset((currentPosition + 1) % length));
    }
  };
  let items = children.map((item, index) => ({
    index,
    item
  }));
  if (isLooping) {
    const before = createLoopingListWithIndex(children, length - 1, paddingItemCount, false).reverse().map(([index, item]) => ({
      index,
      item
    }));
    const after = createLoopingListWithIndex(children, 0, paddingItemCount).map(([index, item]) => ({
      index,
      item
    }));
    items = [
      ...before,
      ...items,
      ...after
    ];
  }
  const onDragStart = (x) => setCarouselInformation((prevState) => ({
    ...prevState,
    dragState: {
      lastX: x,
      startX: x,
      startTime: Date.now(),
      startIndex: currentPosition
    },
    animationState: void 0
    // cancel animation
  }));
  const onDrag = (x, width) => {
    if (!dragState || x === 0) {
      return;
    }
    const offsetUpdate = (dragState.lastX - x) / width;
    const newPosition = util.getCorrectedPosition(currentPosition + offsetUpdate);
    setCarouselInformation((prevState) => ({
      ...prevState,
      currentPosition: newPosition,
      dragState: {
        ...dragState,
        lastX: x
      }
    }));
  };
  const onDragEnd = (x, width) => {
    if (!dragState) {
      return;
    }
    const distance = dragState.startX - x;
    const relativeDistance = distance / width;
    const duration = Date.now() - dragState.startTime;
    const velocity = distance / (Date.now() - dragState.startTime);
    const isSlide = Math.abs(velocity) > 2 || duration < 200 && (Math.abs(relativeDistance) > 0.2 || Math.abs(distance) > 50);
    if (isSlide) {
      if (distance > 0 && canGoRight()) {
        right();
        return;
      } else if (distance < 0 && canGoLeft()) {
        left();
        return;
      }
    }
    startAnimation();
  };
  const dragHandlers = {
    draggable: true,
    onDragStart: (event) => {
      onDragStart(event.clientX);
      event.dataTransfer.setDragImage(document.createElement("div"), 0, 0);
    },
    onDrag: (event) => onDrag(event.clientX, event.target.getBoundingClientRect().width),
    onDragEnd: (event) => onDragEnd(event.clientX, event.target.getBoundingClientRect().width),
    onTouchStart: (event) => onDragStart(event.touches[0].clientX),
    onTouchMove: (event) => onDrag(event.touches[0].clientX, event.target.getBoundingClientRect().width),
    onTouchEnd: (event) => onDragEnd(event.changedTouches[0].clientX, event.target.getBoundingClientRect().width),
    onTouchCancel: (event) => onDragEnd(event.changedTouches[0].clientX, event.target.getBoundingClientRect().width)
  };
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "col items-center w-full gap-y-2", children: [
    /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: (0, import_clsx2.default)(`relative w-full overflow-hidden`, heightClassName, className), children: [
      arrows && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
        /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
          IconButton,
          {
            color: "neutral",
            className: (0, import_clsx2.default)("absolute z-10 left-0 top-1/2 -translate-y-1/2 shadow-md", { hidden: !canGoLeft() }),
            disabled: !canGoLeft(),
            onClick: () => left(),
            children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ChevronLeft, { size: 24 })
          }
        ),
        /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
          IconButton,
          {
            color: "neutral",
            className: (0, import_clsx2.default)("absolute z-10 right-0 top-1/2 -translate-y-1/2 shadow-md", { hidden: !canGoRight() }),
            disabled: !canGoRight(),
            onClick: () => right(),
            children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ChevronRight, { size: 24 })
          }
        )
      ] }),
      hintNext ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: (0, import_clsx2.default)(`relative row h-full`, heightClassName), children: [
        /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "relative row h-full w-full px-2 overflow-hidden", children: items.map(({
          item,
          index
        }, listIndex) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
          "div",
          {
            className: (0, import_clsx2.default)(`absolute left-[50%] h-full overflow-hidden`, widthClassName, { "!cursor-grabbing": !!dragState }),
            style: { translate: getStyleOffset(listIndex - (isLooping ? paddingItemCount : 0)) },
            ...dragHandlers,
            onClick: () => startAnimation(index),
            children: item
          },
          listIndex
        )) }),
        /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
          "div",
          {
            className: (0, import_clsx2.default)(`hidden pointer-events-none desktop:block absolute left-0 h-full w-[20%] bg-gradient-to-r to-transparent`, blurColor)
          }
        ),
        /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
          "div",
          {
            className: (0, import_clsx2.default)(`hidden pointer-events-none desktop:block absolute right-0 h-full w-[20%] bg-gradient-to-l to-transparent`, blurColor)
          }
        )
      ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: (0, import_clsx2.default)("px-16 h-full", { "!cursor-grabbing": !!dragState }), ...dragHandlers, children: children[currentIndex] })
    ] }),
    dots && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
      "div",
      {
        className: "row items-center justify-center w-full my-2",
        children: range(length).map((index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
          "button",
          {
            className: (0, import_clsx2.default)("w-8 min-w-8 h-3 min-h-3 first:rounded-l-md last:rounded-r-md", {
              "bg-carousel-dot-disabled hover:bg-carousel-dot-active": currentIndex !== index,
              "bg-carousel-dot-active hover:brightness-90": currentIndex === index
            }),
            onClick: () => startAnimation(index)
          },
          index
        ))
      }
    )
  ] });
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Carousel
});
//# sourceMappingURL=Carousel.js.map