UNPKG

vue-book-reader

Version:

vue-book-reader is a vue wrapper for [foliate-js](https://github.com/johnfactotum/foliate-js) - library for rendering e-books in the browser. Supports EPUB, MOBI, KF8 (AZW3), FB2, CBZ, PDF (experimental; requires PDF.js), or add support for other formats

737 lines (736 loc) 29.3 kB
var te = Object.defineProperty; var ee = (o, s, t) => s in o ? te(o, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[s] = t; var jt = (o, s, t) => (ee(o, typeof s != "symbol" ? s + "" : s, t), t), $t = (o, s, t) => { if (!s.has(o)) throw TypeError("Cannot " + t); }; var e = (o, s, t) => ($t(o, s, "read from private field"), t ? t.call(o) : s.get(o)), l = (o, s, t) => { if (s.has(o)) throw TypeError("Cannot add the same private member more than once"); s instanceof WeakSet ? s.add(o) : s.set(o, t); }, m = (o, s, t, i) => ($t(o, s, "write to private field"), i ? i.call(o, t) : s.set(o, t), t); var c = (o, s, t) => ($t(o, s, "access private method"), t); const ie = (o) => new Promise((s) => setTimeout(s, o)), se = (o, s, t) => { let i; return (...n) => { const r = () => { i = null, t || o(...n); }, h = t && !i; i && clearTimeout(i), i = setTimeout(r, s), h && o(...n); }; }, ne = (o, s, t) => t * (s - o) + o, re = (o) => 1 - (1 - o) * (1 - o), oe = (o, s, t, i, n) => new Promise((r) => { let h; const a = (d) => { h ?? (h = d); const u = Math.min(1, (d - h) / t); n(ne(o, s, i(u))), u < 1 ? requestAnimationFrame(a) : r(); }; requestAnimationFrame(a); }), he = (o) => { if (!(o != null && o.collapsed)) return o; const { endOffset: s, endContainer: t } = o; if (t.nodeType === 1) return t; if (s + 1 < t.length) o.setEnd(t, s + 1); else if (s > 1) o.setStart(t, s - 1); else return t.parentNode; return o; }, bt = (o, s, t, i = t) => { const n = o.createRange(); return n.setStart(s, t), n.setEnd(s, i), n; }, Et = (o, s, t, i = 0, n = s.nodeValue.length) => { if (n - i === 1) return t(bt(o, s, i), bt(o, s, n)) < 0 ? i : n; const r = Math.floor(i + (n - i) / 2), h = t(bt(o, s, i, r), bt(o, s, r, n)); return h < 0 ? Et(o, s, t, i, r) : h > 0 ? Et(o, s, t, r, n) : r; }, { SHOW_ELEMENT: ae, SHOW_TEXT: le, SHOW_CDATA_SECTION: ce, FILTER_ACCEPT: Dt, FILTER_REJECT: Wt, FILTER_SKIP: qt } = NodeFilter, de = ae | le | ce, Ht = (o, s, t, i) => { const n = (f) => { var _, b; const w = (_ = f.localName) == null ? void 0 : _.toLowerCase(); if (w === "script" || w === "style") return Wt; if (f.nodeType === 1) { const { left: T, right: L } = i(f.getBoundingClientRect()); if (L < s || T > t) return Wt; if (T >= s && L <= t) return Dt; } else { if (!((b = f.nodeValue) != null && b.trim())) return qt; const T = o.createRange(); T.selectNodeContents(f); const { left: L, right: wt } = i(T.getBoundingClientRect()); if (wt >= s && L <= t) return Dt; } return qt; }, r = o.createTreeWalker(o.body, de, { acceptNode: n }), h = []; for (let f = r.nextNode(); f; f = r.nextNode()) h.push(f); const a = h[0] ?? o.body, d = h[h.length - 1] ?? a, u = a.nodeType === 1 ? 0 : Et(o, a, (f, w) => { const _ = i(f.getBoundingClientRect()), b = i(w.getBoundingClientRect()); return _.right < s && b.left > s ? 0 : b.left > s ? -1 : 1; }), v = d.nodeType === 1 ? 0 : Et(o, d, (f, w) => { const _ = i(f.getBoundingClientRect()), b = i(w.getBoundingClientRect()); return _.right < t && b.left > t ? 0 : b.left > t ? -1 : 1; }), p = o.createRange(); return p.setStart(a, u), p.setEnd(d, v), p; }, ue = (o) => { const { defaultView: s } = o, { writingMode: t, direction: i } = s.getComputedStyle(o.body), n = t === "vertical-rl" || t === "vertical-lr", r = o.body.dir === "rtl" || i === "rtl" || o.documentElement.dir === "rtl"; return { vertical: n, rtl: r }; }, At = (o) => { const s = o.defaultView.getComputedStyle(o.body); return s.backgroundColor === "rgba(0, 0, 0, 0)" && s.backgroundImage === "none" ? o.defaultView.getComputedStyle(o.documentElement).background : s.background; }, Qt = (o, s) => Array.from({ length: o }, () => { const t = document.createElement("div"), i = document.createElement("div"); return t.append(i), i.setAttribute("part", s), t; }), st = (o, s) => { const { style: t } = o; for (const [i, n] of Object.entries(s)) t.setProperty(i, n, "important"); }; var ot, E, x, ht, y, S, at, J, M, K; class me { constructor({ container: s, onExpand: t }) { l(this, ot, new ResizeObserver(() => this.expand())); l(this, E, document.createElement("div")); l(this, x, document.createElement("iframe")); l(this, ht, document.createRange()); l(this, y, void 0); l(this, S, !1); l(this, at, !1); l(this, J, !0); l(this, M, void 0); l(this, K, {}); this.container = s, this.onExpand = t, e(this, x).setAttribute("part", "filter"), e(this, E).append(e(this, x)), Object.assign(e(this, E).style, { boxSizing: "content-box", position: "relative", overflow: "hidden", flex: "0 0 auto", width: "100%", height: "100%", display: "flex", justifyContent: "center", alignItems: "center" }), Object.assign(e(this, x).style, { overflow: "hidden", border: "0", display: "none", width: "100%", height: "100%" }), e(this, x).setAttribute("sandbox", "allow-same-origin allow-scripts"), e(this, x).setAttribute("scrolling", "no"); } get element() { return e(this, E); } get document() { return e(this, x).contentDocument; } async load(s, t, i) { if (typeof s != "string") throw new Error(`${s} is not string`); return new Promise((n) => { e(this, x).addEventListener("load", () => { const r = this.document; t == null || t(r), e(this, x).style.display = "block"; const { vertical: h, rtl: a } = ue(r), d = At(r); e(this, x).style.display = "none", m(this, S, h), m(this, at, a), e(this, ht).selectNodeContents(r.body); const u = i == null ? void 0 : i({ vertical: h, rtl: a, background: d }); e(this, x).style.display = "block", this.render(u), e(this, ot).observe(r.body), r.fonts.ready.then(() => this.expand()), n(); }, { once: !0 }), e(this, x).src = s; }); } render(s) { s && (m(this, J, s.flow !== "scrolled"), m(this, K, s), e(this, J) ? this.columnize(s) : this.scrolled(s)); } scrolled({ gap: s, columnWidth: t }) { const i = e(this, S), n = this.document; st(n.documentElement, { "box-sizing": "border-box", padding: i ? `${s}px 0` : `0 ${s}px`, "column-width": "auto", height: "auto", width: "auto" }), st(n.body, { [i ? "max-height" : "max-width"]: `${t}px`, margin: "auto" }), this.setImageSize(), this.expand(); } columnize({ width: s, height: t, gap: i, columnWidth: n }) { const r = e(this, S); m(this, M, r ? t : s); const h = this.document; st(h.documentElement, { "box-sizing": "border-box", "column-width": `${Math.trunc(n)}px`, "column-gap": `${i}px`, "column-fill": "auto", ...r ? { width: `${s}px` } : { height: `${t}px` }, padding: r ? `${i / 2}px 0` : `0 ${i / 2}px`, overflow: "hidden", // force wrap long words "overflow-wrap": "break-word", // reset some potentially problematic props position: "static", border: "0", margin: "0", "max-height": "none", "max-width": "none", "min-height": "none", "min-width": "none", // fix glyph clipping in WebKit "-webkit-line-box-contain": "block glyphs replaced" }), st(h.body, { "max-height": "none", "max-width": "none", margin: "0" }), this.setImageSize(), this.expand(); } setImageSize() { const { width: s, height: t, margin: i } = e(this, K), n = e(this, S), r = this.document; for (const h of r.body.querySelectorAll("img, svg, video")) { const { maxHeight: a, maxWidth: d } = r.defaultView.getComputedStyle(h); st(h, { "max-height": n ? a !== "none" && a !== "0px" ? a : "100%" : `${t - i * 2}px`, "max-width": n ? `${s - i * 2}px` : d !== "none" && d !== "0px" ? d : "100%", "object-fit": "contain", "page-break-inside": "avoid", "break-inside": "avoid", "box-sizing": "border-box" }); } } expand() { const { documentElement: s } = this.document; if (e(this, J)) { const t = e(this, S) ? "height" : "width", i = e(this, S) ? "width" : "height", n = e(this, ht).getBoundingClientRect(), r = s.getBoundingClientRect(), a = (e(this, S) ? 0 : e(this, at) ? r.right - n.right : n.left - r.left) + n[t], u = Math.ceil(a / e(this, M)) * e(this, M); e(this, E).style.padding = "0", e(this, x).style[t] = `${u}px`, e(this, E).style[t] = `${u + e(this, M) * 2}px`, e(this, x).style[i] = "100%", e(this, E).style[i] = "100%", s.style[t] = `${e(this, M)}px`, e(this, y) && (e(this, y).element.style.margin = "0", e(this, y).element.style.left = e(this, S) ? "0" : `${e(this, M)}px`, e(this, y).element.style.top = e(this, S) ? `${e(this, M)}px` : "0", e(this, y).element.style[t] = `${u}px`, e(this, y).redraw()); } else { const t = e(this, S) ? "width" : "height", i = e(this, S) ? "height" : "width", r = s.getBoundingClientRect()[t], { margin: h } = e(this, K), a = e(this, S) ? `0 ${h}px` : `${h}px 0`; e(this, E).style.padding = a, e(this, x).style[t] = `${r}px`, e(this, E).style[t] = `${r}px`, e(this, x).style[i] = "100%", e(this, E).style[i] = "100%", e(this, y) && (e(this, y).element.style.margin = a, e(this, y).element.style.left = "0", e(this, y).element.style.top = "0", e(this, y).element.style[t] = `${r}px`, e(this, y).redraw()); } this.onExpand(); } set overlayer(s) { m(this, y, s), e(this, E).append(s.element); } get overlayer() { return e(this, y); } destroy() { this.document && e(this, ot).unobserve(this.document.body); } } ot = new WeakMap(), E = new WeakMap(), x = new WeakMap(), ht = new WeakMap(), y = new WeakMap(), S = new WeakMap(), at = new WeakMap(), J = new WeakMap(), M = new WeakMap(), K = new WeakMap(); var A, lt, R, D, z, V, W, g, C, k, P, $, I, U, q, ct, dt, ut, Z, N, H, tt, zt, Gt, mt, Rt, gt, Pt, pt, It, ft, Bt, Q, nt, _t, Yt, O, G, F, Y, Ct, Jt, Tt, Kt, X, rt, xt, Lt, yt, Vt, et, St, kt, Ut, Mt, Zt, B, j, vt, Nt; class Xt extends HTMLElement { constructor() { super(); l(this, zt); l(this, mt); l(this, gt); l(this, pt); l(this, ft); // allows one to process rects as if they were LTR and horizontal l(this, Q); l(this, _t); l(this, O); l(this, F); l(this, Ct); l(this, Tt); l(this, X); l(this, xt); l(this, yt); l(this, et); l(this, kt); l(this, Mt); l(this, B); l(this, vt); l(this, A, this.attachShadow({ mode: "closed" })); l(this, lt, new ResizeObserver(() => this.render())); l(this, R, void 0); l(this, D, void 0); l(this, z, void 0); l(this, V, void 0); l(this, W, void 0); l(this, g, void 0); l(this, C, !1); l(this, k, !1); l(this, P, 0); l(this, $, -1); l(this, I, 0); // anchor view to a fraction (0-1), Range, or Element l(this, U, !1); l(this, q, !1); // while true, prevent any further navigation l(this, ct, void 0); l(this, dt, /* @__PURE__ */ new WeakMap()); l(this, ut, matchMedia("(prefers-color-scheme: dark)")); l(this, Z, void 0); l(this, N, void 0); l(this, H, void 0); l(this, tt, void 0); e(this, A).innerHTML = `<style> :host { display: block; container-type: size; } :host, #top { box-sizing: border-box; position: relative; overflow: hidden; width: 100%; height: 100%; } #top { --_gap: 7%; --_margin: 48px; --_max-inline-size: 720px; --_max-block-size: 1440px; --_max-column-count: 2; --_max-column-count-portrait: 1; --_max-column-count-spread: var(--_max-column-count); --_half-gap: calc(var(--_gap) / 2); --_max-width: calc(var(--_max-inline-size) * var(--_max-column-count-spread)); --_max-height: var(--_max-block-size); display: grid; grid-template-columns: minmax(var(--_half-gap), 1fr) var(--_half-gap) minmax(0, calc(var(--_max-width) - var(--_gap))) var(--_half-gap) minmax(var(--_half-gap), 1fr); grid-template-rows: minmax(var(--_margin), 1fr) minmax(0, var(--_max-height)) minmax(var(--_margin), 1fr); &.vertical { --_max-column-count-spread: var(--_max-column-count-portrait); --_max-width: var(--_max-block-size); --_max-height: calc(var(--_max-inline-size) * var(--_max-column-count-spread)); } @container (orientation: portrait) { & { --_max-column-count-spread: var(--_max-column-count-portrait); } &.vertical { --_max-column-count-spread: var(--_max-column-count); } } } #background { grid-column: 1 / -1; grid-row: 1 / -1; } #container { grid-column: 2 / 5; grid-row: 2; overflow: hidden; } :host([flow="scrolled"]) #container { grid-column: 1 / -1; grid-row: 1 / -1; overflow: auto; } #header { grid-column: 3 / 4; grid-row: 1; } #footer { grid-column: 3 / 4; grid-row: 3; align-self: end; } #header, #footer { display: grid; height: var(--_margin); } :is(#header, #footer) > * { display: flex; align-items: center; min-width: 0; } :is(#header, #footer) > * > * { width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; text-align: center; font-size: .75em; opacity: .6; } </style> <div id="top"> <div id="background" part="filter"></div> <div id="header"></div> <div id="container"></div> <div id="footer"></div> </div> `, m(this, R, e(this, A).getElementById("top")), m(this, D, e(this, A).getElementById("background")), m(this, z, e(this, A).getElementById("container")), m(this, V, e(this, A).getElementById("header")), m(this, W, e(this, A).getElementById("footer")), e(this, lt).observe(e(this, z)), e(this, z).addEventListener("scroll", se(() => { this.scrolled && (e(this, U) ? m(this, U, !1) : c(this, X, rt).call(this, "scroll")); }, 250)); const t = { passive: !1 }; this.addEventListener("touchstart", c(this, gt, Pt).bind(this), t), this.addEventListener("touchmove", c(this, pt, It).bind(this), t), this.addEventListener("touchend", c(this, ft, Bt).bind(this)), this.addEventListener("load", ({ detail: { doc: i } }) => { i.addEventListener("touchstart", c(this, gt, Pt).bind(this), t), i.addEventListener("touchmove", c(this, pt, It).bind(this), t), i.addEventListener("touchend", c(this, ft, Bt).bind(this)); }), m(this, Z, () => { e(this, g) && (e(this, D).style.background = At(e(this, g).document)); }), e(this, ut).addEventListener("change", e(this, Z)); } attributeChangedCallback(t, i, n) { switch (t) { case "flow": this.render(); break; case "gap": case "margin": case "max-block-size": case "max-column-count": e(this, R).style.setProperty("--_" + t, n); break; case "max-inline-size": e(this, R).style.setProperty("--_" + t, n), this.render(); break; } } open(t) { this.bookDir = t.dir, this.sections = t.sections; } render() { e(this, g) && (e(this, g).render(c(this, mt, Rt).call(this, { vertical: e(this, C), rtl: e(this, k) })), this.scrollToAnchor(e(this, I))); } get scrolled() { return this.getAttribute("flow") === "scrolled"; } get scrollProp() { const { scrolled: t } = this; return e(this, C) ? t ? "scrollLeft" : "scrollTop" : t ? "scrollTop" : "scrollLeft"; } get sideProp() { const { scrolled: t } = this; return e(this, C) ? t ? "width" : "height" : t ? "height" : "width"; } get size() { return e(this, z).getBoundingClientRect()[this.sideProp]; } get viewSize() { return e(this, g).element.getBoundingClientRect()[this.sideProp]; } get start() { return Math.abs(e(this, z)[this.scrollProp]); } get end() { return this.start + this.size; } get page() { return Math.floor((this.start + this.end) / 2 / this.size); } get pages() { return Math.round(this.viewSize / this.size); } scrollBy(t, i) { const n = e(this, C) ? i : t, r = e(this, z), { scrollProp: h } = this, [a, d, u] = e(this, N), v = e(this, k), p = v ? a - u : a - d, f = v ? a + d : a + u; r[h] = Math.max(p, Math.min( f, r[h] + n )); } snap(t, i) { const n = e(this, C) ? i : t, [r, h, a] = e(this, N), { start: d, end: u, pages: v, size: p } = this, f = Math.abs(r) - h, w = Math.abs(r) + a, _ = n * (e(this, k) ? -p : p), b = Math.floor( Math.max(f, Math.min(w, (d + u) / 2 + (isNaN(_) ? 0 : _))) / p ); c(this, F, Y).call(this, b, "snap").then(() => { const T = b <= 0 ? -1 : b >= v - 1 ? 1 : null; if (T) return c(this, et, St).call(this, { index: c(this, B, j).call(this, T), anchor: T < 0 ? () => 1 : () => 0 }); }); } async scrollToAnchor(t, i) { var d, u; m(this, I, t); const n = (u = (d = he(t)) == null ? void 0 : d.getClientRects) == null ? void 0 : u.call(d); if (n) { const v = Array.from(n).find((p) => p.width > 0 && p.height > 0) || n[0]; if (!v) return; await c(this, _t, Yt).call(this, v, "anchor"), i && c(this, Ct, Jt).call(this); return; } if (this.scrolled) { await c(this, O, G).call(this, t * this.viewSize, "anchor"); return; } const { pages: r } = this; if (!r) return; const h = r - 2, a = Math.round(t * (h - 1)); await c(this, F, Y).call(this, a + 1, "anchor"); } async goTo(t) { if (e(this, q)) return; const i = await t; if (c(this, yt, Vt).call(this, i.index)) return c(this, et, St).call(this, i); } get atStart() { return c(this, B, j).call(this, -1) == null && this.page <= 1; } get atEnd() { return c(this, B, j).call(this, 1) == null && this.page >= this.pages - 2; } prev(t) { return c(this, vt, Nt).call(this, -1, t); } next(t) { return c(this, vt, Nt).call(this, 1, t); } prevSection() { return this.goTo({ index: c(this, B, j).call(this, -1) }); } nextSection() { return this.goTo({ index: c(this, B, j).call(this, 1) }); } firstSection() { const t = this.sections.findIndex((i) => i.linear !== "no"); return this.goTo({ index: t }); } lastSection() { const t = this.sections.findLastIndex((i) => i.linear !== "no"); return this.goTo({ index: t }); } getContents() { return e(this, g) ? [{ index: e(this, $), overlayer: e(this, g).overlayer, doc: e(this, g).document }] : []; } setStyles(t) { var h, a, d, u, v; m(this, ct, t); const i = e(this, dt).get((h = e(this, g)) == null ? void 0 : h.document); if (!i) return; const [n, r] = i; if (Array.isArray(t)) { const [p, f] = t; n.textContent = p, r.textContent = f; } else r.textContent = t; e(this, D).style.background = At(e(this, g).document), (v = (u = (d = (a = e(this, g)) == null ? void 0 : a.document) == null ? void 0 : d.fonts) == null ? void 0 : u.ready) == null || v.then(() => e(this, g).expand()); } destroy() { var t, i; e(this, lt).unobserve(this), e(this, g).destroy(), m(this, g, null), (i = (t = this.sections[e(this, $)]) == null ? void 0 : t.unload) == null || i.call(t), e(this, ut).removeEventListener("change", e(this, Z)); } } A = new WeakMap(), lt = new WeakMap(), R = new WeakMap(), D = new WeakMap(), z = new WeakMap(), V = new WeakMap(), W = new WeakMap(), g = new WeakMap(), C = new WeakMap(), k = new WeakMap(), P = new WeakMap(), $ = new WeakMap(), I = new WeakMap(), U = new WeakMap(), q = new WeakMap(), ct = new WeakMap(), dt = new WeakMap(), ut = new WeakMap(), Z = new WeakMap(), N = new WeakMap(), H = new WeakMap(), tt = new WeakMap(), zt = new WeakSet(), Gt = function() { return e(this, g) && (e(this, g).destroy(), e(this, z).removeChild(e(this, g).element)), m(this, g, new me({ container: this, onExpand: () => this.scrollToAnchor(e(this, I)) })), e(this, z).append(e(this, g).element), e(this, g); }, mt = new WeakSet(), Rt = function({ vertical: t, rtl: i, background: n }) { m(this, C, t), m(this, k, i), e(this, R).classList.toggle("vertical", t), e(this, D).style.background = n; const { width: r, height: h } = e(this, z).getBoundingClientRect(), a = t ? h : r, d = getComputedStyle(e(this, R)), u = parseFloat(d.getPropertyValue("--_max-inline-size")), v = parseInt(d.getPropertyValue("--_max-column-count-spread")), p = parseFloat(d.getPropertyValue("--_margin")); m(this, P, p); const f = parseFloat(d.getPropertyValue("--_gap")) / 100, w = -f / (f - 1) * a, _ = this.getAttribute("flow"); if (_ === "scrolled") { this.setAttribute("dir", t ? "rtl" : "ltr"), e(this, R).style.padding = "0"; const it = u; return this.heads = null, this.feet = null, e(this, V).replaceChildren(), e(this, W).replaceChildren(), { flow: _, margin: p, gap: w, columnWidth: it }; } const b = Math.min(v, Math.ceil(a / u)), T = a / b - w; this.setAttribute("dir", i ? "rtl" : "ltr"); const L = t ? Math.min(2, Math.ceil(r / u)) : b, wt = { gridTemplateColumns: `repeat(${L}, 1fr)`, gap: `${w}px`, direction: this.bookDir === "rtl" ? "rtl" : "ltr" }; Object.assign(e(this, V).style, wt), Object.assign(e(this, W).style, wt); const Ot = Qt(L, "head"), Ft = Qt(L, "foot"); return this.heads = Ot.map((it) => it.children[0]), this.feet = Ft.map((it) => it.children[0]), e(this, V).replaceChildren(...Ot), e(this, W).replaceChildren(...Ft), { height: h, width: r, margin: p, gap: w, columnWidth: T }; }, gt = new WeakSet(), Pt = function(t) { const i = t.changedTouches[0]; m(this, H, { x: i == null ? void 0 : i.screenX, y: i == null ? void 0 : i.screenY, t: t.timeStamp, vx: 0, xy: 0 }); }, pt = new WeakSet(), It = function(t) { const i = e(this, H); if (i.pinched || (i.pinched = globalThis.visualViewport.scale > 1, this.scrolled || i.pinched)) return; if (t.touches.length > 1) { e(this, tt) && t.preventDefault(); return; } t.preventDefault(); const n = t.changedTouches[0], r = n.screenX, h = n.screenY, a = i.x - r, d = i.y - h, u = t.timeStamp - i.t; i.x = r, i.y = h, i.t = t.timeStamp, i.vx = a / u, i.vy = d / u, m(this, tt, !0), this.scrollBy(a, d); }, ft = new WeakSet(), Bt = function() { m(this, tt, !1), !this.scrolled && requestAnimationFrame(() => { globalThis.visualViewport.scale === 1 && this.snap(e(this, H).vx, e(this, H).vy); }); }, Q = new WeakSet(), nt = function() { if (this.scrolled) { const i = this.viewSize, n = e(this, P); return e(this, C) ? ({ left: r, right: h }) => ({ left: i - h - n, right: i - r - n }) : ({ top: r, bottom: h }) => ({ left: r + n, right: h + n }); } const t = this.pages * this.size; return e(this, k) ? ({ left: i, right: n }) => ({ left: t - n, right: t - i }) : e(this, C) ? ({ top: i, bottom: n }) => ({ left: i, right: n }) : (i) => i; }, _t = new WeakSet(), Yt = async function(t, i) { if (this.scrolled) { const r = c(this, Q, nt).call(this)(t).left - e(this, P); return c(this, O, G).call(this, r, i); } const n = c(this, Q, nt).call(this)(t).left + e(this, P) / 2; return c(this, F, Y).call(this, Math.floor(n / this.size) + (e(this, k) ? -1 : 1), i); }, O = new WeakSet(), G = async function(t, i, n) { const r = e(this, z), { scrollProp: h, size: a } = this; if (r[h] === t) { m(this, N, [t, this.atStart ? 0 : a, this.atEnd ? 0 : a]), c(this, X, rt).call(this, i); return; } if (this.scrolled && e(this, C) && (t = -t), (i === "snap" || n) && this.hasAttribute("animated")) return oe( r[h], t, 300, re, (d) => r[h] = d ).then(() => { m(this, N, [t, this.atStart ? 0 : a, this.atEnd ? 0 : a]), c(this, X, rt).call(this, i); }); r[h] = t, m(this, N, [t, this.atStart ? 0 : a, this.atEnd ? 0 : a]), c(this, X, rt).call(this, i); }, F = new WeakSet(), Y = async function(t, i, n) { const r = this.size * (e(this, k) ? -t : t); return c(this, O, G).call(this, r, i, n); }, Ct = new WeakSet(), Jt = function() { const { defaultView: t } = e(this, g).document; if (e(this, I).startContainer) { const i = t.getSelection(); i.removeAllRanges(), i.addRange(e(this, I)); } }, Tt = new WeakSet(), Kt = function() { if (this.scrolled) return Ht( e(this, g).document, this.start + e(this, P), this.end - e(this, P), c(this, Q, nt).call(this) ); const t = e(this, k) ? -this.size : this.size; return Ht( e(this, g).document, this.start - t, this.end - t, c(this, Q, nt).call(this) ); }, X = new WeakSet(), rt = function(t) { const i = c(this, Tt, Kt).call(this); t !== "anchor" ? m(this, I, i) : m(this, U, !0); const n = e(this, $), r = { reason: t, range: i, index: n }; if (this.scrolled) r.fraction = this.start / this.viewSize; else if (this.pages > 0) { const { page: h, pages: a } = this; e(this, V).style.visibility = h > 1 ? "visible" : "hidden", r.fraction = (h - 1) / (a - 2), r.size = 1 / (a - 2); } this.dispatchEvent(new CustomEvent("relocate", { detail: r })); }, xt = new WeakSet(), Lt = async function(t) { const { index: i, src: n, anchor: r, onLoad: h, select: a } = await t; if (m(this, $, i), n) { const d = c(this, zt, Gt).call(this), u = (p) => { if (p.head) { const f = p.createElement("style"); p.head.prepend(f); const w = p.createElement("style"); p.head.append(w), e(this, dt).set(p, [f, w]); } h == null || h({ doc: p, index: i }); }, v = c(this, mt, Rt).bind(this); await d.load(n, u, v), this.dispatchEvent(new CustomEvent("create-overlayer", { detail: { doc: d.document, index: i, attach: (p) => d.overlayer = p } })), m(this, g, d); } await this.scrollToAnchor((typeof r == "function" ? r(e(this, g).document) : r) ?? 0, a); }, yt = new WeakSet(), Vt = function(t) { return t >= 0 && t <= this.sections.length - 1; }, et = new WeakSet(), St = async function({ index: t, anchor: i, select: n }) { if (t === e(this, $)) await c(this, xt, Lt).call(this, { index: t, anchor: i, select: n }); else { const r = e(this, $), h = (a) => { var d, u; (u = (d = this.sections[r]) == null ? void 0 : d.unload) == null || u.call(d), this.setStyles(e(this, ct)), this.dispatchEvent(new CustomEvent("load", { detail: a })); }; await c(this, xt, Lt).call(this, Promise.resolve(this.sections[t].load()).then((a) => ({ index: t, src: a, anchor: i, onLoad: h, select: n })).catch((a) => (console.warn(a), console.warn(new Error(`Failed to load section ${t}`)), {}))); } }, kt = new WeakSet(), Ut = function(t) { if (!e(this, g)) return !0; if (this.scrolled) return this.start > 0 ? c(this, O, G).call(this, Math.max(0, this.start - (t ?? this.size)), null, !0) : !0; if (this.atStart) return; const i = this.page - 1; return c(this, F, Y).call(this, i, "page", !0).then(() => i <= 0); }, Mt = new WeakSet(), Zt = function(t) { if (!e(this, g)) return !0; if (this.scrolled) return this.viewSize - this.end > 2 ? c(this, O, G).call(this, Math.min(this.viewSize, t ? this.start + t : this.end), null, !0) : !0; if (this.atEnd) return; const i = this.page + 1, n = this.pages; return c(this, F, Y).call(this, i, "page", !0).then(() => i >= n - 1); }, B = new WeakSet(), j = function(t) { var i; for (let n = e(this, $) + t; c(this, yt, Vt).call(this, n); n += t) if (((i = this.sections[n]) == null ? void 0 : i.linear) !== "no") return n; }, vt = new WeakSet(), Nt = async function(t, i) { if (e(this, q)) return; m(this, q, !0); const n = t === -1, r = await (n ? c(this, kt, Ut).call(this, i) : c(this, Mt, Zt).call(this, i)); r && await c(this, et, St).call(this, { index: c(this, B, j).call(this, t), anchor: n ? () => 1 : () => 0 }), (r || !this.hasAttribute("animated")) && await ie(100), m(this, q, !1); }, jt(Xt, "observedAttributes", [ "flow", "gap", "margin", "max-inline-size", "max-block-size", "max-column-count" ]); customElements.define("foliate-paginator", Xt); export { Xt as Paginator };