UNPKG

opfs-worker

Version:

A robust TypeScript library for working with Origin Private File System (OPFS) through Web Workers

1,485 lines (1,484 loc) 77.8 kB
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("comlink"),n=require("./helpers-Cvjm0f_r.cjs"),i=`/** * @license * Copyright 2019 Google LLC * SPDX-License-Identifier: Apache-2.0 */ const ut = Symbol("Comlink.proxy"), Dt = Symbol("Comlink.endpoint"), Nt = Symbol("Comlink.releaseProxy"), U = Symbol("Comlink.finalizer"), L = Symbol("Comlink.thrown"), ft = (s) => typeof s == "object" && s !== null || typeof s == "function", Tt = { canHandle: (s) => ft(s) && s[ut], serialize(s) { const { port1: t, port2: e } = new MessageChannel(); return J(s, t), [e, [e]]; }, deserialize(s) { return s.start(), Pt(s); } }, Ft = { canHandle: (s) => ft(s) && L in s, serialize({ value: s }) { let t; return s instanceof Error ? t = { isError: !0, value: { message: s.message, name: s.name, stack: s.stack } } : t = { isError: !1, value: s }, [t, []]; }, deserialize(s) { throw s.isError ? Object.assign(new Error(s.value.message), s.value) : s.value; } }, dt = /* @__PURE__ */ new Map([ ["proxy", Tt], ["throw", Ft] ]); function Mt(s, t) { for (const e of s) if (t === e || e === "*" || e instanceof RegExp && e.test(t)) return !0; return !1; } function J(s, t = globalThis, e = ["*"]) { t.addEventListener("message", function n(i) { if (!i || !i.data) return; if (!Mt(e, i.origin)) { console.warn(\`Invalid origin '\${i.origin}' for comlink proxy\`); return; } const { id: r, type: o, path: a } = Object.assign({ path: [] }, i.data), l = (i.data.argumentList || []).map(C); let h; try { const c = a.slice(0, -1).reduce((u, d) => u[d], s), f = a.reduce((u, d) => u[d], s); switch (o) { case "GET": h = f; break; case "SET": c[a.slice(-1)[0]] = C(i.data.value), h = !0; break; case "APPLY": h = f.apply(c, l); break; case "CONSTRUCT": { const u = new f(...l); h = zt(u); } break; case "ENDPOINT": { const { port1: u, port2: d } = new MessageChannel(); J(s, d), h = It(u, [u]); } break; case "RELEASE": h = void 0; break; default: return; } } catch (c) { h = { value: c, [L]: 0 }; } Promise.resolve(h).catch((c) => ({ value: c, [L]: 0 })).then((c) => { const [f, u] = H(c); t.postMessage(Object.assign(Object.assign({}, f), { id: r }), u), o === "RELEASE" && (t.removeEventListener("message", n), pt(t), U in s && typeof s[U] == "function" && s[U]()); }).catch((c) => { const [f, u] = H({ value: new TypeError("Unserializable return value"), [L]: 0 }); t.postMessage(Object.assign(Object.assign({}, f), { id: r }), u); }); }), t.start && t.start(); } function $t(s) { return s.constructor.name === "MessagePort"; } function pt(s) { $t(s) && s.close(); } function Pt(s, t) { const e = /* @__PURE__ */ new Map(); return s.addEventListener("message", function(i) { const { data: r } = i; if (!r || !r.id) return; const o = e.get(r.id); if (o) try { o(r); } finally { e.delete(r.id); } }), X(s, e, [], t); } function R(s) { if (s) throw new Error("Proxy has been released and is not useable"); } function gt(s) { return O(s, /* @__PURE__ */ new Map(), { type: "RELEASE" }).then(() => { pt(s); }); } const I = /* @__PURE__ */ new WeakMap(), z = "FinalizationRegistry" in globalThis && new FinalizationRegistry((s) => { const t = (I.get(s) || 0) - 1; I.set(s, t), t === 0 && gt(s); }); function Rt(s, t) { const e = (I.get(t) || 0) + 1; I.set(t, e), z && z.register(s, t, s); } function kt(s) { z && z.unregister(s); } function X(s, t, e = [], n = function() { }) { let i = !1; const r = new Proxy(n, { get(o, a) { if (R(i), a === Nt) return () => { kt(r), gt(s), t.clear(), i = !0; }; if (a === "then") { if (e.length === 0) return { then: () => r }; const l = O(s, t, { type: "GET", path: e.map((h) => h.toString()) }).then(C); return l.then.bind(l); } return X(s, t, [...e, a]); }, set(o, a, l) { R(i); const [h, c] = H(l); return O(s, t, { type: "SET", path: [...e, a].map((f) => f.toString()), value: h }, c).then(C); }, apply(o, a, l) { R(i); const h = e[e.length - 1]; if (h === Dt) return O(s, t, { type: "ENDPOINT" }).then(C); if (h === "bind") return X(s, t, e.slice(0, -1)); const [c, f] = st(l); return O(s, t, { type: "APPLY", path: e.map((u) => u.toString()), argumentList: c }, f).then(C); }, construct(o, a) { R(i); const [l, h] = st(a); return O(s, t, { type: "CONSTRUCT", path: e.map((c) => c.toString()), argumentList: l }, h).then(C); } }); return Rt(r, s), r; } function Lt(s) { return Array.prototype.concat.apply([], s); } function st(s) { const t = s.map(H); return [t.map((e) => e[0]), Lt(t.map((e) => e[1]))]; } const mt = /* @__PURE__ */ new WeakMap(); function It(s, t) { return mt.set(s, t), s; } function zt(s) { return Object.assign(s, { [ut]: !0 }); } function H(s) { for (const [t, e] of dt) if (e.canHandle(s)) { const [n, i] = e.serialize(s); return [ { type: "HANDLER", name: t, value: n }, i ]; } return [ { type: "RAW", value: s }, mt.get(s) || [] ]; } function C(s) { switch (s.type) { case "HANDLER": return dt.get(s.name).deserialize(s.value); case "RAW": return s.value; } } function O(s, t, e, n) { return new Promise((i) => { const r = Ht(); t.set(r, i), s.start && s.start(), s.postMessage(Object.assign({ id: r }, e), n); }); } function Ht() { return new Array(4).fill(0).map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16)).join("-"); } class g extends Error { constructor(t, e, n, i) { super(t, { cause: i }), this.code = e, this.path = n, this.name = "OPFSError"; } } class Wt extends g { constructor(t) { super("OPFS is not supported in this browser", "OPFS_NOT_SUPPORTED", void 0, t); } } class jt extends g { constructor(t, e, n) { super(t, "INVALID_PATH", e, n); } } class _ extends g { constructor(t, e) { super(\`File not found: \${t}\`, "FILE_NOT_FOUND", t, e); } } function Ut(s, t = "utf-8") { switch (t) { case "utf8": case "utf-8": return new TextEncoder().encode(s); case "utf16le": case "ucs2": case "ucs-2": return Bt(s); case "ascii": return Vt(s); case "latin1": return qt(s); case "binary": return Uint8Array.from(s, (e) => e.charCodeAt(0)); case "base64": return Uint8Array.from(atob(s), (e) => e.charCodeAt(0)); case "hex": if (!/^[\\da-f]+$/i.test(s) || s.length % 2 !== 0) throw new g("Invalid hex string", "INVALID_HEX_FORMAT"); return Uint8Array.from(s.match(/.{1,2}/g).map((e) => parseInt(e, 16))); default: return console.warn("Encoding not supported, falling back to UTF-8"), new TextEncoder().encode(s); } } function _t(s, t = "utf-8") { switch (t) { case "utf8": case "utf-8": return new TextDecoder().decode(s); case "utf16le": case "utf-16le": case "ucs2": case "ucs-2": return Gt(s); case "latin1": return String.fromCharCode(...s); case "ascii": return String.fromCharCode(...s.map((e) => e & 127)); case "base64": return btoa(String.fromCharCode(...s)); case "hex": return Array.from(s).map((e) => e.toString(16).padStart(2, "0")).join(""); default: return console.warn("Unsupported encoding, falling back to UTF-8"), new TextDecoder().decode(s); } } function Bt(s) { const t = new Uint8Array(s.length * 2); for (let e = 0; e < s.length; e++) { const n = s.charCodeAt(e); t[e * 2] = n & 255, t[e * 2 + 1] = n >> 8; } return t; } function Gt(s) { s.length % 2 !== 0 && (console.warn("Invalid UTF-16LE buffer length, truncating last byte"), s = s.slice(0, s.length - 1)); const t = new Uint16Array(s.buffer, s.byteOffset, s.byteLength / 2); return String.fromCharCode(...t); } function qt(s) { const t = new Uint8Array(s.length); for (let e = 0; e < s.length; e++) t[e] = s.charCodeAt(e) & 255; return t; } function Vt(s) { const t = new Uint8Array(s.length); for (let e = 0; e < s.length; e++) t[e] = s.charCodeAt(e) & 127; return t; } const wt = (s, t, e) => { const n = s instanceof RegExp ? nt(s, e) : s, i = t instanceof RegExp ? nt(t, e) : t, r = n !== null && i != null && Xt(n, i, e); return r && { start: r[0], end: r[1], pre: e.slice(0, r[0]), body: e.slice(r[0] + n.length, r[1]), post: e.slice(r[1] + i.length) }; }, nt = (s, t) => { const e = t.match(s); return e ? e[0] : null; }, Xt = (s, t, e) => { let n, i, r, o, a, l = e.indexOf(s), h = e.indexOf(t, l + 1), c = l; if (l >= 0 && h > 0) { if (s === t) return [l, h]; for (n = [], r = e.length; c >= 0 && !a; ) { if (c === l) n.push(c), l = e.indexOf(s, c + 1); else if (n.length === 1) { const f = n.pop(); f !== void 0 && (a = [f, h]); } else i = n.pop(), i !== void 0 && i < r && (r = i, o = h), h = e.indexOf(t, c + 1); c = l < h && l >= 0 ? l : h; } n.length && o !== void 0 && (a = [r, o]); } return a; }, yt = "\\0SLASH" + Math.random() + "\\0", Et = "\\0OPEN" + Math.random() + "\\0", K = "\\0CLOSE" + Math.random() + "\\0", St = "\\0COMMA" + Math.random() + "\\0", xt = "\\0PERIOD" + Math.random() + "\\0", Yt = new RegExp(yt, "g"), Zt = new RegExp(Et, "g"), Jt = new RegExp(K, "g"), Kt = new RegExp(St, "g"), Qt = new RegExp(xt, "g"), te = /\\\\\\\\/g, ee = /\\\\{/g, se = /\\\\}/g, ne = /\\\\,/g, ie = /\\\\./g; function B(s) { return isNaN(s) ? s.charCodeAt(0) : parseInt(s, 10); } function re(s) { return s.replace(te, yt).replace(ee, Et).replace(se, K).replace(ne, St).replace(ie, xt); } function oe(s) { return s.replace(Yt, "\\\\").replace(Zt, "{").replace(Jt, "}").replace(Kt, ",").replace(Qt, "."); } function bt(s) { if (!s) return [""]; const t = [], e = wt("{", "}", s); if (!e) return s.split(","); const { pre: n, body: i, post: r } = e, o = n.split(","); o[o.length - 1] += "{" + i + "}"; const a = bt(r); return r.length && (o[o.length - 1] += a.shift(), o.push.apply(o, a)), t.push.apply(t, o), t; } function ae(s) { return s ? (s.slice(0, 2) === "{}" && (s = "\\\\{\\\\}" + s.slice(2)), M(re(s), !0).map(oe)) : []; } function ce(s) { return "{" + s + "}"; } function le(s) { return /^-?0\\d/.test(s); } function he(s, t) { return s <= t; } function ue(s, t) { return s >= t; } function M(s, t) { const e = [], n = wt("{", "}", s); if (!n) return [s]; const i = n.pre, r = n.post.length ? M(n.post, !1) : [""]; if (/\\$$/.test(n.pre)) for (let o = 0; o < r.length; o++) { const a = i + "{" + n.body + "}" + r[o]; e.push(a); } else { const o = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/.test(n.body), a = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/.test(n.body), l = o || a, h = n.body.indexOf(",") >= 0; if (!l && !h) return n.post.match(/,(?!,).*\\}/) ? (s = n.pre + "{" + n.body + K + n.post, M(s)) : [s]; let c; if (l) c = n.body.split(/\\.\\./); else if (c = bt(n.body), c.length === 1 && c[0] !== void 0 && (c = M(c[0], !1).map(ce), c.length === 1)) return r.map((u) => n.pre + c[0] + u); let f; if (l && c[0] !== void 0 && c[1] !== void 0) { const u = B(c[0]), d = B(c[1]), m = Math.max(c[0].length, c[1].length); let p = c.length === 3 && c[2] !== void 0 ? Math.abs(B(c[2])) : 1, S = he; d < u && (p *= -1, S = ue); const N = c.some(le); f = []; for (let x = u; S(x, d); x += p) { let w; if (a) w = String.fromCharCode(x), w === "\\\\" && (w = ""); else if (w = String(x), N) { const T = m - w.length; if (T > 0) { const P = new Array(T + 1).join("0"); x < 0 ? w = "-" + P + w.slice(1) : w = P + w; } } f.push(w); } } else { f = []; for (let u = 0; u < c.length; u++) f.push.apply(f, M(c[u], !1)); } for (let u = 0; u < f.length; u++) for (let d = 0; d < r.length; d++) { const m = i + f[u] + r[d]; (!t || l || m) && e.push(m); } } return e; } const fe = 1024 * 64, W = (s) => { if (typeof s != "string") throw new TypeError("invalid pattern"); if (s.length > fe) throw new TypeError("pattern is too long"); }, de = { "[:alnum:]": ["\\\\p{L}\\\\p{Nl}\\\\p{Nd}", !0], "[:alpha:]": ["\\\\p{L}\\\\p{Nl}", !0], "[:ascii:]": ["\\\\x00-\\\\x7f", !1], "[:blank:]": ["\\\\p{Zs}\\\\t", !0], "[:cntrl:]": ["\\\\p{Cc}", !0], "[:digit:]": ["\\\\p{Nd}", !0], "[:graph:]": ["\\\\p{Z}\\\\p{C}", !0, !0], "[:lower:]": ["\\\\p{Ll}", !0], "[:print:]": ["\\\\p{C}", !0], "[:punct:]": ["\\\\p{P}", !0], "[:space:]": ["\\\\p{Z}\\\\t\\\\r\\\\n\\\\v\\\\f", !0], "[:upper:]": ["\\\\p{Lu}", !0], "[:word:]": ["\\\\p{L}\\\\p{Nl}\\\\p{Nd}\\\\p{Pc}", !0], "[:xdigit:]": ["A-Fa-f0-9", !1] }, F = (s) => s.replace(/[[\\]\\\\-]/g, "\\\\$&"), pe = (s) => s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, "\\\\$&"), it = (s) => s.join(""), ge = (s, t) => { const e = t; if (s.charAt(e) !== "[") throw new Error("not in a brace expression"); const n = [], i = []; let r = e + 1, o = !1, a = !1, l = !1, h = !1, c = e, f = ""; t: for (; r < s.length; ) { const p = s.charAt(r); if ((p === "!" || p === "^") && r === e + 1) { h = !0, r++; continue; } if (p === "]" && o && !l) { c = r + 1; break; } if (o = !0, p === "\\\\" && !l) { l = !0, r++; continue; } if (p === "[" && !l) { for (const [S, [A, N, x]] of Object.entries(de)) if (s.startsWith(S, r)) { if (f) return ["$.", !1, s.length - e, !0]; r += S.length, x ? i.push(A) : n.push(A), a = a || N; continue t; } } if (l = !1, f) { p > f ? n.push(F(f) + "-" + F(p)) : p === f && n.push(F(p)), f = "", r++; continue; } if (s.startsWith("-]", r + 1)) { n.push(F(p + "-")), r += 2; continue; } if (s.startsWith("-", r + 1)) { f = p, r += 2; continue; } n.push(F(p)), r++; } if (c < r) return ["", !1, 0, !1]; if (!n.length && !i.length) return ["$.", !1, s.length - e, !0]; if (i.length === 0 && n.length === 1 && /^\\\\?.$/.test(n[0]) && !h) { const p = n[0].length === 2 ? n[0].slice(-1) : n[0]; return [pe(p), !1, c - e, !1]; } const u = "[" + (h ? "^" : "") + it(n) + "]", d = "[" + (h ? "" : "^") + it(i) + "]"; return [n.length && i.length ? "(" + u + "|" + d + ")" : n.length ? u : d, a, c - e, !0]; }, $ = (s, { windowsPathsNoEscape: t = !1 } = {}) => t ? s.replace(/\\[([^\\/\\\\])\\]/g, "$1") : s.replace(/((?!\\\\).|^)\\[([^\\/\\\\])\\]/g, "$1$2").replace(/\\\\([^\\/])/g, "$1"), me = /* @__PURE__ */ new Set(["!", "?", "+", "*", "@"]), rt = (s) => me.has(s), we = "(?!(?:^|/)\\\\.\\\\.?(?:$|/))", k = "(?!\\\\.)", ye = /* @__PURE__ */ new Set(["[", "."]), Ee = /* @__PURE__ */ new Set(["..", "."]), Se = new Set("().*{}+?[]^$\\\\!"), xe = (s) => s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, "\\\\$&"), Q = "[^/]", ot = Q + "*?", at = Q + "+?"; class E { type; #s; #n; #r = !1; #t = []; #e; #o; #c; #a = !1; #i; #l; // set to true if it's an extglob with no children // (which really means one child of '') #u = !1; constructor(t, e, n = {}) { this.type = t, t && (this.#n = !0), this.#e = e, this.#s = this.#e ? this.#e.#s : this, this.#i = this.#s === this ? n : this.#s.#i, this.#c = this.#s === this ? [] : this.#s.#c, t === "!" && !this.#s.#a && this.#c.push(this), this.#o = this.#e ? this.#e.#t.length : 0; } get hasMagic() { if (this.#n !== void 0) return this.#n; for (const t of this.#t) if (typeof t != "string" && (t.type || t.hasMagic)) return this.#n = !0; return this.#n; } // reconstructs the pattern toString() { return this.#l !== void 0 ? this.#l : this.type ? this.#l = this.type + "(" + this.#t.map((t) => String(t)).join("|") + ")" : this.#l = this.#t.map((t) => String(t)).join(""); } #d() { if (this !== this.#s) throw new Error("should only call on root"); if (this.#a) return this; this.toString(), this.#a = !0; let t; for (; t = this.#c.pop(); ) { if (t.type !== "!") continue; let e = t, n = e.#e; for (; n; ) { for (let i = e.#o + 1; !n.type && i < n.#t.length; i++) for (const r of t.#t) { if (typeof r == "string") throw new Error("string part in extglob AST??"); r.copyIn(n.#t[i]); } e = n, n = e.#e; } } return this; } push(...t) { for (const e of t) if (e !== "") { if (typeof e != "string" && !(e instanceof E && e.#e === this)) throw new Error("invalid part: " + e); this.#t.push(e); } } toJSON() { const t = this.type === null ? this.#t.slice().map((e) => typeof e == "string" ? e : e.toJSON()) : [this.type, ...this.#t.map((e) => e.toJSON())]; return this.isStart() && !this.type && t.unshift([]), this.isEnd() && (this === this.#s || this.#s.#a && this.#e?.type === "!") && t.push({}), t; } isStart() { if (this.#s === this) return !0; if (!this.#e?.isStart()) return !1; if (this.#o === 0) return !0; const t = this.#e; for (let e = 0; e < this.#o; e++) { const n = t.#t[e]; if (!(n instanceof E && n.type === "!")) return !1; } return !0; } isEnd() { if (this.#s === this || this.#e?.type === "!") return !0; if (!this.#e?.isEnd()) return !1; if (!this.type) return this.#e?.isEnd(); const t = this.#e ? this.#e.#t.length : 0; return this.#o === t - 1; } copyIn(t) { typeof t == "string" ? this.push(t) : this.push(t.clone(this)); } clone(t) { const e = new E(this.type, t); for (const n of this.#t) e.copyIn(n); return e; } static #h(t, e, n, i) { let r = !1, o = !1, a = -1, l = !1; if (e.type === null) { let d = n, m = ""; for (; d < t.length; ) { const p = t.charAt(d++); if (r || p === "\\\\") { r = !r, m += p; continue; } if (o) { d === a + 1 ? (p === "^" || p === "!") && (l = !0) : p === "]" && !(d === a + 2 && l) && (o = !1), m += p; continue; } else if (p === "[") { o = !0, a = d, l = !1, m += p; continue; } if (!i.noext && rt(p) && t.charAt(d) === "(") { e.push(m), m = ""; const S = new E(p, e); d = E.#h(t, S, d, i), e.push(S); continue; } m += p; } return e.push(m), d; } let h = n + 1, c = new E(null, e); const f = []; let u = ""; for (; h < t.length; ) { const d = t.charAt(h++); if (r || d === "\\\\") { r = !r, u += d; continue; } if (o) { h === a + 1 ? (d === "^" || d === "!") && (l = !0) : d === "]" && !(h === a + 2 && l) && (o = !1), u += d; continue; } else if (d === "[") { o = !0, a = h, l = !1, u += d; continue; } if (rt(d) && t.charAt(h) === "(") { c.push(u), u = ""; const m = new E(d, c); c.push(m), h = E.#h(t, m, h, i); continue; } if (d === "|") { c.push(u), u = "", f.push(c), c = new E(null, e); continue; } if (d === ")") return u === "" && e.#t.length === 0 && (e.#u = !0), c.push(u), u = "", e.push(...f, c), h; u += d; } return e.type = null, e.#n = void 0, e.#t = [t.substring(n - 1)], h; } static fromGlob(t, e = {}) { const n = new E(null, void 0, e); return E.#h(t, n, 0, e), n; } // returns the regular expression if there's magic, or the unescaped // string if not. toMMPattern() { if (this !== this.#s) return this.#s.toMMPattern(); const t = this.toString(), [e, n, i, r] = this.toRegExpSource(); if (!(i || this.#n || this.#i.nocase && !this.#i.nocaseMagicOnly && t.toUpperCase() !== t.toLowerCase())) return n; const a = (this.#i.nocase ? "i" : "") + (r ? "u" : ""); return Object.assign(new RegExp(\`^\${e}$\`, a), { _src: e, _glob: t }); } get options() { return this.#i; } // returns the string match, the regexp source, whether there's magic // in the regexp (so a regular expression is required) and whether or // not the uflag is needed for the regular expression (for posix classes) // TODO: instead of injecting the start/end at this point, just return // the BODY of the regexp, along with the start/end portions suitable // for binding the start/end in either a joined full-path makeRe context // (where we bind to (^|/), or a standalone matchPart context (where // we bind to ^, and not /). Otherwise slashes get duped! // // In part-matching mode, the start is: // - if not isStart: nothing // - if traversal possible, but not allowed: ^(?!\\.\\.?$) // - if dots allowed or not possible: ^ // - if dots possible and not allowed: ^(?!\\.) // end is: // - if not isEnd(): nothing // - else: $ // // In full-path matching mode, we put the slash at the START of the // pattern, so start is: // - if first pattern: same as part-matching mode // - if not isStart(): nothing // - if traversal possible, but not allowed: /(?!\\.\\.?(?:$|/)) // - if dots allowed or not possible: / // - if dots possible and not allowed: /(?!\\.) // end is: // - if last pattern, same as part-matching mode // - else nothing // // Always put the (?:$|/) on negated tails, though, because that has to be // there to bind the end of the negated pattern portion, and it's easier to // just stick it in now rather than try to inject it later in the middle of // the pattern. // // We can just always return the same end, and leave it up to the caller // to know whether it's going to be used joined or in parts. // And, if the start is adjusted slightly, can do the same there: // - if not isStart: nothing // - if traversal possible, but not allowed: (?:/|^)(?!\\.\\.?$) // - if dots allowed or not possible: (?:/|^) // - if dots possible and not allowed: (?:/|^)(?!\\.) // // But it's better to have a simpler binding without a conditional, for // performance, so probably better to return both start options. // // Then the caller just ignores the end if it's not the first pattern, // and the start always gets applied. // // But that's always going to be $ if it's the ending pattern, or nothing, // so the caller can just attach $ at the end of the pattern when building. // // So the todo is: // - better detect what kind of start is needed // - return both flavors of starting pattern // - attach $ at the end of the pattern when creating the actual RegExp // // Ah, but wait, no, that all only applies to the root when the first pattern // is not an extglob. If the first pattern IS an extglob, then we need all // that dot prevention biz to live in the extglob portions, because eg // +(*|.x*) can match .xy but not .yx. // // So, return the two flavors if it's #root and the first child is not an // AST, otherwise leave it to the child AST to handle it, and there, // use the (?:^|/) style of start binding. // // Even simplified further: // - Since the start for a join is eg /(?!\\.) and the start for a part // is ^(?!\\.), we can just prepend (?!\\.) to the pattern (either root // or start or whatever) and prepend ^ or / at the Regexp construction. toRegExpSource(t) { const e = t ?? !!this.#i.dot; if (this.#s === this && this.#d(), !this.type) { const l = this.isStart() && this.isEnd(), h = this.#t.map((d) => { const [m, p, S, A] = typeof d == "string" ? E.#p(d, this.#n, l) : d.toRegExpSource(t); return this.#n = this.#n || S, this.#r = this.#r || A, m; }).join(""); let c = ""; if (this.isStart() && typeof this.#t[0] == "string" && !(this.#t.length === 1 && Ee.has(this.#t[0]))) { const m = ye, p = ( // dots are allowed, and the pattern starts with [ or . e && m.has(h.charAt(0)) || // the pattern starts with \\., and then [ or . h.startsWith("\\\\.") && m.has(h.charAt(2)) || // the pattern starts with \\.\\., and then [ or . h.startsWith("\\\\.\\\\.") && m.has(h.charAt(4)) ), S = !e && !t && m.has(h.charAt(0)); c = p ? we : S ? k : ""; } let f = ""; return this.isEnd() && this.#s.#a && this.#e?.type === "!" && (f = "(?:$|\\\\/)"), [ c + h + f, $(h), this.#n = !!this.#n, this.#r ]; } const n = this.type === "*" || this.type === "+", i = this.type === "!" ? "(?:(?!(?:" : "(?:"; let r = this.#f(e); if (this.isStart() && this.isEnd() && !r && this.type !== "!") { const l = this.toString(); return this.#t = [l], this.type = null, this.#n = void 0, [l, $(this.toString()), !1, !1]; } let o = !n || t || e || !k ? "" : this.#f(!0); o === r && (o = ""), o && (r = \`(?:\${r})(?:\${o})*?\`); let a = ""; if (this.type === "!" && this.#u) a = (this.isStart() && !e ? k : "") + at; else { const l = this.type === "!" ? ( // !() must match something,but !(x) can match '' "))" + (this.isStart() && !e && !t ? k : "") + ot + ")" ) : this.type === "@" ? ")" : this.type === "?" ? ")?" : this.type === "+" && o ? ")" : this.type === "*" && o ? ")?" : \`)\${this.type}\`; a = i + r + l; } return [ a, $(r), this.#n = !!this.#n, this.#r ]; } #f(t) { return this.#t.map((e) => { if (typeof e == "string") throw new Error("string type in extglob ast??"); const [n, i, r, o] = e.toRegExpSource(t); return this.#r = this.#r || o, n; }).filter((e) => !(this.isStart() && this.isEnd()) || !!e).join("|"); } static #p(t, e, n = !1) { let i = !1, r = "", o = !1; for (let a = 0; a < t.length; a++) { const l = t.charAt(a); if (i) { i = !1, r += (Se.has(l) ? "\\\\" : "") + l; continue; } if (l === "\\\\") { a === t.length - 1 ? r += "\\\\\\\\" : i = !0; continue; } if (l === "[") { const [h, c, f, u] = ge(t, a); if (f) { r += h, o = o || c, a += f - 1, e = e || u; continue; } } if (l === "*") { n && t === "*" ? r += at : r += ot, e = !0; continue; } if (l === "?") { r += Q, e = !0; continue; } r += xe(l); } return [r, $(t), !!e, o]; } } const be = (s, { windowsPathsNoEscape: t = !1 } = {}) => t ? s.replace(/[?*()[\\]]/g, "[$&]") : s.replace(/[?*()[\\]\\\\]/g, "\\\\$&"), y = (s, t, e = {}) => (W(t), !e.nocomment && t.charAt(0) === "#" ? !1 : new j(t, e).match(s)), ve = /^\\*+([^+@!?\\*\\[\\(]*)$/, Ae = (s) => (t) => !t.startsWith(".") && t.endsWith(s), Ce = (s) => (t) => t.endsWith(s), Oe = (s) => (s = s.toLowerCase(), (t) => !t.startsWith(".") && t.toLowerCase().endsWith(s)), De = (s) => (s = s.toLowerCase(), (t) => t.toLowerCase().endsWith(s)), Ne = /^\\*+\\.\\*+$/, Te = (s) => !s.startsWith(".") && s.includes("."), Fe = (s) => s !== "." && s !== ".." && s.includes("."), Me = /^\\.\\*+$/, $e = (s) => s !== "." && s !== ".." && s.startsWith("."), Pe = /^\\*+$/, Re = (s) => s.length !== 0 && !s.startsWith("."), ke = (s) => s.length !== 0 && s !== "." && s !== "..", Le = /^\\?+([^+@!?\\*\\[\\(]*)?$/, Ie = ([s, t = ""]) => { const e = vt([s]); return t ? (t = t.toLowerCase(), (n) => e(n) && n.toLowerCase().endsWith(t)) : e; }, ze = ([s, t = ""]) => { const e = At([s]); return t ? (t = t.toLowerCase(), (n) => e(n) && n.toLowerCase().endsWith(t)) : e; }, He = ([s, t = ""]) => { const e = At([s]); return t ? (n) => e(n) && n.endsWith(t) : e; }, We = ([s, t = ""]) => { const e = vt([s]); return t ? (n) => e(n) && n.endsWith(t) : e; }, vt = ([s]) => { const t = s.length; return (e) => e.length === t && !e.startsWith("."); }, At = ([s]) => { const t = s.length; return (e) => e.length === t && e !== "." && e !== ".."; }, Ct = typeof process == "object" && process ? typeof process.env == "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix", ct = { win32: { sep: "\\\\" }, posix: { sep: "/" } }, je = Ct === "win32" ? ct.win32.sep : ct.posix.sep; y.sep = je; const v = Symbol("globstar **"); y.GLOBSTAR = v; const Ue = "[^/]", _e = Ue + "*?", Be = "(?:(?!(?:\\\\/|^)(?:\\\\.{1,2})($|\\\\/)).)*?", Ge = "(?:(?!(?:\\\\/|^)\\\\.).)*?", qe = (s, t = {}) => (e) => y(e, s, t); y.filter = qe; const b = (s, t = {}) => Object.assign({}, s, t), Ve = (s) => { if (!s || typeof s != "object" || !Object.keys(s).length) return y; const t = y; return Object.assign((n, i, r = {}) => t(n, i, b(s, r)), { Minimatch: class extends t.Minimatch { constructor(i, r = {}) { super(i, b(s, r)); } static defaults(i) { return t.defaults(b(s, i)).Minimatch; } }, AST: class extends t.AST { /* c8 ignore start */ constructor(i, r, o = {}) { super(i, r, b(s, o)); } /* c8 ignore stop */ static fromGlob(i, r = {}) { return t.AST.fromGlob(i, b(s, r)); } }, unescape: (n, i = {}) => t.unescape(n, b(s, i)), escape: (n, i = {}) => t.escape(n, b(s, i)), filter: (n, i = {}) => t.filter(n, b(s, i)), defaults: (n) => t.defaults(b(s, n)), makeRe: (n, i = {}) => t.makeRe(n, b(s, i)), braceExpand: (n, i = {}) => t.braceExpand(n, b(s, i)), match: (n, i, r = {}) => t.match(n, i, b(s, r)), sep: t.sep, GLOBSTAR: v }); }; y.defaults = Ve; const Ot = (s, t = {}) => (W(s), t.nobrace || !/\\{(?:(?!\\{).)*\\}/.test(s) ? [s] : ae(s)); y.braceExpand = Ot; const Xe = (s, t = {}) => new j(s, t).makeRe(); y.makeRe = Xe; const Ye = (s, t, e = {}) => { const n = new j(t, e); return s = s.filter((i) => n.match(i)), n.options.nonull && !s.length && s.push(t), s; }; y.match = Ye; const lt = /[?*]|[+@!]\\(.*?\\)|\\[|\\]/, Ze = (s) => s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, "\\\\$&"); class j { options; set; pattern; windowsPathsNoEscape; nonegate; negate; comment; empty; preserveMultipleSlashes; partial; globSet; globParts; nocase; isWindows; platform; windowsNoMagicRoot; regexp; constructor(t, e = {}) { W(t), e = e || {}, this.options = e, this.pattern = t, this.platform = e.platform || Ct, this.isWindows = this.platform === "win32", this.windowsPathsNoEscape = !!e.windowsPathsNoEscape || e.allowWindowsEscape === !1, this.windowsPathsNoEscape && (this.pattern = this.pattern.replace(/\\\\/g, "/")), this.preserveMultipleSlashes = !!e.preserveMultipleSlashes, this.regexp = null, this.negate = !1, this.nonegate = !!e.nonegate, this.comment = !1, this.empty = !1, this.partial = !!e.partial, this.nocase = !!this.options.nocase, this.windowsNoMagicRoot = e.windowsNoMagicRoot !== void 0 ? e.windowsNoMagicRoot : !!(this.isWindows && this.nocase), this.globSet = [], this.globParts = [], this.set = [], this.make(); } hasMagic() { if (this.options.magicalBraces && this.set.length > 1) return !0; for (const t of this.set) for (const e of t) if (typeof e != "string") return !0; return !1; } debug(...t) { } make() { const t = this.pattern, e = this.options; if (!e.nocomment && t.charAt(0) === "#") { this.comment = !0; return; } if (!t) { this.empty = !0; return; } this.parseNegate(), this.globSet = [...new Set(this.braceExpand())], e.debug && (this.debug = (...r) => console.error(...r)), this.debug(this.pattern, this.globSet); const n = this.globSet.map((r) => this.slashSplit(r)); this.globParts = this.preprocess(n), this.debug(this.pattern, this.globParts); let i = this.globParts.map((r, o, a) => { if (this.isWindows && this.windowsNoMagicRoot) { const l = r[0] === "" && r[1] === "" && (r[2] === "?" || !lt.test(r[2])) && !lt.test(r[3]), h = /^[a-z]:/i.test(r[0]); if (l) return [...r.slice(0, 4), ...r.slice(4).map((c) => this.parse(c))]; if (h) return [r[0], ...r.slice(1).map((c) => this.parse(c))]; } return r.map((l) => this.parse(l)); }); if (this.debug(this.pattern, i), this.set = i.filter((r) => r.indexOf(!1) === -1), this.isWindows) for (let r = 0; r < this.set.length; r++) { const o = this.set[r]; o[0] === "" && o[1] === "" && this.globParts[r][2] === "?" && typeof o[3] == "string" && /^[a-z]:$/i.test(o[3]) && (o[2] = "?"); } this.debug(this.pattern, this.set); } // various transforms to equivalent pattern sets that are // faster to process in a filesystem walk. The goal is to // eliminate what we can, and push all ** patterns as far // to the right as possible, even if it increases the number // of patterns that we have to process. preprocess(t) { if (this.options.noglobstar) for (let n = 0; n < t.length; n++) for (let i = 0; i < t[n].length; i++) t[n][i] === "**" && (t[n][i] = "*"); const { optimizationLevel: e = 1 } = this.options; return e >= 2 ? (t = this.firstPhasePreProcess(t), t = this.secondPhasePreProcess(t)) : e >= 1 ? t = this.levelOneOptimize(t) : t = this.adjascentGlobstarOptimize(t), t; } // just get rid of adjascent ** portions adjascentGlobstarOptimize(t) { return t.map((e) => { let n = -1; for (; (n = e.indexOf("**", n + 1)) !== -1; ) { let i = n; for (; e[i + 1] === "**"; ) i++; i !== n && e.splice(n, i - n); } return e; }); } // get rid of adjascent ** and resolve .. portions levelOneOptimize(t) { return t.map((e) => (e = e.reduce((n, i) => { const r = n[n.length - 1]; return i === "**" && r === "**" ? n : i === ".." && r && r !== ".." && r !== "." && r !== "**" ? (n.pop(), n) : (n.push(i), n); }, []), e.length === 0 ? [""] : e)); } levelTwoFileOptimize(t) { Array.isArray(t) || (t = this.slashSplit(t)); let e = !1; do { if (e = !1, !this.preserveMultipleSlashes) { for (let i = 1; i < t.length - 1; i++) { const r = t[i]; i === 1 && r === "" && t[0] === "" || (r === "." || r === "") && (e = !0, t.splice(i, 1), i--); } t[0] === "." && t.length === 2 && (t[1] === "." || t[1] === "") && (e = !0, t.pop()); } let n = 0; for (; (n = t.indexOf("..", n + 1)) !== -1; ) { const i = t[n - 1]; i && i !== "." && i !== ".." && i !== "**" && (e = !0, t.splice(n - 1, 2), n -= 2); } } while (e); return t.length === 0 ? [""] : t; } // First phase: single-pattern processing // <pre> is 1 or more portions // <rest> is 1 or more portions // <p> is any portion other than ., .., '', or ** // <e> is . or '' // // **/.. is *brutal* for filesystem walking performance, because // it effectively resets the recursive walk each time it occurs, // and ** cannot be reduced out by a .. pattern part like a regexp // or most strings (other than .., ., and '') can be. // // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>} // <pre>/<e>/<rest> -> <pre>/<rest> // <pre>/<p>/../<rest> -> <pre>/<rest> // **/**/<rest> -> **/<rest> // // **/*/<rest> -> */**/<rest> <== not valid because ** doesn't follow // this WOULD be allowed if ** did follow symlinks, or * didn't firstPhasePreProcess(t) { let e = !1; do { e = !1; for (let n of t) { let i = -1; for (; (i = n.indexOf("**", i + 1)) !== -1; ) { let o = i; for (; n[o + 1] === "**"; ) o++; o > i && n.splice(i + 1, o - i); let a = n[i + 1]; const l = n[i + 2], h = n[i + 3]; if (a !== ".." || !l || l === "." || l === ".." || !h || h === "." || h === "..") continue; e = !0, n.splice(i, 1); const c = n.slice(0); c[i] = "**", t.push(c), i--; } if (!this.preserveMultipleSlashes) { for (let o = 1; o < n.length - 1; o++) { const a = n[o]; o === 1 && a === "" && n[0] === "" || (a === "." || a === "") && (e = !0, n.splice(o, 1), o--); } n[0] === "." && n.length === 2 && (n[1] === "." || n[1] === "") && (e = !0, n.pop()); } let r = 0; for (; (r = n.indexOf("..", r + 1)) !== -1; ) { const o = n[r - 1]; if (o && o !== "." && o !== ".." && o !== "**") { e = !0; const l = r === 1 && n[r + 1] === "**" ? ["."] : []; n.splice(r - 1, 2, ...l), n.length === 0 && n.push(""), r -= 2; } } } } while (e); return t; } // second phase: multi-pattern dedupes // {<pre>/*/<rest>,<pre>/<p>/<rest>} -> <pre>/*/<rest> // {<pre>/<rest>,<pre>/<rest>} -> <pre>/<rest> // {<pre>/**/<rest>,<pre>/<rest>} -> <pre>/**/<rest> // // {<pre>/**/<rest>,<pre>/**/<p>/<rest>} -> <pre>/**/<rest> // ^-- not valid because ** doens't follow symlinks secondPhasePreProcess(t) { for (let e = 0; e < t.length - 1; e++) for (let n = e + 1; n < t.length; n++) { const i = this.partsMatch(t[e], t[n], !this.preserveMultipleSlashes); if (i) { t[e] = [], t[n] = i; break; } } return t.filter((e) => e.length); } partsMatch(t, e, n = !1) { let i = 0, r = 0, o = [], a = ""; for (; i < t.length && r < e.length; ) if (t[i] === e[r]) o.push(a === "b" ? e[r] : t[i]), i++, r++; else if (n && t[i] === "**" && e[r] === t[i + 1]) o.push(t[i]), i++; else if (n && e[r] === "**" && t[i] === e[r + 1]) o.push(e[r]), r++; else if (t[i] === "*" && e[r] && (this.options.dot || !e[r].startsWith(".")) && e[r] !== "**") { if (a === "b") return !1; a = "a", o.push(t[i]), i++, r++; } else if (e[r] === "*" && t[i] && (this.options.dot || !t[i].startsWith(".")) && t[i] !== "**") { if (a === "a") return !1; a = "b", o.push(e[r]), i++, r++; } else return !1; return t.length === e.length && o; } parseNegate() { if (this.nonegate) return; const t = this.pattern; let e = !1, n = 0; for (let i = 0; i < t.length && t.charAt(i) === "!"; i++) e = !e, n++; n && (this.pattern = t.slice(n)), this.negate = e; } // set partial to true to test if, for example, // "/a/b" matches the start of "/*/b/*/d" // Partial means, if you run out of file before you run // out of pattern, then that's fine, as long as all // the parts match. matchOne(t, e, n = !1) { const i = this.options; if (this.isWindows) { const p = typeof t[0] == "string" && /^[a-z]:$/i.test(t[0]), S = !p && t[0] === "" && t[1] === "" && t[2] === "?" && /^[a-z]:$/i.test(t[3]), A = typeof e[0] == "string" && /^[a-z]:$/i.test(e[0]), N = !A && e[0] === "" && e[1] === "" && e[2] === "?" && typeof e[3] == "string" && /^[a-z]:$/i.test(e[3]), x = S ? 3 : p ? 0 : void 0, w = N ? 3 : A ? 0 : void 0; if (typeof x == "number" && typeof w == "number") { const [T, P] = [t[x], e[w]]; T.toLowerCase() === P.toLowerCase() && (e[w] = T, w > x ? e = e.slice(w) : x > w && (t = t.slice(x))); } } const { optimizationLevel: r = 1 } = this.options; r >= 2 && (t = this.levelTwoFileOptimize(t)), this.debug("matchOne", this, { file: t, pattern: e }), this.debug("matchOne", t.length, e.length); for (var o = 0, a = 0, l = t.length, h = e.length; o < l && a < h; o++, a++) { this.debug("matchOne loop"); var c = e[a], f = t[o]; if (this.debug(e, c, f), c === !1) return !1; if (c === v) { this.debug("GLOBSTAR", [e, c, f]); var u = o, d = a + 1; if (d === h) { for (this.debug("** at the end"); o < l; o++) if (t[o] === "." || t[o] === ".." || !i.dot && t[o].charAt(0) === ".") return !1; return !0; } for (; u < l; ) { var m = t[u]; if (this.debug(\` globstar while\`, t, u, e, d, m), this.matchOne(t.slice(u), e.slice(d), n)) return this.debug("globstar found match!", u, l, m), !0; if (m === "." || m === ".." || !i.dot && m.charAt(0) === ".") { this.debug("dot detected!", t, u, e, d); break; } this.debug("globstar swallow a segment, and continue"), u++; } return !!(n && (this.debug(\` >>> no match, partial?\`, t, u, e, d), u === l)); } let p; if (typeof c == "string" ? (p = f === c, this.debug("string match", c, f, p)) : (p = c.test(f), this.debug("pattern match", c, f, p)), !p) return !1; } if (o === l && a === h) return !0; if (o === l) return n; if (a === h) return o === l - 1 && t[o] === ""; throw new Error("wtf?"); } braceExpand() { return Ot(this.pattern, this.options); } parse(t) { W(t); const e = this.options; if (t === "**") return v; if (t === "") return ""; let n, i = null; (n = t.match(Pe)) ? i = e.dot ? ke : Re : (n = t.match(ve)) ? i = (e.nocase ? e.dot ? De : Oe : e.dot ? Ce : Ae)(n[1]) : (n = t.match(Le)) ? i = (e.nocase ? e.dot ? ze : Ie : e.dot ? He : We)(n) : (n = t.match(Ne)) ? i = e.dot ? Fe : Te : (n = t.match(Me)) && (i = $e); const r = E.fromGlob(t, this.options).toMMPattern(); return i && typeof r == "object" && Reflect.defineProperty(r, "test", { value: i }), r; } makeRe() { if (this.regexp || this.regexp === !1) return this.regexp; const t = this.set; if (!t.length) return this.regexp = !1, this.regexp; const e = this.options, n = e.noglobstar ? _e : e.dot ? Be : Ge, i = new Set(e.nocase ? ["i"] : []); let r = t.map((l) => { const h = l.map((c) => { if (c instanceof RegExp) for (const f of c.flags.split("")) i.add(f); return typeof c == "string" ? Ze(c) : c === v ? v : c._src; }); return h.forEach((c, f) => { const u = h[f + 1], d = h[f - 1]; c !== v || d === v || (d === void 0 ? u !== void 0 && u !== v ? h[f + 1] = "(?:\\\\/|" + n + "\\\\/)?" + u : h[f] = n : u === void 0 ? h[f - 1] = d + "(?:\\\\/|" + n + ")?" : u !== v && (h[f - 1] = d + "(?:\\\\/|\\\\/" + n + "\\\\/)" + u, h[f + 1] = v)); }), h.filter((c) => c !== v).join("/"); }).join("|"); const [o, a] = t.length > 1 ? ["(?:", ")"] : ["", ""]; r = "^" + o + r + a + "$", this.negate && (r = "^(?!" + r + ").+$"); try { this.regexp = new RegExp(r, [...i].join("")); } catch { this.regexp = !1; } return this.regexp; } slashSplit(t) { return this.preserveMultipleSlashes ? t.split("/") : this.isWindows && /^\\/\\/[^\\/]+/.test(t) ? ["", ...t.split(/\\/+/)] : t.split(/\\/+/); } match(t, e = this.partial) { if (this.debug("match", t, this.pattern), this.comment) return !1; if (this.empty) return t === ""; if (t === "/" && e) return !0; const n = this.options; this.isWindows && (t = t.split("\\\\").join("/")); const i = this.slashSplit(t); this.debug(this.pattern, "split", i); const r = this.set; this.debug(this.pattern, "set", r); let o = i[i.length - 1]; if (!o) for (let a = i.length - 2; !o && a >= 0; a--) o = i[a]; for (let a = 0; a < r.length; a++) { const l = r[a]; let h = i; if (n.matchBase && l.length === 1 && (h = [o]), this.matchOne(h, l, e)) return n.flipNegate ? !0 : !this.negate; } return n.flipNegate ? !1 : this.negate; } static defaults(t) { return y.defaults(t).Minimatch; } } y.AST = E; y.Minimatch = j; y.escape = be; y.unescape = $; const Je = [ // Images ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", ".svg", ".ico", ".tiff", ".tga", // Audio ".mp3", ".wav", ".ogg", ".flac", ".aac", ".wma", ".m4a", // Video ".mp4", ".avi", ".mov", ".wmv", ".flv", ".webm", ".mkv", ".m4v", // Documents ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", // Archives ".zip", ".rar", ".7z", ".tar", ".gz", ".bz2", // Executables ".exe", ".dll", ".so", ".dylib", ".bin", // Other binary formats ".dat", ".db", ".sqlite", ".bin", ".obj", ".fbx", ".3ds" ]; function G(s) { const t = s.toLowerCase().substring(s.lastIndexOf(".")); return Je.includes(t); } function Ke() { if (!("storage" in navigator) || !("getDirectory" in navigator.storage)) throw new Wt(); } async function tt(s, t, e) { return typeof navigator < "u" && navigator.locks?.request ? navigator.locks.request(\`opfs:\${s.replace(/\\/+/g, "/").toLowerCase()}\`, { mode: t }, e) : e(); } function D(s) { return Array.isArray(s) ? s : (s.startsWith("~/") ? s.slice(2) : s).split("/").filter(Boolean); } function et(s) { return typeof s == "string" ? s ?? "/" : \`/\${s.join("/")}\`; } function Y(s) { const t = D(s); return t[t.length - 1] || ""; } function q(s) { const t = D(s); return t.pop(), et(t); } function Z(s) { return !s || s === "/" ? "/" : s.startsWith("~/") ? \`/\${s.slice(2)}\` : s.startsWith("/") ? s : \`/\${s}\`; } function Qe(s, t = !1) { return s = s.replace(/\\/$/, ""), t && !s.includes("*") ? \`\${s}/**\` : s; } function V(s, t) { return y(s, t, { dot: !0, matchBase: !0 }); } function ts(s) { const t = Z(s), e = D(t), n = []; for (const i of e) if (!(i === "." || i === "")) if (i === "..") { if (n.length === 0) continue; n.pop(); } else n.push(i); return et(n); } function es(s, t = "utf-8") { return typeof s == "string" ? Ut(s, t) : s instanceof Uint8Array ? s : new Uint8Array(s); } async function ss(s, t) { return tt(t, "shared", async () => { const n = await (await s.getFile()).arrayBuffer(); return new Uint8Array(n); }); } async function ht(s, t, e, n, i = {}) { const r = async () => { let o = null; const a = i.append || !1, l = !a && (i.truncate ?? !0); try { o = await s.createSyncAccessHandle(); const h = es(t, e), c = a ? o.getSize() : 0; o.write(h, { at: c }), l && o.truncate(h.byteLength), o.flush(); } catch (h) { console.error(h); const c = a ? "append" : "write"; throw new g(\`Failed to \${c} file\`, \`\${c.toUpperCase()}_FAILED\`, void 0, h); } finally { try { o?.close(); } catch { } } }; return n ? tt(n, "exclusive", r) : r(); } async function ns(s, t = "SHA-1", e = 50 * 1024 * 1024) { if (s instanceof File && (s = await s.arrayBuffer()), s.byteLength > e) throw new Error(\`File size \${s.byteLength} bytes exceeds maximum allowed size \${e} bytes\`); const n = new Uint8Array(s), i = await crypto.subtle.digest(t, n); return Array.from(new Uint8Array(i)).map((o) => o.toString(16).padStart(2, "0")).join(""); } async function is(s) { const t = await s.arrayBuffer(); return new Uint8Array(t); } async function rs(s, t, e = {}) { const n = Y(t); return tt(t, "exclusive", async () => { const i = e.recursive ?? !1, r = e.force ?? !1; e.useTrash; try { await s.removeEntry(n, { recursive: i }); } catch (o) { if (o.name === "NotFoundError") { if (!r) throw new g(\`No such file or directory: \${t}\`, "ENOENT", void 0, o); } else throw o.name === "InvalidModificationError" ? new g(\`Directory not empty: \${t}. Use recursive option to force removal.\`, "ENOTEMPTY", void 0, o) : o.name === "TypeMismatchError" && !i ? new g(\`Cannot remove directory without recursive option: \${t}\`, "EISDIR", void 0, o) : new g(\`Failed to remove entry: \${t}\`, "RM_FAILED", void 0, o); } }); } class os { /** Root directory handle for the file system */ root; /** Map of watched paths and options */ watchers = /* @__PURE__ */ new Map(); /** Promise to prevent concurrent mount operations */ mountingPromise = null; /** BroadcastChannel instance for sending events */ broadcastChannel = null; /** Configuration options */ options = { root: "/", namespace: "", maxFileSize: 50 * 1024 * 1024, hashAlgorithm: null, broadcastChannel: "opfs-worker" }; /** * Notify about internal changes to the file system * * This method is called by internal operations to notify clients about * changes, even when no specific paths are being watched. * * @param path - The path that was changed * @param type - The type of change (create, change, delete) */