@aiquants/markdown-explorer 0.1.0 → 0.2.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/README.md +31 -13
  3. package/dist/{ExplorerSplit-BESGFcu6.cjs → ExplorerSplit-D2plJRRe.cjs} +1 -1
  4. package/dist/{ExplorerSplit-DwEFmvQM.js → ExplorerSplit-DB37U7Kh.js} +3 -3
  5. package/dist/MultiLayout-DCPDu1-l.js +909 -0
  6. package/dist/MultiLayout-UyWxs6Xy.cjs +1 -0
  7. package/dist/TreeLayout-BoyFelK2.js +22 -0
  8. package/dist/TreeLayout-CLWbWjOc.cjs +1 -0
  9. package/dist/core/config.d.cts +6 -0
  10. package/dist/core/config.d.ts +6 -0
  11. package/dist/core/labels.d.cts +6 -1
  12. package/dist/core/labels.d.ts +6 -1
  13. package/dist/{index-BgkZ9ATV.js → index-BfuAu2GV.js} +947 -901
  14. package/dist/index-Cx3-jSna.cjs +3 -0
  15. package/dist/index.cjs +1 -1
  16. package/dist/index.js +2 -2
  17. package/dist/location-Oo21lTyV.cjs +1 -0
  18. package/dist/{location-Cb2Ak55B.js → location-fVl2R1ee.js} +154 -141
  19. package/dist/sanitizeWorker.cjs +1 -1
  20. package/dist/sanitizeWorker.js +196 -206
  21. package/dist/server.cjs +1 -1
  22. package/dist/server.js +1 -1
  23. package/dist/styles/markdown-explorer.css +1 -1
  24. package/docs/behavior/dom-hooks.md +4 -4
  25. package/docs/behavior/layout.md +21 -9
  26. package/docs/behavior/localization.md +4 -3
  27. package/docs/behavior/security.md +7 -3
  28. package/docs/behavior/url-contract.md +8 -2
  29. package/package.json +5 -5
  30. package/dist/MultiLayout-DxPiARsv.js +0 -896
  31. package/dist/MultiLayout-r_qx1Mfz.cjs +0 -1
  32. package/dist/TreeLayout-9-20bbSM.cjs +0 -1
  33. package/dist/TreeLayout-CW7lgV_e.js +0 -19
  34. package/dist/index-y9tVvDW7.cjs +0 -3
  35. package/dist/location-DWHQYntR.cjs +0 -1
@@ -1,10 +1,11 @@
1
- import { CONTENT_ALIGNS as x, DEFAULT_MARKDOWN_STYLES as Y } from "@aiquants/markdown/viewer-settings";
1
+ import { NO_EMBEDS as Y, isEmbedProviderId as Q, EMBED_PROVIDER_IDS as ee, isLinkCardEndpoint as te } from "@aiquants/markdown/embeds";
2
+ import { CONTENT_ALIGNS as b, DEFAULT_MARKDOWN_STYLES as re } from "@aiquants/markdown/viewer-settings";
2
3
  import { i as k } from "./dataRoute-Bkfwfp1R.js";
