UNPKG

qb-flip-book

Version:
2,141 lines 73.4 kB
var L = Object.defineProperty;
var W = (a, e, t) => e in a ? L(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
var r = (a, e, t) => (W(a, typeof e != "symbol" ? e + "" : e, t), t);
var u = /* @__PURE__ */ ((a) => (a[a.LEFT = 0] = "LEFT", a[a.RIGHT = 1] = "RIGHT", a))(u || {}), w = /* @__PURE__ */ ((a) => (a.SOFT = "soft", a.HARD = "hard", a))(w || {});
class v {
  constructor(e, t) {
    /** State of the page on the basis of which rendering */
    r(this, "state");
    /** Render object */
    r(this, "render");
    /** Page Orientation */
    r(this, "orientation");
    /** Density at creation */
    r(this, "createdDensity");
    /** Density at the time of rendering (Depends on neighboring pages) */
    r(this, "nowDrawingDensity");
    this.state = {
      angle: 0,
      area: [],
      position: { x: 0, y: 0 },
      hardAngle: 0,
      hardDrawingAngle: 0
    }, this.createdDensity = t, this.nowDrawingDensity = this.createdDensity, this.render = e;
  }
  /**
   * Set a constant page density
   *
   * @param {PageDensity} density
   */
  setDensity(e) {
    this.createdDensity = e, this.nowDrawingDensity = e;
  }
  /**
   * Set temp page density to next render
   *
   * @param {PageDensity}  density
   */
  setDrawingDensity(e) {
    this.nowDrawingDensity = e;
  }
  /**
   * Set page position
   *
   * @param {Point} pagePos
   */
  setPosition(e) {
    this.state.position = e;
  }
  /**
   * Set page angle
   *
   * @param {number} angle
   */
  setAngle(e) {
    this.state.angle = e;
  }
  /**
   * Set page crop area
   *
   * @param {Point[]} area
   */
  setArea(e) {
    this.state.area = e;
  }
  /**
   * Rotate angle for hard pages to next render
   *
   * @param {number} angle
   */
  setHardDrawingAngle(e) {
    this.state.hardDrawingAngle = e;
  }
  /**
   * Rotate angle for hard pages
   *
   * @param {number} angle
   */
  setHardAngle(e) {
    this.state.hardAngle = e, this.state.hardDrawingAngle = e;
  }
  /**
   * Set page orientation
   *
   * @param {PageOrientation} orientation
   */
  setOrientation(e) {
    this.orientation = e;
  }
  /**
   * Get temp page density
   */
  getDrawingDensity() {
    return this.nowDrawingDensity;
  }
  /**
   * Get a constant page density
   */
  getDensity() {
    return this.createdDensity;
  }
  /**
   * Get rotate angle for hard pages
   */
  getHardAngle() {
    return this.state.hardAngle;
  }
}
class M extends v {
  constructor(t, i, s) {
    super(t, s);
    r(this, "image", null);
    r(this, "isLoad", !1);
    r(this, "loadingAngle", 0);
    this.image = new Image(), this.image.src = i;
  }
  draw(t) {
    console.log("%c tempDensity: ", "background-color: pink", t);
    const i = this.render.getContext(), s = this.render.convertToGlobal(this.state.position), n = this.render.getRect().pageWidth, h = this.render.getRect().height;
    i.save(), i.translate(s.x, s.y), i.beginPath();
    for (let o of this.state.area)
      o !== null && (o = this.render.convertToGlobal(o), i.lineTo(o.x - s.x, o.y - s.y));
    i.rotate(this.state.angle), i.clip(), this.isLoad ? i.drawImage(this.image, 0, 0, n, h) : this.drawLoader(i, { x: 0, y: 0 }, n, h), i.restore();
  }
  simpleDraw(t) {
    const i = this.render.getRect(), s = this.render.getContext(), n = i.pageWidth, h = i.height, o = t === u.RIGHT ? i.left + i.pageWidth : i.left, g = i.top;
    this.isLoad ? s.drawImage(this.image, o, g, n, h) : this.drawLoader(s, { x: o, y: g }, n, h);
  }
  drawLoader(t, i, s, n) {
    t.beginPath(), t.strokeStyle = "rgb(200, 200, 200)", t.fillStyle = "rgb(255, 255, 255)", t.lineWidth = 1, t.rect(i.x + 1, i.y + 1, s - 1, n - 1), t.stroke(), t.fill();
    const h = {
      x: i.x + s / 2,
      y: i.y + n / 2
    };
    t.beginPath(), t.lineWidth = 10, t.arc(
      h.x,
      h.y,
      20,
      this.loadingAngle,
      3 * Math.PI / 2 + this.loadingAngle
    ), t.stroke(), t.closePath(), this.loadingAngle += 0.07, this.loadingAngle >= 2 * Math.PI && (this.loadingAngle = 0);
  }
  load() {
    this.isLoad || (this.image.onload = () => {
      this.isLoad = !0;
    });
  }
  newTemporaryCopy() {
    return this;
  }
  getTemporaryCopy() {
    return this;
  }
  hideTemporaryCopy() {
  }
}
class d {
  /**
   * Get the distance between two points
   *
   * @param {Point} point1
   * @param {Point} point2
   */
  static GetDistanceBetweenTwoPoint(e, t) {
    return e === null || t === null ? 1 / 0 : Math.sqrt(
      Math.pow(t.x - e.x, 2) + Math.pow(t.y - e.y, 2)
    );
  }
  /**
   * Get the length of the line segment
   *
   * @param {Segment} segment
   */
  static GetSegmentLength(e) {
    return d.GetDistanceBetweenTwoPoint(e[0], e[1]);
  }
  /**
   * Get the angle between two lines
   *
   * @param {Segment} line1
   * @param {Segment} line2
   */
  static GetAngleBetweenTwoLine(e, t) {
    const i = e[0].y - e[1].y, s = t[0].y - t[1].y, n = e[1].x - e[0].x, h = t[1].x - t[0].x;
    return Math.acos(
      (i * s + n * h) / (Math.sqrt(i * i + n * n) * Math.sqrt(s * s + h * h))
    );
  }
  /**
   * Check for a point in a rectangle
   *
   * @param {Rect} rect
   * @param {Point} pos
   *
   * @returns {Point} If the point enters the rectangle its coordinates will be returned, otherwise - null
   */
  static PointInRect(e, t) {
    return t === null ? null : t.x >= e.left && t.x <= e.width + e.left && t.y >= e.top && t.y <= e.top + e.height ? t : null;
  }
  /**
   * Transform point coordinates to a given angle
   *
   * @param {Point} transformedPoint - Point to rotate
   * @param {Point} startPoint - Transformation reference point
   * @param {number} angle - Rotation angle (in radians)
   *
   * @returns {Point} Point coordinates after rotation
   */
  static GetRotatedPoint(e, t, i) {
    return {
      x: e.x * Math.cos(i) + e.y * Math.sin(i) + t.x,
      y: e.y * Math.cos(i) - e.x * Math.sin(i) + t.y
    };
  }
  /**
   * Limit a point "linePoint" to a given circle centered at point "startPoint" and a given radius
   *
   * @param {Point} startPoint - Circle center
   * @param {number} radius - Circle radius
   * @param {Point} limitedPoint - Сhecked point
   *
   * @returns {Point} If "linePoint" enters the circle, then its coordinates are returned.
   * Else will be returned the intersection point between the line ([startPoint, linePoint]) and the circle
   */
  static LimitPointToCircle(e, t, i) {
    if (d.GetDistanceBetweenTwoPoint(e, i) <= t)
      return i;
    const s = e.x, n = e.y, h = i.x, o = i.y;
    let g = Math.sqrt(
      Math.pow(t, 2) * Math.pow(s - h, 2) / (Math.pow(s - h, 2) + Math.pow(n - o, 2))
    ) + s;
    i.x < 0 && (g *= -1);
    let c = (g - s) * (n - o) / (s - h) + n;
    return s - h + n === 0 && (c = t), { x: g, y: c };
  }
  /**
   * Find the intersection of two lines bounded by a rectangle "rectBorder"
   *
   * @param {Rect} rectBorder
   * @param {Segment} one
   * @param {Segment} two
   *
   * @returns {Point} The intersection point, or "null" if it does not exist, or it lies outside the rectangle "rectBorder"
   */
  static GetIntersectBetweenTwoSegment(e, t, i) {
    return d.PointInRect(
      e,
      d.GetIntersectBeetwenTwoLine(t, i)
    );
  }
  /**
   * Find the intersection point of two lines
   *
   * @param one
   * @param two
   *
   * @returns {Point} The intersection point, or "null" if it does not exist
   * @throws Error if the segments are on the same line
   */
  static GetIntersectBeetwenTwoLine(e, t) {
    const i = e[0].y - e[1].y, s = t[0].y - t[1].y, n = e[1].x - e[0].x, h = t[1].x - t[0].x, o = e[0].x * e[1].y - e[1].x * e[0].y, g = t[0].x * t[1].y - t[1].x * t[0].y, c = i * g - s * o, x = n * g - h * o, f = -((o * h - g * n) / (i * h - s * n)), y = -((i * g - s * o) / (i * h - s * n));
    if (isFinite(f) && isFinite(y))
      return { x: f, y };
    if (Math.abs(c - x) < 0.1)
      throw new Error("Segment included");
    return null;
  }
  /**
   * Get a list of coordinates (step: 1px) between two points
   *
   * @param pointOne
   * @param pointTwo
   *
   * @returns {Point[]}
   */
  static GetCordsFromTwoPoint(e, t) {
    const i = Math.abs(e.x - t.x), s = Math.abs(e.y - t.y), n = Math.max(i, s), h = [e];
    function o(g, c, x, f, y) {
      return c > g ? g + y * (x / f) : c < g ? g - y * (x / f) : g;
    }
    for (let g = 1; g <= n; g += 1)
      h.push({
        x: o(e.x, t.x, i, n, g),
        y: o(e.y, t.y, s, n, g)
      });
    return h;
  }
}
class O {
  /**
   * @constructor
   *
   * @param {FlipDirection} direction - Flipping direction
   * @param {FlipCorner} corner - Flipping corner
   * @param pageWidth - Current page width
   * @param pageHeight - Current page height
   */
  constructor(e, t, i, s) {
    /** Calculated rotation angle to flipping page */
    r(this, "angle");
    /** Calculated position to flipping page */
    r(this, "position");
    r(this, "rect");
    /** The point of intersection of the page with the borders of the book */
    r(this, "topIntersectPoint", null);
    // With top border
    r(this, "sideIntersectPoint", null);
    // With side border
    r(this, "bottomIntersectPoint", null);
    // With bottom border
    r(this, "pageWidth");
    r(this, "pageHeight");
    this.direction = e, this.corner = t, this.pageWidth = parseInt(i, 10), this.pageHeight = parseInt(s, 10);
  }
  /**
   * The main calculation method
   *
   * @param {Point} localPos - Touch Point Coordinates (relative active page!)
   *
   * @returns {boolean} True - if the calculations were successful, false if errors occurred
   */
  calc(e) {
    try {
      return this.position = this.calcAngleAndPosition(e), this.calculateIntersectPoint(this.position), !0;
    } catch {
      return !1;
    }
  }
  /**
   * Get the crop area for the flipping page
   *
   * @returns {Point[]} Polygon page
   */
  getFlippingClipArea() {
    const e = [];
    let t = !1;
    return e.push(this.rect.topLeft), e.push(this.topIntersectPoint), this.sideIntersectPoint === null ? t = !0 : (e.push(this.sideIntersectPoint), this.bottomIntersectPoint === null && (t = !1)), e.push(this.bottomIntersectPoint), (t || this.corner === p.BOTTOM) && e.push(this.rect.bottomLeft), e;
  }
  /**
   * Get the crop area for the page that is below the page to be flipped
   *
   * @returns {Point[]} Polygon page
   */
  getBottomClipArea() {
    const e = [];
    return e.push(this.topIntersectPoint), this.corner === p.TOP ? e.push({ x: this.pageWidth, y: 0 }) : (this.topIntersectPoint !== null && e.push({ x: this.pageWidth, y: 0 }), e.push({ x: this.pageWidth, y: this.pageHeight })), this.sideIntersectPoint !== null ? d.GetDistanceBetweenTwoPoint(
      this.sideIntersectPoint,
      this.topIntersectPoint
    ) >= 10 && e.push(this.sideIntersectPoint) : this.corner === p.TOP && e.push({ x: this.pageWidth, y: this.pageHeight }), e.push(this.bottomIntersectPoint), e.push(this.topIntersectPoint), e;
  }
  /**
   * Get page rotation angle
   */
  getAngle() {
    return this.direction === l.FORWARD ? -this.angle : this.angle;
  }
  /**
   * Get page area while flipping
   */
  getRect() {
    return this.rect;
  }
  /**
   * Get the position of the active angle when turning
   */
  getPosition() {
    return this.position;
  }
  /**
   * Get the active corner of the page (which pull)
   */
  getActiveCorner() {
    return this.direction === l.FORWARD ? this.rect.topLeft : this.rect.topRight;
  }
  /**
   * Get flipping direction
   */
  getDirection() {
    return this.direction;
  }
  /**
   * Get flipping progress (0-100)
   */
  getFlippingProgress() {
    return Math.abs(
      (this.position.x - this.pageWidth) / (2 * this.pageWidth) * 100
    );
  }
  /**
   * Get flipping corner position (top, bottom)
   */
  getCorner() {
    return this.corner;
  }
  /**
   * Get start position for the page that is below the page to be flipped
   */
  getBottomPagePosition() {
    return this.direction === l.BACK ? { x: this.pageWidth, y: 0 } : { x: 0, y: 0 };
  }
  /**
   * Get the starting position of the shadow
   */
  getShadowStartPoint() {
    return this.corner === p.TOP ? this.topIntersectPoint : this.sideIntersectPoint !== null ? this.sideIntersectPoint : this.topIntersectPoint;
  }
  /**
   * Get the rotate angle of the shadow
   */
  getShadowAngle() {
    const e = d.GetAngleBetweenTwoLine(this.getSegmentToShadowLine(), [
      { x: 0, y: 0 },
      { x: this.pageWidth, y: 0 }
    ]);
    return this.direction === l.FORWARD ? e : Math.PI - e;
  }
  calcAngleAndPosition(e) {
    let t = e;
    if (this.updateAngleAndGeometry(t), this.corner === p.TOP ? t = this.checkPositionAtCenterLine(
      t,
      { x: 0, y: 0 },
      { x: 0, y: this.pageHeight }
    ) : t = this.checkPositionAtCenterLine(
      t,
      { x: 0, y: this.pageHeight },
      { x: 0, y: 0 }
    ), Math.abs(t.x - this.pageWidth) < 1 && Math.abs(t.y) < 1)
      throw new Error("Point is too small");
    return t;
  }
  updateAngleAndGeometry(e) {
    this.angle = this.calculateAngle(e), this.rect = this.getPageRect(e);
  }
  calculateAngle(e) {
    const t = this.pageWidth - e.x + 1, i = this.corner === p.BOTTOM ? this.pageHeight - e.y : e.y;
    let s = 2 * Math.acos(t / Math.sqrt(i * i + t * t));
    i < 0 && (s = -s);
    const n = Math.PI - s;
    if (!isFinite(s) || n >= 0 && n < 3e-3)
      throw new Error("The G point is too small");
    return this.corner === p.BOTTOM && (s = -s), s;
  }
  getPageRect(e) {
    return this.corner === p.TOP ? this.getRectFromBasePoint(
      [
        { x: 0, y: 0 },
        { x: this.pageWidth, y: 0 },
        { x: 0, y: this.pageHeight },
        { x: this.pageWidth, y: this.pageHeight }
      ],
      e
    ) : this.getRectFromBasePoint(
      [
        { x: 0, y: -this.pageHeight },
        { x: this.pageWidth, y: -this.pageHeight },
        { x: 0, y: 0 },
        { x: this.pageWidth, y: 0 }
      ],
      e
    );
  }
  getRectFromBasePoint(e, t) {
    return {
      topLeft: this.getRotatedPoint(e[0], t),
      topRight: this.getRotatedPoint(e[1], t),
      bottomLeft: this.getRotatedPoint(e[2], t),
      bottomRight: this.getRotatedPoint(e[3], t)
    };
  }
  getRotatedPoint(e, t) {
    return {
      x: e.x * Math.cos(this.angle) + e.y * Math.sin(this.angle) + t.x,
      y: e.y * Math.cos(this.angle) - e.x * Math.sin(this.angle) + t.y
    };
  }
  calculateIntersectPoint(e) {
    const t = {
      left: -1,
      top: -1,
      width: this.pageWidth + 2,
      height: this.pageHeight + 2
    };
    this.corner === p.TOP ? (this.topIntersectPoint = d.GetIntersectBetweenTwoSegment(
      t,
      [e, this.rect.topRight],
      [
        { x: 0, y: 0 },
        { x: this.pageWidth, y: 0 }
      ]
    ), this.sideIntersectPoint = d.GetIntersectBetweenTwoSegment(
      t,
      [e, this.rect.bottomLeft],
      [
        { x: this.pageWidth, y: 0 },
        { x: this.pageWidth, y: this.pageHeight }
      ]
    ), this.bottomIntersectPoint = d.GetIntersectBetweenTwoSegment(
      t,
      [this.rect.bottomLeft, this.rect.bottomRight],
      [
        { x: 0, y: this.pageHeight },
        { x: this.pageWidth, y: this.pageHeight }
      ]
    )) : (this.topIntersectPoint = d.GetIntersectBetweenTwoSegment(
      t,
      [this.rect.topLeft, this.rect.topRight],
      [
        { x: 0, y: 0 },
        { x: this.pageWidth, y: 0 }
      ]
    ), this.sideIntersectPoint = d.GetIntersectBetweenTwoSegment(
      t,
      [e, this.rect.topLeft],
      [
        { x: this.pageWidth, y: 0 },
        { x: this.pageWidth, y: this.pageHeight }
      ]
    ), this.bottomIntersectPoint = d.GetIntersectBetweenTwoSegment(
      t,
      [this.rect.bottomLeft, this.rect.bottomRight],
      [
        { x: 0, y: this.pageHeight },
        { x: this.pageWidth, y: this.pageHeight }
      ]
    ));
  }
  checkPositionAtCenterLine(e, t, i) {
    let s = e;
    const n = d.LimitPointToCircle(t, this.pageWidth, s);
    s !== n && (s = n, this.updateAngleAndGeometry(s));
    const h = Math.sqrt(
      Math.pow(this.pageWidth, 2) + Math.pow(this.pageHeight, 2)
    );
    let o = this.rect.bottomRight, g = this.rect.topLeft;
    if (this.corner === p.BOTTOM && (o = this.rect.topRight, g = this.rect.bottomLeft), o.x <= 0) {
      const c = d.LimitPointToCircle(
        i,
        h,
        g
      );
      c !== s && (s = c, this.updateAngleAndGeometry(s));
    }
    return s;
  }
  getSegmentToShadowLine() {
    const e = this.getShadowStartPoint(), t = e !== this.sideIntersectPoint && this.sideIntersectPoint !== null ? this.sideIntersectPoint : this.bottomIntersectPoint;
    return [e, t];
  }
}
var l = /* @__PURE__ */ ((a) => (a[a.FORWARD = 0] = "FORWARD", a[a.BACK = 1] = "BACK", a))(l || {}), p = /* @__PURE__ */ ((a) => (a.TOP = "top", a.BOTTOM = "bottom", a))(p || {}), P = /* @__PURE__ */ ((a) => (a.USER_FOLD = "user_fold", a.FOLD_CORNER = "fold_corner", a.FLIPPING = "flipping", a.READ = "read", a))(P || {});
class T {
  constructor(e, t) {
    r(this, "render");
    r(this, "app");
    r(this, "flippingPage", null);
    r(this, "bottomPage", null);
    r(this, "calc", null);
    r(this, "state", "read");
    this.render = e, this.app = t;
  }
  /**
   * Called when the page folding (User drags page corner)
   *
   * @param globalPos - Touch Point Coordinates (relative window)
   */
  fold(e) {
    this.setState(
      "user_fold"
      /* USER_FOLD */
    ), this.calc === null && this.start(e), this.do(this.render.convertToPage(e));
  }
  /**
   * Page turning with animation
   *
   * @param globalPos - Touch Point Coordinates (relative window)
   */
  flip(e) {
    if (this.app.getSettings().disableFlipByClick && !this.isPointOnCorners(e) || (this.calc !== null && this.render.finishAnimation(), !this.start(e)))
      return;
    const t = this.getBoundsRect();
    this.setState(
      "flipping"
      /* FLIPPING */
    );
    const i = t.height / 10, s = this.calc.getCorner() === "bottom" ? t.height - i : i, n = this.calc.getCorner() === "bottom" ? t.height : 0;
    this.calc.calc({ x: t.pageWidth - i, y: s }), this.animateFlippingTo(
      { x: t.pageWidth - i, y: s },
      { x: -t.pageWidth, y: n },
      !0
    );
  }
  /**
   * Start the flipping process. Find direction and corner of flipping. Creating an object for calculation.
   *
   * @param {Point} globalPos - Touch Point Coordinates (relative window)
   *
   * @returns {boolean} True if flipping is possible, false otherwise
   */
  start(e) {
    this.reset();
    const t = this.render.convertToBook(e), i = this.getBoundsRect(), s = this.getDirectionByPoint(t), n = t.y >= i.height / 2 ? "bottom" : "top";
    if (!this.checkDirection(s))
      return !1;
    try {
      if (this.flippingPage = this.app.getPageCollection().getFlippingPage(s), this.bottomPage = this.app.getPageCollection().getBottomPage(s), this.render.getOrientation() === m.LANDSCAPE)
        if (s === 1) {
          const h = this.app.getPageCollection().nextBy(this.flippingPage);
          h !== null && this.flippingPage.getDensity() !== h.getDensity() && (this.flippingPage.setDrawingDensity(w.HARD), h.setDrawingDensity(w.HARD));
        } else {
          const h = this.app.getPageCollection().prevBy(this.flippingPage);
          h !== null && this.flippingPage.getDensity() !== h.getDensity() && (this.flippingPage.setDrawingDensity(w.HARD), h.setDrawingDensity(w.HARD));
        }
      return this.render.setDirection(s), this.calc = new O(
        s,
        n,
        i.pageWidth.toString(10),
        // fix bug with type casting
        i.height.toString(10)
        // fix bug with type casting
      ), !0;
    } catch {
      return !1;
    }
  }
  /**
   * Perform calculations for the current page position. Pass data to render object
   *
   * @param {Point} pagePos - Touch Point Coordinates (relative active page)
   */
  do(e) {
    if (this.calc !== null && this.calc.calc(e)) {
      const t = this.calc.getFlippingProgress();
      this.bottomPage.setArea(this.calc.getBottomClipArea()), this.bottomPage.setPosition(this.calc.getBottomPagePosition()), this.bottomPage.setAngle(0), this.bottomPage.setHardAngle(0), this.flippingPage.setArea(this.calc.getFlippingClipArea()), this.flippingPage.setPosition(this.calc.getActiveCorner()), this.flippingPage.setAngle(this.calc.getAngle()), this.calc.getDirection() === 0 ? this.flippingPage.setHardAngle(90 * (200 - t * 2) / 100) : this.flippingPage.setHardAngle(-90 * (200 - t * 2) / 100), this.render.setPageRect(this.calc.getRect()), this.render.setBottomPage(this.bottomPage), this.render.setFlippingPage(this.flippingPage), this.render.setShadowData(
        this.calc.getShadowStartPoint(),
        this.calc.getShadowAngle(),
        t,
        this.calc.getDirection()
      );
    }
  }
  /**
   * Turn to the specified page number (with animation)
   *
   * @param {number} page - New page number
   * @param {FlipCorner} corner - Active page corner when turning
   */
  flipToPage(e, t) {
    const i = this.app.getPageCollection().getCurrentSpreadIndex(), s = this.app.getPageCollection().getSpreadIndexByPage(e);
    try {
      s > i && (this.app.getPageCollection().setCurrentSpreadIndex(s - 1), this.flipNext(t)), s < i && (this.app.getPageCollection().setCurrentSpreadIndex(s + 1), this.flipPrev(t));
    } catch {
    }
  }
  /**
   * Turn to the next page (with animation)
   *
   * @param {FlipCorner} corner - Active page corner when turning
   */
  flipNext(e) {
    this.flip({
      x: this.render.getRect().left + this.render.getRect().pageWidth * 2 - 10,
      y: e === "top" ? 1 : this.render.getRect().height - 2
    });
  }
  /**
   * Turn to the prev page (with animation)
   *
   * @param {FlipCorner} corner - Active page corner when turning
   */
  flipPrev(e) {
    this.flip({
      x: 10,
      y: e === "top" ? 1 : this.render.getRect().height - 2
    });
  }
  /**
   * Called when the user has stopped flipping
   */
  stopMove() {
    if (this.calc === null)
      return;
    const e = this.calc.getPosition(), t = this.getBoundsRect(), i = this.calc.getCorner() === "bottom" ? t.height : 0;
    e.x <= 0 ? this.animateFlippingTo(e, { x: -t.pageWidth, y: i }, !0) : this.animateFlippingTo(e, { x: t.pageWidth, y: i }, !1);
  }
  /**
   * Fold the corners of the book when the mouse pointer is over them.
   * Called when the mouse pointer is over the book without clicking
   *
   * @param globalPos
   */
  showCorner(e) {
    if (!this.checkState(
      "read",
      "fold_corner"
      /* FOLD_CORNER */
    ))
      return;
    const t = this.getBoundsRect(), i = t.pageWidth;
    if (this.isPointOnCorners(e))
      if (this.calc === null) {
        if (!this.start(e))
          return;
        this.setState(
          "fold_corner"
          /* FOLD_CORNER */
        ), this.calc.calc({ x: i - 1, y: 1 });
        const s = 50, n = this.calc.getCorner() === "bottom" ? t.height - 1 : 1, h = this.calc.getCorner() === "bottom" ? t.height - s : s;
        this.animateFlippingTo(
          { x: i - 1, y: n },
          { x: i - s, y: h },
          !1,
          !1
        );
      } else
        this.do(this.render.convertToPage(e));
    else
      this.setState(
        "read"
        /* READ */
      ), this.render.finishAnimation(), this.stopMove();
  }
  /**
   * Starting the flipping animation process
   *
   * @param {Point} start - animation start point
   * @param {Point} dest - animation end point
   * @param {boolean} isTurned - will the page turn over, or just bring it back
   * @param {boolean} needReset - reset the flipping process at the end of the animation
   */
  animateFlippingTo(e, t, i, s = !0) {
    const n = d.GetCordsFromTwoPoint(e, t), h = [];
    for (const g of n)
      h.push(() => this.do(g));
    const o = this.getAnimationDuration(n.length);
    this.render.startAnimation(h, o, () => {
      this.calc && (i && (this.calc.getDirection() === 1 ? this.app.turnToPrevPage() : this.app.turnToNextPage()), s && (this.render.setBottomPage(null), this.render.setFlippingPage(null), this.render.clearShadow(), this.setState(
        "read"
        /* READ */
      ), this.reset()));
    });
  }
  /**
   * Get the current calculations object
   */
  getCalculation() {
    return this.calc;
  }
  /**
   * Get current flipping state
   */
  getState() {
    return this.state;
  }
  setState(e) {
    this.state !== e && (this.app.updateState(e), this.state = e);
  }
  getDirectionByPoint(e) {
    const t = this.getBoundsRect();
    if (this.render.getOrientation() === m.PORTRAIT) {
      if (e.x - t.pageWidth <= t.width / 5)
        return 1;
    } else if (e.x < t.width / 2)
      return 1;
    return 0;
  }
  getAnimationDuration(e) {
    const t = this.app.getSettings().flippingTime;
    return e >= 1e3 ? t : e / 1e3 * t;
  }
  checkDirection(e) {
    return e === 0 ? this.app.getCurrentPageIndex() < this.app.getPageCount() - 1 : this.app.getCurrentPageIndex() >= 1;
  }
  reset() {
    this.calc = null, this.flippingPage = null, this.bottomPage = null;
  }
  getBoundsRect() {
    return this.render.getRect();
  }
  checkState(...e) {
    for (const t of e)
      if (this.state === t)
        return !0;
    return !1;
  }
  isPointOnCorners(e) {
    const t = this.getBoundsRect(), i = t.pageWidth, s = Math.sqrt(Math.pow(i, 2) + Math.pow(t.height, 2)) / 5, n = this.render.convertToBook(e);
    return n.x > 0 && n.y > 0 && n.x < t.width && n.y < t.height && (n.x < s || n.x > t.width - s) && (n.y < s || n.y > t.height - s);
  }
}
var S = /* @__PURE__ */ ((a) => (a.FIXED = "fixed", a.STRETCH = "stretch", a))(S || {});
class H {
  constructor() {
    r(this, "_default", {
      startPage: 0,
      size: "fixed",
      width: 0,
      height: 0,
      minWidth: 0,
      maxWidth: 0,
      minHeight: 0,
      maxHeight: 0,
      drawShadow: !0,
      flippingTime: 1e3,
      usePortrait: !0,
      startZIndex: 0,
      autoSize: !0,
      maxShadowOpacity: 1,
      showCover: !1,
      mobileScrollSupport: !0,
      swipeDistance: 30,
      clickEventForward: !0,
      useMouseEvents: !0,
      showPageCorners: !0,
      disableFlipByClick: !1
    });
  }
  /**
   * Processing parameters received from the user. Substitution default values
   *
   * @param userSetting
   * @returns {FlipSetting} Сonfiguration object
   */
  getSettings(e) {
    const t = this._default;
    if (Object.assign(t, e), t.size !== "stretch" && t.size !== "fixed")
      throw new Error(
        'Invalid size type. Available only "fixed" and "stretch" value'
      );
    if (t.width <= 0 || t.height <= 0)
      throw new Error("Invalid width or height");
    if (t.flippingTime <= 0)
      throw new Error("Invalid flipping time");
    return t.size === "stretch" ? (t.minWidth <= 0 && (t.minWidth = 100), t.maxWidth < t.minWidth && (t.maxWidth = 2e3), t.minHeight <= 0 && (t.minHeight = 100), t.maxHeight < t.minHeight && (t.maxHeight = 2e3)) : (t.minWidth = t.width, t.maxWidth = t.width, t.minHeight = t.height, t.maxHeight = t.height), t;
  }
}
var m = /* @__PURE__ */ ((a) => (a.PORTRAIT = "portrait", a.LANDSCAPE = "landscape", a))(m || {});
class I {
  constructor(e, t) {
    r(this, "setting");
    r(this, "app");
    /** Left static book page */
    r(this, "leftPage", null);
    /** Right static book page */
    r(this, "rightPage", null);
    /** Page currently flipping */
    r(this, "flippingPage", null);
    /** Next page at the time of flipping */
    r(this, "bottomPage", null);
    /** Current flipping direction */
    r(this, "direction", null);
    /** Current book orientation */
    r(this, "orientation", null);
    /** Сurrent state of the shadows */
    r(this, "shadow", null);
    /** Сurrent animation process */
    r(this, "animation", null);
    /** Page borders while flipping */
    r(this, "pageRect", null);
    /** Current book area */
    r(this, "boundsRect", null);
    /** Timer started from start of rendering */
    r(this, "timer", 0);
    /**
     * Safari browser definitions for resolving a bug with a css property clip-area
     *
     * https://bugs.webkit.org/show_bug.cgi?id=126207
     */
    r(this, "safari", !1);
    this.setting = t, this.app = e;
    const i = new RegExp("Version\\/[\\d\\.]+.*Safari/");
    this.safari = i.exec(window.navigator.userAgent) !== null;
  }
  /**
   * Executed when requestAnimationFrame is called. Performs the current animation process and call drawFrame()
   *
   * @param timer
   */
  render(e) {
    if (this.animation !== null) {
      const t = Math.round(
        (e - this.animation.startedAt) / this.animation.durationFrame
      );
      t < this.animation.frames.length ? this.animation.frames[t]() : (this.animation.onAnimateEnd(), this.animation = null);
    }
    this.timer = e, this.drawFrame();
  }
  /**
   * Running requestAnimationFrame, and rendering process
   */
  start() {
    this.update();
    const e = (t) => {
      this.render(t), requestAnimationFrame(e);
    };
    requestAnimationFrame(e);
  }
  /**
   * Start a new animation process
   *
   * @param {FrameAction[]} frames - Frame list
   * @param {number} duration - total animation duration
   * @param {AnimationSuccessAction} onAnimateEnd - Animation callback function
   */
  startAnimation(e, t, i) {
    this.finishAnimation(), this.animation = {
      frames: e,
      duration: t,
      durationFrame: t / e.length,
      onAnimateEnd: i,
      startedAt: this.timer
    };
  }
  /**
   * End the current animation process and call the callback
   */
  finishAnimation() {
    this.animation !== null && (this.animation.frames[this.animation.frames.length - 1](), this.animation.onAnimateEnd !== null && this.animation.onAnimateEnd()), this.animation = null;
  }
  /**
   * Recalculate the size of the displayed area, and update the page orientation
   */
  update() {
    this.boundsRect = null;
    const e = this.calculateBoundsRect();
    this.orientation !== e && (this.orientation = e, this.app.updateOrientation(e));
  }
  /**
   * Calculate the size and position of the book depending on the parent element and configuration parameters
   */
  calculateBoundsRect() {
    let e = "landscape";
    const t = this.getBlockWidth(), i = {
      x: t / 2,
      y: this.getBlockHeight() / 2
    }, s = this.setting.width / this.setting.height;
    let n = this.setting.width, h = this.setting.height, o = i.x - n;
    return this.setting.size === S.STRETCH ? (t < this.setting.minWidth * 2 && this.app.getSettings().usePortrait && (e = "portrait"), n = e === "portrait" ? this.getBlockWidth() : this.getBlockWidth() / 2, n > this.setting.maxWidth && (n = this.setting.maxWidth), h = n / s, h > this.getBlockHeight() && (h = this.getBlockHeight(), n = h * s), o = e === "portrait" ? i.x - n / 2 - n : i.x - n) : t < n * 2 && this.app.getSettings().usePortrait && (e = "portrait", o = i.x - n / 2 - n), this.boundsRect = {
      left: o,
      top: i.y - h / 2,
      width: n * 2,
      height: h,
      pageWidth: n
    }, e;
  }
  /**
   * Set the current parameters of the drop shadow
   *
   * @param {Point} pos - Shadow Position Start Point
   * @param {number} angle - The angle of the shadows relative to the book
   * @param {number} progress - Flipping progress in percent (0 - 100)
   * @param {FlipDirection} direction - Flipping Direction, the direction of the shadow gradients
   */
  setShadowData(e, t, i, s) {
    if (!this.app.getSettings().drawShadow)
      return;
    const n = 100 * this.getSettings().maxShadowOpacity;
    this.shadow = {
      pos: e,
      angle: t,
      width: this.getRect().pageWidth * 3 / 4 * i / 100,
      opacity: (100 - i) * n / 100 / 100,
      direction: s,
      progress: i * 2
    };
  }
  /**
   * Clear shadow
   */
  clearShadow() {
    this.shadow = null;
  }
  /**
   * Get parent block offset width
   */
  getBlockWidth() {
    return this.app.getUI().getDistElement().offsetWidth;
  }
  /**
   * Get parent block offset height
   */
  getBlockHeight() {
    return this.app.getUI().getDistElement().offsetHeight;
  }
  /**
   * Get current flipping direction
   */
  getDirection() {
    return this.direction;
  }
  /**
   * Сurrent size and position of the book
   */
  getRect() {
    return this.boundsRect === null && this.calculateBoundsRect(), this.boundsRect;
  }
  /**
   * Get configuration object
   */
  getSettings() {
    return this.app.getSettings();
  }
  /**
   * Get current book orientation
   */
  getOrientation() {
    return this.orientation;
  }
  /**
   * Set page area while flipping
   *
   * @param direction
   */
  setPageRect(e) {
    this.pageRect = e;
  }
  /**
   * Set flipping direction
   *
   * @param direction
   */
  setDirection(e) {
    this.direction = e;
  }
  /**
   * Set right static book page
   *
   * @param page
   */
  setRightPage(e) {
    e !== null && e.setOrientation(u.RIGHT), this.rightPage = e;
  }
  /**
   * Set left static book page
   * @param page
   */
  setLeftPage(e) {
    e !== null && e.setOrientation(u.LEFT), this.leftPage = e;
  }
  /**
   * Set next page at the time of flipping
   * @param page
   */
  setBottomPage(e) {
    e !== null && e.setOrientation(
      this.direction === l.BACK ? u.LEFT : u.RIGHT
    ), this.bottomPage = e;
  }
  /**
   * Set currently flipping page
   *
   * @param page
   */
  setFlippingPage(e) {
    e !== null && e.setOrientation(
      this.direction === l.FORWARD && this.orientation !== "portrait" ? u.LEFT : u.RIGHT
    ), this.flippingPage = e;
  }
  /**
   * Coordinate conversion function. Window coordinates -> to book coordinates
   *
   * @param {Point} pos - Global coordinates relative to the window
   * @returns {Point} Coordinates relative to the book
   */
  convertToBook(e) {
    const t = this.getRect();
    return {
      x: e.x - t.left,
      y: e.y - t.top
    };
  }
  isSafari() {
    return this.safari;
  }
  /**
   * Coordinate conversion function. Window coordinates -> to current coordinates of the working page
   *
   * @param {Point} pos - Global coordinates relative to the window
   * @param {FlipDirection} direction  - Current flipping direction
   *
   * @returns {Point} Coordinates relative to the work page
   */
  convertToPage(e, t) {
    t || (t = this.direction);
    const i = this.getRect();
    return {
      x: t === l.FORWARD ? e.x - i.left - i.width / 2 : i.width / 2 - e.x + i.left,
      y: e.y - i.top
    };
  }
  /**
   * Coordinate conversion function. Coordinates relative to the work page -> Window coordinates
   *
   * @param {Point} pos - Coordinates relative to the work page
   * @param {FlipDirection} direction  - Current flipping direction
   *
   * @returns {Point} Global coordinates relative to the window
   */
  convertToGlobal(e, t) {
    if (t || (t = this.direction), e == null)
      return null;
    const i = this.getRect();
    return {
      x: t === l.FORWARD ? e.x + i.left + i.width / 2 : i.width / 2 - e.x + i.left,
      y: e.y + i.top
    };
  }
  /**
   * Casting the coordinates of the corners of the rectangle in the coordinates relative to the window
   *
   * @param {RectPoints} rect - Coordinates of the corners of the rectangle relative to the work page
   * @param {FlipDirection} direction  - Current flipping direction
   *
   * @returns {RectPoints} Coordinates of the corners of the rectangle relative to the window
   */
  convertRectToGlobal(e, t) {
    return t || (t = this.direction), {
      topLeft: this.convertToGlobal(e.topLeft, t),
      topRight: this.convertToGlobal(e.topRight, t),
      bottomLeft: this.convertToGlobal(e.bottomLeft, t),
      bottomRight: this.convertToGlobal(e.bottomRight, t)
    };
  }
}
class C {
  constructor(e, t) {
    r(this, "app");
    r(this, "render");
    r(this, "isShowCover");
    /** Pages List */
    r(this, "pages", []);
    /** Index of the current page in list */
    r(this, "currentPageIndex", 0);
    /** Number of the current spread in book */
    r(this, "currentSpreadIndex", 0);
    /**  Two-page spread in landscape mode */
    r(this, "landscapeSpread", []);
    /**  One-page spread in portrait mode */
    r(this, "portraitSpread", []);
    this.render = t, this.app = e, this.currentPageIndex = 0, this.isShowCover = this.app.getSettings().showCover;
  }
  /**
   * Clear pages list
   */
  destroy() {
    this.pages = [];
  }
  /**
   * Split the book on the two-page spread in landscape mode and one-page spread in portrait mode
   */
  createSpread() {
    this.landscapeSpread = [], this.portraitSpread = [];
    for (let t = 0; t < this.pages.length; t++)
      this.portraitSpread.push([t]);
    let e = 0;
    this.isShowCover && (this.pages[0].setDensity(w.HARD), this.landscapeSpread.push([e]), e++);
    for (let t = e; t < this.pages.length; t += 2)
      t < this.pages.length - 1 ? this.landscapeSpread.push([t, t + 1]) : (this.landscapeSpread.push([t]), this.pages[t].setDensity(w.HARD));
  }
  /**
   * Get spread by mode (portrait or landscape)
   */
  getSpread() {
    return this.render.getOrientation() === m.LANDSCAPE ? this.landscapeSpread : this.portraitSpread;
  }
  /**
   * Get spread index by page number
   *
   * @param {number} pageNum - page index
   */
  getSpreadIndexByPage(e) {
    const t = this.getSpread();
    for (let i = 0; i < t.length; i++)
      if (e === t[i][0] || e === t[i][1])
        return i;
    return null;
  }
  /**
   * Get the total number of pages
   */
  getPageCount() {
    return this.pages.length;
  }
  /**
   * Get the pages list
   */
  getPages() {
    return this.pages;
  }
  /**
   * Get page by index
   *
   * @param {number} pageIndex
   */
  getPage(e) {
    if (e >= 0 && e < this.pages.length)
      return this.pages[e];
    throw new Error("Invalid page number");
  }
  /**
   * Get the next page from the specified
   *
   * @param {Page} current
   */
  nextBy(e) {
    const t = this.pages.indexOf(e);
    return t < this.pages.length - 1 ? this.pages[t + 1] : null;
  }
  /**
   * Get previous page from specified
   *
   * @param {Page} current
   */
  prevBy(e) {
    const t = this.pages.indexOf(e);
    return t > 0 ? this.pages[t - 1] : null;
  }
  /**
   * Get flipping page depending on the direction
   *
   * @param {FlipDirection} direction
   */
  getFlippingPage(e) {
    const t = this.currentSpreadIndex;
    if (this.render.getOrientation() === m.PORTRAIT)
      return e === l.FORWARD ? this.pages[t].newTemporaryCopy() : this.pages[t - 1];
    {
      const i = e === l.FORWARD ? this.getSpread()[t + 1] : this.getSpread()[t - 1];
      return i.length === 1 ? this.pages[i[0]] : e === l.FORWARD ? this.pages[i[0]] : this.pages[i[1]];
    }
  }
  /**
   * Get Next page at the time of flipping
   *
   * @param {FlipDirection}  direction
   */
  getBottomPage(e) {
    const t = this.currentSpreadIndex;
    if (this.render.getOrientation() === m.PORTRAIT)
      return e === l.FORWARD ? this.pages[t + 1] : this.pages[t - 1];
    {
      const i = e === l.FORWARD ? this.getSpread()[t + 1] : this.getSpread()[t - 1];
      return i.length === 1 ? this.pages[i[0]] : e === l.FORWARD ? this.pages[i[1]] : this.pages[i[0]];
    }
  }
  /**
   * Show next spread
   */
  showNext() {
    this.currentSpreadIndex < this.getSpread().length && (this.currentSpreadIndex++, this.showSpread());
  }
  /**
   * Show prev spread
   */
  showPrev() {
    this.currentSpreadIndex > 0 && (this.currentSpreadIndex--, this.showSpread());
  }
  /**
   * Get the number of the current spread in book
   */
  getCurrentPageIndex() {
    return this.currentPageIndex;
  }
  /**
   * Show specified page
   * @param {number} pageNum - Page index (from 0s)
   */
  show(e = null) {
    if (e === null && (e = this.currentPageIndex), e < 0 || e >= this.pages.length)
      return;
    const t = this.getSpreadIndexByPage(e);
    t !== null && (this.currentSpreadIndex = t, this.showSpread());
  }
  /**
   * Index of the current page in list
   */
  getCurrentSpreadIndex() {
    return this.currentSpreadIndex;
  }
  /**
   * Set new spread index as current
   *
   * @param {number} newIndex - new spread index
   */
  setCurrentSpreadIndex(e) {
    if (e >= 0 && e < this.getSpread().length)
      this.currentSpreadIndex = e;
    else
      throw new Error("Invalid page");
  }
  /**
   * Show current spread
   */
  showSpread() {
    const e = this.getSpread()[this.currentSpreadIndex];
    e.length === 2 ? (this.render.setLeftPage(this.pages[e[0]]), this.render.setRightPage(this.pages[e[1]])) : this.render.getOrientation() === m.LANDSCAPE ? e[0] === this.pages.length - 1 ? (this.render.setLeftPage(this.pages[e[0]]), this.render.setRightPage(null)) : (this.render.setLeftPage(null), this.render.setRightPage(this.pages[e[0]])) : (this.render.setLeftPage(null), this.render.setRightPage(this.pages[e[0]])), this.currentPageIndex = e[0], this.app.updatePageIndex(this.currentPageIndex);
  }
}
class D extends C {
  constructor(t, i, s) {
    super(t, i);
    r(this, "imagesHref");
    this.imagesHref = s;
  }
  load() {
    for (const t of this.imagesHref) {
      const i = new M(this.render, t, w.SOFT);
      i.load(), this.pages.push(i);
    }
    this.createSpread();
  }
}
class R extends v {
  constructor(t, i, s) {
    super(t, s);
    r(this, "element");
    r(this, "copiedElement", null);
    r(this, "temporaryCopy", null);
    r(this, "isLoad", !1);
    this.element = i, this.element.classList.add("stf__item"), this.element.classList.add("--" + s);
  }
  newTemporaryCopy() {
    return this.nowDrawingDensity === w.HARD ? this : (this.temporaryCopy === null && (this.copiedElement = this.element.cloneNode(!0), this.element.parentElement.appendChild(this.copiedElement), this.temporaryCopy = new R(
      this.render,
      this.copiedElement,
      this.nowDrawingDensity
    )), this.getTemporaryCopy());
  }
  getTemporaryCopy() {
    return this.temporaryCopy;
  }
  hideTemporaryCopy() {
    this.temporaryCopy !== null && (this.copiedElement.remove(), this.copiedElement = null, this.temporaryCopy = null);
  }
  draw(t) {
    const i = t || this.nowDrawingDensity, s = this.render.convertToGlobal(this.state.position), n = this.render.getRect().pageWidth, h = this.render.getRect().height;
    this.element.classList.remove("--simple");
    const o = `
            display: block;
            z-index: ${this.element.style.zIndex};
            left: 0;
            top: 0;
            width: ${n}px;
            height: ${h}px;
        `;
    i === w.HARD ? this.drawHard(o) : this.drawSoft(s, o);
  }
  drawHard(t = "") {
    const i = this.render.getRect().left + this.render.getRect().width / 2, s = this.state.hardDrawingAngle, n = t + `
                backface-visibility: hidden;
                -webkit-backface-visibility: hidden;
                clip-path: none;
                -webkit-clip-path: none;
            ` + (this.orientation === u.LEFT ? `transform-origin: ${this.render.getRect().pageWidth}px 0; 
                   transform: translate3d(0, 0, 0) rotateY(${s}deg);` : `transform-origin: 0 0; 
                   transform: translate3d(${i}px, 0, 0) rotateY(${s}deg);`);
    this.element.style.cssText = n;
  }
  drawSoft(t, i = "") {
    let s = "polygon( ";
    for (const h of this.state.area)
      if (h !== null) {
        let o = this.render.getDirection() === l.BACK ? {
          x: -h.x + this.state.position.x,
          y: h.y - this.state.position.y
        } : {
          x: h.x - this.state.position.x,
          y: h.y - this.state.position.y
        };
        o = d.GetRotatedPoint(o, { x: 0, y: 0 }, this.state.angle), s += o.x + "px " + o.y + "px, ";
      }
    s = s.slice(0, -2), s += ")";
    const n = i + `transform-origin: 0 0; clip-path: ${s}; -webkit-clip-path: ${s};` + (this.render.isSafari() && this.state.angle === 0 ? `transform: translate(${t.x}px, ${t.y}px);` : `transform: translate3d(${t.x}px, ${t.y}px, 0) rotate(${this.state.angle}rad);`);
    this.element.style.cssText = n;
  }
  simpleDraw(t) {
    const i = this.render.getRect(), s = i.pageWidth, n = i.height, h = t === u.RIGHT ? i.left + i.pageWidth : i.left, o = i.top;
    this.element.classList.add("--simple"), this.element.style.cssText = `
            position: absolute; 
            display: block; 
            height: ${n}px; 
            left: ${h}px; 
            top: ${o}px; 
            width: ${s}px; 
            z-index: ${this.render.getSettings().startZIndex + 1};`;
  }
  getElement() {
    return this.element;
  }
  load() {
    this.isLoad = !0, console.log("%c this.isLoad: ", "background-color: pink", this.isLoad);
  }
  setOrientation(t) {
    super.setOrientation(t), this.element.classList.remove("--left", "--right"), this.element.classList.add(
      t === u.RIGHT ? "--right" : "--left"
    );
  }
  setDrawingDensity(t) {
    this.element.classList.remove("--soft", "--hard"), this.element.classList.add("--" + t), super.setDrawingDensity(t);
  }
}
class b extends C {
  constructor(t, i, s, n) {
    super(t, i);
    r(this, "element");
    r(this, "pagesElement");
    this.element = s, this.pagesElement = n;
  }
  load() {
    for (const t of this.pagesElement) {
      const i = new R(
        this.render,
        t,
        t.dataset.density === "hard" ? w.HARD : w.SOFT
      );
      i.load(), this.pages.push(i);
    }
    this.createSpread(), console.log("%c element: ", "background-color: pink", this.element);
  }
}
class E extends I {
  constructor(t, i, s) {
    super(t, i);
    r(this, "canvas");
    r(this, "ctx");
    this.canvas = s, this.ctx = s.getContext("2d");
  }
  getContext() {
    return this.ctx;
  }
  reload() {
  }
  drawFrame() {
    this.clear(), this.orientation !== m.PORTRAIT && this.leftPage != null && this.leftPage.simpleDraw(u.LEFT), this.rightPage != null && this.rightPage.simpleDraw(u.RIGHT), this.bottomPage != null && this.bottomPage.draw(), this.drawBookShadow(), this.flippingPage != null && this.flippingPage.draw(), this.shadow != null && (this.drawOuterShadow(), this.drawInnerShadow());
    const t = this.getRect();
    this.orientation === m.PORTRAIT && (this.ctx.beginPath(), this.ctx.rect(t.left + t.pageWidth, t.top, t.width, t.height), this.ctx.clip());
  }
  drawBookShadow() {
    const t = this.getRect();
    this.ctx.save(), this.ctx.beginPath();
    const i = t.width / 20;
    this.ctx.rect(t.left, t.top, t.width, t.height);
    const s = { x: t.left + t.width / 2 - i / 2, y: 0 };
    this.ctx.translate(s.x, s.y);
    const n = this.ctx.createLinearGradient(0, 0, i, 0);
    n.addColorStop(0, "rgba(0, 0, 0, 0)"), n.addColorStop(0.4, "rgba(0, 0, 0, 0.2)"), n.addColorStop(0.49, "rgba(0, 0, 0, 0.1)"), n.addColorStop(0.5, "rgba(0, 0, 0, 0.5)"), n.addColorStop(0.51, "rgba(0, 0, 0, 0.4)"), n.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.clip(), this.ctx.fillStyle = n, this.ctx.fillRect(0, 0, i, t.height * 2), this.ctx.restore();
  }
  drawOuterShadow() {
    const t = this.getRect();
    this.ctx.save(), this.ctx.beginPath(), this.ctx.rect(t.left, t.top, t.width, t.height);
    const i = this.convertToGlobal({ x: this.shadow.pos.x, y: this.shadow.pos.y });
    this.ctx.translate(i.x, i.y), this.ctx.rotate(Math.PI + this.shadow.angle + Math.PI / 2);
    const s = this.ctx.createLinearGradient(0, 0, this.shadow.width, 0);
    this.shadow.direction === l.FORWARD ? (this.ctx.translate(0, -100), s.addColorStop(0, "rgba(0, 0, 0, " + this.shadow.opacity + ")"), s.addColorStop(1, "rgba(0, 0, 0, 0)")) : (this.ctx.translate(-this.shadow.width, -100), s.addColorStop(0, "rgba(0, 0, 0, 0)"), s.addColorStop(1, "rgba(0, 0, 0, " + this.shadow.opacity + ")")), this.ctx.clip(), this.ctx.fillStyle = s, this.ctx.fillRect(0, 0, this.shadow.width, t.height * 2), this.ctx.restore();
  }
  drawInnerShadow() {
    const t = this.getRect();
    this.ctx.save(), this.ctx.beginPath();
    const i = this.convertToGlobal({ x: this.shadow.pos.x, y: this.shadow.pos.y }), s = this.convertRectToGlobal(this.pageRect);
    this.ctx.moveTo(s.topLeft.x, s.topLeft.y), this.ctx.lineTo(s.topRight.x, s.topRight.y), this.ctx.lineTo(s.bottomRight.x, s.bottomRight.y), this.ctx.lineTo(s.bottomLeft.x, s.bottomLeft.y), this.ctx.translate(i.x, i.y), this.ctx.rotate(Math.PI + this.shadow.angle + Math.PI / 2);
    const n = this.shadow.width * 3 / 4, h = this.ctx.createLinearGradient(0, 0, n, 0);
    this.shadow.direction === l.FORWARD ? (this.ctx.translate(-n, -100), h.addColorStop(1, "rgba(0, 0, 0, " + this.shadow.opacity + ")"), h.addColorStop(0.9, "rgba(0, 0, 0, 0.05)"), h.addColorStop(0.7, "rgba(0, 0, 0, " + this.shadow.opacity + ")"), h.addColorStop(0, "rgba(0, 0, 0, 0)")) : (this.ctx.translate(0, -100), h.addColorStop(0, "rgba(0, 0, 0, " + this.shadow.opacity + ")"), h.addColorStop(0.1, "rgba(0, 0, 0, 0.05)"), h.addColorStop(0.3, "rgba(0, 0, 0, " + this.shadow.opacity + ")"), h.addColorStop(1, "rgba(0, 0, 0, 0)")), this.ctx.clip(), this.ctx.fillStyle = h, this.ctx.fillRect(0, 0, n, t.height * 2), this.ctx.restore();
  }
  clear() {
    this.ctx.fillStyle = "white", this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
  }
}
class A {
  /**
   * @constructor
   *
   * @param {HTMLElement} inBlock - Root HTML Element
   * @param {PageFlip} app - PageFlip instanse
   * @param {FlipSetting} setting - Configuration object
   */
  constructor(e, t, i) {
    r(this, "parentElement");
    r(this, "app");
    r(this, "wrapper");
    r(this, "distElement");
    r(this, "touchPoint", null);
    r(this, "swipeTimeout", 250);
    r(this, "swipeDistance");
    r(this, "onResize", () => {
      this.update();
    });
    r(this, "onMouseDown", (e) => {
      if (this.checkTarget(e.target)) {
        const t = this.getMousePos(e.clientX, e.clientY);
        this.app.startUserTouch(t), e.preventDefault();
      }
    });
    r(this, "onTouchStart", (e) => {
      if (this.checkTarget(e.target) && e.changedTouches.length > 0) {
        const t = e.changedTouches[0], i = this.getMousePos(t.clientX, t.clientY);
        this.touchPoint = {
          point: i,
          time: Date.now()
        }, setTimeout(() => {
          this.touchPoint !== null && this.app.startUserTouch(i);
        }, this.swipeTimeout), this.app.getSettings().mobileScrollSupport || e.preventDefault();
      }
    });
    r(this, "onMouseUp", (e) => {
      const t = this.getMousePos(e.clientX, e.clientY);
      this.app.userStop(t);
    });
    r(this, "onMouseMove", (e) => {
      const t = this.getMousePos(e.clientX, e.clientY);
      this.app.userMove(t, !1);
    });
    r(this, "onTouchMove", (e) => {
      if (e.changedTouches.length > 0) {
        const t = e.changedTouches[0], i = this.getMousePos(t.clientX, t.clientY);
        this.app.getSettings().mobileScrollSupport ? (this.touchPoint !== null && (Math.abs(this.touchPoint.point.x - i.x) > 10 || this.app.getState() !== P.READ) && e.cancelable && this.app.userMove(i, !0), this.app.getState() !== P.READ && e.preventDefault()) : this.app.userMove(i, !0);
      }
    });
    r(this, "onTouchEnd", (e) => {
      if (e.changedTouches.length > 0) {
        const t = e.changedTouches[0], i = this.getMousePos(t.clientX, t.clientY);
        let s = !1;
        if (this.touchPoint !== null) {
          const n = i.x - this.touchPoint.point.x, h = Math.abs(i.y - this.touchPoint.point.y);
          Math.abs(n) > this.swipeDistance && h < this.swipeDistance * 2 && Date.now() - this.touchPoint.time < this.swipeTimeout && (n > 0 ? this.app.flipPrev(
            this.touchPoint.point.y < this.app.getRender().getRect().height / 2 ? p.TOP : p.BOTTOM
          ) : this.app.flipNext(
            this.touchPoint.point.y < this.app.getRender().getRect().height / 2 ? p.TOP : p.BOTTOM
          ), s = !0), this.touchPoint = null;
        }
        this.app.userStop(i, s);
      }
    });
    this.parentElement = e, e.classList.add("stf__parent"), e.insertAdjacentHTML(
      "afterbegin",
      '<div class="stf__wrapper"></div>'
    ), this.wrapper = e.querySelector(".stf__wrapper"), this.app = t;
    const s = this.app.getSettings().usePortrait ? 1 : 2;
    e.style.minWidth = i.minWidth * s + "px", e.style.minHeight = i.minHeight + "px", i.size === S.FIXED && (e.style.minWidth = i.width * s + "px", e.style.minHeight = i.height + "px"), i.autoSize && (e.style.width = "100%", e.style.maxWidth = i.maxWidth * 2 + "px"), e.style.display = "block", window.addEventListener("resize", this.onResize, !1), this.swipeDistance = i.swipeDistance;
  }
  /**
   * Destructor. Remove all HTML elements and all event handlers
   */
  destroy() {
    this.app.getSettings().useMouseEvents && this.removeHandlers(), this.distElement.remove(), this.wrapper.remove();
  }
  /**
   * Get parent element for book
   *
   * @returns {HTMLElement}
   */
  getDistElement() {
    return this.distElement;
  }
  /**
   * Get wrapper element
   *
   * @returns {HTMLElement}
   */
  getWrapper() {
    return this.wrapper;
  }
  /**
   * Updates styles and sizes based on book orientation
   *
   * @param {Orientation} orientation - New book orientation
   */
  setOrientationStyle(e) {
    this.wrapper.classList.remove("--portrait", "--landscape"), e === m.PORTRAIT ? (this.app.getSettings().autoSize && (this.wrapper.style.paddingBottom = this.app.getSettings().height / this.app.getSettings().width * 100 + "%"), this.wrapper.classList.add("--portrait")) : (this.app.getSettings().autoSize && (this.wrapper.style.paddingBottom = this.app.getSettings().height / (this.app.getSettings().width * 2) * 100 + "%"), this.wrapper.classList.add("--landscape")), this.update();
  }
  removeHandlers() {
    window.removeEventListener("resize", this.onResize), this.distElement.removeEventListener("mousedown", this.onMouseDown), this.distElement.removeEventListener("touchstart", this.onTouchStart), window.removeEventListener("mousemove", this.onMouseMove), window.removeEventListener("touchmove", this.onTouchMove), window.removeEventListener("mouseup", this.onMouseUp), window.removeEventListener("touchend", this.onTouchEnd);
  }
  setHandlers() {
    window.addEventListener("resize", this.onResize, !1), this.app.getSettings().useMouseEvents && (this.distElement.addEventListener("mousedown", this.onMouseDown), this.distElement.addEventListener("touchstart", this.onTouchStart), window.addEventListener("mousemove", this.onMouseMove), window.addEventListener("touchmove", this.onTouchMove, {
      passive: !this.app.getSettings().mobileScrollSupport
    }), window.addEventListener("mouseup", this.onMouseUp), window.addEventListener("touchend", this.onTouchEnd));
  }
  /**
   * Convert global coordinates to relative book coordinates
   *
   * @param x
   * @param y
   */
  getMousePos(e, t) {
    const i = this.distElement.getBoundingClientRect();
    return {
      x: e - i.left,
      y: t - i.top
    };
  }
  checkTarget(e) {
    return this.app.getSettings().clickEventForward ? !["a", "button"].includes(e.tagName.toLowerCase()) : !0;
  }
}
class B extends A {
  constructor(t, i, s, n) {
    super(t, i, s);
    r(this, "items");
    this.wrapper.insertAdjacentHTML(
      "afterbegin",
      '<div class="stf__block"></div>'
    ), this.distElement = t.querySelector(".stf__block"), this.items = n;
    for (const h of n)
      this.distElement.appendChild(h);
    this.setHandlers();
  }
  clear() {
    for (const t of this.items)
      this.parentElement.appendChild(t);
  }
  /**
   * Update page list from HTMLElements
   *
   * @param {(NodeListOf<HTMLElement>|HTMLElement[])} items - List of pages as HTML Element
   */
  updateItems(t) {
    this.removeHandlers(), this.distElement.innerHTML = "";
    for (const i of t)
      this.distElement.appendChild(i);
    this.items = t, this.setHandlers();
  }
  update() {
    this.app.getRender().update();
  }
}
class F extends A {
  constructor(t, i, s) {
    super(t, i, s);
    r(this, "canvas");
    this.wrapper.innerHTML = '<canvas class="stf__canvas"></canvas>', this.canvas = t.querySelectorAll("canvas")[0], this.distElement = this.canvas, this.resizeCanvas(), this.setHandlers();
  }
  resizeCanvas() {
    const t = getComputedStyle(this.canvas), i = parseInt(t.getPropertyValue("width"), 10), s = parseInt(t.getPropertyValue("height"), 10);
    this.canvas.width = i, this.canvas.height = s;
  }
  /**
   * Get canvas element
   */
  getCanvas() {
    return this.canvas;
  }
  update() {
    this.resizeCanvas(), this.app.getRender().update();
  }
}
class G {
  constructor() {
    r(this, "events", /* @__PURE__ */ new Map());
  }
  /**
   * Add new event handler
   *
   * @param {string} eventName
   * @param {EventCallback} callback
   */
  on(e, t) {
    return this.events.has(e) ? this.events.get(e).push(t) : this.events.set(e, [t]), this;
  }
  /**
   * Removing all handlers from an event
   *
   * @param {string} event - Event name
   */
  off(e) {
    this.events.delete(e);
  }
  trigger(e, t, i = null) {
    if (this.events.has(e))
      for (const s of this.events.get(e))
        s({ data: i, object: t });
  }
}
class k extends I {
  /**
   * @constructor
   *
   * @param {PageFlip} app - PageFlip object
   * @param {FlipSetting} setting - Configuration object
   * @param {HTMLElement} element - Parent HTML Element
   */
  constructor(t, i, s) {
    super(t, i);
    /** Parent HTML Element */
    r(this, "element");
    /** Pages List as HTMLElements */
    // private readonly items: NodeListOf<HTMLElement> | HTMLElement[];
    r(this, "outerShadow", null);
    r(this, "innerShadow", null);
    r(this, "hardShadow", null);
    r(this, "hardInnerShadow", null);
    this.element = s, this.createShadows();
  }
  createShadows() {
    this.element.insertAdjacentHTML(
      "beforeend",
      `<div class="stf__outerShadow"></div>
             <div class="stf__innerShadow"></div>
             <div class="stf__hardShadow"></div>
             <div class="stf__hardInnerShadow"></div>`
    ), this.outerShadow = this.element.querySelector(".stf__outerShadow"), this.innerShadow = this.element.querySelector(".stf__innerShadow"), this.hardShadow = this.element.querySelector(".stf__hardShadow"), this.hardInnerShadow = this.element.querySelector(".stf__hardInnerShadow");
  }
  clearShadow() {
    super.clearShadow(), this.outerShadow.style.cssText = "display: none", this.innerShadow.style.cssText = "display: none", this.hardShadow.style.cssText = "display: none", this.hardInnerShadow.style.cssText = "display: none";
  }
  reload() {
    this.element.querySelector(".stf__outerShadow") || this.createShadows();
  }
  /**
   * Draw inner shadow to the hard page
   */
  drawHardInnerShadow() {
    const t = this.getRect(), i = this.shadow.progress > 100 ? 200 - this.shadow.progress : this.shadow.progress;
    let s = (100 - i) * (2.5 * t.pageWidth) / 100 + 20;
    s > t.pageWidth && (s = t.pageWidth);
    let n = `
            display: block;
            z-index: ${(this.getSettings().startZIndex + 5).toString(10)};
            width: ${s}px;
            height: ${t.height}px;
            background: linear-gradient(to right,
                rgba(0, 0, 0, ${this.shadow.opacity * i / 100}) 5%,
                rgba(0, 0, 0, 0) 100%);
            left: ${t.left + t.width / 2}px;
            transform-origin: 0 0;
        `;
    n += this.getDirection() === l.FORWARD && this.shadow.progress > 100 || this.getDirection() === l.BACK && this.shadow.progress <= 100 ? "transform: translate3d(0, 0, 0);" : "transform: translate3d(0, 0, 0) rotateY(180deg);", this.hardInnerShadow.style.cssText = n;
  }
  /**
   * Draw outer shadow to the hard page
   */
  drawHardOuterShadow() {
    const t = this.getRect();
    let s = (100 - (this.shadow.progress > 100 ? 200 - this.shadow.progress : this.shadow.progress)) * (2.5 * t.pageWidth) / 100 + 20;
    s > t.pageWidth && (s = t.pageWidth);
    let n = `
            display: block;
            z-index: ${(this.getSettings().startZIndex + 4).toString(10)};
            width: ${s}px;
            height: ${t.height}px;
            background: linear-gradient(to left, rgba(0, 0, 0, ${this.shadow.opacity}) 5%, rgba(0, 0, 0, 0) 100%);
            left: ${t.left + t.width / 2}px;
            transform-origin: 0 0;
        `;
    n += this.getDirection() === l.FORWARD && this.shadow.progress > 100 || this.getDirection() === l.BACK && this.shadow.progress <= 100 ? "transform: translate3d(0, 0, 0) rotateY(180deg);" : "transform: translate3d(0, 0, 0);", this.hardShadow.style.cssText = n;
  }
  /**
   * Draw inner shadow to the soft page
   */
  drawInnerShadow() {
    const t = this.getRect(), i = this.shadow.width * 3 / 4, s = this.getDirection() === l.FORWARD ? i : 0, n = this.getDirection() === l.FORWARD ? "to left" : "to right", h = this.convertToGlobal(this.shadow.pos), o = this.shadow.angle + 3 * Math.PI / 2, g = [
      this.pageRect.topLeft,
      this.pageRect.topRight,
      this.pageRect.bottomRight,
      this.pageRect.bottomLeft
    ];
    let c = "polygon( ";
    for (const f of g) {
      let y = this.getDirection() === l.BACK ? {
        x: -f.x + this.shadow.pos.x,
        y: f.y - this.shadow.pos.y
      } : {
        x: f.x - this.shadow.pos.x,
        y: f.y - this.shadow.pos.y
      };
      y = d.GetRotatedPoint(y, { x: s, y: 100 }, o), c += y.x + "px " + y.y + "px, ";
    }
    c = c.slice(0, -2), c += ")";
    const x = `
            display: block;
            z-index: ${(this.getSettings().startZIndex + 10).toString(10)};
            width: ${i}px;
            height: ${t.height * 2}px;
            background: linear-gradient(${n},
                rgba(0, 0, 0, ${this.shadow.opacity}) 5%,
                rgba(0, 0, 0, 0.05) 15%,
                rgba(0, 0, 0, ${this.shadow.opacity}) 35%,
                rgba(0, 0, 0, 0) 100%);
            transform-origin: ${s}px 100px;
            transform: translate3d(${h.x - s}px, ${h.y - 100}px, 0) rotate(${o}rad);
            clip-path: ${c};
            -webkit-clip-path: ${c};
        `;
    this.innerShadow.style.cssText = x;
  }
  /**
   * Draw outer shadow to the soft page
   */
  drawOuterShadow() {
    const t = this.getRect(), i = this.convertToGlobal({ x: this.shadow.pos.x, y: this.shadow.pos.y }), s = this.shadow.angle + 3 * Math.PI / 2, n = this.getDirection() === l.BACK ? this.shadow.width : 0, h = this.getDirection() === l.FORWARD ? "to right" : "to left", o = [
      { x: 0, y: 0 },
      { x: t.pageWidth, y: 0 },
      { x: t.pageWidth, y: t.height },
      { x: 0, y: t.height }
    ];
    let g = "polygon( ";
    for (const x of o)
      if (x !== null) {
        let f = this.getDirection() === l.BACK ? {
          x: -x.x + this.shadow.pos.x,
          y: x.y - this.shadow.pos.y
        } : {
          x: x.x - this.shadow.pos.x,
          y: x.y - this.shadow.pos.y
        };
        f = d.GetRotatedPoint(f, { x: n, y: 100 }, s), g += f.x + "px " + f.y + "px, ";
      }
    g = g.slice(0, -2), g += ")";
    const c = `
            display: block;
            z-index: ${(this.getSettings().startZIndex + 10).toString(10)};
            width: ${this.shadow.width}px;
            height: ${t.height * 2}px;
            background: linear-gradient(${h}, rgba(0, 0, 0, ${this.shadow.opacity}), rgba(0, 0, 0, 0));
            transform-origin: ${n}px 100px;
            transform: translate3d(${i.x - n}px, ${i.y - 100}px, 0) rotate(${s}rad);
            clip-path: ${g};
            -webkit-clip-path: ${g};
        `;
    this.outerShadow.style.cssText = c;
  }
  /**
   * Draw left static page
   */
  drawLeftPage() {
    this.orientation === m.PORTRAIT || this.leftPage === null || (this.direction === l.BACK && this.flippingPage !== null && this.flippingPage.getDrawingDensity() === w.HARD ? (this.leftPage.getElement().style.zIndex = (this.getSettings().startZIndex + 5).toString(10), this.leftPage.setHardDrawingAngle(180 + this.flippingPage.getHardAngle()), this.leftPage.draw(this.flippingPage.getDrawingDensity())) : this.leftPage.simpleDraw(u.LEFT));
  }
  /**
   * Draw right static page
   */
  drawRightPage() {
    this.rightPage !== null && (this.direction === l.FORWARD && this.flippingPage !== null && this.flippingPage.getDrawingDensity() === w.HARD ? (this.rightPage.getElement().style.zIndex = (this.getSettings().startZIndex + 5).toString(10), this.rightPage.setHardDrawingAngle(180 + this.flippingPage.getHardAngle()), this.rightPage.draw(this.flippingPage.getDrawingDensity())) : this.rightPage.simpleDraw(u.RIGHT));
  }
  /**
   * Draw the next page at the time of flipping
   */
  drawBottomPage() {
    if (this.bottomPage === null)
      return;
    const t = this.flippingPage != null ? this.flippingPage.getDrawingDensity() : null;
    this.orientation === m.PORTRAIT && this.direction === l.BACK || (this.bottomPage.getElement().style.zIndex = (this.getSettings().startZIndex + 3).toString(10), this.bottomPage.draw(t));
  }
  drawFrame() {
    this.clear(), this.drawLeftPage(), this.drawRightPage(), this.drawBottomPage(), this.flippingPage != null && (this.flippingPage.getElement().style.zIndex = (this.getSettings().startZIndex + 5).toString(10), this.flippingPage.draw()), this.shadow != null && this.flippingPage !== null && (this.flippingPage.getDrawingDensity() === w.SOFT ? (this.drawOuterShadow(), this.drawInnerShadow()) : (this.drawHardOuterShadow(), this.drawHardInnerShadow()));
  }
  clear() {
    for (const t of this.app.getPageCollection().getPages())
      t !== this.leftPage && t !== this.rightPage && t !== this.flippingPage && t !== this.bottomPage && (t.getElement().style.cssText = "display: none"), t.getTemporaryCopy() !== this.flippingPage && t.hideTemporaryCopy();
  }
  update() {
    super.update(), this.rightPage !== null && this.rightPage.setOrientation(u.RIGHT), this.leftPage !== null && this.leftPage.setOrientation(u.LEFT);
  }
}
class z extends G {
  /**
   * Create a new PageFlip instance
   *
   * @constructor
   * @param {HTMLElement} inBlock - Root HTML Element
   * @param {Object} setting - Configuration object
   */
  constructor(t, i) {
    super();
    r(this, "mousePosition");
    r(this, "isUserTouch", !1);
    r(this, "isUserMove", !1);
    r(this, "setting", null);
    r(this, "block");
    // Root HTML Element
    r(this, "pages", null);
    r(this, "flipController");
    r(this, "render");
    r(this, "ui");
    this.setting = new H().getSettings(i), this.block = t;
  }
  /**
   * Destructor. Remove a root HTML element and all event handlers
   */
  destroy() {
    this.ui.destroy(), this.block.remove();
  }
  /**
   * Update the render area. Re-show current page.
   */
  update() {
    this.render.update(), this.pages.show();
  }
  /**
   * Load pages from images on the Canvas mode
   *
   * @param {string[]} imagesHref - List of paths to images
   */
  loadFromImages(t) {
    this.ui = new F(this.block, this, this.setting);
    const i = this.ui.getCanvas();
    this.render = new E(this, this.setting, i), this.flipController = new T(this.render, this), this.pages = new D(this, this.render, t), this.pages.load(), this.render.start(), this.pages.show(this.setting.startPage), setTimeout(() => {
      this.ui.update(), this.trigger("init", this, {
        page: this.setting.startPage,
        mode: this.render.getOrientation()
      });
    }, 1);
  }
  /**
   * Load pages from HTML elements on the HTML mode
   *
   * @param {(NodeListOf<HTMLElement>|HTMLElement[])} items - List of pages as HTML Element
   */
  loadFromHTML(t) {
    this.ui = new B(this.block, this, this.setting, t), this.render = new k(this, this.setting, this.ui.getDistElement()), this.flipController = new T(this.render, this), this.pages = new b(
      this,
      this.render,
      this.ui.getDistElement(),
      t
    ), this.pages.load(), this.render.start(), this.pages.show(this.setting.startPage), setTimeout(() => {
      this.ui.update(), this.trigger("init", this, {
        page: this.setting.startPage,
        mode: this.render.getOrientation()
      });
    }, 1);
  }
  /**
   * Update current pages from images
   *
   * @param {string[]} imagesHref - List of paths to images
   */
  updateFromImages(t) {
    const i = this.pages.getCurrentPageIndex();
    this.pages.destroy(), this.pages = new D(this, this.render, t), this.pages.load(), this.pages.show(i), this.trigger("update", this, {
      page: i,
      mode: this.render.getOrientation()
    });
  }
  /**
   * Update current pages from HTML
   *
   * @param {(NodeListOf<HTMLElement>|HTMLElement[])} items - List of pages as HTML Element
   */
  updateFromHtml(t) {
    const i = this.pages.getCurrentPageIndex();
    this.pages.destroy(), this.pages = new b(
      this,
      this.render,
      this.ui.getDistElement(),
      t
    ), this.pages.load(), this.ui.updateItems(t), this.render.reload(), this.pages.show(i), this.trigger("update", this, {
      page: i,
      mode: this.render.getOrientation()
    });
  }
  /**
   * Clear pages from HTML (remove to initinalState)
   */
  clear() {
    this.pages.destroy(), this.ui.clear();
  }
  /**
   * Turn to the previous page (without animation)
   */
  turnToPrevPage() {
    this.pages.showPrev();
  }
  /**
   * Turn to the next page (without animation)
   */
  turnToNextPage() {
    this.pages.showNext();
  }
  /**
   * Turn to the specified page number (without animation)
   *
   * @param {number} page - New page number
   */
  turnToPage(t) {
    this.pages.show(t);
  }
  /**
   * Turn to the next page (with animation)
   *
   * @param {FlipCorner} corner - Active page corner when turning
   */
  flipNext(t = p.TOP) {
    this.flipController.flipNext(t);
  }
  /**
   * Turn to the prev page (with animation)
   *
   * @param {FlipCorner} corner - Active page corner when turning
   */
  flipPrev(t = p.TOP) {
    this.flipController.flipPrev(t);
  }
  /**
   * Turn to the specified page number (with animation)
   *
   * @param {number} page - New page number
   * @param {FlipCorner} corner - Active page corner when turning
   */
  flip(t, i = p.TOP) {
    this.flipController.flipToPage(t, i);
  }
  /**
   * Call a state change event trigger
   *
   * @param {FlippingState} newState - New  state of the object
   */
  updateState(t) {
    this.trigger("changeState", this, t);
  }
  /**
   * Call a page number change event trigger
   *
   * @param {number} newPage - New page Number
   */
  updatePageIndex(t) {
    this.trigger("flip", this, t);
  }
  /**
   * Call a page orientation change event trigger. Update UI and rendering area
   *
   * @param {Orientation} newOrientation - New page orientation (portrait, landscape)
   */
  updateOrientation(t) {
    this.ui.setOrientationStyle(t), this.update(), this.trigger("changeOrientation", this, t);
  }
  /**
   * Get the total number of pages in a book
   *
   * @returns {number}
   */
  getPageCount() {
    return this.pages.getPageCount();
  }
  /**
   * Get the index of the current page in the page list (starts at 0)
   *
   * @returns {number}
   */
  getCurrentPageIndex() {
    return this.pages.getCurrentPageIndex();
  }
  /**
   * Get page from collection by number
   *
   * @param {number} pageIndex
   * @returns {Page}
   */
  getPage(t) {
    return this.pages.getPage(t);
  }
  /**
   * Get the current rendering object
   *
   * @returns {Render}
   */
  getRender() {
    return this.render;
  }
  /**
   * Get current object responsible for flipping
   *
   * @returns {Flip}
   */
  getFlipController() {
    return this.flipController;
  }
  /**
   * Get current page orientation
   *
   * @returns {Orientation} Сurrent orientation: portrait or landscape
   */
  getOrientation() {
    return this.render.getOrientation();
  }
  /**
   * Get current book sizes and position
   *
   * @returns {PageRect}
   */
  getBoundsRect() {
    return this.render.getRect();
  }
  /**
   * Get configuration object
   *
   * @returns {FlipSetting}
   */
  getSettings() {
    return this.setting;
  }
  /**
   * Get UI object
   *
   * @returns {UI}
   */
  getUI() {
    return this.ui;
  }
  /**
   * Get current flipping state
   *
   * @returns {FlippingState}
   */
  getState() {
    return this.flipController.getState();
  }
  /**
   * Get page collection
   *
   * @returns {PageCollection}
   */
  getPageCollection() {
    return this.pages;
  }
  /**
   * Start page turning. Called when a user clicks or touches
   *
   * @param {Point} pos - Touch position in coordinates relative to the book
   */
  startUserTouch(t) {
    this.mousePosition = t, this.isUserTouch = !0, this.isUserMove = !1;
  }
  /**
   * Called when a finger / mouse moves
   *
   * @param {Point} pos - Touch position in coordinates relative to the book
   * @param {boolean} isTouch - True if there was a touch event, not a mouse click
   */
  userMove(t, i) {
    !this.isUserTouch && !i && this.setting.showPageCorners ? this.flipController.showCorner(t) : this.isUserTouch && d.GetDistanceBetweenTwoPoint(this.mousePosition, t) > 5 && (this.isUserMove = !0, this.flipController.fold(t));
  }
  /**
   * Сalled when the user has stopped touching
   *
   * @param {Point} pos - Touch end position in coordinates relative to the book
   * @param {boolean} isSwipe - true if there was a mobile swipe event
   */
  userStop(t, i = !1) {
    this.isUserTouch && (this.isUserTouch = !1, i || (this.isUserMove ? this.flipController.stopMove() : this.flipController.flip(t)));
  }
}
export {
  z as PageFlip
};