"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/Cube.ts
var Cube_exports = {};
__export(Cube_exports, {
  CUBE_ATTRIBUTES: () => CUBE_ATTRIBUTES,
  default: () => Cube
});
module.exports = __toCommonJS(Cube_exports);

// ../slider/dist/esm/effects/cube-slider.js
function applyCss(el, styles) {
  Object.keys(styles).forEach((key) => el.style.setProperty(key, styles[key]));
}
var SLIDE_STYLES = ["left", "position", "top", "transform", "z-index"];
var BOX_STYLES = [
  "left",
  "overflow",
  "position",
  "top",
  "transform",
  "transform-style",
  "transition",
  "z-index"
];
var VIEWPORT_STYLES = ["overflow", "perspective", "position"];
var CubeSlider = class {
  options;
  translateZ;
  transitionTimer = 0;
  constructor(options) {
    this.options = {
      direction: options?.direction || "horizontal",
      perspective: options?.perspective || 1e3
    };
  }
  initialize(el, slides, stateStore, options) {
    const width = el.offsetWidth;
    const height = el.offsetHeight;
    const perspective = `${this.options.perspective}px`;
    const viewport = el.parentElement;
    if (viewport == null) {
      throw new Error("Unable to locate viewport element for Cube slider");
    }
    this.translateZ = this.options.direction === "vertical" ? height / 2 : width / 2;
    stateStore.storeStyles(slides, SLIDE_STYLES);
    stateStore.storeStyles(el, BOX_STYLES);
    stateStore.storeStyles(viewport, VIEWPORT_STYLES);
    slides.forEach(
      (slide) => applyCss(slide, {
        left: "0",
        position: "absolute",
        top: "0"
      })
    );
    applyCss(el, {
      left: "0",
      overflow: "visible",
      position: "absolute",
      top: "0"
    });
    if (["absolute", "fixed", "relative"].indexOf(
      getComputedStyle(viewport).position
    ) === -1) {
      applyCss(viewport, { position: "relative" });
    }
    applyCss(viewport, {
      overflow: "visible",
      perspective
    });
    applyCss(slides[options.startIndex || 0], {
      transform: `${this.rotation(0)} translate3d(0, 0, ${this.translateZ}px)`
    });
    applyCss(el, {
      "transform-style": "preserve-3d",
      transform: `translate3d(0, 0, -${this.translateZ}px)`
    });
    this.transitionTimer = window.setTimeout(
      () => applyCss(el, {
        transition: `transform ${options.speed}ms`
      }),
      50
    );
  }
  transition(settings) {
    return new Promise((resolve) => {
      const angle = settings.isPrevious ? 90 : -90;
      applyCss(settings.slides[settings.nextIndex], {
        transform: `${this.rotation(-angle)} translate3d(0, 0, ${this.translateZ}px)`,
        "z-index": "2"
      });
      applyCss(settings.el, {
        transition: `transform ${settings.speed}ms`,
        transform: `translate3d(0, 0, -${this.translateZ}px) ${this.rotation(
          angle
        )}`
      });
      this.transitionTimer = window.setTimeout(() => {
        settings.slides.forEach((s, index) => {
          if (index !== settings.nextIndex) {
            applyCss(s, { transform: "initial" });
          }
        });
        applyCss(settings.el, {
          transition: "initial",
          transform: `translate3d(0, 0, -${this.translateZ}px) ${this.rotation(
            0
          )}`
        });
        applyCss(settings.slides[settings.nextIndex], {
          transform: `${this.rotation(0)} translate3d(0, 0, ${this.translateZ}px)`,
          "z-index": "1"
        });
        resolve();
      }, settings.speed);
    });
  }
  destroy() {
    window.clearTimeout(this.transitionTimer);
  }
  rotation(angle) {
    return `rotate3d(${this.options.direction === "vertical" ? "1, 0, 0" : "0, 1, 0"}, ${angle}deg)`;
  }
};