3
4
  const F = (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" }), v = Object.freeze({
8
+ }, v = new Intl.Collator("en", { numeric: !0, sensitivity: "variant" }), P = 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
- }), Q = [!0, !1], ee = (e, t) => t ? e.settingOn : e.settingOff, u = (e, t) => ({ key: e, labelKey: t, values: Q, formatValue: ee, requiresItemSelection: !1 }), p = Object.freeze([
20
+ }), ne = [!0, !1], oe = (e, t) => t ? e.settingOn : e.settingOff, g = (e, t) => ({ key: e, labelKey: t, values: ne, formatValue: oe, 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
- u("directoriesFirst", "settingDirectoriesFirst"),
28
+ g("directoriesFirst", "settingDirectoriesFirst"),
28
29
  {
29
30
  key: "selectionMode",
30
31
  labelKey: "settingSelectionMode",
@@ -46,91 +47,91 @@ const F = (e) => {
46
47
  formatValue: (e, t) => e.expandIconSizeValue(t),
47
48
  requiresItemSelection: !1
48
49
  },
49
- u("alwaysExpanded", "settingAlwaysExpanded"),
50
- u("removeRootIndent", "settingRemoveRootIndent"),
51
- u("lines", "settingTreeLines"),
52
- u("expandIcons", "settingExpandIcons"),
53
- u("directoryIcons", "settingDirectoryIcons"),
54
- u("fileIcons", "settingFileIcons")
55
- ]), je = (e) => e ? p : p.filter((t) => !t.requiresItemSelection), V = (e) => {
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
+ ]), Ge = (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
- }, De = (e, t) => {
60
+ }, Je = (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
- }, Ce = (e, t, r) => V(r).formatValue(e, t[r]), U = 2, L = Object.freeze({}), $ = (e, t) => Object.freeze(Object.fromEntries(p.filter((r) => t(r, e[r.key])).map((r) => [r.key, e[r.key]]))), Fe = (e) => {
63
- if (e === null || typeof e != "object" || Array.isArray(e)) return L;
63
+ }, Xe = (e, t, r) => V(r).formatValue(e, t[r]), U = 2, M = Object.freeze({}), $ = (e, t) => Object.freeze(Object.fromEntries(p.filter((r) => t(r, e[r.key])).map((r) => [r.key, e[r.key]]))), We = (e) => {
64
+ if (e === null || typeof e != "object" || Array.isArray(e)) return M;
64
65
  const t = e;
65
- return t.version !== U || t.settings === null || typeof t.settings != "object" || Array.isArray(t.settings) ? L : $(t.settings, (r, n) => r.values.includes(n));
66
- }, Ve = (e, t) => {
66
+ return t.version !== U || t.settings === null || typeof t.settings != "object" || Array.isArray(t.settings) ? M : $(t.settings, (r, n) => r.values.includes(n));
67
+ }, He = (e, t) => {
67
68
  const r = $(t, (n, o) => o !== void 0 && o !== e[n.key]);
68
69
  return Object.keys(r).length === 0 ? e : Object.freeze({ ...e, ...r });
69
- }, Ue = (e, t, r, n) => $({ ...e, [t]: r }, (o, s) => s !== void 0 && !(o.key === t && s === n[t])), Ge = (e) => JSON.stringify({ version: U, settings: e }), Je = (e) => {
70
+ }, qe = (e, t, r, n) => $({ ...e, [t]: r }, (o, s) => s !== void 0 && !(o.key === t && s === n[t])), Be = (e) => JSON.stringify({ version: U, settings: e }), Ke = (e) => {
70
71
  if (e.sortMode === "native" && !e.directoriesFirst) return;
71
72
  const t = e.sortMode === "desc" ? -1 : 1;
72
73
  return (r, n) => {
73
74
  if (e.directoriesFirst && r.type !== n.type) return r.type === "directory" ? -1 : 1;
74
75
  if (e.sortMode === "native") return 0;
75
- const o = P.compare(r.name, n.name);
76
- return t * (o !== 0 ? o : P.compare(r.path, n.path));
76
+ const o = v.compare(r.name, n.name);
77
+ return t * (o !== 0 ? o : v.compare(r.path, n.path));
77
78
  };
78
- }, w = (1 + Math.sqrt(5)) / 2, Xe = 100 / w ** 3, We = 100 / w ** 4, G = 100 / w ** 2, te = 13, He = 16, qe = Object.freeze({ gripThickness: 5, gripLength: 34, barThickness: 2, barLength: 21 }), re = Object.freeze([89, 144, 233, 377]), Ke = 34, Be = 44, Ze = 24, Ye = 1 / w, Qe = 1 / w ** 3, et = "40ch", ne = (e) => {
79
+ }, w = (1 + Math.sqrt(5)) / 2, Ze = 100 / w ** 3, Ye = 100 / w ** 4, G = 100 / w ** 2, se = 13, Qe = 16, et = Object.freeze({ gripThickness: 5, gripLength: 34, barThickness: 2, barLength: 21 }), ie = Object.freeze([89, 144, 233, 377]), tt = 34, rt = 44, nt = 24, ot = 1 / w, st = 1 / w ** 3, it = "40ch", ae = (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
- }, oe = (e) => (ne(e), te * e), tt = (e) => oe(e) * w ** 2, rt = 233, nt = re[0], M = (e, t) => {
82
+ }, ce = (e) => (ae(e), se * e), at = (e) => ce(e) * w ** 2, ct = 233, lt = ie[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
- }, se = ({ trackInlineSize: e, gap: t, minColumnInlineSize: r, logicalColumns: n }) => {
85
- if (M("trackInlineSize", e), M("gap", t), !Number.isFinite(r) || r <= 0)
85
+ }, le = ({ 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
- }, ot = (e, t) => {
92
+ }, dt = (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 = se(t);
95
+ const i = le(t);
95
96
  if (e === null || i === e) return i;
96
97
  const l = Math.min(s, Math.max(1, e));
97
98
  if (i > l) {
98
- const T = (l + 1) * o + l * n + n / w;
99
- return r >= T ? i : l;
99
+ const _ = (l + 1) * o + l * n + n / w;
100
+ return r >= _ ? i : l;
100
101
  }
101
102
  return r >= l * o + (l - 1) * n ? l : i;
102
- }, st = (e, t) => {
103
+ }, mt = (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
- }, ie = 31536e3, ae = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/u, ce = (e) => {
107
- if (typeof e != "string" || !ae.test(e))
107
+ }, de = 31536e3, me = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/u, fe = (e) => {
108
+ if (typeof e != "string" || !me.test(e))
108
109
  throw new RangeError(`[markdown-explorer] settingsCookie must be a cookie-name token; got ${JSON.stringify(e)}`);
109
- }, z = (e) => typeof e == "number" && Number.isFinite(e) && e > 0 && e <= G, le = (e, t) => {
110
+ }, z = (e) => typeof e == "number" && Number.isFinite(e) && e > 0 && e <= G, ue = (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
  ...z(n) ? { treeExplorer: n } : {},
114
115
  ...z(o) ? { multiExplorer: o } : {},
115
116
  ...typeof s == "string" && t.includes(s) ? { style: s } : {},
116
- ...typeof a == "string" && x.includes(a) ? { align: a } : {}
117
+ ...typeof a == "string" && b.includes(a) ? { align: a } : {}
117
118
  };
118
- }, it = (e, t) => {
119
+ }, ft = (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
- }, at = (e, t) => {
126
+ }, ut = (e, t) => {
126
127
  if (e === void 0 || e === "") return {};
127
128
  try {
128
- return le(JSON.parse(decodeURIComponent(e)), t);
129
+ return ue(JSON.parse(decodeURIComponent(e)), t);
129
130
  } catch {
130
131
  return {};
131
132
  }
132
- }, O = 100, de = Math.floor(G * O) / O, me = (e) => {
133
- const t = (r) => Math.min(de, Math.max(1, Math.round(r * O)) / O);
133
+ }, O = 100, ge = Math.floor(G * O) / O, we = (e) => {
134
+ const t = (r) => Math.min(ge, 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,61 @@ const F = (e) => {
139
140
  ...e.align === void 0 ? {} : { align: e.align }
140
141
  })
141
142
  );
