@aiquants/markdown-explorer 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -1
- package/README.md +53 -16
- package/dist/{ExplorerSplit-DwEFmvQM.js → ExplorerSplit-B7pmzR8t.js} +3 -3
- package/dist/{ExplorerSplit-BESGFcu6.cjs → ExplorerSplit-Bi3yU6NG.cjs} +1 -1
- package/dist/MultiLayout-BxeXOLX1.js +909 -0
- package/dist/MultiLayout-DtFrFRmS.cjs +1 -0
- package/dist/TreeLayout-BQUfVNlA.cjs +1 -0
- package/dist/TreeLayout-D6hCSihW.js +22 -0
- package/dist/core/config.d.cts +8 -0
- package/dist/core/config.d.ts +8 -0
- package/dist/core/labels.d.cts +6 -1
- package/dist/core/labels.d.ts +6 -1
- package/dist/{dataRoute-CKbdwkQ7.cjs → dataRoute-B9Wk-G7A.cjs} +1 -1
- package/dist/{dataRoute-Bkfwfp1R.js → dataRoute-zUX-oR9j.js} +39 -38
- package/dist/{index-BgkZ9ATV.js → index-BJTmp0lR.js} +947 -901
- package/dist/index-DkiGlM7C.cjs +3 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +13 -13
- package/dist/location-DfYTzfFS.cjs +1 -0
- package/dist/{location-Cb2Ak55B.js → location-V5BKeWNs.js} +189 -162
- package/dist/sanitizeWorker.cjs +1 -1
- package/dist/sanitizeWorker.js +196 -206
- package/dist/server/anonymous.d.cts +2 -2
- package/dist/server/anonymous.d.ts +2 -2
- package/dist/server/ports.d.cts +4 -1
- package/dist/server/ports.d.ts +4 -1
- package/dist/server.cjs +1 -1
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +631 -603
- package/dist/styles/markdown-explorer.css +1 -1
- package/docs/behavior/dom-hooks.md +4 -4
- package/docs/behavior/layout.md +21 -9
- package/docs/behavior/localization.md +4 -3
- package/docs/behavior/security.md +23 -5
- package/docs/behavior/url-contract.md +8 -2
- package/package.json +5 -5
- package/dist/MultiLayout-DxPiARsv.js +0 -896
- package/dist/MultiLayout-r_qx1Mfz.cjs +0 -1
- package/dist/TreeLayout-9-20bbSM.cjs +0 -1
- package/dist/TreeLayout-CW7lgV_e.js +0 -19
- package/dist/index-y9tVvDW7.cjs +0 -3
- package/dist/location-DWHQYntR.cjs +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { NO_EMBEDS as Y, isEmbedProviderId as Q, EMBED_PROVIDER_IDS as ee, isLinkCardSize as te, LINK_CARD_SIZES as re } from "@aiquants/markdown/embeds";
|
|
2
|
+
import { CONTENT_ALIGNS as x, DEFAULT_MARKDOWN_STYLES as ne } from "@aiquants/markdown/viewer-settings";
|
|
3
|
+
import { a as oe, i as I } from "./dataRoute-zUX-oR9j.js";
|
|
4
|
+
const $ = (e) => {
|
|
4
5
|
if (e === null || typeof e != "object") return !1;
|
|
5
6
|
const t = Object.getPrototypeOf(e);
|
|
6
7
|
return t === Object.prototype || t === null;
|
|
7
|
-
}, P = new Intl.Collator("en", { numeric: !0, sensitivity: "variant" }),
|
|
8
|
+
}, P = new Intl.Collator("en", { numeric: !0, sensitivity: "variant" }), C = Object.freeze({
|
|
8
9
|
sortMode: "native",
|
|
9
10
|
directoriesFirst: !1,
|
|
10
11
|
selectionMode: "single",
|
|
@@ -16,7 +17,7 @@ const F = (e) => {
|
|
|
16
17
|
expandIcons: !0,
|
|
17
18
|
directoryIcons: !0,
|
|
18
19
|
fileIcons: !0
|
|
19
|
-
}),
|
|
20
|
+
}), se = [!0, !1], ie = (e, t) => t ? e.settingOn : e.settingOff, g = (e, t) => ({ key: e, labelKey: t, values: se, formatValue: ie, requiresItemSelection: !1 }), p = Object.freeze([
|
|
20
21
|
{
|
|
21
22
|
key: "sortMode",
|
|
22
23
|
labelKey: "settingSortMode",
|
|
@@ -24,7 +25,7 @@ const F = (e) => {
|
|
|
24
25
|
formatValue: (e, t) => t === "native" ? e.sortNative : t === "asc" ? e.sortAscending : e.sortDescending,
|
|
25
26
|
requiresItemSelection: !1
|
|
26
27
|
},
|
|
27
|
-
|
|
28
|
+
g("directoriesFirst", "settingDirectoriesFirst"),
|
|
28
29
|
{
|
|
29
30
|
key: "selectionMode",
|
|
30
31
|
labelKey: "settingSelectionMode",
|
|
@@ -46,27 +47,27 @@ const F = (e) => {
|
|
|
46
47
|
formatValue: (e, t) => e.expandIconSizeValue(t),
|
|
47
48
|
requiresItemSelection: !1
|
|
48
49
|
},
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
]),
|
|
50
|
+
g("alwaysExpanded", "settingAlwaysExpanded"),
|
|
51
|
+
g("removeRootIndent", "settingRemoveRootIndent"),
|
|
52
|
+
g("lines", "settingTreeLines"),
|
|
53
|
+
g("expandIcons", "settingExpandIcons"),
|
|
54
|
+
g("directoryIcons", "settingDirectoryIcons"),
|
|
55
|
+
g("fileIcons", "settingFileIcons")
|
|
56
|
+
]), We = (e) => e ? p : p.filter((t) => !t.requiresItemSelection), V = (e) => {
|
|
56
57
|
const t = p.find((r) => r.key === e);
|
|
57
58
|
if (t === void 0) throw new RangeError(`[markdown-explorer] no tree setting descriptor for ${e}`);
|
|
58
59
|
return t;
|
|
59
|
-
},
|
|
60
|
+
}, He = (e, t) => {
|
|
60
61
|
const r = V(t).values, n = r[(r.indexOf(e[t]) + 1) % r.length];
|
|
61
62
|
return { ...e, [t]: n };
|
|
62
|
-
},
|
|
63
|
-
if (e === null || typeof e != "object" || Array.isArray(e)) return
|
|
63
|
+
}, qe = (e, t, r) => V(r).formatValue(e, t[r]), U = 2, z = Object.freeze({}), v = (e, t) => Object.freeze(Object.fromEntries(p.filter((r) => t(r, e[r.key])).map((r) => [r.key, e[r.key]]))), Be = (e) => {
|
|
64
|
+
if (e === null || typeof e != "object" || Array.isArray(e)) return z;
|
|
64
65
|
const t = e;
|
|
65
|
-
return t.version !== U || t.settings === null || typeof t.settings != "object" || Array.isArray(t.settings) ?
|
|
66
|
-
},
|
|
67
|
-
const r =
|
|
66
|
+
return t.version !== U || t.settings === null || typeof t.settings != "object" || Array.isArray(t.settings) ? z : v(t.settings, (r, n) => r.values.includes(n));
|
|
67
|
+
}, Ke = (e, t) => {
|
|
68
|
+
const r = v(t, (n, o) => o !== void 0 && o !== e[n.key]);
|
|
68
69
|
return Object.keys(r).length === 0 ? e : Object.freeze({ ...e, ...r });
|
|
69
|
-
},
|
|
70
|
+
}, Ze = (e, t, r, n) => v({ ...e, [t]: r }, (o, s) => s !== void 0 && !(o.key === t && s === n[t])), Ye = (e) => JSON.stringify({ version: U, settings: e }), Qe = (e) => {
|
|
70
71
|
if (e.sortMode === "native" && !e.directoriesFirst) return;
|
|
71
72
|
const t = e.sortMode === "desc" ? -1 : 1;
|
|
72
73
|
return (r, n) => {
|
|
@@ -75,62 +76,62 @@ const F = (e) => {
|
|
|
75
76
|
const o = P.compare(r.name, n.name);
|
|
76
77
|
return t * (o !== 0 ? o : P.compare(r.path, n.path));
|
|
77
78
|
};
|
|
78
|
-
}, w = (1 + Math.sqrt(5)) / 2,
|
|
79
|
+
}, w = (1 + Math.sqrt(5)) / 2, et = 100 / w ** 3, tt = 100 / w ** 4, G = 100 / w ** 2, ae = 13, rt = 16, nt = Object.freeze({ gripThickness: 5, gripLength: 34, barThickness: 2, barLength: 21 }), le = Object.freeze([89, 144, 233, 377]), ot = 34, st = 44, it = 24, at = 1 / w, lt = 1 / w ** 3, ct = "40ch", ce = (e) => {
|
|
79
80
|
if (!Number.isFinite(e) || e <= 0)
|
|
80
81
|
throw new RangeError(`[markdown-explorer] rootFontPixels must be a finite number > 0; got ${String(e)}`);
|
|
81
|
-
},
|
|
82
|
+
}, de = (e) => (ce(e), ae * e), dt = (e) => de(e) * w ** 2, mt = 233, ft = le[0], L = (e, t) => {
|
|
82
83
|
if (!Number.isFinite(t) || t < 0)
|
|
83
84
|
throw new RangeError(`[markdown-explorer] ${e} must be a finite number >= 0; got ${String(t)}`);
|
|
84
|
-
},
|
|
85
|
-
if (
|
|
85
|
+
}, me = ({ trackInlineSize: e, gap: t, minColumnInlineSize: r, logicalColumns: n }) => {
|
|
86
|
+
if (L("trackInlineSize", e), L("gap", t), !Number.isFinite(r) || r <= 0)
|
|
86
87
|
throw new RangeError(`[markdown-explorer] minColumnInlineSize must be a finite number > 0; got ${String(r)}`);
|
|
87
88
|
if (!Number.isInteger(n) || n < 1)
|
|
88
89
|
throw new RangeError(`[markdown-explorer] logicalColumns must be a positive integer; got ${String(n)}`);
|
|
89
90
|
const o = Math.floor((e + t) / (r + t));
|
|
90
91
|
return Math.min(n, Math.max(1, o));
|
|
91
|
-
},
|
|
92
|
+
}, ut = (e, t) => {
|
|
92
93
|
const { trackInlineSize: r, gap: n, minColumnInlineSize: o, logicalColumns: s } = t;
|
|
93
94
|
if (!([r, n, o].every(Number.isFinite) && r > 0 && n >= 0 && o > 0)) return e;
|
|
94
|
-
const i =
|
|
95
|
+
const i = me(t);
|
|
95
96
|
if (e === null || i === e) return i;
|
|
96
|
-
const
|
|
97
|
-
if (i >
|
|
98
|
-
const
|
|
99
|
-
return r >=
|
|
97
|
+
const d = Math.min(s, Math.max(1, e));
|
|
98
|
+
if (i > d) {
|
|
99
|
+
const k = (d + 1) * o + d * n + n / w;
|
|
100
|
+
return r >= k ? i : d;
|
|
100
101
|
}
|
|
101
|
-
return r >=
|
|
102
|
-
},
|
|
102
|
+
return r >= d * o + (d - 1) * n ? d : i;
|
|
103
|
+
}, gt = (e, t) => {
|
|
103
104
|
if (!(Number.isInteger(e) && Number.isInteger(t)) || t < 1 || t > e)
|
|
104
105
|
throw new RangeError(`[markdown-explorer] visible columns must be an integer in 1..${String(e)}; got ${String(t)}`);
|
|
105
106
|
return Array.from({ length: t }, (r, n) => [Math.floor(n * e / t), Math.floor((n + 1) * e / t)]);
|
|
106
|
-
},
|
|
107
|
-
if (typeof e != "string" || !
|
|
107
|
+
}, fe = 31536e3, ue = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/u, ge = (e) => {
|
|
108
|
+
if (typeof e != "string" || !ue.test(e))
|
|
108
109
|
throw new RangeError(`[markdown-explorer] settingsCookie must be a cookie-name token; got ${JSON.stringify(e)}`);
|
|
109
|
-
},
|
|
110
|
+
}, j = (e) => typeof e == "number" && Number.isFinite(e) && e > 0 && e <= G, we = (e, t) => {
|
|
110
111
|
if (e === null || typeof e != "object" || Array.isArray(e)) return {};
|
|
111
112
|
const r = e, { treeExplorer: n, multiExplorer: o, style: s, align: a } = r;
|
|
112
113
|
return {
|
|
113
|
-
...
|
|
114
|
-
...
|
|
114
|
+
...j(n) ? { treeExplorer: n } : {},
|
|
115
|
+
...j(o) ? { multiExplorer: o } : {},
|
|
115
116
|
...typeof s == "string" && t.includes(s) ? { style: s } : {},
|
|
116
117
|
...typeof a == "string" && x.includes(a) ? { align: a } : {}
|
|
117
118
|
};
|
|
118
|
-
},
|
|
119
|
+
}, wt = (e, t) => {
|
|
119
120
|
if (e !== null)
|
|
120
121
|
for (const r of e.split(";")) {
|
|
121
122
|
const n = r.indexOf("=");
|
|
122
123
|
if (!(n < 0) && r.slice(0, n).trim() === t)
|
|
123
124
|
return r.slice(n + 1).trim();
|
|
124
125
|
}
|
|
125
|
-
},
|
|
126
|
+
}, pt = (e, t) => {
|
|
126
127
|
if (e === void 0 || e === "") return {};
|
|
127
128
|
try {
|
|
128
|
-
return
|
|
129
|
+
return we(JSON.parse(decodeURIComponent(e)), t);
|
|
129
130
|
} catch {
|
|
130
131
|
return {};
|
|
131
132
|
}
|
|
132
|
-
}, O = 100,
|
|
133
|
-
const t = (r) => Math.min(
|
|
133
|
+
}, O = 100, pe = Math.floor(G * O) / O, he = (e) => {
|
|
134
|
+
const t = (r) => Math.min(pe, Math.max(1, Math.round(r * O)) / O);
|
|
134
135
|
return encodeURIComponent(
|
|
135
136
|
JSON.stringify({
|
|
136
137
|
...e.treeExplorer === void 0 ? {} : { treeExplorer: t(e.treeExplorer) },
|
|
@@ -139,50 +140,65 @@ const F = (e) => {
|
|
|
139
140
|
...e.align === void 0 ? {} : { align: e.align }
|
|
140
141
|
})
|
|
141
142
|
);
|
|
142
|
-
},
|
|
143
|
+
}, ht = (e, t, r) => `${e}=${he(t)}; Path=/; Max-Age=${String(fe)}; SameSite=Lax${r ? "; Secure" : ""}`, M = Object.freeze({ tree: "tree", multi: "multi", single: "single" }), Ee = Object.freeze({ default: 12, min: 1, max: 64 }), Se = Object.freeze({ default: 4, min: 1, max: 6 }), ye = Object.freeze({ default: 500, min: 1, max: 1e4 }), be = Object.freeze({ default: 16, min: 1, max: 64 }), xe = /^\/(?:[A-Za-z0-9._~-]+\/)*[A-Za-z0-9._~-]+$/u, Oe = /^[A-Za-z0-9][A-Za-z0-9_-]*$/u, ke = /^[a-z0-9][a-z0-9-]*$/u, Re = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/u, D = (e, t) => {
|
|
143
144
|
if (typeof t != "string") throw new TypeError(`[markdown-explorer] ${e} must be a string; got ${typeof t}`);
|
|
144
|
-
if (!
|
|
145
|
+
if (!xe.test(t) || t.split("/").some((r) => r === "." || r === ".."))
|
|
145
146
|
throw new RangeError(`[markdown-explorer] ${e} must start with "/", have no trailing "/", and use only letters, digits and "._~-" in each segment; got ${JSON.stringify(t)}`);
|
|
146
|
-
},
|
|
147
|
+
}, c = (e) => typeof e == "string" ? JSON.stringify(e) : typeof e == "bigint" ? `${String(e)}n` : Object.is(e, -0) ? "-0" : typeof e == "function" ? "a function" : Array.isArray(e) ? "an array" : e !== null && typeof e == "object" ? $(e) ? "a plain object" : `a non-plain object (${Object.prototype.toString.call(e)})` : String(e), S = (e, t, r) => {
|
|
147
148
|
if (t === void 0) return [];
|
|
148
|
-
if (
|
|
149
|
+
if (!$(t)) throw new TypeError(`[markdown-explorer] ${e} must be a plain object; got ${c(t)}`);
|
|
149
150
|
const n = Object.entries(t);
|
|
150
151
|
for (const [o] of n)
|
|
151
152
|
if (!r.includes(o)) throw new RangeError(`[markdown-explorer] ${e}.${o} is not an option; expected ${r.join(", ")}`);
|
|
152
153
|
return n.filter(([, o]) => o !== void 0);
|
|
153
|
-
},
|
|
154
|
-
const t = { ...
|
|
155
|
-
for (const [r, n] of
|
|
154
|
+
}, _e = (e) => {
|
|
155
|
+
const t = { ...M };
|
|
156
|
+
for (const [r, n] of S("views", e, Object.keys(M))) t[r] = n;
|
|
156
157
|
for (const [r, n] of Object.entries(t))
|
|
157
|
-
if (typeof n != "string" || !
|
|
158
|
+
if (typeof n != "string" || !Oe.test(n))
|
|
158
159
|
throw new RangeError(`[markdown-explorer] views.${r} must start with a letter or digit and use only letters, digits, "_" and "-"; got ${JSON.stringify(n)}`);
|
|
159
160
|
return Object.freeze(t);
|
|
160
|
-
},
|
|
161
|
+
}, b = (e, t, r) => {
|
|
161
162
|
if (t === void 0) return r.default;
|
|
162
163
|
if (typeof t != "number" || !Number.isInteger(t) || t < r.min || t > r.max)
|
|
163
|
-
throw new RangeError(`[markdown-explorer] ${e} must be an integer in ${String(r.min)}..${String(r.max)}; got ${
|
|
164
|
+
throw new RangeError(`[markdown-explorer] ${e} must be an integer in ${String(r.min)}..${String(r.max)}; got ${c(t)}`);
|
|
164
165
|
return t;
|
|
165
|
-
},
|
|
166
|
+
}, Te = (e, t) => {
|
|
167
|
+
const r = new Map(S("embeds", e, ["providers", "linkCards", "linkCardSize"]));
|
|
168
|
+
if (r.size === 0) return Y;
|
|
169
|
+
const n = r.has("providers") ? r.get("providers") : [];
|
|
170
|
+
if (!Array.isArray(n)) throw new RangeError(`[markdown-explorer] embeds.providers must be an array of provider ids; got ${c(n)}`);
|
|
171
|
+
for (const i of n)
|
|
172
|
+
if (!Q(i)) throw new RangeError(`[markdown-explorer] embeds.providers must hold only ${ee.join(", ")}; got ${c(i)}`);
|
|
173
|
+
const o = r.has("linkCards") ? r.get("linkCards") : !1;
|
|
174
|
+
if (typeof o != "boolean") throw new RangeError(`[markdown-explorer] embeds.linkCards must be a boolean; got ${c(o)}`);
|
|
175
|
+
const s = { providers: Object.freeze([...new Set(n)]), linkCardEndpoint: o ? oe(t) : null };
|
|
176
|
+
if (!r.has("linkCardSize")) return Object.freeze(s);
|
|
177
|
+
const a = r.get("linkCardSize");
|
|
178
|
+
if (!te(a)) throw new RangeError(`[markdown-explorer] embeds.linkCardSize must be one of ${re.join(", ")}; got ${c(a)}`);
|
|
179
|
+
if (!o) throw new RangeError(`[markdown-explorer] embeds.linkCardSize needs embeds.linkCards: true; got linkCardSize ${c(a)} with linkCards ${c(o)}`);
|
|
180
|
+
return Object.freeze({ ...s, linkCardSize: a });
|
|
181
|
+
}, Ne = (e) => {
|
|
166
182
|
const t = new Map(
|
|
167
|
-
|
|
183
|
+
S(
|
|
168
184
|
"defaultTreeSettings",
|
|
169
185
|
e,
|
|
170
186
|
p.map((n) => n.key)
|
|
171
187
|
)
|
|
172
188
|
);
|
|
173
|
-
if (t.size === 0) return
|
|
174
|
-
const r = { ...
|
|
189
|
+
if (t.size === 0) return C;
|
|
190
|
+
const r = { ...C };
|
|
175
191
|
for (const n of p) {
|
|
176
192
|
if (!t.has(n.key)) continue;
|
|
177
193
|
const o = t.get(n.key), s = n.values;
|
|
178
|
-
if (!s.includes(o)) throw new RangeError(`[markdown-explorer] defaultTreeSettings.${n.key} must be one of ${s.map(
|
|
194
|
+
if (!s.includes(o)) throw new RangeError(`[markdown-explorer] defaultTreeSettings.${n.key} must be one of ${s.map(c).join(", ")}; got ${c(o)}`);
|
|
179
195
|
r[n.key] = o;
|
|
180
196
|
}
|
|
181
197
|
return Object.freeze(r);
|
|
182
|
-
},
|
|
198
|
+
}, Ae = (e) => {
|
|
183
199
|
if (e === null || typeof e != "object") throw new TypeError("[markdown-explorer] the explorer configuration must be an object");
|
|
184
200
|
D("basePath", e.basePath), D("dataPath", e.dataPath);
|
|
185
|
-
const t =
|
|
201
|
+
const t = _e(e.views);
|
|
186
202
|
if ((/* @__PURE__ */ new Set([t.tree, t.multi, t.single])).size !== 3)
|
|
187
203
|
throw new RangeError(`[markdown-explorer] the view slugs must differ; got ${JSON.stringify(t)}`);
|
|
188
204
|
if (e.dataPath === e.basePath) throw new RangeError("[markdown-explorer] dataPath must differ from basePath");
|
|
@@ -191,11 +207,11 @@ const F = (e) => {
|
|
|
191
207
|
if (i === t.tree || i === t.multi || i === t.single)
|
|
192
208
|
throw new RangeError(`[markdown-explorer] dataPath must not start with a view slug under basePath; got ${JSON.stringify(e.dataPath)}`);
|
|
193
209
|
}
|
|
194
|
-
|
|
210
|
+
ge(e.settingsCookie);
|
|
195
211
|
const r = e.iframeHosts ?? [];
|
|
196
|
-
if (!Array.isArray(r) || r.some((i) => typeof i != "string" || !
|
|
212
|
+
if (!Array.isArray(r) || r.some((i) => typeof i != "string" || !Re.test(i)))
|
|
197
213
|
throw new RangeError(`[markdown-explorer] iframeHosts must be lowercase host names without scheme, port or path; got ${JSON.stringify(r)}`);
|
|
198
|
-
const n = Object.fromEntries(
|
|
214
|
+
const n = Object.fromEntries(S("multiView", e.multiView, ["maxPanels", "columns"])), o = Object.fromEntries(S("expandAll", e.expandAll, ["maxFolders", "maxDepth"])), s = e.documentStyles ?? ne;
|
|
199
215
|
if (!Array.isArray(s) || s.length === 0) throw new RangeError("[markdown-explorer] documentStyles must be a non-empty array");
|
|
200
216
|
const a = /* @__PURE__ */ new Set();
|
|
201
217
|
for (const i of s) {
|
|
@@ -210,25 +226,35 @@ const F = (e) => {
|
|
|
210
226
|
settingsCookie: e.settingsCookie,
|
|
211
227
|
views: t,
|
|
212
228
|
multiView: Object.freeze({
|
|
213
|
-
maxPanels:
|
|
214
|
-
columns:
|
|
229
|
+
maxPanels: b("multiView.maxPanels", n.maxPanels, Ee),
|
|
230
|
+
columns: b("multiView.columns", n.columns, Se)
|
|
215
231
|
}),
|
|
216
232
|
expandAll: Object.freeze({
|
|
217
|
-
maxFolders:
|
|
218
|
-
maxDepth:
|
|
233
|
+
maxFolders: b("expandAll.maxFolders", o.maxFolders, ye),
|
|
234
|
+
maxDepth: b("expandAll.maxDepth", o.maxDepth, be)
|
|
219
235
|
}),
|
|
220
236
|
documentStyles: Object.freeze(s.map((i) => Object.freeze({ name: i.name, className: i.className }))),
|
|
221
237
|
iframeHosts: Object.freeze([...new Set(r)]),
|
|
222
|
-
|
|
238
|
+
embeds: Te(e.embeds, e.dataPath),
|
|
239
|
+
defaultTreeSettings: Ne(e.defaultTreeSettings)
|
|
223
240
|
});
|
|
224
|
-
},
|
|
225
|
-
|
|
226
|
-
if (
|
|
241
|
+
}, Et = (e) => {
|
|
242
|
+
const t = e.embeds;
|
|
243
|
+
if (!$(t)) throw new TypeError(`[markdown-explorer] config.embeds must be the embeds defineExplorerConfig resolved; got ${c(t)}`);
|
|
244
|
+
if (Object.hasOwn(t, "linkCards"))
|
|
245
|
+
throw new RangeError(`[markdown-explorer] config.embeds.linkCards is an option of defineExplorerConfig, not a key of the embeds it resolves; pass the option to defineExplorerConfig (got linkCards ${c(t.linkCards)})`);
|
|
246
|
+
const { linkCardEndpoint: r, ...n } = t, o = Ae({ ...e, embeds: { ...n, linkCards: r !== null } });
|
|
247
|
+
if (o.embeds.linkCardEndpoint !== r)
|
|
248
|
+
throw new RangeError(`[markdown-explorer] config.embeds.linkCardEndpoint must be ${c(o.embeds.linkCardEndpoint)} (the data route's link-card path) or null; got ${c(r)}`);
|
|
249
|
+
return o;
|
|
250
|
+
}, Ie = (e) => typeof e == "string" && ke.test(e), St = (e, t) => {
|
|
251
|
+
if (e === null || typeof e != "object") throw new TypeError(`[markdown-explorer] withExplorerSources needs the configuration of defineExplorerConfig; got ${c(e)}`);
|
|
252
|
+
if (!Array.isArray(t) || t.length === 0) throw new RangeError(`[markdown-explorer] sourceIds must be a non-empty array; got ${c(t)}`);
|
|
227
253
|
for (const r of t)
|
|
228
|
-
if (!
|
|
254
|
+
if (!Ie(r)) throw new RangeError(`[markdown-explorer] each source id must use lowercase letters, digits and "-" and start with a letter or digit; got ${c(r)}`);
|
|
229
255
|
if (new Set(t).size !== t.length) throw new RangeError(`[markdown-explorer] source ids must be unique; got ${JSON.stringify(t)}`);
|
|
230
256
|
return Object.freeze({ ...e, sourceIds: Object.freeze([...t]) });
|
|
231
|
-
},
|
|
257
|
+
}, yt = (e) => e.documentStyles.map((t) => t.name), l = Object.freeze({
|
|
232
258
|
source: "source",
|
|
233
259
|
doc: "doc",
|
|
234
260
|
maximized: "maximized",
|
|
@@ -240,143 +266,144 @@ const F = (e) => {
|
|
|
240
266
|
padding: "padding",
|
|
241
267
|
width: "width",
|
|
242
268
|
maxWidth: "maxWidth"
|
|
243
|
-
}),
|
|
269
|
+
}), F = ".data", J = 256, X = /^\d+(?:\.\d+)?$/u, A = /^\d+(?:\.\d+)?(?:px|rem|em|ch|vw|%)$/u, W = Object.freeze(["showToc", "showStyle", "showAlign"]), $e = (e) => {
|
|
244
270
|
const t = encodeURIComponent(e.replaceAll("%", "%25"));
|
|
245
|
-
return t.endsWith(
|
|
246
|
-
},
|
|
271
|
+
return t.endsWith(F) ? `${t.slice(0, -F.length)}%2Edata` : t;
|
|
272
|
+
}, ve = (e) => e.replaceAll("%25", "%"), H = (e) => {
|
|
247
273
|
const { sourceIds: t } = e;
|
|
248
274
|
if (t === void 0) throw new TypeError("[markdown-explorer] the configuration has no source ids; join the server's sources with withExplorerSources(config, sourceIds)");
|
|
249
275
|
return t;
|
|
250
|
-
},
|
|
251
|
-
const n = r.getAll(
|
|
276
|
+
}, Pe = (e, t, r) => {
|
|
277
|
+
const n = r.getAll(l.source);
|
|
252
278
|
if (n.length === 0) return t;
|
|
253
279
|
const [o] = n;
|
|
254
280
|
return n.length > 1 || o === void 0 || o === t || !e.includes(o) ? null : o;
|
|
255
|
-
},
|
|
256
|
-
const r = t.get(
|
|
281
|
+
}, Ce = (e, t) => {
|
|
282
|
+
const r = t.get(l.style), n = t.get(l.align);
|
|
257
283
|
return {
|
|
258
284
|
...r !== null && e.documentStyles.some((o) => o.name === r) ? { style: r } : {},
|
|
259
285
|
...n !== null && x.includes(n) ? { align: n } : {}
|
|
260
286
|
};
|
|
261
|
-
}, q = (e) => Number.isFinite(e) && e >= 0 && e <= J && X.test(String(e)),
|
|
262
|
-
const t = e.get(
|
|
287
|
+
}, q = (e) => Number.isFinite(e) && e >= 0 && e <= J && X.test(String(e)), ze = (e) => {
|
|
288
|
+
const t = e.get(l.padding), r = t !== null && X.test(t) ? Number(t) : Number.NaN, n = e.get(l.width), o = e.get(l.maxWidth);
|
|
263
289
|
return {
|
|
264
|
-
...e.get(
|
|
265
|
-
...e.get(
|
|
266
|
-
...e.get(
|
|
290
|
+
...e.get(l.showToc) === "false" ? { showToc: !1 } : {},
|
|
291
|
+
...e.get(l.showStyle) === "false" ? { showStyle: !1 } : {},
|
|
292
|
+
...e.get(l.showAlign) === "false" ? { showAlign: !1 } : {},
|
|
267
293
|
...q(r) ? { padding: r } : {},
|
|
268
|
-
...n !== null &&
|
|
269
|
-
...o !== null &&
|
|
294
|
+
...n !== null && A.test(n) ? { width: n } : {},
|
|
295
|
+
...o !== null && A.test(o) ? { maxWidth: o } : {}
|
|
270
296
|
};
|
|
271
|
-
},
|
|
272
|
-
for (const n of t)
|
|
297
|
+
}, Le = (e, t) => [...new Set(t.filter(I))].slice(0, e.multiView.maxPanels), je = (e, t, r) => {
|
|
298
|
+
for (const n of t) B(n);
|
|
273
299
|
if (new Set(t).size !== t.length) throw new RangeError(`[markdown-explorer] multi-view documents must each appear once; got ${String(t.length)} with repeats`);
|
|
274
300
|
if (t.length > e.multiView.maxPanels) throw new RangeError(`[markdown-explorer] the multi view opens at most ${String(e.multiView.maxPanels)} documents; got ${String(t.length)}`);
|
|
275
301
|
if (r !== null && !t.includes(r)) throw new RangeError(`[markdown-explorer] the maximized document must be one of the open documents; got ${JSON.stringify(r.slice(0, 80))}`);
|
|
276
|
-
},
|
|
277
|
-
if (!
|
|
302
|
+
}, B = (e) => {
|
|
303
|
+
if (!I(e)) throw new RangeError(`[markdown-explorer] not an acceptable document path: ${JSON.stringify(String(e).slice(0, 80))}`);
|
|
278
304
|
return e;
|
|
279
|
-
},
|
|
305
|
+
}, Me = (e, t) => {
|
|
280
306
|
if (t.style !== void 0 && !e.documentStyles.some((r) => r.name === t.style))
|
|
281
307
|
throw new RangeError(`[markdown-explorer] overrides.style must name a configured document style (${e.documentStyles.map((r) => JSON.stringify(r.name)).join(", ")}); got ${JSON.stringify(t.style)}`);
|
|
282
308
|
if (t.align !== void 0 && !x.includes(t.align))
|
|
283
309
|
throw new RangeError(`[markdown-explorer] overrides.align must be one of ${x.join(", ")}; got ${JSON.stringify(t.align)}`);
|
|
284
|
-
},
|
|
310
|
+
}, De = (e) => {
|
|
285
311
|
for (const t of W)
|
|
286
312
|
if (e[t] !== void 0 && typeof e[t] != "boolean") throw new RangeError(`[markdown-explorer] embed.${t} must be a boolean; got ${JSON.stringify(e[t])}`);
|
|
287
313
|
if (e.padding !== void 0 && !q(e.padding)) throw new RangeError(`[markdown-explorer] embed.padding must be 0..${String(J)} px in plain decimal digits; got ${String(e.padding)}`);
|
|
288
314
|
for (const t of ["width", "maxWidth"]) {
|
|
289
315
|
const r = e[t];
|
|
290
|
-
if (r !== void 0 && !
|
|
316
|
+
if (r !== void 0 && !A.test(r)) throw new RangeError(`[markdown-explorer] embed.${t} must be a CSS length in px, rem, em, ch, vw or %; got ${JSON.stringify(r)}`);
|
|
291
317
|
}
|
|
292
|
-
},
|
|
318
|
+
}, Fe = (e, t) => {
|
|
293
319
|
const r = new URLSearchParams();
|
|
294
320
|
let n = `${e.basePath}/${e.views[t.view]}`;
|
|
295
321
|
if (t.view === "multi") {
|
|
296
322
|
const s = t.docs ?? [], a = t.maximized ?? null;
|
|
297
|
-
|
|
298
|
-
for (const i of s) r.append(
|
|
299
|
-
a !== null && r.set(
|
|
300
|
-
} else t.doc !== void 0 && t.doc !== null && (n += `/${
|
|
323
|
+
je(e, s, a);
|
|
324
|
+
for (const i of s) r.append(l.doc, i);
|
|
325
|
+
a !== null && r.set(l.maximized, a);
|
|
326
|
+
} else t.doc !== void 0 && t.doc !== null && (n += `/${$e(B(t.doc))}`);
|
|
301
327
|
if (t.source !== void 0) {
|
|
302
328
|
const s = H(e);
|
|
303
329
|
if (!s.includes(t.source)) throw new RangeError(`[markdown-explorer] unknown source ${JSON.stringify(t.source)}; expected one of ${s.join(", ")}`);
|
|
304
|
-
t.source !== s[0] && r.set(
|
|
330
|
+
t.source !== s[0] && r.set(l.source, t.source);
|
|
305
331
|
}
|
|
306
|
-
if (t.view !== "multi" && t.overrides !== void 0 && (
|
|
332
|
+
if (t.view !== "multi" && t.overrides !== void 0 && (Me(e, t.overrides), t.overrides.style !== void 0 && r.set(l.style, t.overrides.style), t.overrides.align !== void 0 && r.set(l.align, t.overrides.align)), t.view === "single" && t.embed !== void 0) {
|
|
307
333
|
const { embed: s } = t;
|
|
308
|
-
|
|
309
|
-
for (const a of W) s[a] === !1 && r.set(
|
|
310
|
-
s.padding !== void 0 && r.set(
|
|
334
|
+
De(s);
|
|
335
|
+
for (const a of W) s[a] === !1 && r.set(l[a], "false");
|
|
336
|
+
s.padding !== void 0 && r.set(l.padding, String(s.padding)), s.width !== void 0 && r.set(l.width, s.width), s.maxWidth !== void 0 && r.set(l.maxWidth, s.maxWidth);
|
|
311
337
|
}
|
|
312
338
|
const o = r.toString();
|
|
313
339
|
return o === "" ? n : `${n}?${o}`;
|
|
314
|
-
},
|
|
340
|
+
}, Ve = (e, t) => Object.keys(e.views).find((r) => e.views[r] === t), bt = (e, t, r) => {
|
|
315
341
|
const n = H(e), [o] = n;
|
|
316
342
|
if (o === void 0) throw new RangeError("[markdown-explorer] the configuration has no source");
|
|
317
|
-
const s =
|
|
318
|
-
if (t === void 0 || t === "") return
|
|
319
|
-
const h = t.indexOf("/"),
|
|
320
|
-
if (
|
|
321
|
-
if (
|
|
322
|
-
const
|
|
323
|
-
return
|
|
343
|
+
const s = Pe(n, o, r), a = s === null ? o : s, i = (m) => ({ kind: "redirect", href: Fe(e, m), location: m }), d = () => i({ view: "tree", source: a, doc: null, overrides: {} });
|
|
344
|
+
if (t === void 0 || t === "") return d();
|
|
345
|
+
const h = t.indexOf("/"), k = h < 0 ? t : t.slice(0, h), R = h < 0 ? null : t.slice(h + 1), f = Ve(e, k);
|
|
346
|
+
if (f === void 0) return d();
|
|
347
|
+
if (f === "multi") {
|
|
348
|
+
const m = r.getAll(l.doc), E = Le(e, m), _ = r.getAll(l.maximized), [T] = _, N = _.length === 1 && T !== void 0 && E.includes(T) ? T : null;
|
|
349
|
+
return R === null && s !== null && E.length === m.length && E.every((K, Z) => K === m[Z]) && (_.length === 0 || N !== null) ? { kind: "location", location: { view: "multi", source: a, docs: E, maximized: N } } : i({ view: "multi", source: a, docs: E, maximized: N });
|
|
324
350
|
}
|
|
325
|
-
const
|
|
326
|
-
if (
|
|
327
|
-
const
|
|
328
|
-
if (
|
|
329
|
-
if (
|
|
330
|
-
const
|
|
331
|
-
return s === null ? i({ view:
|
|
351
|
+
const u = R === null ? null : ve(R);
|
|
352
|
+
if (u !== null && !I(u)) return d();
|
|
353
|
+
const y = Ce(e, r);
|
|
354
|
+
if (f === "single") {
|
|
355
|
+
if (u === null) return d();
|
|
356
|
+
const m = ze(r);
|
|
357
|
+
return s === null ? i({ view: f, source: a, doc: u, overrides: y, embed: m }) : { kind: "location", location: { view: f, source: a, doc: u, overrides: y, embed: m } };
|
|
332
358
|
}
|
|
333
|
-
return s === null ? i({ view:
|
|
359
|
+
return s === null ? i({ view: f, source: a, doc: u, overrides: y }) : { kind: "location", location: { view: f, source: a, doc: u, overrides: y } };
|
|
334
360
|
};
|
|
335
361
|
export {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
362
|
+
rt as A,
|
|
363
|
+
Ye as B,
|
|
364
|
+
ot as C,
|
|
365
|
+
z as D,
|
|
366
|
+
mt as E,
|
|
367
|
+
it as F,
|
|
342
368
|
w as G,
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
369
|
+
Be as H,
|
|
370
|
+
ht as I,
|
|
371
|
+
ct as J,
|
|
372
|
+
C as K,
|
|
373
|
+
M as L,
|
|
374
|
+
be as M,
|
|
349
375
|
P as N,
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
376
|
+
ye as O,
|
|
377
|
+
at as P,
|
|
378
|
+
ae as Q,
|
|
379
|
+
Se as R,
|
|
380
|
+
nt as S,
|
|
381
|
+
Ee as T,
|
|
382
|
+
Ae as U,
|
|
383
|
+
bt as a,
|
|
384
|
+
wt as b,
|
|
385
|
+
Le as c,
|
|
386
|
+
yt as d,
|
|
387
|
+
Fe as e,
|
|
388
|
+
$ as f,
|
|
389
|
+
gt as g,
|
|
390
|
+
ut as h,
|
|
391
|
+
Ie as i,
|
|
392
|
+
lt as j,
|
|
393
|
+
Qe as k,
|
|
394
|
+
qe as l,
|
|
395
|
+
dt as m,
|
|
396
|
+
de as n,
|
|
370
397
|
G as o,
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
398
|
+
pt as p,
|
|
399
|
+
et as q,
|
|
400
|
+
Et as r,
|
|
401
|
+
tt as s,
|
|
402
|
+
st as t,
|
|
403
|
+
ft as u,
|
|
404
|
+
We as v,
|
|
405
|
+
St as w,
|
|
406
|
+
Ze as x,
|
|
407
|
+
He as y,
|
|
408
|
+
Ke as z
|
|
382
409
|
};
|
package/dist/sanitizeWorker.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const ee=require("node:worker_threads"),S=require("parse5"),w=require("isomorphic-dompurify"),B=require("./dataRoute-CKbdwkQ7.cjs"),F=512,te=4096,P=1024,G=Symbol("placement"),j=2,re=3,ne=new Set(["html","head","body"]),b=0,y=1,I=2,V=3,D=4,L=5,O=6,N=7,$=8,k=9,W=10,_=-1,se=0,oe=1,ae=2,ie=3,ce=4,le=5,q=6,ue=7,fe=t=>{switch(t){case 9:case 10:case 12:case 13:case 32:return se;case 47:return oe;case 62:return ae;case 61:return ie;case 34:return ce;case 39:return le;default:return q}},de=Uint8Array.from({length:128},(t,n)=>fe(n)),U=60,Q=47,pe=/[\t\n\f\r />="'<]/g,Ae=/["<]/g,Ee=/['<]/g,m=-1-I,he=Int8Array.from([[y,k,_,b,b,b,b],[y,k,_,m,m,m,m],[V,k,_,D,I,I,I],[V,k,_,D,m,m,m],[D,N,_,N,L,O,N],[L,L,L,L,$,L,L],[O,O,O,O,O,$,O],[y,N,_,N,N,N,N],[y,k,_,m,m,m,m],[y,k,_,m,m,m,m]].flat()),X=t=>t>=65&&t<=90||t>=97&&t<=122,me=(t,n)=>{let s=new Int32Array(W),l=new Int32Array(W),i=0,T=0,o=0;for(;o<t.length;){if(i===0){const r=t.indexOf("<",o);if(r<0)return!1;o=r+1,t.charCodeAt(o)===Q&&(o+=1),X(t.charCodeAt(o))&&(s[b]=0,i=1<<b,o+=1);continue}if((i&-230)===0&&o>=T){const r=i===1<<L?Ae:i===1<<O?Ee:pe;r.lastIndex=o;const d=r.exec(t);if(d===null)return!1;o=d.index,t.charCodeAt(o)===U&&(T=o+3)}const E=t.charCodeAt(o),g=E<128?de[E]:q;let h=0;for(let r=i;r!==0;r&=r-1){const d=31-Math.clz32(r&-r);let f=he[d*ue+g],A=s[d];if(f<_&&(f=-1-f,A+=1,A>n))return!0;if(f===_)continue;const R=1<<f;((h&R)===0||A>l[f])&&(l[f]=A),h|=R}X(E)&&(t.charCodeAt(o-1)===U||t.charCodeAt(o-1)===Q&&t.charCodeAt(o-2)===U)&&(h&1<<b)===0&&(l[b]=0,h|=1<<b);const u=s;s=l,l=u,i=h,o+=1}return!1};class C extends Error{status;constructor(n){super(`[markdown-explorer] the nesting guard stopped the parse: ${n}`),this.name="ParseStop",this.status=n}}const Te=(t,n,s,l)=>{if(!Number.isSafeInteger(n)||n<=0)throw new RangeError(`[markdown-explorer] the nesting guard's depth limit must be a positive safe integer; got ${String(n)}`);if(!Number.isSafeInteger(s)||s<=0)throw new RangeError(`[markdown-explorer] the nesting guard's node budget must be a positive safe integer; got ${String(s)}`);if(!Number.isSafeInteger(l)||l<=0)throw new RangeError(`[markdown-explorer] the nesting guard's attribute character budget must be a positive safe integer; got ${String(l)}`);if(me(t,P))return{status:"too-many-attributes"};const i=n+j,T=t.length+re;let o=null,E=0,g=0,h=0,u=0;const r=e=>{if(g+=e,g>s)throw new C("too-many-nodes")},d=e=>{for(const a of e)u+=a.name.length+a.value.length;if(u>l)throw new C("too-many-attribute-characters")},f=(e,a,c,p)=>{const v={node:e,above:null,levels:a,height:0,keepsChildren:c,attributes:p,first:null,next:null,previous:null},Z=e;return Z[G]=v,v},A=e=>{const c=e[G];if(c===void 0)throw new Error("[markdown-explorer] the nesting guard was handed a node it did not create");return c},R=(e,a)=>{let c=a;for(let p=e;p!==null&&c>p.height;p=p.above)p.height=c,c+=p.levels;if(o!==null&&o.height>i)throw new C("too-deep")},M=e=>{const a=e.above;a?.keepsChildren&&(e.previous===null?a.first=e.next:e.previous.next=e.next,e.next!==null&&(e.next.previous=e.previous)),e.above=null,e.next=null,e.previous=null},H=(e,a)=>{if(!S.defaultTreeAdapter.isElementNode(a))return;const c=A(a),p=A(e);M(c),c.above=p,p.keepsChildren&&(c.next=p.first,p.first!==null&&(p.first.previous=c),p.first=c),a.parentNode=e,R(p,c.height+c.levels)},K={...S.defaultTreeAdapter,createDocument:()=>{const e=S.defaultTreeAdapter.createDocument();return o=f(e,0,!1,0),e},createDocumentFragment:()=>{const e=S.defaultTreeAdapter.createDocumentFragment();return f(e,0,!1,0),e},createElement:(e,a,c)=>{if(E+=1,E>T)throw new C("too-many-elements");r(1+c.length),d(c);const p=S.defaultTreeAdapter.createElement(e,a,c);return f(p,1,!(a===S.html.NS.HTML&&ne.has(e)),c.length),p},createCommentNode:e=>{if(h+=1,h>te)throw new C("too-many-comments");return r(1),S.defaultTreeAdapter.createCommentNode(e)},setTemplateContent:(e,a)=>{S.defaultTreeAdapter.setTemplateContent(e,a);const c=A(a);c.above=A(e),R(c.above,c.height)},appendChild:H,insertBefore:(e,a)=>H(e,a),detachNode:e=>{S.defaultTreeAdapter.isElementNode(e)&&(M(A(e)),e.parentNode=null)},getFirstChild:e=>{const a=A(e);if(!a.keepsChildren)throw new Error("[markdown-explorer] the nesting guard was asked for the children of a node whose children it does not keep");return a.first===null?null:a.first.node},getChildNodes:()=>{throw new Error("[markdown-explorer] the nesting guard keeps no child lists for source locations")},onItemPop:e=>{const a=A(e);a.keepsChildren=!1,a.first=null},insertText:()=>{},insertTextBefore:()=>{},adoptAttributes:(e,a)=>{r(a.length),d(a);const c=A(e);if(c.attributes+=a.length,c.attributes>P)throw new C("too-many-attributes")}};let z;try{z=S.parse(t,{scriptingEnabled:!1,treeAdapter:K})}catch(e){if(e instanceof C)return{status:e.status};throw e}return{status:"within",depth:A(z).height-j,elements:E,nodes:g}};class J extends RangeError{constructor(n){super(`[markdown-explorer] the HTML nests deeper than ${String(n)} levels`),this.name="HtmlNestingLimitError"}}const ge=["script","style","noscript","template","form","button","textarea","select","option","object","embed","base","meta","link","frame","frameset"],Se=["srcdoc","formaction"],we=/^(?:(?:https?|mailto|tel):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))/iu,_e=new Set(["left","right","center","justify","start","end"]),be=new Set(["h1","h2","h3","h4","h5","h6"]),x=1,Y=Object.freeze({a:Object.freeze(["target","data-link-kind","data-doc-path","data-doc-exists","data-footnote-ref","data-footnote-backref"]),area:Object.freeze(["target"]),img:Object.freeze(["data-asset-src","data-asset-exists"]),section:Object.freeze(["data-footnotes"]),iframe:Object.freeze(["allow","allowfullscreen","frameborder","referrerpolicy"])}),Ne=[...new Set(Object.values(Y).flatMap(t=>t.filter(n=>n.startsWith("data-"))))],Le=new Set(["no-referrer","origin","same-origin","strict-origin","strict-origin-when-cross-origin"]),Oe=new Set(["autoplay","clipboard-write","encrypted-media","fullscreen","picture-in-picture","web-share"]),Re=new Set(["src","href","xlink:href"]),Ce=/^data:/iu,ke=Object.freeze({FORBID_TAGS:ge,FORBID_ATTR:Se,ADD_TAGS:["iframe"],ADD_ATTR:(t,n)=>Y[n]?.includes(t)===!0,ADD_URI_SAFE_ATTR:Ne,ALLOWED_URI_REGEXP:we,ALLOW_DATA_ATTR:!1}),ye=t=>{let n=null;for(const s of t.split(";")){const l=s.indexOf(":");if(l<0||s.slice(0,l).trim().toLowerCase()!=="text-align")continue;const i=s.slice(l+1).trim().toLowerCase();_e.has(i)&&(n=i)}return n===null?null:`text-align: ${n}`},Ie=t=>{const n=new Set;for(const s of t.split(";")){const[l]=s.trim().toLowerCase().split(/\s+/u);l!==void 0&&Oe.has(l)&&n.add(l)}return n.size===0?null:[...n].join("; ")},De=(t,n)=>{if(t===null)return!1;let s;try{s=new URL(t.trim())}catch{return!1}return s.protocol==="https:"&&s.username===""&&s.password===""&&s.port===""&&n.has(s.hostname)},Ue=t=>{const n=t.getAttribute("type");return n!==null&&n.trim().toLowerCase()==="checkbox"&&t.hasAttribute("disabled")},xe=(t,n,s)=>{if(w.isSupported!==!0)throw new Error("[markdown-explorer] the HTML sanitizer cannot run in this environment");if(!Number.isSafeInteger(s)||s<=0)throw new RangeError(`[markdown-explorer] the HTML sanitizer's depth limit must be a positive integer; got ${String(s)}`);const l=new Set(t);let i=new WeakMap;const T=u=>{const r=u.parentNode===null?void 0:i.get(u.parentNode),d=r===void 0?0:r+1;if(i.set(u,d),u.nodeType===x&&d>s)throw new J(s)},o=(u,r)=>{if(u.nodeType!==x)return;const d=u;(r.tagName==="input"&&!Ue(d)||r.tagName==="iframe"&&!De(d.getAttribute("src"),l))&&d.parentNode?.removeChild(d)},E=(u,r)=>{const d=u.nodeName.toLowerCase();if(r.attrName==="style"){const f=ye(r.attrValue);f===null?r.keepAttr=!1:r.attrValue=f}else if(r.attrName==="allow"&&d==="iframe"){const f=Ie(r.attrValue);f===null?r.keepAttr=!1:r.attrValue=f}else if(r.attrName==="referrerpolicy"&&d==="iframe"){const f=r.attrValue.trim().toLowerCase();Le.has(f)?r.attrValue=f:r.keepAttr=!1}else Re.has(r.attrName)&&Ce.test(r.attrValue)?r.keepAttr=!1:r.attrName==="id"&&be.has(d)&&(r.forceKeepAttr=!0)},g=u=>{const r=u.getAttribute("data-asset-src");r!==null&&(u.getAttribute("data-asset-exists")!=="false"&&B.isAcceptableDocumentPath(r)?u.setAttribute("src",B.explorerAssetHref(n,r,null)):u.removeAttribute("src"))},h=u=>{if(u.nodeType!==x)return;const r=u;r.nodeName.toLowerCase()==="img"&&g(r);const d=r.getAttribute("target");if(d===null||d.trim().toLowerCase()==="_self")return;const f=r.getAttribute("rel"),A=new Set(f===null?[]:f.split(/\s+/u).filter(R=>R!==""));A.add("noopener"),A.add("noreferrer"),r.setAttribute("rel",[...A].join(" "))};return u=>{i=new WeakMap,w.addHook("beforeSanitizeElements",T),w.addHook("uponSanitizeElement",o),w.addHook("uponSanitizeAttribute",E),w.addHook("afterSanitizeAttributes",h);try{return w.sanitize(u,ke)}finally{w.removeHook("beforeSanitizeElements",T),w.removeHook("uponSanitizeElement",o),w.removeHook("uponSanitizeAttribute",E),w.removeHook("afterSanitizeAttributes",h)}}},Me=t=>{if(t===null||typeof t!="object")return!1;const{id:n,input:s}=t;if(typeof n!="number"||s===null||typeof s!="object")return!1;const{html:l,iframeHosts:i,dataPath:T,maxNodes:o,maxAttributeChars:E,maxSanitizedChars:g}=s;return typeof l=="string"&&Array.isArray(i)&&i.every(h=>typeof h=="string")&&typeof T=="string"&&T!==""&&[o,E,g].every(h=>Number.isSafeInteger(h)&&h>0)},He=()=>{const t=ee.parentPort;if(t===null)throw new Error("[markdown-explorer] the sanitizer worker must run in a worker thread");const n=new Map;t.on("message",s=>{if(!Me(s))throw new TypeError("[markdown-explorer] the sanitizer worker received a message that is not a job");const{id:l,input:i}=s;let T;try{if(Te(i.html,F,i.maxNodes,i.maxAttributeChars).status!=="within"){t.postMessage({id:l,output:{status:"too-large"}});return}const o=JSON.stringify([i.iframeHosts,i.dataPath]);let E=n.get(o);E===void 0&&(E=xe(i.iframeHosts,i.dataPath,F),n.set(o,E));const g=E(i.html);T=g.length>i.maxSanitizedChars?{status:"too-large"}:{status:"sanitized",html:g}}catch(o){T=o instanceof J?{status:"too-large"}:{status:"error",message:o instanceof Error?`${o.name}: ${o.message}`:String(o)}}t.postMessage({id:l,output:T})}),t.postMessage({ready:!0})};He();
|
|
1
|
+
"use strict";const te=require("node:worker_threads"),_=require("parse5"),R=require("@aiquants/markdown/embeds"),S=require("isomorphic-dompurify"),F=require("./dataRoute-B9Wk-G7A.cjs"),G=512,re=4096,j=1024,V=Symbol("placement"),$=2,ne=3,se=new Set(["html","head","body"]),b=0,M=1,U=2,W=3,z=4,O=5,k=6,N=7,Q=8,y=9,X=10,w=-1,oe=0,ae=1,ie=2,le=3,ce=4,ue=5,J=6,fe=7,de=t=>{switch(t){case 9:case 10:case 12:case 13:case 32:return oe;case 47:return ae;case 62:return ie;case 61:return le;case 34:return ce;case 39:return ue;default:return J}},Ee=Uint8Array.from({length:128},(t,i)=>de(i)),B=60,q=47,pe=/[\t\n\f\r />="'<]/g,Te=/["<]/g,Ae=/['<]/g,m=-1-U,he=Int8Array.from([[M,y,w,b,b,b,b],[M,y,w,m,m,m,m],[W,y,w,z,U,U,U],[W,y,w,z,m,m,m],[z,N,w,N,O,k,N],[O,O,O,O,Q,O,O],[k,k,k,k,k,Q,k],[M,N,w,N,N,N,N],[M,y,w,m,m,m,m],[M,y,w,m,m,m,m]].flat()),K=t=>t>=65&&t<=90||t>=97&&t<=122,me=(t,i)=>{let u=new Int32Array(X),f=new Int32Array(X),l=0,A=0,n=0;for(;n<t.length;){if(l===0){const E=t.indexOf("<",n);if(E<0)return!1;n=E+1,t.charCodeAt(n)===q&&(n+=1),K(t.charCodeAt(n))&&(u[b]=0,l=1<<b,n+=1);continue}if((l&-230)===0&&n>=A){const E=l===1<<O?Te:l===1<<k?Ae:pe;E.lastIndex=n;const a=E.exec(t);if(a===null)return!1;n=a.index,t.charCodeAt(n)===B&&(A=n+3)}const T=t.charCodeAt(n),g=T<128?Ee[T]:J;let h=0;for(let E=l;E!==0;E&=E-1){const a=31-Math.clz32(E&-E);let r=he[a*fe+g],s=u[a];if(r<w&&(r=-1-r,s+=1,s>i))return!0;if(r===w)continue;const p=1<<r;((h&p)===0||s>f[r])&&(f[r]=s),h|=p}K(T)&&(t.charCodeAt(n-1)===B||t.charCodeAt(n-1)===q&&t.charCodeAt(n-2)===B)&&(h&1<<b)===0&&(f[b]=0,h|=1<<b);const C=u;u=f,f=C,l=h,n+=1}return!1};class L extends Error{status;constructor(i){super(`[markdown-explorer] the nesting guard stopped the parse: ${i}`),this.name="ParseStop",this.status=i}}const ge=(t,i,u,f)=>{if(!Number.isSafeInteger(i)||i<=0)throw new RangeError(`[markdown-explorer] the nesting guard's depth limit must be a positive safe integer; got ${String(i)}`);if(!Number.isSafeInteger(u)||u<=0)throw new RangeError(`[markdown-explorer] the nesting guard's node budget must be a positive safe integer; got ${String(u)}`);if(!Number.isSafeInteger(f)||f<=0)throw new RangeError(`[markdown-explorer] the nesting guard's attribute character budget must be a positive safe integer; got ${String(f)}`);if(me(t,j))return{status:"too-many-attributes"};const l=i+$,A=t.length+ne;let n=null,T=0,g=0,h=0,C=0;const E=e=>{if(g+=e,g>u)throw new L("too-many-nodes")},a=e=>{for(const o of e)C+=o.name.length+o.value.length;if(C>f)throw new L("too-many-attribute-characters")},r=(e,o,c,d)=>{const P={node:e,above:null,levels:o,height:0,keepsChildren:c,attributes:d,first:null,next:null,previous:null},ee=e;return ee[V]=P,P},s=e=>{const c=e[V];if(c===void 0)throw new Error("[markdown-explorer] the nesting guard was handed a node it did not create");return c},p=(e,o)=>{let c=o;for(let d=e;d!==null&&c>d.height;d=d.above)d.height=c,c+=d.levels;if(n!==null&&n.height>l)throw new L("too-deep")},D=e=>{const o=e.above;o?.keepsChildren&&(e.previous===null?o.first=e.next:e.previous.next=e.next,e.next!==null&&(e.next.previous=e.previous)),e.above=null,e.next=null,e.previous=null},I=(e,o)=>{if(!_.defaultTreeAdapter.isElementNode(o))return;const c=s(o),d=s(e);D(c),c.above=d,d.keepsChildren&&(c.next=d.first,d.first!==null&&(d.first.previous=c),d.first=c),o.parentNode=e,p(d,c.height+c.levels)},H={..._.defaultTreeAdapter,createDocument:()=>{const e=_.defaultTreeAdapter.createDocument();return n=r(e,0,!1,0),e},createDocumentFragment:()=>{const e=_.defaultTreeAdapter.createDocumentFragment();return r(e,0,!1,0),e},createElement:(e,o,c)=>{if(T+=1,T>A)throw new L("too-many-elements");E(1+c.length),a(c);const d=_.defaultTreeAdapter.createElement(e,o,c);return r(d,1,!(o===_.html.NS.HTML&&se.has(e)),c.length),d},createCommentNode:e=>{if(h+=1,h>re)throw new L("too-many-comments");return E(1),_.defaultTreeAdapter.createCommentNode(e)},setTemplateContent:(e,o)=>{_.defaultTreeAdapter.setTemplateContent(e,o);const c=s(o);c.above=s(e),p(c.above,c.height)},appendChild:I,insertBefore:(e,o)=>I(e,o),detachNode:e=>{_.defaultTreeAdapter.isElementNode(e)&&(D(s(e)),e.parentNode=null)},getFirstChild:e=>{const o=s(e);if(!o.keepsChildren)throw new Error("[markdown-explorer] the nesting guard was asked for the children of a node whose children it does not keep");return o.first===null?null:o.first.node},getChildNodes:()=>{throw new Error("[markdown-explorer] the nesting guard keeps no child lists for source locations")},onItemPop:e=>{const o=s(e);o.keepsChildren=!1,o.first=null},insertText:()=>{},insertTextBefore:()=>{},adoptAttributes:(e,o)=>{E(o.length),a(o);const c=s(e);if(c.attributes+=o.length,c.attributes>j)throw new L("too-many-attributes")}};let v;try{v=_.parse(t,{scriptingEnabled:!1,treeAdapter:H})}catch(e){if(e instanceof L)return{status:e.status};throw e}return{status:"within",depth:s(v).height-$,elements:T,nodes:g}};class Y extends RangeError{constructor(i){super(`[markdown-explorer] the HTML nests deeper than ${String(i)} levels`),this.name="HtmlNestingLimitError"}}const _e=["script","style","noscript","template","form","button","textarea","select","option","object","embed","base","meta","link","frame","frameset"],Se=["srcdoc","formaction"],we=/^(?:(?:https?|mailto|tel):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))/iu,be=new Set(["left","right","center","justify","start","end"]),Ne=new Set(["h1","h2","h3","h4","h5","h6"]),x=1,Oe=3,ke=7,Re=8,Z=Object.freeze({a:Object.freeze(["target","data-link-kind","data-doc-path","data-doc-exists","data-footnote-ref","data-footnote-backref"]),area:Object.freeze(["target"]),img:Object.freeze(["data-asset-src","data-asset-exists"]),section:Object.freeze(["data-footnotes"]),iframe:Object.freeze(["allow","allowfullscreen","frameborder","referrerpolicy"])}),Le=[...new Set(Object.values(Z).flatMap(t=>t.filter(i=>i.startsWith("data-"))))],Ce=new Set(["src","href","xlink:href"]),Ie=/^data:/iu,ye=Object.freeze({FORBID_TAGS:_e,FORBID_ATTR:Se,ADD_TAGS:["iframe"],ADD_ATTR:(t,i)=>Z[i]?.includes(t)===!0,ADD_URI_SAFE_ATTR:Le,ALLOWED_URI_REGEXP:we,ALLOW_DATA_ATTR:!1}),De=t=>{let i=null;for(const u of t.split(";")){const f=u.indexOf(":");if(f<0||u.slice(0,f).trim().toLowerCase()!=="text-align")continue;const l=u.slice(f+1).trim().toLowerCase();be.has(l)&&(i=l)}return i===null?null:`text-align: ${i}`},Me=t=>t.nodeType===Oe?{kind:"text",text:t.nodeValue??""}:t.nodeType===Re||t.nodeType===ke?{kind:"ignored"}:t.nodeType===x&&t.nodeName.toLowerCase()==="a"?{kind:"link",href:t.getAttribute("href")}:{kind:"element"},Ue=t=>{const i=t.getAttribute("type");return i!==null&&i.trim().toLowerCase()==="checkbox"&&t.hasAttribute("disabled")},xe=(t,i,u)=>{if(S.isSupported!==!0)throw new Error("[markdown-explorer] the HTML sanitizer cannot run in this environment");if(!Number.isSafeInteger(u)||u<=0)throw new RangeError(`[markdown-explorer] the HTML sanitizer's depth limit must be a positive integer; got ${String(u)}`);const f=Object.freeze([...t]);let l=new WeakMap,A=new WeakMap;const n=a=>{const r=a.parentNode===null?void 0:l.get(a.parentNode),s=r===void 0?0:r+1;if(l.set(a,s),a.nodeType===x&&s>u)throw new Y(u)},T=(a,r)=>{if(a.nodeType!==x)return;const s=a;(r.tagName==="input"&&!Ue(s)||r.tagName==="iframe"&&R.allowedFrameUrlOf(s.getAttribute("src")?.trim(),f)===null)&&s.parentNode?.removeChild(s)},g=(a,r)=>{const s=a.nodeName.toLowerCase();if(r.attrName==="style"){const p=De(r.attrValue);p===null?r.keepAttr=!1:r.attrValue=p}else if(r.attrName==="allow"&&s==="iframe"){const p=R.reduceFrameFeatures(r.attrValue);p===null?r.keepAttr=!1:r.attrValue=p}else if(r.attrName==="referrerpolicy"&&s==="iframe"){const p=r.attrValue.trim().toLowerCase();R.EMBED_FRAME_REFERRER_POLICIES.has(p)?r.attrValue=p:r.keepAttr=!1}else r.attrName===R.EMBED_LINK_ATTRIBUTE&&s==="p"?A.set(a,a.getAttribute(R.EMBED_LINK_ATTRIBUTE)):Ce.has(r.attrName)&&Ie.test(r.attrValue)?r.keepAttr=!1:r.attrName==="id"&&Ne.has(s)&&(r.forceKeepAttr=!0)},h=a=>{const r=a.getAttribute("data-asset-src");r!==null&&(a.getAttribute("data-asset-exists")!=="false"&&F.isAcceptableDocumentPath(r)?a.setAttribute("src",F.explorerAssetHref(i,r,null)):a.removeAttribute("src"))},C=a=>{const r=a.parentNode;if(r===null)return;const s=A.get(r);s!=null&&R.placeholderLinkOf(s,[...r.childNodes].map(Me))!==null&&r.setAttribute(R.EMBED_LINK_ATTRIBUTE,s)},E=a=>{if(a.nodeType!==x)return;const r=a,s=r.nodeName.toLowerCase();s==="img"?h(r):s==="a"&&C(r);const p=r.getAttribute("target");if(p===null||p.trim().toLowerCase()==="_self")return;const D=r.getAttribute("rel"),I=new Set(D===null?[]:D.split(/\s+/u).filter(H=>H!==""));I.add("noopener"),I.add("noreferrer"),r.setAttribute("rel",[...I].join(" "))};return a=>{l=new WeakMap,A=new WeakMap,S.addHook("beforeSanitizeElements",n),S.addHook("uponSanitizeElement",T),S.addHook("uponSanitizeAttribute",g),S.addHook("afterSanitizeAttributes",E);try{return S.sanitize(a,ye)}finally{S.removeHook("beforeSanitizeElements",n),S.removeHook("uponSanitizeElement",T),S.removeHook("uponSanitizeAttribute",g),S.removeHook("afterSanitizeAttributes",E)}}},He=t=>{if(t===null||typeof t!="object")return!1;const{id:i,input:u}=t;if(typeof i!="number"||u===null||typeof u!="object")return!1;const{html:f,iframeHosts:l,dataPath:A,maxNodes:n,maxAttributeChars:T,maxSanitizedChars:g}=u;return typeof f=="string"&&Array.isArray(l)&&l.every(h=>typeof h=="string")&&typeof A=="string"&&A!==""&&[n,T,g].every(h=>Number.isSafeInteger(h)&&h>0)},ze=()=>{const t=te.parentPort;if(t===null)throw new Error("[markdown-explorer] the sanitizer worker must run in a worker thread");const i=new Map;t.on("message",u=>{if(!He(u))throw new TypeError("[markdown-explorer] the sanitizer worker received a message that is not a job");const{id:f,input:l}=u;let A;try{if(ge(l.html,G,l.maxNodes,l.maxAttributeChars).status!=="within"){t.postMessage({id:f,output:{status:"too-large"}});return}const n=JSON.stringify([l.iframeHosts,l.dataPath]);let T=i.get(n);T===void 0&&(T=xe(l.iframeHosts,l.dataPath,G),i.set(n,T));const g=T(l.html);A=g.length>l.maxSanitizedChars?{status:"too-large"}:{status:"sanitized",html:g}}catch(n){A=n instanceof Y?{status:"too-large"}:{status:"error",message:n instanceof Error?`${n.name}: ${n.message}`:String(n)}}t.postMessage({id:f,output:A})}),t.postMessage({ready:!0})};ze();
|