// ../slider/dist/esm/box-slider.js
var StateStore = class {
  elementStore;
  constructor() {
    this.elementStore = [];
  }
  storeStyles(elements, styles) {
    this.applyToElements(elements, (el, elementStore) => {
      const computedStyles = getComputedStyle(el);
      styles.forEach(
        (p) => elementStore.styles[p] = computedStyles.getPropertyValue(p)
      );
    });
  }
  storeAttributes(elements, attributes) {
    this.applyToElements(elements, (el, elementStore) => {
      attributes.forEach(
        (attribute) => elementStore.attributes[attribute] = el.getAttribute(attribute)
      );
    });
  }
  revert() {
    this.elementStore.forEach((elementStore) => {
      Object.keys(elementStore.styles).forEach(
        (property) => elementStore.el.style.setProperty(
          property,
          elementStore.styles[property]
        )
      );
      Object.keys(elementStore.attributes).forEach((attribute) => {
        const cachedValue = elementStore.attributes[attribute];
        if (attribute === null || attribute === "") {
          elementStore.el.removeAttribute(attribute);
        } else if (cachedValue !== null) {
          elementStore.el.setAttribute(attribute, cachedValue);
        }
      });
    });
    this.elementStore = [];
  }
  applyToElements(elements, fn) {
    ;
    (Array.isArray(elements) ? elements : [elements]).forEach((el) => {
      let elementStore = this.elementStore.find((s) => s.el === el);
      if (!elementStore) {
        elementStore = { el, styles: {}, attributes: {} };
        this.elementStore.push(elementStore);
      }
      fn(el, elementStore);
    });
  }
};
var boxSliders = [];
var resizeObserver;
if (typeof ResizeObserver !== "undefined") {
  resizeObserver = new ResizeObserver((sliderElements) => {
    sliderElements.forEach(
      (sliderEl) => boxSliders.find((bs) => bs.el === sliderEl.target)?.reset()
    );
  });
}
var responder = {
  add(boxSlider) {
    boxSliders.push(boxSlider);
    resizeObserver?.observe(boxSlider.el);
  },
  remove(boxSlider) {
    resizeObserver?.unobserve(boxSlider.el);
    boxSliders = boxSliders.filter((b) => b !== boxSlider);
  }
};
var createQueue = () => {
  const queue = [];
  const run = () => {
    const fn = queue[0];
    if (fn) {
      fn().then(() => {
        queue.shift();
        run();
      });
    }
  };
  return {
    push(fn) {
      queue.push(fn);
      if (queue.length === 1) {
        run();
      }
    },
    clear() {
      queue.length = 0;
    }
  };
};
var defaultOptions = Object.freeze({
  autoScroll: true,
  pauseOnHover: false,
  speed: 800,
  startIndex: 0,
  swipe: true,
  swipeTolerance: 30,
  timeout: 5e3
});
var BoxSlider = class {
  _activeIndex;
  _el;
  _effect;
  _stateStore;
  options;
  slides;
  autoScrollTimer;
  eventListeners;
  elListeners;
  isDestroyed;
  transitionQueue;
  get activeIndex() {
    return this._activeIndex;
  }
  get el() {
    if (this._el === void 0) {
      throw new Error("Slider element is undefined");
    }
    return this._el;
  }
  get length() {
    return this.slides.length;
  }
  getOption(key) {
    return this.options[key];
  }
  get stateStore() {
    if (this._stateStore === void 0) {
      throw new Error(
        "State store is undefined, are you trying to interact with a destroyed slider?"
      );
    }
    return this._stateStore;
  }
  get effect() {
    if (this._effect === void 0) {
      throw new Error(
        "Slide effect is undefined, are you trying to interact with a destroyed slider?"
      );
    }
    return this._effect;
  }
  constructor(el, effect, options) {
    this._el = el;
    this._stateStore = new StateStore();
    this.transitionQueue = createQueue();
    this.slides = [];
    this.eventListeners = {};
    this.elListeners = {};
    this.isDestroyed = false;
    this.options = {
      autoScroll: true,
      speed: 800,
      timeout: 5e3,
      pauseOnHover: false,
      startIndex: 0,
      swipe: true,
      swipeTolerance: 30,
      ...options
    };
    this._activeIndex = this.options.startIndex;
    this.init(effect);
    if (this.slides.length < this.activeIndex) {
      this.destroy();
      throw new Error(
        `Start index option is out of bounds - slides=${this.slides.length} start=${this.activeIndex}`
      );
    }
    this.applyEventListeners();
    responder.add(this);
  }
  reset(options, effect) {
    this.stopAutoScroll();
    this.effect.destroy && this.effect.destroy(this.el);
    this.stateStore.revert();
    this.options = {
      ...this.options,
      ...options
    };
    if (options?.startIndex !== void 0 && !isNaN(options.startIndex)) {
      this._activeIndex = options.startIndex;
    }
    this.init(effect || this.effect);
  }
  next() {
    return this.skipTo(
      this.activeIndex === this.slides.length - 1 ? 0 : this.activeIndex + 1,
      false
    );
  }
  prev() {
    return this.skipTo(
      this.activeIndex === 0 ? this.slides.length - 1 : this.activeIndex - 1
    );
  }
  skipTo(nextIndex, backwards) {
    return new Promise((resolve) => {
      this.transitionQueue.push(async () => {
        await this.transitionTo(
          nextIndex,
          backwards === void 0 ? nextIndex < this.activeIndex : backwards
        );
        resolve();
      });
    });
  }
  pause() {
    this.options.autoScroll = false;
    if (this.autoScrollTimer) {
      this.stopAutoScroll();
      this.emit("pause");
    }
    return this;
  }
  play() {
    this.options.autoScroll = true;
    this.setAutoScroll();
    this.emit("play");
    return this;
  }
  addEventListener(ev, callback) {
    if (!Array.isArray(this.eventListeners[ev])) {
      this.eventListeners[ev] = [];
    }
    this.eventListeners[ev].push(callback);
    return this;
  }
  removeEventListener(ev, callback) {
    const listeners = this.eventListeners[ev]?.filter(
      (cb) => cb !== callback
    );
    this.eventListeners[ev] = listeners;
    return this;
  }
  destroy() {
    this.isDestroyed = true;
    this.stopAutoScroll();
    if (this.effect.destroy) {
      this.effect.destroy(this.el);
    }
    this.stateStore.revert();
    this.transitionQueue.clear();
    responder.remove(this);
    this.emit("destroy");
    this.eventListeners = {};
    Object.keys(this.elListeners).forEach(
      (ev) => this.elListeners[ev].forEach(
        (listener) => this.el.removeEventListener(ev, listener)
      )
    );
    this.elListeners = {};
    delete this._el;
    delete this._stateStore;
    delete this._effect;
    this.slides.length = 0;
  }
  init(effect) {
    this._effect = effect;
    this.slides = this.getSlides();
    this.effect.initialize(this.el, this.slides, this.stateStore, {
      ...this.options,
      startIndex: this.activeIndex
    });
    this.addAriaAttributes();
    if (this.options.autoScroll) {
      this.setAutoScroll();
    }
  }
  addAriaAttributes() {
    this.stateStore.storeAttributes(this.el, ["aria-live"]);
    this.el.setAttribute("aria-live", "polite");
    this.stateStore.storeAttributes(this.slides, ["aria-roledescription"]);
    this.slides.forEach(
      (slide) => slide.setAttribute("aria-roledescription", "slide")
    );
  }
  getSlides() {
    return Array.from(this.el.children).filter(
      (child) => child instanceof HTMLElement
    );
  }
  transitionTo(nextIndex, backwards) {
    return new Promise((resolve, reject) => {
      if (this.isDestroyed || nextIndex === this.activeIndex) {
        return resolve();
      }
      if (nextIndex < 0 || nextIndex >= this.slides.length) {
        return reject(new Error(`${nextIndex} is not a valid slide index`));
      }
      this.stopAutoScroll();
      const settings = {
        el: this.el,
        slides: this.slides,
        speed: this.options.speed,
        currentIndex: this.activeIndex,
        isPrevious: backwards,
        nextIndex
      };
      this._activeIndex = nextIndex;
      this.emit("before", {
        currentIndex: settings.currentIndex,
        nextIndex: settings.nextIndex,
        speed: settings.speed
      });
      this.effect.transition(settings).then(() => {
        if (this.options.autoScroll) {
          this.setAutoScroll();
        }
        this.emit("after");
        resolve();
      });
    });
  }
  stopAutoScroll() {
    window.clearTimeout(this.autoScrollTimer);
  }
  emit(ev, payload) {
    const handlers = this.eventListeners[ev];
    if (ev === "destroy") {
      const destroyHandlers = handlers;
      destroyHandlers?.forEach((cb) => cb());
    } else {
      handlers?.forEach(
        (cb) => cb({
          currentIndex: this.activeIndex,
          speed: this.options.speed,
          ...payload
        })
      );
    }
  }
  setAutoScroll() {
    this.stopAutoScroll();
    window.requestAnimationFrame(() => {
      if (!this._el) {
        return;
      }
      this.el.setAttribute("aria-live", "off");
      this.autoScrollTimer = window.setTimeout(
        () => this.next(),
        this.options.timeout
      );
    });
  }
  addElListener(ev, handler) {
    this.el.addEventListener(ev, handler);
    this.elListeners[ev] = this.elListeners[ev] || [];
    this.elListeners[ev].push(handler);
  }
  applyEventListeners() {
    this.addElListener("pointerenter", () => {
      if (this.options.autoScroll && this.options.pauseOnHover) {
        this.pause();
      }
    });
    this.addElListener("pointerleave", () => {
      if (this.options.autoScroll && this.options.pauseOnHover) {
        this.play();
      }
    });
    if (this.options.swipe) {
      this.addSwipeNavigation();
    }
  }
  addSwipeNavigation() {
    let pointerTraceX = 0;
    this.addElListener("pointerdown", (ev) => {
      pointerTraceX = ev.clientX;
    });
    this.addElListener("pointerup", (ev) => {
      const distanceX = ev.clientX - pointerTraceX;
      if (Math.abs(distanceX) >= this.options.swipeTolerance) {
        if (distanceX > 0) {
          this.prev();
        } else {
          this.next();
        }
        ev.stopPropagation();
      }
    });
  }
};