142
- }, ct = (e, t, r) => `${e}=${me(t)}; Path=/; Max-Age=${String(ie)}; SameSite=Lax${r ? "; Secure" : ""}`, j = Object.freeze({ tree: "tree", multi: "multi", single: "single" }), fe = Object.freeze({ default: 12, min: 1, max: 64 }), ue = Object.freeze({ default: 4, min: 1, max: 6 }), ge = Object.freeze({ default: 500, min: 1, max: 1e4 }), we = Object.freeze({ default: 16, min: 1, max: 64 }), pe = /^\/(?:[A-Za-z0-9._~-]+\/)*[A-Za-z0-9._~-]+$/u, he = /^[A-Za-z0-9][A-Za-z0-9_-]*$/u, Ee = /^[a-z0-9][a-z0-9-]*$/u, Se = /^(?=.{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
+ }, gt = (e, t, r) => `${e}=${we(t)}; Path=/; Max-Age=${String(de)}; SameSite=Lax${r ? "; Secure" : ""}`, j = Object.freeze({ tree: "tree", multi: "multi", single: "single" }), pe = Object.freeze({ default: 12, min: 1, max: 64 }), he = Object.freeze({ default: 4, min: 1, max: 6 }), Ee = Object.freeze({ default: 500, min: 1, max: 1e4 }), Se = Object.freeze({ default: 16, min: 1, max: 64 }), ye = /^\/(?:[A-Za-z0-9._~-]+\/)*[A-Za-z0-9._~-]+$/u, xe = /^[A-Za-z0-9][A-Za-z0-9_-]*$/u, be = /^[a-z0-9][a-z0-9-]*$/u, Oe = /^(?=.{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 (!pe.test(t) || t.split("/").some((r) => r === "." || r === ".."))
145
+ if (!ye.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
- }, g = (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" ? F(e) ? "a plain object" : `a non-plain object (${Object.prototype.toString.call(e)})` : String(e), b = (e, t, r) => {
147
+ }, d = (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" ? F(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 (!F(t)) throw new TypeError(`[markdown-explorer] ${e} must be a plain object; got ${g(t)}`);
149
+ if (!F(t)) throw new TypeError(`[markdown-explorer] ${e} must be a plain object; got ${d(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
- }, ye = (e) => {
154
+ }, _e = (e) => {
154
155
  const t = { ...j };
155
- for (const [r, n] of b("views", e, Object.keys(j))) t[r] = n;
156
+ for (const [r, n] of S("views", e, Object.keys(j))) t[r] = n;
156
157
  for (const [r, n] of Object.entries(t))
157
- if (typeof n != "string" || !he.test(n))
158
+ if (typeof n != "string" || !xe.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
- }, y = (e, t, r) => {
161
+ }, x = (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 ${g(t)}`);
164
+ throw new RangeError(`[markdown-explorer] ${e} must be an integer in ${String(r.min)}..${String(r.max)}; got ${d(t)}`);
164
165
  return t;
165
- }, xe = (e) => {
166
+ }, Re = (e) => {
167
+ const t = new Map(S("embeds", e, ["providers", "linkCardEndpoint"]));
168
+ if (t.size === 0) return Y;
169
+ const r = t.has("providers") ? t.get("providers") : [];
170
+ if (!Array.isArray(r)) throw new RangeError(`[markdown-explorer] embeds.providers must be an array of provider ids; got ${d(r)}`);
171
+ for (const o of r)
172
+ if (!Q(o)) throw new RangeError(`[markdown-explorer] embeds.providers must hold only ${ee.join(", ")}; got ${d(o)}`);
173
+ const n = t.has("linkCardEndpoint") ? t.get("linkCardEndpoint") : null;
174
+ if (n !== null && !te(n))
175
+ throw new RangeError(`[markdown-explorer] embeds.linkCardEndpoint must start with "/", have no trailing "/", and use only letters, digits and "._~-" in each segment; got ${d(n)}`);
176
+ return Object.freeze({ providers: Object.freeze([...new Set(r)]), linkCardEndpoint: n });
177
+ }, Te = (e) => {
166
178
  const t = new Map(
167
- b(
179
+ S(
168
180
  "defaultTreeSettings",
169
181
  e,
170
182
  p.map((n) => n.key)
171
183
  )
172
184
  );
173
- if (t.size === 0) return v;
174
- const r = { ...v };
185
+ if (t.size === 0) return P;
186
+ const r = { ...P };
175
187
  for (const n of p) {
176
188
  if (!t.has(n.key)) continue;
177
189
  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(g).join(", ")}; got ${g(o)}`);
190
+ if (!s.includes(o)) throw new RangeError(`[markdown-explorer] defaultTreeSettings.${n.key} must be one of ${s.map(d).join(", ")}; got ${d(o)}`);
179
191
  r[n.key] = o;
180
192
  }
181
193
  return Object.freeze(r);
182
- }, lt = (e) => {
194
+ }, wt = (e) => {
183
195
  if (e === null || typeof e != "object") throw new TypeError("[markdown-explorer] the explorer configuration must be an object");
184
196
  D("basePath", e.basePath), D("dataPath", e.dataPath);
185
- const t = ye(e.views);
197
+ const t = _e(e.views);
186
198
  if ((/* @__PURE__ */ new Set([t.tree, t.multi, t.single])).size !== 3)
187
199
  throw new RangeError(`[markdown-explorer] the view slugs must differ; got ${JSON.stringify(t)}`);
188
200
  if (e.dataPath === e.basePath) throw new RangeError("[markdown-explorer] dataPath must differ from basePath");
@@ -191,11 +203,11 @@ const F = (e) => {
191
203
  if (i === t.tree || i === t.multi || i === t.single)
192
204
  throw new RangeError(`[markdown-explorer] dataPath must not start with a view slug under basePath; got ${JSON.stringify(e.dataPath)}`);
193
205
  }
194
- ce(e.settingsCookie);
206
+ fe(e.settingsCookie);
195
207
  const r = e.iframeHosts ?? [];
196
- if (!Array.isArray(r) || r.some((i) => typeof i != "string" || !Se.test(i)))
208
+ if (!Array.isArray(r) || r.some((i) => typeof i != "string" || !Oe.test(i)))
197
209
  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(b("multiView", e.multiView, ["maxPanels", "columns"])), o = Object.fromEntries(b("expandAll", e.expandAll, ["maxFolders", "maxDepth"])), s = e.documentStyles ?? Y;
210
+ const n = Object.fromEntries(S("multiView", e.multiView, ["maxPanels", "columns"])), o = Object.fromEntries(S("expandAll", e.expandAll, ["maxFolders", "maxDepth"])), s = e.documentStyles ?? re;
199
211
  if (!Array.isArray(s) || s.length === 0) throw new RangeError("[markdown-explorer] documentStyles must be a non-empty array");
200
212
  const a = /* @__PURE__ */ new Set();
201
213
  for (const i of s) {
@@ -210,25 +222,26 @@ const F = (e) => {
210
222
  settingsCookie: e.settingsCookie,
211
223
  views: t,
212
224
  multiView: Object.freeze({
213
- maxPanels: y("multiView.maxPanels", n.maxPanels, fe),
214
- columns: y("multiView.columns", n.columns, ue)
225
+ maxPanels: x("multiView.maxPanels", n.maxPanels, pe),
226
+ columns: x("multiView.columns", n.columns, he)
215
227
  }),
216
228
  expandAll: Object.freeze({
217
- maxFolders: y("expandAll.maxFolders", o.maxFolders, ge),
218
- maxDepth: y("expandAll.maxDepth", o.maxDepth, we)
229
+ maxFolders: x("expandAll.maxFolders", o.maxFolders, Ee),
230
+ maxDepth: x("expandAll.maxDepth", o.maxDepth, Se)
219
231
  }),
220
232
  documentStyles: Object.freeze(s.map((i) => Object.freeze({ name: i.name, className: i.className }))),
221
233
  iframeHosts: Object.freeze([...new Set(r)]),
222
- defaultTreeSettings: xe(e.defaultTreeSettings)
234
+ embeds: Re(e.embeds),
235
+ defaultTreeSettings: Te(e.defaultTreeSettings)
223
236
  });
224
- }, Oe = (e) => typeof e == "string" && Ee.test(e), dt = (e, t) => {
225
- if (e === null || typeof e != "object") throw new TypeError(`[markdown-explorer] withExplorerSources needs the configuration of defineExplorerConfig; got ${g(e)}`);
226
- if (!Array.isArray(t) || t.length === 0) throw new RangeError(`[markdown-explorer] sourceIds must be a non-empty array; got ${g(t)}`);
237
+ }, Ne = (e) => typeof e == "string" && be.test(e), pt = (e, t) => {
238
+ if (e === null || typeof e != "object") throw new TypeError(`[markdown-explorer] withExplorerSources needs the configuration of defineExplorerConfig; got ${d(e)}`);
239
+ if (!Array.isArray(t) || t.length === 0) throw new RangeError(`[markdown-explorer] sourceIds must be a non-empty array; got ${d(t)}`);
227
240
  for (const r of t)
228
- if (!Oe(r)) throw new RangeError(`[markdown-explorer] each source id must use lowercase letters, digits and "-" and start with a letter or digit; got ${g(r)}`);
241
+ if (!Ne(r)) throw new RangeError(`[markdown-explorer] each source id must use lowercase letters, digits and "-" and start with a letter or digit; got ${d(r)}`);
229
242
  if (new Set(t).size !== t.length) throw new RangeError(`[markdown-explorer] source ids must be unique; got ${JSON.stringify(t)}`);
230
243
  return Object.freeze({ ...e, sourceIds: Object.freeze([...t]) });
231
- }, mt = (e) => e.documentStyles.map((t) => t.name), c = Object.freeze({
244
+ }, ht = (e) => e.documentStyles.map((t) => t.name), c = Object.freeze({
232
245
  source: "source",
233
246
  doc: "doc",
234
247
  maximized: "maximized",
@@ -240,25 +253,25 @@ const F = (e) => {
240
253
  padding: "padding",
241
254
  width: "width",
242
255
  maxWidth: "maxWidth"
243
- }), C = ".data", J = 256, X = /^\d+(?:\.\d+)?$/u, I = /^\d+(?:\.\d+)?(?:px|rem|em|ch|vw|%)$/u, W = Object.freeze(["showToc", "showStyle", "showAlign"]), be = (e) => {
256
+ }), C = ".data", J = 256, X = /^\d+(?:\.\d+)?$/u, I = /^\d+(?:\.\d+)?(?:px|rem|em|ch|vw|%)$/u, W = Object.freeze(["showToc", "showStyle", "showAlign"]), Ae = (e) => {
244
257
  const t = encodeURIComponent(e.replaceAll("%", "%25"));
245
258
  return t.endsWith(C) ? `${t.slice(0, -C.length)}%2Edata` : t;
246
- }, Te = (e) => e.replaceAll("%25", "%"), H = (e) => {
259
+ }, Ie = (e) => e.replaceAll("%25", "%"), H = (e) => {
247
260
  const { sourceIds: t } = e;
248
261
  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
262
  return t;
250
- }, _e = (e, t, r) => {
263
+ }, ke = (e, t, r) => {
251
264
  const n = r.getAll(c.source);
252
265
  if (n.length === 0) return t;
253
266
  const [o] = n;
254
267
  return n.length > 1 || o === void 0 || o === t || !e.includes(o) ? null : o;
255
- }, Ne = (e, t) => {
268
+ }, $e = (e, t) => {
256
269
  const r = t.get(c.style), n = t.get(c.align);
257
270
  return {
258
271
  ...r !== null && e.documentStyles.some((o) => o.name === r) ? { style: r } : {},
259
- ...n !== null && x.includes(n) ? { align: n } : {}
272
+ ...n !== null && b.includes(n) ? { align: n } : {}
260
273
  };
261
- }, q = (e) => Number.isFinite(e) && e >= 0 && e <= J && X.test(String(e)), Re = (e) => {
274
+ }, q = (e) => Number.isFinite(e) && e >= 0 && e <= J && X.test(String(e)), ve = (e) => {
262
275
  const t = e.get(c.padding), r = t !== null && X.test(t) ? Number(t) : Number.NaN, n = e.get(c.width), o = e.get(c.maxWidth);
263
276
  return {
264
277
  ...e.get(c.showToc) === "false" ? { showToc: !1 } : {},
@@ -268,20 +281,20 @@ const F = (e) => {
268
281
  ...n !== null && I.test(n) ? { width: n } : {},
269
282
  ...o !== null && I.test(o) ? { maxWidth: o } : {}
270
283
  };
271
- }, Ae = (e, t) => [...new Set(t.filter(k))].slice(0, e.multiView.maxPanels), Ie = (e, t, r) => {
272
- for (const n of t) K(n);
284
+ }, Pe = (e, t) => [...new Set(t.filter(k))].slice(0, e.multiView.maxPanels), Me = (e, t, r) => {
285
+ for (const n of t) B(n);
273
286
  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
287
  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
288
  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
- }, K = (e) => {
289
+ }, B = (e) => {
277
290
  if (!k(e)) throw new RangeError(`[markdown-explorer] not an acceptable document path: ${JSON.stringify(String(e).slice(0, 80))}`);
278
291
  return e;
279
- }, ke = (e, t) => {
292
+ }, Le = (e, t) => {
280
293
  if (t.style !== void 0 && !e.documentStyles.some((r) => r.name === t.style))
281
294
  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
- if (t.align !== void 0 && !x.includes(t.align))
283
- throw new RangeError(`[markdown-explorer] overrides.align must be one of ${x.join(", ")}; got ${JSON.stringify(t.align)}`);
284
- }, $e = (e) => {
295
+ if (t.align !== void 0 && !b.includes(t.align))
296
+ throw new RangeError(`[markdown-explorer] overrides.align must be one of ${b.join(", ")}; got ${JSON.stringify(t.align)}`);
297
+ }, ze = (e) => {
285
298
  for (const t of W)
286
299
  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
300
  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)}`);
@@ -289,94 +302,94 @@ const F = (e) => {
289
302
  const r = e[t];
290
303
  if (r !== void 0 && !I.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
304
  }
292
- }, Pe = (e, t) => {
305
+ }, je = (e, t) => {
293
306
  const r = new URLSearchParams();
294
307
  let n = `${e.basePath}/${e.views[t.view]}`;
295
308
  if (t.view === "multi") {
296
309
  const s = t.docs ?? [], a = t.maximized ?? null;
297
- Ie(e, s, a);
310
+ Me(e, s, a);
298
311
  for (const i of s) r.append(c.doc, i);
299
312
  a !== null && r.set(c.maximized, a);
300
- } else t.doc !== void 0 && t.doc !== null && (n += `/${be(K(t.doc))}`);
313
+ } else t.doc !== void 0 && t.doc !== null && (n += `/${Ae(B(t.doc))}`);
301
314
  if (t.source !== void 0) {
302
315
  const s = H(e);
303
316
  if (!s.includes(t.source)) throw new RangeError(`[markdown-explorer] unknown source ${JSON.stringify(t.source)}; expected one of ${s.join(", ")}`);
304
317
  t.source !== s[0] && r.set(c.source, t.source);
305
318
  }
306
- if (t.view !== "multi" && t.overrides !== void 0 && (ke(e, t.overrides), t.overrides.style !== void 0 && r.set(c.style, t.overrides.style), t.overrides.align !== void 0 && r.set(c.align, t.overrides.align)), t.view === "single" && t.embed !== void 0) {
319
+ if (t.view !== "multi" && t.overrides !== void 0 && (Le(e, t.overrides), t.overrides.style !== void 0 && r.set(c.style, t.overrides.style), t.overrides.align !== void 0 && r.set(c.align, t.overrides.align)), t.view === "single" && t.embed !== void 0) {
307
320
  const { embed: s } = t;
308
- $e(s);
321
+ ze(s);
309
322
  for (const a of W) s[a] === !1 && r.set(c[a], "false");
310
323
  s.padding !== void 0 && r.set(c.padding, String(s.padding)), s.width !== void 0 && r.set(c.width, s.width), s.maxWidth !== void 0 && r.set(c.maxWidth, s.maxWidth);
311
324
  }
312
325
  const o = r.toString();
313
326
  return o === "" ? n : `${n}?${o}`;
314
- }, ve = (e, t) => Object.keys(e.views).find((r) => e.views[r] === t), ft = (e, t, r) => {
327
+ }, De = (e, t) => Object.keys(e.views).find((r) => e.views[r] === t), Et = (e, t, r) => {
315
328
  const n = H(e), [o] = n;
316
329
  if (o === void 0) throw new RangeError("[markdown-explorer] the configuration has no source");
317
- const s = _e(n, o, r), a = s === null ? o : s, i = (d) => ({ kind: "redirect", href: Pe(e, d), location: d }), l = () => i({ view: "tree", source: a, doc: null, overrides: {} });
330
+ const s = ke(n, o, r), a = s === null ? o : s, i = (m) => ({ kind: "redirect", href: je(e, m), location: m }), l = () => i({ view: "tree", source: a, doc: null, overrides: {} });
318
331
  if (t === void 0 || t === "") return l();
319
- const h = t.indexOf("/"), T = h < 0 ? t : t.slice(0, h), _ = h < 0 ? null : t.slice(h + 1), m = ve(e, T);
320
- if (m === void 0) return l();
321
- if (m === "multi") {
322
- const d = r.getAll(c.doc), E = Ae(e, d), N = r.getAll(c.maximized), [R] = N, A = N.length === 1 && R !== void 0 && E.includes(R) ? R : null;
323
- return _ === null && s !== null && E.length === d.length && E.every((B, Z) => B === d[Z]) && (N.length === 0 || A !== null) ? { kind: "location", location: { view: "multi", source: a, docs: E, maximized: A } } : i({ view: "multi", source: a, docs: E, maximized: A });
332
+ const h = t.indexOf("/"), _ = h < 0 ? t : t.slice(0, h), R = h < 0 ? null : t.slice(h + 1), f = De(e, _);
333
+ if (f === void 0) return l();
334
+ if (f === "multi") {
335
+ const m = r.getAll(c.doc), E = Pe(e, m), T = r.getAll(c.maximized), [N] = T, A = T.length === 1 && N !== void 0 && E.includes(N) ? N : null;
336
+ return R === null && s !== null && E.length === m.length && E.every((K, Z) => K === m[Z]) && (T.length === 0 || A !== null) ? { kind: "location", location: { view: "multi", source: a, docs: E, maximized: A } } : i({ view: "multi", source: a, docs: E, maximized: A });
324
337
  }
325
- const f = _ === null ? null : Te(_);
326
- if (f !== null && !k(f)) return l();
327
- const S = Ne(e, r);
328
- if (m === "single") {
329
- if (f === null) return l();
330
- const d = Re(r);
331
- return s === null ? i({ view: m, source: a, doc: f, overrides: S, embed: d }) : { kind: "location", location: { view: m, source: a, doc: f, overrides: S, embed: d } };
338
+ const u = R === null ? null : Ie(R);
339
+ if (u !== null && !k(u)) return l();
340
+ const y = $e(e, r);
341
+ if (f === "single") {
342
+ if (u === null) return l();
343
+ const m = ve(r);
344
+ 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
345
  }
333
- return s === null ? i({ view: m, source: a, doc: f, overrides: S }) : { kind: "location", location: { view: m, source: a, doc: f, overrides: S } };
346
+ return s === null ? i({ view: f, source: a, doc: u, overrides: y }) : { kind: "location", location: { view: f, source: a, doc: u, overrides: y } };
334
347
  };
335
348
  export {
336
- He as A,
337
- Ge as B,
338
- Ke as C,
339
- L as D,
340
- rt as E,
341
- Ze as F,
349
+ Qe as A,
350
+ Be as B,
351
+ tt as C,
352
+ M as D,
353
+ ct as E,
354
+ nt as F,
342
355
  w as G,
343
- Fe as H,
344
- ct as I,
345
- et as J,
346
- v as K,
356
+ We as H,
357
+ gt as I,
358
+ it as J,
359
+ P as K,
347
360
  j as L,
348
- we as M,
349
- P as N,
350
- ge as O,
351
- Ye as P,
352
- te as Q,
353
- ue as R,
354
- qe as S,
355
- fe as T,
356
- lt as a,
357
- it as b,
358
- Ae as c,
359
- mt as d,
360
- Pe as e,
361
+ Se as M,
362
+ v as N,
363
+ Ee as O,
364
+ ot as P,
365
+ se as Q,
366
+ he as R,
367
+ et as S,
368
+ pe as T,
369
+ wt as a,
370
+ ft as b,
371
+ Pe as c,
372
+ ht as d,
373
+ je as e,
361
374
  F as f,
362
- st as g,
363
- ot as h,
364
- Oe as i,
365
- Qe as j,
366
- Je as k,
367
- Ce as l,
368
- tt as m,
369
- oe as n,
375
+ mt as g,
376
+ dt as h,
377
+ Ne as i,
378
+ st as j,
379
+ Ke as k,
380
+ Xe as l,
381
+ at as m,
382
+ ce as n,
370
383
  G as o,
371
- at as p,
372
- Xe as q,
373
- ft as r,
374
- We as s,
375
- Be as t,
376
- nt as u,
377
- je as v,
378
- dt as w,
379
- Ue as x,
380
- De as y,
381
- Ve as z
384
+ ut as p,
385
+ Ze as q,
386
+ Et as r,
387
+ Ye as s,
388
+ rt as t,
389
+ lt as u,
390
+ Ge as v,
391
+ pt as w,
392
+ qe as x,
393
+ Je as y,
394
+ He as z
382
395
  };
@@ -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-CKbdwkQ7.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();