// src/Slider.ts
function camelize(str) {
  return str.replace(/-./g, (m) => m[1].toUpperCase());
}
function getNumericAttribute(el, attribute, defaultValue) {
  const attributeValue = el.getAttribute(attribute);
  let value = NaN;
  if (attributeValue !== null) {
    value = parseInt(attributeValue, 10);
  }
  return isNaN(value) ? defaultValue : value;
}
function getBbooleanAttribute(el, attribute, defaultValue) {
  if (el.hasAttribute(attribute)) {
    return el.getAttribute(attribute) !== "false";
  }
  return defaultValue;
}
var BOOLEAN_ATTRIBUTES = ["auto-scroll", "pause-on-hover"];
var NUMBER_ATTRIBUTES = [
  "speed",
  "timeout",
  "start-index",
  "swipe",
  "swipe-tolerance"
];
var SLIDER_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...NUMBER_ATTRIBUTES];
var Slider = class extends HTMLElement {
  #slider;
  get slider() {
    return this.#slider;
  }
  get autoScroll() {
    return getBbooleanAttribute(this, "auto-scroll", defaultOptions.autoScroll);
  }
  get pauseOnHover() {
    return getBbooleanAttribute(
      this,
      "pause-on-hover",
      defaultOptions.pauseOnHover
    );
  }
  get speed() {
    return getNumericAttribute(this, "speed", defaultOptions.speed);
  }
  get startIndex() {
    return getNumericAttribute(this, "start-index", defaultOptions.startIndex);
  }
  get swipe() {
    return getBbooleanAttribute(this, "swipe", defaultOptions.swipe);
  }
  get swipeTolerance() {
    return getNumericAttribute(
      this,
      "swipe-tolerance",
      defaultOptions.swipeTolerance
    );
  }
  get timeout() {
    return getNumericAttribute(this, "timeout", defaultOptions.timeout);
  }
  get options() {
    return {
      autoScroll: this.autoScroll,
      pauseOnHover: this.pauseOnHover,
      speed: this.speed,
      startIndex: this.startIndex,
      swipe: this.swipe,
      swipeTolerance: this.swipeTolerance,
      timeout: this.timeout
    };
  }
  init(effect) {
    const slider = new BoxSlider(this, effect, this.options);
    const events = [
      "play",
      "pause",
      "before",
      "after",
      "destroy"
    ];
    events.forEach(
      (ev) => slider.addEventListener(
        ev,
        (detail) => this.dispatchEvent(new CustomEvent(ev, { detail }))
      )
    );
    this.#slider = slider;
  }
  reset(options, effect) {
    this.slider?.reset(options, effect);
  }
  attributeChangedCallback(name) {
    if (SLIDER_ATTRIBUTES.includes(name)) {
      const propName = camelize(name);
      this.reset({ [propName]: this[propName] });
    }
  }
  disconnectedCallback() {
    this.slider?.destroy();
    this.#slider = void 0;
  }
};

// src/Cube.ts
var CUBE_ATTRIBUTES = ["direction", "perspective"];
var Cube = class extends Slider {
  static observedAttributes = [...SLIDER_ATTRIBUTES, ...CUBE_ATTRIBUTES];
  get direction() {
    const propDirection = this.getAttribute("direction")?.trim();
    if (propDirection === "horizontal" || propDirection === "vertical") {
      return propDirection;
    }
    return "horizontal";
  }
  get perspective() {
    return getNumericAttribute(this, "perspective", 1e3);
  }
  attributeChangedCallback(name) {
    if (CUBE_ATTRIBUTES.includes(name)) {
      const propName = camelize(name);
      this.reset(
        { [propName]: this[propName] },
        new CubeSlider({
          direction: this.direction,
          perspective: this.perspective
        })
      );
    } else {
      super.attributeChangedCallback(name);
    }
  }
  connectedCallback() {
    this.init(
      new CubeSlider({
        direction: this.direction,
        perspective: this.perspective
      })
    );
  }
};
if (typeof customElements !== "undefined") {
  customElements.define("bs-cube", Cube);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  CUBE_ATTRIBUTES
});
