@popcorn245/cornfield-components 0.52.0 → 0.52.1
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/dist/chunks/{around-D7aqHejs.js → around-BFqYTZ0K.js} +10 -10
- package/dist/chunks/{corn-layers-g9AprK6G.js → corn-layers-Cni5rISZ.js} +95 -95
- package/dist/chunks/{corn-map-DE-pg-A0.js → corn-map-B2-YxiEL.js} +3 -3
- package/dist/chunks/{corn-node-panel-CdtFb9IZ.js → corn-node-panel-BkvJThlp.js} +3 -3
- package/dist/chunks/{corn-review-9krtLSPK.js → corn-review-5wf7AT4o.js} +889 -889
- package/dist/chunks/{corn-search-BY1Po63S.js → corn-search-CXs5d06S.js} +39 -39
- package/dist/chunks/{engine-HIgX35hE.js → engine-BmXtSISH.js} +415 -400
- package/dist/chunks/{layers-n1mJVJs8.js → layers-Bj4Tluxe.js} +50 -50
- package/dist/chunks/{map-CeP9M2_w.js → map-BZRFOYkt.js} +749 -718
- package/dist/chunks/{node-panel-CY5xnuKC.js → node-panel-BdvFvWCE.js} +332 -332
- package/dist/chunks/{review-source-DWisOXyR.js → review-source-CK5tYIqk.js} +1 -1
- package/dist/chunks/{scope-CUhp8mkf.js → scope-CqPbHcKL.js} +19 -19
- package/dist/chunks/sheets-D-sMZzSs.js +204 -0
- package/dist/chunks/{status-CsFpnQxw.js → status-DI5QLlAp.js} +55 -55
- package/dist/corn-layers.js +1 -1
- package/dist/corn-map.js +1 -1
- package/dist/corn-node-panel.js +1 -1
- package/dist/corn-review.js +1 -1
- package/dist/corn-scope.js +3 -3
- package/dist/corn-search.js +1 -1
- package/dist/index.js +6 -6
- package/dist/manifest.json +43 -43
- package/dist/version.json +1 -1
- package/package.json +1 -1
- package/dist/chunks/sheets-TFCL_dIn.js +0 -204
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { t as e } from "./rolldown-runtime-CGnMp29N.js";
|
|
2
|
-
import {
|
|
3
|
-
import { a as
|
|
4
|
-
var
|
|
5
|
-
function
|
|
2
|
+
import { At as t, Ct as n, Dn as r, Dt as i, En as a, Et as o, Jt as s, Kt as c, Lt as l, Ot as u, St as d, Tn as f, an as p, bt as m, dn as h, fn as g, in as _, jn as v, jt as y, kt as b, nn as x, on as S, qt as C, rn as ee, sn as w, wt as T, xn as E, xt as D, yn as O, yt as k, zt as A } from "./engine-BmXtSISH.js";
|
|
3
|
+
import { a as j, c as te, d as ne, i as re, n as M, o as ie, u as ae } from "./sheets-D-sMZzSs.js";
|
|
4
|
+
var N = 0;
|
|
5
|
+
function P(e, t = 5) {
|
|
6
6
|
if (e.length <= t + 1) return e.join("");
|
|
7
|
-
let n = `hx-more-${++
|
|
7
|
+
let n = `hx-more-${++N}`, r = e.length - t;
|
|
8
8
|
return `${e.slice(0, t).join("")}<div class="hx-more" id="${n}" hidden>${e.slice(t).join("")}</div><button data-corn="more" data-corn-kind="quiet" type="button" class="hx-btn hx-btn--quiet hx-textact hx-more-btn" data-more="${n}" data-rest="${r}" aria-expanded="false" aria-controls="${n}">and ${r} more</button>`;
|
|
9
9
|
}
|
|
10
|
-
function
|
|
10
|
+
function oe(e) {
|
|
11
11
|
let t = e.closest && e.closest("[data-more]");
|
|
12
12
|
if (!t) return !1;
|
|
13
13
|
let n = t.previousElementSibling, r = n && n.id === t.dataset.more ? n : null, i = t.getAttribute("aria-expanded") !== "true";
|
|
14
14
|
return r && (r.hidden = !i), t.setAttribute("aria-expanded", String(i)), t.textContent = i ? "Show fewer" : `and ${t.dataset.rest} more`, !0;
|
|
15
15
|
}
|
|
16
16
|
// ../explorer/engine/flow-ui.js
|
|
17
|
-
function
|
|
18
|
-
let { state: n } = e, r = (e) => (n.nodes.find((t) => t.id === e) || { label: e }).label, i = n.edges.filter((e) => e.kind === "flow" && (e.from === t.id || e.to === t.id)), a = (e, t, n) => t.length ? `<div class="hx-fact" data-corn="section"><div class="hx-fact-k">${e}</div><div class="hx-fact-v">${
|
|
17
|
+
function se(e, t) {
|
|
18
|
+
let { state: n } = e, r = (e) => (n.nodes.find((t) => t.id === e) || { label: e }).label, i = n.edges.filter((e) => e.kind === "flow" && (e.from === t.id || e.to === t.id)), a = (e, t, n) => t.length ? `<div class="hx-fact" data-corn="section"><div class="hx-fact-k">${e}</div><div class="hx-fact-v">${P(t.map((e) => `<div class="hx-line"><span><span class="hx-name">${c(r(n ? e.to : e.from))}</span> · ${c(e.label)}${e.status === "live" ? "" : " <span class=\"hx-warn\">(proposed)</span>"}</span></div>`))}</div></div>` : "";
|
|
19
19
|
return a("Sends to", i.filter((e) => e.from === t.id), !0) + a("Gets from", i.filter((e) => e.to === t.id && e.from !== t.id), !1);
|
|
20
20
|
}
|
|
21
21
|
// ../explorer/corn-state.js
|
|
22
|
-
var
|
|
22
|
+
var F = Object.freeze([
|
|
23
23
|
"open",
|
|
24
24
|
"merged",
|
|
25
25
|
"closed",
|
|
@@ -40,7 +40,7 @@ var N = Object.freeze([
|
|
|
40
40
|
"removed",
|
|
41
41
|
"edit",
|
|
42
42
|
"sent-back"
|
|
43
|
-
]),
|
|
43
|
+
]), I = Object.freeze([
|
|
44
44
|
"added",
|
|
45
45
|
"changed",
|
|
46
46
|
"removed",
|
|
@@ -55,7 +55,7 @@ Object.freeze([
|
|
|
55
55
|
"failed",
|
|
56
56
|
"stopped"
|
|
57
57
|
]);
|
|
58
|
-
var
|
|
58
|
+
var ce = Object.freeze({
|
|
59
59
|
quiet: "waiting",
|
|
60
60
|
"stop-requested": "stopped",
|
|
61
61
|
neutral: "done",
|
|
@@ -76,20 +76,20 @@ var ue = Object.freeze({
|
|
|
76
76
|
error: "failure",
|
|
77
77
|
idle: "running"
|
|
78
78
|
});
|
|
79
|
-
function
|
|
79
|
+
function L(e) {
|
|
80
80
|
let t = String(e || "");
|
|
81
|
-
return
|
|
81
|
+
return ce[t] || (F.includes(t) && !I.includes(t) ? t : "");
|
|
82
82
|
}
|
|
83
|
-
function
|
|
83
|
+
function le(e) {
|
|
84
84
|
let t = String(e || "");
|
|
85
|
-
return
|
|
85
|
+
return I.includes(t) ? t : "";
|
|
86
86
|
}
|
|
87
|
-
function
|
|
88
|
-
let t =
|
|
87
|
+
function R(e) {
|
|
88
|
+
let t = le(e);
|
|
89
89
|
return t ? ` data-corn-state="${t}"` : "";
|
|
90
90
|
}
|
|
91
|
-
function
|
|
92
|
-
let t =
|
|
91
|
+
function z(e) {
|
|
92
|
+
let t = L(e);
|
|
93
93
|
return t ? ` data-corn-state="${t}"` : "";
|
|
94
94
|
}
|
|
95
95
|
Object.freeze({
|
|
@@ -119,7 +119,7 @@ Object.freeze({
|
|
|
119
119
|
quiet: "waiting",
|
|
120
120
|
"stop-requested": "stopped"
|
|
121
121
|
});
|
|
122
|
-
function
|
|
122
|
+
function ue(e) {
|
|
123
123
|
let t = Math.max(0, Math.round(e / 1e3));
|
|
124
124
|
return t < 60 ? `${t} s` : t < 3600 ? `${Math.floor(t / 60)} min` : `${Math.floor(t / 3600)} h`;
|
|
125
125
|
}
|
|
@@ -183,32 +183,32 @@ Object.freeze([
|
|
|
183
183
|
local: "draft",
|
|
184
184
|
unknown: "failure"
|
|
185
185
|
});
|
|
186
|
-
function
|
|
186
|
+
function de(e) {
|
|
187
187
|
let t = e && e.report && typeof e.report.note == "string" ? e.report.note.replace(/\s+/g, " ").trim() : "", n = t.length > 90 ? `${t.slice(0, 89).trimEnd()}\u2026` : t;
|
|
188
188
|
return `A run is waiting on you${n ? `: ${n}` : ""}`;
|
|
189
189
|
}
|
|
190
190
|
// ../explorer/proposal-model.js
|
|
191
|
-
var
|
|
191
|
+
var fe = [
|
|
192
192
|
"before",
|
|
193
193
|
"diff",
|
|
194
194
|
"after"
|
|
195
|
-
],
|
|
195
|
+
], pe = [
|
|
196
196
|
"added",
|
|
197
197
|
"changed",
|
|
198
198
|
"removed"
|
|
199
199
|
];
|
|
200
|
-
function
|
|
201
|
-
let t =
|
|
200
|
+
function me(e) {
|
|
201
|
+
let t = he({
|
|
202
202
|
...e,
|
|
203
203
|
scenarios: 0
|
|
204
204
|
}).filter((e) => e.mark).map((e) => e.text.replace(/^\+/, ""));
|
|
205
205
|
return t.length ? t.join(" · ") : "No changes";
|
|
206
206
|
}
|
|
207
|
-
function
|
|
207
|
+
function he(e) {
|
|
208
208
|
let t = (t) => e?.[t] || 0, n = (e, t) => `${e} ${t}${e === 1 ? "" : "s"}`, r = (r) => {
|
|
209
209
|
let i = e?.nodes?.[r] || 0, a = e?.edges?.[r] || 0;
|
|
210
210
|
return !e?.nodes || i + a !== t(r) ? `${r === "added" ? "+" : ""}${t(r)} ${r}` : `${[i && n(i, "node"), a && n(a, "edge")].filter(Boolean).join(", ")} ${r}`;
|
|
211
|
-
}, i =
|
|
211
|
+
}, i = pe.filter((e) => t(e) > 0).map((e) => ({
|
|
212
212
|
mark: e,
|
|
213
213
|
text: r(e)
|
|
214
214
|
}));
|
|
@@ -220,15 +220,15 @@ function _e(e) {
|
|
|
220
220
|
text: "No changes"
|
|
221
221
|
}];
|
|
222
222
|
}
|
|
223
|
-
var
|
|
224
|
-
function
|
|
223
|
+
var ge = (e) => `${e === "before" ? "Before" : e === "after" ? "After" : "Diff"} view`, _e = (e, t) => `${t}, ${String(e).toLowerCase()}. The map is on it.`, ve = /^[A-Za-z0-9][A-Za-z0-9._-]*$/, ye = 200, be = (e) => typeof e == "string" && e.length <= ye && ve.test(e);
|
|
224
|
+
function xe(e) {
|
|
225
225
|
let t = String(e ?? ""), n = t.length > 60 ? `${t.slice(0, 59)}\u2026` : t;
|
|
226
226
|
return n.trim() ? `\u201c${n}\u201d is not a proposal's name.` : "That is not a proposal's name.";
|
|
227
227
|
}
|
|
228
|
-
function
|
|
228
|
+
function Se(e) {
|
|
229
229
|
return e == null ? "" : typeof e == "string" ? e : JSON.stringify(e);
|
|
230
230
|
}
|
|
231
|
-
var
|
|
231
|
+
var Ce = [
|
|
232
232
|
"mark",
|
|
233
233
|
"editOp",
|
|
234
234
|
"before",
|
|
@@ -243,48 +243,48 @@ var we = [
|
|
|
243
243
|
"from",
|
|
244
244
|
"to"
|
|
245
245
|
];
|
|
246
|
-
function
|
|
247
|
-
return
|
|
246
|
+
function we(e) {
|
|
247
|
+
return y(e) === "added" ? Object.keys(e).filter((t) => !Ce.includes(t) && e[t] !== void 0).map((t) => ({
|
|
248
248
|
field: t,
|
|
249
249
|
before: "",
|
|
250
|
-
after:
|
|
250
|
+
after: Se(e[t])
|
|
251
251
|
})) : e.mark === "changed" && e.before ? Object.keys(e.before).map((t) => ({
|
|
252
252
|
field: t,
|
|
253
|
-
before:
|
|
254
|
-
after:
|
|
253
|
+
before: Se(e.before[t]),
|
|
254
|
+
after: Se(e[t])
|
|
255
255
|
})) : [];
|
|
256
256
|
}
|
|
257
|
-
var
|
|
257
|
+
var B = {
|
|
258
258
|
added: "Added",
|
|
259
259
|
changed: "Changed",
|
|
260
260
|
removed: "Removed",
|
|
261
261
|
edit: "Your edit"
|
|
262
262
|
};
|
|
263
|
-
function
|
|
264
|
-
if (!
|
|
265
|
-
let
|
|
266
|
-
return `<div class="hx-sec hx-proposal-sec hx-proposal-sec--${
|
|
267
|
-
<strong class="hx-strong"><span class="hx-mark-dot hx-mark-dot--${
|
|
268
|
-
${e.why ? `<div class="hx-why">${
|
|
269
|
-
${
|
|
263
|
+
function Te(e) {
|
|
264
|
+
if (!t(e)) return "";
|
|
265
|
+
let n = we(e).map((t) => e.mark === "changed" ? `<div class="hx-change" data-corn="field-change"><span class="hx-change-field">${c(t.field)}</span><span class="hx-change-before">${c(t.before) || "<em>nothing</em>"}</span><span class="hx-change-arrow" aria-hidden="true">→</span><span class="hx-change-after">${c(t.after) || "<em>nothing</em>"}</span></div>` : `<div class="hx-change" data-corn="field-change"><span class="hx-change-field">${c(t.field)}</span><span class="hx-change-after">${c(t.after)}</span></div>`).join("");
|
|
266
|
+
return `<div class="hx-sec hx-proposal-sec hx-proposal-sec--${c(e.mark)}" data-proposal-mark="${c(e.mark)}" data-corn="section">
|
|
267
|
+
<strong class="hx-strong"><span class="hx-mark-dot hx-mark-dot--${c(e.mark)}" data-corn="mark-dot"${R(e.mark)}></span>${c(e.mark === "edit" ? `${e.editOp === "removed" ? "Removed" : "Added"} by your edit` : `${B[e.mark] || e.mark} by this proposal`)}</strong>
|
|
268
|
+
${e.why ? `<div class="hx-why">${c(e.why)}</div>` : ""}
|
|
269
|
+
${n}
|
|
270
270
|
</div>`;
|
|
271
271
|
}
|
|
272
|
-
var
|
|
273
|
-
function
|
|
272
|
+
var Ee = (e, t) => `${e} ${t}${e === 1 ? "" : "s"}`;
|
|
273
|
+
function De(e) {
|
|
274
274
|
if (!Array.isArray(e) || e.length === 0) return "no checks";
|
|
275
275
|
let t = (t) => e.filter((e) => t.includes(e.state)).length, n = t(["failure"]), r = t(["cancelled"]), i = t(["running", "queued"]), a = [];
|
|
276
|
-
return n && a.push(`${
|
|
276
|
+
return n && a.push(`${Ee(n, "check")} failed`), r && a.push(`${Ee(r, "check")} cancelled`), i && a.push(`${Ee(i, "check")} running`), a.length ? a.join(", ") : e.length === 1 ? "1 check passed" : `all ${e.length} checks passed`;
|
|
277
277
|
}
|
|
278
|
-
function
|
|
278
|
+
function V(e) {
|
|
279
279
|
let t = typeof e == "string" ? /^pull\/([1-9]\d{0,8})$/.exec(e) : null;
|
|
280
280
|
return t ? Number(t[1]) : null;
|
|
281
281
|
}
|
|
282
|
-
function
|
|
283
|
-
let t =
|
|
282
|
+
function Oe(e) {
|
|
283
|
+
let t = V(e);
|
|
284
284
|
return t ? `PR #${t}` : !e || e === "checkout" ? "the checkout" : `worktree ${e}`;
|
|
285
285
|
}
|
|
286
|
-
function
|
|
287
|
-
let r =
|
|
286
|
+
function ke(e, t = null, n = null) {
|
|
287
|
+
let r = V(e);
|
|
288
288
|
if (!r) {
|
|
289
289
|
let t = !e || e === "checkout" ? "in the checkout" : `in worktree ${e}`;
|
|
290
290
|
return {
|
|
@@ -295,30 +295,30 @@ function Ae(e, t = null, n = null) {
|
|
|
295
295
|
};
|
|
296
296
|
}
|
|
297
297
|
let i = [`PR #${r}`], a = t ? t.state === "merged" || t.state === "closed" ? t.state : typeof t.draft == "boolean" ? t.draft ? "draft" : "open" : "" : "";
|
|
298
|
-
return a && i.push(a), Array.isArray(n) && i.push(
|
|
298
|
+
return a && i.push(a), Array.isArray(n) && i.push(De(n)), {
|
|
299
299
|
text: i.join(" · "),
|
|
300
300
|
href: t && typeof t.url == "string" ? t.url : null,
|
|
301
301
|
state: a,
|
|
302
302
|
label: `Reviewing spec pull request: ${i.join(", ")}`
|
|
303
303
|
};
|
|
304
304
|
}
|
|
305
|
-
function
|
|
306
|
-
return t ?
|
|
305
|
+
function Ae(e, t, n = null) {
|
|
306
|
+
return t ? V(t) || t === "checkout" || n && n.has(t) && ve.test(t) ? `There is no proposal called ${e} in ${Oe(t)}.` : `There is no proposal called ${e}. This link's source is not a PR, the checkout or a worktree.` : `There is no proposal called ${e}.`;
|
|
307
307
|
}
|
|
308
|
-
function
|
|
308
|
+
function je(e) {
|
|
309
309
|
let t = new URLSearchParams(e || "");
|
|
310
310
|
if (!t.has("proposal")) return null;
|
|
311
311
|
let n = t.get("proposal") || "";
|
|
312
|
-
return
|
|
312
|
+
return ve.test(n) ? null : n.trim() ? `This link does not name a proposal: ${xe(n)}` : "This link does not name a proposal.";
|
|
313
313
|
}
|
|
314
|
-
function
|
|
315
|
-
return Array.isArray(e) ? e.filter((e) => e && e.slug === t && e.source !== n && !e.error).sort((e, t) => +!!
|
|
314
|
+
function Me(e, t, n) {
|
|
315
|
+
return Array.isArray(e) ? e.filter((e) => e && e.slug === t && e.source !== n && !e.error).sort((e, t) => +!!V(t.source) - !!V(e.source)).map((e) => ({
|
|
316
316
|
slug: e.slug,
|
|
317
317
|
source: e.source,
|
|
318
|
-
label:
|
|
318
|
+
label: V(e.source) ? `Open the copy in PR #${V(e.source)}${e.pull && e.pull.draft ? " (draft)" : ""}` : `Open the copy ${e.source === "checkout" ? "in the checkout" : `in worktree ${e.source}`}`
|
|
319
319
|
})) : [];
|
|
320
320
|
}
|
|
321
|
-
function
|
|
321
|
+
function Ne(e, t = !1) {
|
|
322
322
|
let n = Array.isArray(e) ? e : [];
|
|
323
323
|
if (!n.length) return "";
|
|
324
324
|
let r = (e) => n.filter((t) => t && e.includes(t.op)).length, i = (e, t) => `${e} ${t}${e === 1 ? "" : "s"}`, a = [];
|
|
@@ -343,7 +343,7 @@ function Pe(e, t = !1) {
|
|
|
343
343
|
return s > 0 && a.push(i(s, "other edit")), `yours: ${a.join(", ")}${t ? " (hidden)" : ""}`;
|
|
344
344
|
}
|
|
345
345
|
// ../core/proposal.js
|
|
346
|
-
var
|
|
346
|
+
var Pe = [
|
|
347
347
|
"version",
|
|
348
348
|
"spec",
|
|
349
349
|
"title",
|
|
@@ -352,18 +352,18 @@ var Fe = [
|
|
|
352
352
|
"edges",
|
|
353
353
|
"mockups",
|
|
354
354
|
"scenarios"
|
|
355
|
-
],
|
|
355
|
+
], Fe = [
|
|
356
356
|
"node",
|
|
357
357
|
"path",
|
|
358
358
|
"title"
|
|
359
|
-
],
|
|
359
|
+
], Ie = [
|
|
360
360
|
"png",
|
|
361
361
|
"jpg",
|
|
362
362
|
"jpeg",
|
|
363
363
|
"webp",
|
|
364
364
|
"svg",
|
|
365
365
|
"html"
|
|
366
|
-
],
|
|
366
|
+
], Le = [
|
|
367
367
|
"id",
|
|
368
368
|
"title",
|
|
369
369
|
"steps",
|
|
@@ -371,7 +371,7 @@ var Fe = [
|
|
|
371
371
|
"linkNodes",
|
|
372
372
|
"actor",
|
|
373
373
|
"down"
|
|
374
|
-
],
|
|
374
|
+
], Re = [
|
|
375
375
|
"node",
|
|
376
376
|
"edge",
|
|
377
377
|
"text",
|
|
@@ -380,23 +380,23 @@ var Fe = [
|
|
|
380
380
|
"at",
|
|
381
381
|
"check",
|
|
382
382
|
"expect"
|
|
383
|
-
],
|
|
383
|
+
], ze = [
|
|
384
384
|
"GET",
|
|
385
385
|
"POST",
|
|
386
386
|
"PUT",
|
|
387
387
|
"PATCH",
|
|
388
388
|
"DELETE"
|
|
389
|
-
],
|
|
389
|
+
], Be = [
|
|
390
390
|
"read",
|
|
391
391
|
"write",
|
|
392
392
|
"delete"
|
|
393
|
-
],
|
|
393
|
+
], Ve = [
|
|
394
394
|
"own",
|
|
395
395
|
"household",
|
|
396
396
|
"others",
|
|
397
397
|
"shared-read",
|
|
398
398
|
"shared-write"
|
|
399
|
-
],
|
|
399
|
+
], He = ["allowed", "refused"], Ue = /^[a-z0-9]+(?:-[a-z0-9]+)*$/, We = `live-room-<id>, live-floor-<id> or live-device-<kind>-<id> (kind one of ${k.join(", ")})`, Ge = [
|
|
400
400
|
"add",
|
|
401
401
|
"change",
|
|
402
402
|
"remove"
|
|
@@ -425,7 +425,7 @@ function Ze(e) {
|
|
|
425
425
|
if (t.some((e) => e === "" || e === "." || e === "..")) return "\"path\" stays inside the proposals folder: no \"..\", no \".\" and no empty parts.";
|
|
426
426
|
if (t.some((e) => e.startsWith("."))) return "\"path\" has a hidden part (one that starts with a dot).";
|
|
427
427
|
let n = t[t.length - 1].split(".").length > 1 ? t[t.length - 1].split(".").pop().toLowerCase() : "";
|
|
428
|
-
return
|
|
428
|
+
return Ie.includes(n) ? null : `A mockup is one of: ${Ie.join(", ")}.`;
|
|
429
429
|
}
|
|
430
430
|
function Qe(e) {
|
|
431
431
|
if (!H(e) || !Array.isArray(e.mockups)) return [];
|
|
@@ -447,7 +447,7 @@ var $e = (e) => ({
|
|
|
447
447
|
to: e.id
|
|
448
448
|
});
|
|
449
449
|
function et(e, t) {
|
|
450
|
-
let
|
|
450
|
+
let r = [], a = (e, t, n) => r.push(n ? {
|
|
451
451
|
path: e,
|
|
452
452
|
message: t,
|
|
453
453
|
state: n
|
|
@@ -455,10 +455,10 @@ function et(e, t) {
|
|
|
455
455
|
path: e,
|
|
456
456
|
message: t
|
|
457
457
|
});
|
|
458
|
-
if (!H(t)) return a("", "A proposal is a JSON object."),
|
|
459
|
-
for (let e of Object.keys(t))
|
|
458
|
+
if (!H(t)) return a("", "A proposal is a JSON object."), r;
|
|
459
|
+
for (let e of Object.keys(t)) Pe.includes(e) || a(e, `Unknown key "${e}". A proposal has: ${Pe.join(", ")}.`);
|
|
460
460
|
t.version !== 1 && a("version", `"version" must be the number 1 (got ${JSON.stringify(t.version)}).`), U(t.title) || a("title", "\"title\" must be a non-empty string."), U(t.summary) || a("summary", "\"summary\" must be a non-empty string: the one sentence the maintainer reads first."), t.spec !== void 0 && !U(t.spec) && a("spec", "\"spec\" must be the spec number as a string, like \"0013\".");
|
|
461
|
-
let
|
|
461
|
+
let s = (e) => {
|
|
462
462
|
let n = t[e];
|
|
463
463
|
if (n === void 0) return {
|
|
464
464
|
add: [],
|
|
@@ -474,112 +474,112 @@ function et(e, t) {
|
|
|
474
474
|
for (let t of Object.keys(n)) Ge.includes(t) || a(`${e}.${t}`, `Unknown key "${t}" in "${e}". Use add, change or remove.`);
|
|
475
475
|
for (let t of Ge) n[t] === void 0 ? r[t] = [] : Array.isArray(n[t]) ? r[t] = n[t] : (a(`${e}.${t}`, `"${e}.${t}" must be a list.`), r[t] = []);
|
|
476
476
|
return r;
|
|
477
|
-
},
|
|
478
|
-
|
|
479
|
-
H(e) && U(e.id) && !
|
|
477
|
+
}, c = s("nodes"), l = s("edges"), f = new Map(G(e?.nodes).map((e) => [e.id, e])), p = new Set(G(e?.edges).map(K)), h = /* @__PURE__ */ new Map();
|
|
478
|
+
c.add.forEach((e, t) => {
|
|
479
|
+
H(e) && U(e.id) && !h.has(e.id) && h.set(e.id, t);
|
|
480
480
|
});
|
|
481
|
-
let
|
|
482
|
-
|
|
483
|
-
let
|
|
484
|
-
if (!H(e)) return a(
|
|
485
|
-
U(e.id) ?
|
|
486
|
-
for (let t of Ke) t in e && a(`${
|
|
487
|
-
if (e.type === "device" && !
|
|
488
|
-
let t =
|
|
489
|
-
!t || t.type !== e.type ? a(`${
|
|
481
|
+
let g = new Set(c.remove.filter((e) => H(e) && U(e.id)).map((e) => e.id)), _ = (e) => f.has(e) || h.has(e), v = /* @__PURE__ */ new Set(), y = /* @__PURE__ */ new Map();
|
|
482
|
+
c.add.forEach((e, t) => {
|
|
483
|
+
let r = `nodes.add[${t}]`;
|
|
484
|
+
if (!H(e)) return a(r, "An added node is an object with an id, a label and a type.");
|
|
485
|
+
U(e.id) ? f.has(e.id) ? a(`${r}.id`, `Node "${e.id}" already exists in the map. Use nodes.change to change it.`, "exists") : v.has(e.id) && a(`${r}.id`, `Node "${e.id}" is added twice.`) : a(`${r}.id`, "An added node needs an \"id\"."), U(e.id) && v.add(e.id), U(e.label) || a(`${r}.label`, "An added node needs a \"label\"."), U(e.type) ? T[e.type] ? e.type === "page" && U(e.label) && (e.label.startsWith("/") || a(`${r}.label`, `A page label "${e.label}" must start with a slash route (like "/meals"), as topology validate demands.`), e.label.includes(".html") && a(`${r}.label`, `A page label "${e.label}" must not contain ".html".`)) : a(`${r}.type`, `Unknown node type "${e.type}". Valid types: ${Object.keys(T).join(", ")}.`) : a(`${r}.type`, "An added node needs a \"type\".");
|
|
486
|
+
for (let t of Ke) t in e && a(`${r}.${t}`, `"${t}" is set when the proposal is applied; leave it out.`);
|
|
487
|
+
if (e.type === "device" && !k.includes(e.kind) && a(`${r}.kind`, `A device needs "kind", one of: ${k.join(", ")}.`), e.type === "external" && e.kind !== void 0 && !D.includes(e.kind) && a(`${r}.kind`, `An external's "kind" is one of: ${D.join(", ")} (or none, until the registry draws it).`), U(e.id) && T[e.type] && i(e)) {
|
|
488
|
+
let t = u(e.id), i = e.type === "device" ? `live-device-${k.includes(e.kind) ? e.kind : "<kind>"}-<id>` : `live-${e.type}-<id>`;
|
|
489
|
+
!t || t.type !== e.type ? a(`${r}.id`, [
|
|
490
490
|
"floor",
|
|
491
491
|
"room",
|
|
492
492
|
"device"
|
|
493
|
-
].includes(e.type) ? `"${e.id}" is a ${e.type} only the live layer draws${e.type === "device" ? " (no code file derives it)" : ""}: its id must be ${i}.` : `"${e.id}" starts with "${
|
|
493
|
+
].includes(e.type) ? `"${e.id}" is a ${e.type} only the live layer draws${e.type === "device" ? " (no code file derives it)" : ""}: its id must be ${i}.` : `"${e.id}" starts with "${n}", which only the live layer's floors, rooms and devices use (${We}).`) : t.kind && k.includes(e.kind) && t.kind !== e.kind && a(`${r}.kind`, `"${e.id}" names the kind "${t.kind}" but the node says "${e.kind}".`);
|
|
494
494
|
}
|
|
495
|
-
e.parent !== void 0 && (U(e.parent) ? e.parent === e.id ? a(`${
|
|
495
|
+
e.parent !== void 0 && (U(e.parent) ? e.parent === e.id ? a(`${r}.parent`, "A node cannot be its own parent.") : _(e.parent) ? g.has(e.parent) ? a(`${r}.parent`, `Parent "${e.parent}" is a node this proposal removes.`) : U(e.id) && y.set(K($e(e)), `nodes.add[${t}].parent`) : a(`${r}.parent`, `Parent "${e.parent}" is in neither the map nor the added nodes.`, "dangling") : a(`${r}.parent`, "\"parent\" must be the id of a node."));
|
|
496
496
|
});
|
|
497
|
-
let
|
|
498
|
-
|
|
497
|
+
let x = /* @__PURE__ */ new Set();
|
|
498
|
+
c.change.forEach((e, t) => {
|
|
499
499
|
let n = `nodes.change[${t}]`;
|
|
500
500
|
if (!H(e)) return a(n, "A changed node is an object with an id, a set and a why.");
|
|
501
|
-
if (U(e.id) ?
|
|
501
|
+
if (U(e.id) ? h.has(e.id) ? a(`${n}.id`, `Node "${e.id}" is added by this proposal: change its entry in nodes.add instead.`) : f.has(e.id) ? x.has(e.id) && a(`${n}.id`, `Node "${e.id}" is changed twice: merge the two sets.`) : a(`${n}.id`, `Node "${e.id}" does not exist in the map, so it cannot be changed.`, "missing-target") : a(`${n}.id`, "A changed node needs an \"id\"."), U(e.id) && x.add(e.id), !H(e.set) || Object.keys(e.set).length === 0) a(`${n}.set`, "\"set\" must be an object of the fields to change.");
|
|
502
502
|
else {
|
|
503
503
|
"id" in e.set && a(`${n}.set.id`, "A change cannot set \"id\": it names the node."), "parent" in e.set && a(`${n}.set.parent`, "\"parent\" is not a node field: remove the ownership edge and add a new one.");
|
|
504
504
|
for (let t of qe) t in e.set && a(`${n}.set.${t}`, `"${t}" is set when the proposal is applied; leave it out of "set".`);
|
|
505
|
-
"type" in e.set && !
|
|
505
|
+
"type" in e.set && !T[e.set.type] && a(`${n}.set.type`, `Unknown node type "${e.set.type}". Valid types: ${Object.keys(T).join(", ")}.`);
|
|
506
506
|
}
|
|
507
507
|
U(e.why) || a(`${n}.why`, "A change needs a \"why\": the reason the maintainer reads.");
|
|
508
508
|
});
|
|
509
|
-
let
|
|
510
|
-
|
|
509
|
+
let S = /* @__PURE__ */ new Set();
|
|
510
|
+
c.remove.forEach((e, t) => {
|
|
511
511
|
let n = `nodes.remove[${t}]`;
|
|
512
512
|
if (!H(e)) return a(n, "A removed node is an object with an id and a why.");
|
|
513
|
-
U(e.id) ?
|
|
513
|
+
U(e.id) ? h.has(e.id) ? a(`${n}.id`, `Node "${e.id}" is added by this proposal: drop its entry from nodes.add instead of removing it.`) : f.has(e.id) ? S.has(e.id) ? a(`${n}.id`, `Node "${e.id}" is removed twice.`) : x.has(e.id) && a(`${n}.id`, `Node "${e.id}" is both changed and removed.`) : a(`${n}.id`, `Node "${e.id}" does not exist in the map, so it cannot be removed.`, "missing-target") : a(`${n}.id`, "A removed node needs an \"id\"."), U(e.id) && S.add(e.id), U(e.why) || a(`${n}.why`, "A removal needs a \"why\".");
|
|
514
514
|
});
|
|
515
|
-
let
|
|
516
|
-
...
|
|
517
|
-
...
|
|
518
|
-
} : void 0),
|
|
515
|
+
let C = new Map(c.change.filter((e) => H(e) && U(e.id) && H(e.set)).map((e) => [e.id, e.set])), ee = new Map(c.add.filter((e) => H(e) && U(e.id)).map((e) => [e.id, e])), w = (e) => ee.get(e) || (f.has(e) ? {
|
|
516
|
+
...f.get(e),
|
|
517
|
+
...C.get(e) || {}
|
|
518
|
+
} : void 0), E = (e, t) => {
|
|
519
519
|
U(e.from) || a(`${t}.from`, "An edge needs a \"from\" node id."), U(e.to) || a(`${t}.to`, "An edge needs a \"to\" node id.");
|
|
520
520
|
let n = U(e.from) && U(e.to);
|
|
521
|
-
return e.kind !== void 0 && !
|
|
522
|
-
},
|
|
523
|
-
|
|
521
|
+
return e.kind !== void 0 && !m.includes(e.kind) && (a(`${t}.kind`, `Unknown edge kind "${e.kind}". Valid kinds: ${m.join(", ")} (or none, for ownership).`), n = !1), e.kind === "flow" ? d.includes(e.flow) || (a(`${t}.flow`, `A flow edge needs "flow", one of: ${d.join(", ")}.`), n = !1) : e.flow !== void 0 && a(`${t}.flow`, "\"flow\" only goes on an edge of kind \"flow\"."), n ? K(e) : null;
|
|
522
|
+
}, O = (e) => `${e.from} -> ${e.to}${e.kind ? ` (${e.kind === "flow" ? `flow ${e.flow}` : e.kind})` : " (ownership)"}`, A = new Map([...y]);
|
|
523
|
+
l.add.forEach((e, t) => {
|
|
524
524
|
let n = `edges.add[${t}]`;
|
|
525
525
|
if (!H(e)) return a(n, "An added edge is an object with from, to and optionally a kind.");
|
|
526
|
-
let r =
|
|
526
|
+
let r = E(e, n);
|
|
527
527
|
for (let t of Ke) t in e && a(`${n}.${t}`, `"${t}" is set when the proposal is applied; leave it out.`);
|
|
528
|
-
for (let t of ["from", "to"]) U(e[t]) && (_(e[t]) ?
|
|
529
|
-
let i = w(e.from),
|
|
530
|
-
if (i &&
|
|
531
|
-
for (let t of ["when", "side"]) if (e[t] !== void 0) for (let r of
|
|
528
|
+
for (let t of ["from", "to"]) U(e[t]) && (_(e[t]) ? g.has(e[t]) && a(`${n}.${t}`, `Node "${e[t]}" is a node this proposal removes, so an edge cannot be added to it.`) : a(`${n}.${t}`, `Node "${e[t]}" is in neither the map nor the added nodes.`, "dangling"));
|
|
529
|
+
let i = w(e.from), s = w(e.to);
|
|
530
|
+
if (i && s) {
|
|
531
|
+
for (let t of ["when", "side"]) if (e[t] !== void 0) for (let r of o({
|
|
532
532
|
kind: e.kind,
|
|
533
533
|
[t]: e[t]
|
|
534
|
-
}, i,
|
|
534
|
+
}, i, s)) a(`${n}.${t}`, `The edge ${r}`);
|
|
535
535
|
}
|
|
536
|
-
r && (
|
|
536
|
+
r && (p.has(r) ? a(n, `Edge ${O(e)} already exists in the map.`, "exists") : A.has(r) && a(n, `Edge ${O(e)} is already added by ${A.get(r)}.`), A.set(r, A.get(r) || n));
|
|
537
537
|
});
|
|
538
|
-
let
|
|
539
|
-
let r =
|
|
540
|
-
return r ? (
|
|
538
|
+
let j = /* @__PURE__ */ new Map(), te = (e, t, n) => {
|
|
539
|
+
let r = E(e, t);
|
|
540
|
+
return r ? (p.has(r) ? j.has(r) ? a(t, `Edge ${O(e)} is already ${j.get(r)} by this proposal.`) : j.set(r, n === "change" ? "changed" : "removed") : a(t, `Edge ${O(e)} does not exist in the map, so it cannot be ${n === "change" ? "changed" : "removed"}.`, "missing-target"), r) : null;
|
|
541
541
|
};
|
|
542
|
-
|
|
542
|
+
l.change.forEach((e, t) => {
|
|
543
543
|
let n = `edges.change[${t}]`;
|
|
544
544
|
if (!H(e)) return a(n, "A changed edge is an object with from, to, set and why.");
|
|
545
|
-
if (
|
|
545
|
+
if (te(e, n, "change"), !H(e.set) || Object.keys(e.set).length === 0) a(`${n}.set`, "\"set\" must be an object of the fields to change.");
|
|
546
546
|
else {
|
|
547
547
|
for (let t of Je) t in e.set && a(`${n}.set.${t}`, `A change cannot set "${t}": it names the edge. Remove the edge and add a new one.`);
|
|
548
548
|
for (let t of qe) t in e.set && a(`${n}.set.${t}`, `"${t}" is set when the proposal is applied; leave it out of "set".`);
|
|
549
549
|
}
|
|
550
550
|
U(e.why) || a(`${n}.why`, "A change needs a \"why\".");
|
|
551
|
-
}),
|
|
551
|
+
}), l.remove.forEach((e, t) => {
|
|
552
552
|
let n = `edges.remove[${t}]`;
|
|
553
553
|
if (!H(e)) return a(n, "A removed edge is an object with from, to and why.");
|
|
554
|
-
|
|
554
|
+
te(e, n, "remove"), U(e.why) || a(`${n}.why`, "A removal needs a \"why\".");
|
|
555
555
|
});
|
|
556
|
-
function
|
|
557
|
-
if (!U(e) || !
|
|
558
|
-
let
|
|
559
|
-
_(
|
|
556
|
+
function ne(e, t) {
|
|
557
|
+
if (!U(e) || !Ue.test(e)) return a(t, `"actor" must be a persona id: lower-case words joined by dashes, like "child" (got ${JSON.stringify(e)}).`);
|
|
558
|
+
let n = b(e);
|
|
559
|
+
_(n) || a(t, `Actor "${e}" is no persona: "${n}" is in neither the map nor the added nodes.`, "dangling");
|
|
560
560
|
}
|
|
561
|
-
function
|
|
562
|
-
if (!U(e)) return a(t, `"at" must be a node id or a live id (${
|
|
563
|
-
_(e) ||
|
|
561
|
+
function re(e, t) {
|
|
562
|
+
if (!U(e)) return a(t, `"at" must be a node id or a live id (${We}).`);
|
|
563
|
+
_(e) || u(e) || (e.startsWith("live-") ? a(t, `"${e}" is not a live id: write ${We}.`) : a(t, `Step happens nowhere: "${e}" is in neither the map nor the added nodes, and is not a live id.`, "dangling"));
|
|
564
564
|
}
|
|
565
|
-
let
|
|
566
|
-
function
|
|
567
|
-
if (!H(e)) return a(t, `${
|
|
565
|
+
let M = "A check is { route, method } or { table, op, row? }";
|
|
566
|
+
function ie(e, t) {
|
|
567
|
+
if (!H(e)) return a(t, `${M}.`);
|
|
568
568
|
let n = "route" in e || "method" in e, r = "table" in e || "op" in e || "row" in e;
|
|
569
|
-
if (n && r) return a(t, `${
|
|
570
|
-
if (!n && !r) return a(t, `${
|
|
569
|
+
if (n && r) return a(t, `${M}: either one, not both.`);
|
|
570
|
+
if (!n && !r) return a(t, `${M}.`);
|
|
571
571
|
let i = n ? ["route", "method"] : [
|
|
572
572
|
"table",
|
|
573
573
|
"op",
|
|
574
574
|
"row"
|
|
575
575
|
];
|
|
576
576
|
for (let r of Object.keys(e)) i.includes(r) || a(`${t}.${r}`, `Unknown key "${r}" in a ${n ? "route" : "table"} check. It has: ${i.join(", ")}.`);
|
|
577
|
-
n ? (U(e.route) && e.route.startsWith("/") || a(`${t}.route`, "\"route\" must be a path starting with a slash, as the map labels it (\"/api/v1/rooms/[id]\") or a concrete one."),
|
|
577
|
+
n ? (U(e.route) && e.route.startsWith("/") || a(`${t}.route`, "\"route\" must be a path starting with a slash, as the map labels it (\"/api/v1/rooms/[id]\") or a concrete one."), ze.includes(e.method) || a(`${t}.method`, `"method" must be one of: ${ze.join(", ")}.`)) : (U(e.table) || a(`${t}.table`, "\"table\" must be the SQL table name."), Be.includes(e.op) || a(`${t}.op`, `"op" must be one of: ${Be.join(", ")}.`), e.row !== void 0 && !Ve.includes(e.row) && a(`${t}.row`, `"row" must be one of: ${Ve.join(", ")}.`));
|
|
578
578
|
}
|
|
579
|
-
function
|
|
580
|
-
Array.isArray(e) ? e.forEach((e, n) =>
|
|
579
|
+
function ae(e, t) {
|
|
580
|
+
Array.isArray(e) ? e.forEach((e, n) => ie(e, `${t}[${n}]`)) : ie(e, t);
|
|
581
581
|
}
|
|
582
|
-
function
|
|
582
|
+
function N(e, t) {
|
|
583
583
|
if (!Array.isArray(e)) return a(t, "\"down\" must be a list of the cloud node ids the scenario takes down.");
|
|
584
584
|
if (e.length === 0) return a(t, "\"down\" needs at least one cloud node id; leave it out for a scenario that is no outage.");
|
|
585
585
|
let n = /* @__PURE__ */ new Set();
|
|
@@ -589,53 +589,53 @@ function et(e, t) {
|
|
|
589
589
|
if (n.has(e)) return a(i, `"${e}" is down twice.`);
|
|
590
590
|
n.add(e);
|
|
591
591
|
let o = w(e);
|
|
592
|
-
if (!o) return a(i, `Down node "${e}" is in neither the map nor the added nodes.`,
|
|
592
|
+
if (!o) return a(i, `Down node "${e}" is in neither the map nor the added nodes.`, g.has(e) ? "missing-target" : "dangling");
|
|
593
593
|
if (o.type !== "external" || o.kind !== "cloud") {
|
|
594
594
|
let t = o.type === "external" ? o.kind === void 0 ? "an external with no kind" : `an external of kind ${o.kind}` : `a ${o.type}`;
|
|
595
595
|
a(i, `"${e}" is ${t}: only an external of kind cloud can be down (a container, a stack or a machine is the House view's; the public web is never down as a whole).`);
|
|
596
596
|
}
|
|
597
597
|
});
|
|
598
598
|
}
|
|
599
|
-
let
|
|
599
|
+
let P = new Set(l.remove.filter((e) => H(e) && U(e.from) && U(e.to)).map(K)), oe = (e, t) => P.has(e) || g.has(t.from) || g.has(t.to);
|
|
600
600
|
t.scenarios !== void 0 && !Array.isArray(t.scenarios) && a("scenarios", "\"scenarios\" must be a list.");
|
|
601
|
-
let
|
|
601
|
+
let se = /* @__PURE__ */ new Set();
|
|
602
602
|
if (G(t.scenarios).forEach((e, t) => {
|
|
603
603
|
let n = `scenarios[${t}]`;
|
|
604
604
|
if (!H(e)) return a(n, "A scenario is an object with an id, a title and steps.");
|
|
605
|
-
U(e.id) ?
|
|
606
|
-
for (let t of Object.keys(e))
|
|
607
|
-
if (e.stepMs !== void 0 && !Ye(e.stepMs) && a(`${n}.stepMs`, "\"stepMs\" must be a positive number of milliseconds."), e.linkNodes !== void 0 && typeof e.linkNodes != "boolean" && a(`${n}.linkNodes`, "\"linkNodes\" must be true or false."), e.actor !== void 0 &&
|
|
605
|
+
U(e.id) ? se.has(e.id) && a(`${n}.id`, `Scenario id "${e.id}" is used twice.`) : a(`${n}.id`, "A scenario needs an \"id\"."), U(e.id) && se.add(e.id), U(e.title) || a(`${n}.title`, "A scenario needs a \"title\".");
|
|
606
|
+
for (let t of Object.keys(e)) Le.includes(t) || a(`${n}.${t}`, `Unknown key "${t}" in a scenario. A scenario has: ${Le.join(", ")}.`);
|
|
607
|
+
if (e.stepMs !== void 0 && !Ye(e.stepMs) && a(`${n}.stepMs`, "\"stepMs\" must be a positive number of milliseconds."), e.linkNodes !== void 0 && typeof e.linkNodes != "boolean" && a(`${n}.linkNodes`, "\"linkNodes\" must be true or false."), e.actor !== void 0 && ne(e.actor, `${n}.actor`), e.down !== void 0 && N(e.down, `${n}.down`), !Array.isArray(e.steps)) return a(`${n}.steps`, "\"steps\" must be a list.");
|
|
608
608
|
if (e.steps.length === 0) return a(`${n}.steps`, "A scenario needs at least one step.");
|
|
609
609
|
e.steps.forEach((t, r) => {
|
|
610
610
|
let i = `${n}.steps[${r}]`;
|
|
611
611
|
if (!H(t)) return a(i, "A step is an object with a \"node\" or an \"edge\", and some \"text\".");
|
|
612
|
-
for (let e of Object.keys(t))
|
|
613
|
-
if (U(t.text) || a(`${i}.text`, "A step needs \"text\": what happens at this point."), t.ms !== void 0 && !Ye(t.ms) && a(`${i}.ms`, "\"ms\" must be a positive number of milliseconds."), t.actor !== void 0 &&
|
|
612
|
+
for (let e of Object.keys(t)) Re.includes(e) || a(`${i}.${e}`, `Unknown key "${e}" in a step. A step has "node" or "edge", and "text"; optionally ${Re.slice(3).join(", ")}.`);
|
|
613
|
+
if (U(t.text) || a(`${i}.text`, "A step needs \"text\": what happens at this point."), t.ms !== void 0 && !Ye(t.ms) && a(`${i}.ms`, "\"ms\" must be a positive number of milliseconds."), t.actor !== void 0 && ne(t.actor, `${i}.actor`), t.at !== void 0 && re(t.at, `${i}.at`), t.check !== void 0 && ae(t.check, `${i}.check`), t.expect !== void 0 && (He.includes(t.expect) ? t.actor === void 0 && e.actor === void 0 && a(`${i}.expect`, "\"expect\" needs an actor, on the step or its scenario: a step with no actor is never checked.") : a(`${i}.expect`, `"expect" must be one of: ${He.join(", ")}.`)), t.node === void 0 == (t.edge === void 0) && a(i, "A step points at exactly one of \"node\" or \"edge\"."), t.node !== void 0 && (U(t.node) ? _(t.node) || a(`${i}.node`, `Step points at nothing: node "${t.node}" is in neither the map nor the added nodes.`, g.has(t.node) ? "missing-target" : "dangling") : a(`${i}.node`, "\"node\" must be a node id.")), t.edge !== void 0) {
|
|
614
614
|
if (!H(t.edge)) return a(`${i}.edge`, "\"edge\" must be an object with from and to.");
|
|
615
|
-
let e =
|
|
616
|
-
e && !
|
|
615
|
+
let e = E(t.edge, `${i}.edge`);
|
|
616
|
+
e && !p.has(e) && !A.has(e) && a(`${i}.edge`, `Step points at nothing: edge ${O(t.edge)} is in neither the map nor the added edges.`, oe(e, t.edge) ? "missing-target" : "dangling");
|
|
617
617
|
}
|
|
618
618
|
});
|
|
619
619
|
}), t.mockups !== void 0 && !Array.isArray(t.mockups)) a("mockups", "\"mockups\" must be a list.");
|
|
620
620
|
else if (Array.isArray(t.mockups)) {
|
|
621
621
|
t.mockups.length > 40 && a("mockups", "At most 40 mockups in one proposal.");
|
|
622
622
|
let e = /* @__PURE__ */ new Set([
|
|
623
|
-
...
|
|
624
|
-
...
|
|
625
|
-
...
|
|
623
|
+
...h.keys(),
|
|
624
|
+
...g,
|
|
625
|
+
...c.change.filter((e) => H(e) && U(e.id)).map((e) => e.id)
|
|
626
626
|
]), n = /* @__PURE__ */ new Set();
|
|
627
627
|
t.mockups.forEach((t, r) => {
|
|
628
628
|
let i = `mockups[${r}]`;
|
|
629
629
|
if (!H(t)) return a(i, "A mockup is an object with a node, a path and a title.");
|
|
630
|
-
for (let e of Object.keys(t))
|
|
630
|
+
for (let e of Object.keys(t)) Fe.includes(e) || a(`${i}.${e}`, `Unknown key "${e}" in a mockup. A mockup has: ${Fe.join(", ")}.`);
|
|
631
631
|
U(t.title) || a(`${i}.title`, "A mockup needs a \"title\": what the screen is. It is also its alt text.");
|
|
632
632
|
let o = Ze(t.path);
|
|
633
633
|
o ? a(`${i}.path`, o) : n.has(`${t.node}|${t.path}`) ? a(i, `Mockup "${t.path}" is listed twice for node "${t.node}".`) : n.add(`${t.node}|${t.path}`), U(t.node) ? e.has(t.node) || a(`${i}.node`, `Mockup is beside node "${t.node}", which this proposal does not add, change or remove. Name a node the proposal touches.`) : a(`${i}.node`, "A mockup needs the \"node\" it belongs to.");
|
|
634
634
|
});
|
|
635
635
|
}
|
|
636
|
-
return
|
|
636
|
+
return r;
|
|
637
637
|
}
|
|
638
|
-
var tt =
|
|
638
|
+
var tt = T.external;
|
|
639
639
|
function nt(e, t) {
|
|
640
640
|
let n = e.nodes.map((e) => ({
|
|
641
641
|
...e,
|
|
@@ -652,7 +652,7 @@ function nt(e, t) {
|
|
|
652
652
|
add: G(t[e]?.add),
|
|
653
653
|
change: G(t[e]?.change),
|
|
654
654
|
remove: G(t[e]?.remove)
|
|
655
|
-
}), s = o("nodes"), c = o("edges"),
|
|
655
|
+
}), s = o("nodes"), c = o("edges"), l = (e, t, n) => {
|
|
656
656
|
let r = {}, i = (t, n) => {
|
|
657
657
|
Xe(e[t], n) || (r[t] = e[t] === void 0 ? null : e[t], e[t] = W(n));
|
|
658
658
|
};
|
|
@@ -662,10 +662,10 @@ function nt(e, t) {
|
|
|
662
662
|
for (let e of s.change) {
|
|
663
663
|
let t = i.get(e.id);
|
|
664
664
|
if (!t) continue;
|
|
665
|
-
let n = { ...e.set }, r =
|
|
666
|
-
r && ("color" in n || (n.color = r.color), "r" in n || (n.r = r.r)),
|
|
665
|
+
let n = { ...e.set }, r = T[n.type];
|
|
666
|
+
r && ("color" in n || (n.color = r.color), "r" in n || (n.r = r.r)), l(t, n, e.why);
|
|
667
667
|
}
|
|
668
|
-
for (let e of c.change) for (let t of a.get(K(e)) || [])
|
|
668
|
+
for (let e of c.change) for (let t of a.get(K(e)) || []) l(t, e.set, e.why);
|
|
669
669
|
for (let e of c.remove) for (let t of a.get(K(e)) || []) delete t.before, t.mark = "removed", t.why = e.why;
|
|
670
670
|
for (let e of s.remove) {
|
|
671
671
|
let t = i.get(e.id);
|
|
@@ -674,7 +674,7 @@ function nt(e, t) {
|
|
|
674
674
|
for (let t of r) (t.from === e.id || t.to === e.id) && t.mark !== "removed" && (delete t.before, t.mark = "removed", t.why = e.why);
|
|
675
675
|
}
|
|
676
676
|
}
|
|
677
|
-
let
|
|
677
|
+
let u = [], d = (e) => {
|
|
678
678
|
let t = a.get(K(e));
|
|
679
679
|
t ? t.forEach((e) => {
|
|
680
680
|
e.mark === "none" && (e.mark = "added");
|
|
@@ -684,78 +684,78 @@ function nt(e, t) {
|
|
|
684
684
|
});
|
|
685
685
|
};
|
|
686
686
|
for (let e of s.add) {
|
|
687
|
-
let { parent: t, ...r } = W(e), a =
|
|
687
|
+
let { parent: t, ...r } = W(e), a = T[e.type] || tt, o = i.get(e.id);
|
|
688
688
|
o ? o.mark === "none" && (o.mark = "added") : n.push({
|
|
689
689
|
...r,
|
|
690
690
|
color: a.color,
|
|
691
691
|
r: e.r ?? a.r,
|
|
692
692
|
mark: "added"
|
|
693
|
-
}), t &&
|
|
693
|
+
}), t && u.push({
|
|
694
694
|
from: t,
|
|
695
695
|
to: e.id
|
|
696
696
|
});
|
|
697
697
|
}
|
|
698
|
-
for (let e of
|
|
699
|
-
for (let e of c.add)
|
|
698
|
+
for (let e of u) d(e);
|
|
699
|
+
for (let e of c.add) d(e);
|
|
700
700
|
return {
|
|
701
701
|
nodes: n,
|
|
702
702
|
edges: r
|
|
703
703
|
};
|
|
704
704
|
}
|
|
705
705
|
function rt(e, t) {
|
|
706
|
-
let n = new Map(e.nodes.map((e) => [e.id, e])), r = /* @__PURE__ */ new Map(),
|
|
706
|
+
let n = new Map(e.nodes.map((e) => [e.id, e])), r = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
|
|
707
707
|
for (let t of e.edges) {
|
|
708
708
|
let e = K(t);
|
|
709
709
|
r.has(e) || r.set(e, t);
|
|
710
710
|
let n = `${t.from}|${t.to}`;
|
|
711
|
-
|
|
711
|
+
a.has(n) || a.set(n, /* @__PURE__ */ new Set()), a.get(n).add(e), !t.kind && !t.dashed && (o.has(t.to) || o.set(t.to, /* @__PURE__ */ new Set()), o.get(t.to).add(t.from));
|
|
712
712
|
}
|
|
713
|
-
let
|
|
713
|
+
let s = (e, t) => Object.entries(t || {}).every(([t, n]) => Xe(e[t], n)), c = (e, n) => G(t?.[e]?.[n]), l = new Set(c("nodes", "add").filter((e) => H(e) && i(e)).map((e) => e.id)), u = (e) => l.has(e) || typeof e == "string" && e.startsWith("live-"), d = [], f = (e, t, n, r) => d.push({
|
|
714
714
|
kind: e,
|
|
715
715
|
op: t,
|
|
716
716
|
key: n,
|
|
717
717
|
status: r
|
|
718
718
|
});
|
|
719
|
-
for (let e of
|
|
720
|
-
if (
|
|
719
|
+
for (let e of c("nodes", "add")) {
|
|
720
|
+
if (l.has(e.id)) {
|
|
721
721
|
f("node", "add", e.id, "live");
|
|
722
722
|
continue;
|
|
723
723
|
}
|
|
724
724
|
let t = n.get(e.id);
|
|
725
|
-
f("node", "add", e.id, t ? t.type !== e.type || e.parent && !
|
|
725
|
+
f("node", "add", e.id, t ? t.type !== e.type || e.parent && !o.get(e.id)?.has(e.parent) ? "diverged" : "landed" : "pending");
|
|
726
726
|
}
|
|
727
|
-
for (let e of
|
|
727
|
+
for (let e of c("nodes", "change")) {
|
|
728
728
|
let t = n.get(e.id);
|
|
729
|
-
f("node", "change", e.id, t ?
|
|
729
|
+
f("node", "change", e.id, t ? s(t, e.set) ? "landed" : "pending" : "diverged");
|
|
730
730
|
}
|
|
731
|
-
for (let e of
|
|
732
|
-
for (let e of
|
|
731
|
+
for (let e of c("nodes", "remove")) f("node", "remove", e.id, n.has(e.id) ? "pending" : "landed");
|
|
732
|
+
for (let e of c("edges", "add")) {
|
|
733
733
|
let t = K(e);
|
|
734
|
-
if (
|
|
734
|
+
if (u(e.from) || u(e.to)) {
|
|
735
735
|
f("edge", "add", t, "live");
|
|
736
736
|
continue;
|
|
737
737
|
}
|
|
738
|
-
let n = [...
|
|
738
|
+
let n = [...a.get(`${e.from}|${e.to}`) || []].some((e) => e !== t);
|
|
739
739
|
f("edge", "add", t, r.has(t) ? "landed" : n ? "diverged" : "pending");
|
|
740
740
|
}
|
|
741
|
-
for (let e of
|
|
741
|
+
for (let e of c("edges", "change")) {
|
|
742
742
|
let t = K(e), n = r.get(t);
|
|
743
|
-
f("edge", "change", t, n ?
|
|
743
|
+
f("edge", "change", t, n ? s(n, e.set) ? "landed" : "pending" : "diverged");
|
|
744
744
|
}
|
|
745
|
-
for (let e of
|
|
745
|
+
for (let e of c("edges", "remove")) {
|
|
746
746
|
let t = K(e);
|
|
747
747
|
f("edge", "remove", t, r.has(t) ? "pending" : "landed");
|
|
748
748
|
}
|
|
749
749
|
let p = {
|
|
750
|
-
total:
|
|
750
|
+
total: d.length,
|
|
751
751
|
pending: 0,
|
|
752
752
|
landed: 0,
|
|
753
753
|
diverged: 0,
|
|
754
754
|
live: 0
|
|
755
755
|
};
|
|
756
|
-
for (let e of
|
|
756
|
+
for (let e of d) p[e.status]++;
|
|
757
757
|
return {
|
|
758
|
-
items:
|
|
758
|
+
items: d,
|
|
759
759
|
summary: p
|
|
760
760
|
};
|
|
761
761
|
}
|
|
@@ -805,8 +805,8 @@ function ut(e, t, n, r, i = {}) {
|
|
|
805
805
|
function dt(e) {
|
|
806
806
|
if (!e.length) return "";
|
|
807
807
|
let t = e.map((e) => `<li class="hx-mockup-item" data-corn="row">
|
|
808
|
-
<button data-corn-kind="secondary" type="button" class="hx-btn hx-mockup-open" data-mockup="${e.index}" aria-haspopup="dialog">${
|
|
809
|
-
<span class="hx-mockup-state hx-mockup-state--${
|
|
808
|
+
<button data-corn-kind="secondary" type="button" class="hx-btn hx-mockup-open" data-mockup="${e.index}" aria-haspopup="dialog">${c(e.title)}<span class="hx-sr-only"> (${e.type === "page" ? "page" : "image"}, opens in a window)</span></button>
|
|
809
|
+
<span class="hx-mockup-state hx-mockup-state--${c(e.state)}" data-corn="state-pill"${z(e.state)}>${c(st(e.state))}</span>
|
|
810
810
|
</li>`).join("");
|
|
811
811
|
return `<div class="hx-sec hx-mockups" data-mockups data-corn="section">
|
|
812
812
|
<h3 class="hx-sec-title" id="hx-mockups-h">${e.length === 1 ? "Mockup" : "Mockups"}</h3>
|
|
@@ -826,7 +826,7 @@ function mt(e, t, n, r = 0) {
|
|
|
826
826
|
}
|
|
827
827
|
function ht(e, t, { padding: n = 40, minZoom: r = pt } = {}) {
|
|
828
828
|
if (e.length < 2) return e;
|
|
829
|
-
let i =
|
|
829
|
+
let i = E(n, t), a = (t.width - i * 2) / r, o = (t.height - i * 2) / r, s = e.map(O), c = (t, n) => e.filter((e, r) => s[r].left >= t && s[r].right <= t + a && s[r].top >= n && s[r].bottom <= n + o), l = s.map((e) => e.left), u = s.map((e) => e.top), d = [], f = e.length <= 120 ? l.flatMap((e) => u.map((t) => [e, t])) : s.map((e) => [e.left, e.top]);
|
|
830
830
|
for (let [t, n] of f) {
|
|
831
831
|
if (d.length === e.length) break;
|
|
832
832
|
let r = c(t, n);
|
|
@@ -864,24 +864,24 @@ var vt = {
|
|
|
864
864
|
return t === 1 ? n[0] : n[1];
|
|
865
865
|
};
|
|
866
866
|
function bt(e, t, n) {
|
|
867
|
-
let r = new Map(t.map((e) => [e.id, e])),
|
|
867
|
+
let r = new Map(t.map((e) => [e.id, e])), i = new Map(Object.keys(l).map((e) => [e, /* @__PURE__ */ new Map()]));
|
|
868
868
|
for (let t of n) {
|
|
869
869
|
if (t.kind !== "calls" || t.to !== e.id) continue;
|
|
870
|
-
let n =
|
|
870
|
+
let n = i.get(A(t)), a = r.get(t.from) || {
|
|
871
871
|
id: t.from,
|
|
872
872
|
label: t.from,
|
|
873
873
|
type: "node"
|
|
874
874
|
}, o = n.get(t.from) || {
|
|
875
875
|
id: t.from,
|
|
876
|
-
label: String(
|
|
877
|
-
type:
|
|
876
|
+
label: String(a.label || t.from),
|
|
877
|
+
type: a.type,
|
|
878
878
|
vias: [],
|
|
879
879
|
browser: !1
|
|
880
880
|
};
|
|
881
881
|
t.label && !o.vias.includes(t.label) && o.vias.push(t.label), t.side === "browser" && (o.browser = !0), n.set(t.from, o);
|
|
882
882
|
}
|
|
883
|
-
let
|
|
884
|
-
for (let [e, t] of
|
|
883
|
+
let a = [];
|
|
884
|
+
for (let [e, t] of i) {
|
|
885
885
|
if (t.size === 0) continue;
|
|
886
886
|
let n = /* @__PURE__ */ new Map();
|
|
887
887
|
for (let { vias: e, ...r } of t.values()) n.has(r.type) || n.set(r.type, []), n.get(r.type).push({
|
|
@@ -892,33 +892,33 @@ function bt(e, t, n) {
|
|
|
892
892
|
type: e,
|
|
893
893
|
noun: yt(e, 1),
|
|
894
894
|
items: t.sort((e, t) => e.label.localeCompare(t.label))
|
|
895
|
-
})).sort((e, t) => t.items.length - e.items.length || e.type.localeCompare(t.type)), { title:
|
|
896
|
-
|
|
895
|
+
})).sort((e, t) => t.items.length - e.items.length || e.type.localeCompare(t.type)), { title: i, color: o } = l[e];
|
|
896
|
+
a.push({
|
|
897
897
|
when: e,
|
|
898
|
-
title:
|
|
899
|
-
color:
|
|
898
|
+
title: i,
|
|
899
|
+
color: o,
|
|
900
900
|
count: t.size,
|
|
901
901
|
types: r
|
|
902
902
|
});
|
|
903
903
|
}
|
|
904
|
-
return
|
|
904
|
+
return a;
|
|
905
905
|
}
|
|
906
906
|
var xt = {
|
|
907
907
|
run: "Breaks now",
|
|
908
908
|
deploy: "Breaks on deploy",
|
|
909
909
|
renew: "Breaks on renewal"
|
|
910
|
-
}, J = (e, t) => t.length ? `<div class="hx-fact" data-corn="section"><div class="hx-fact-k">${
|
|
910
|
+
}, J = (e, t) => t.length ? `<div class="hx-fact" data-corn="section"><div class="hx-fact-k">${c(e)}</div><div class="hx-fact-v">${P(t)}</div></div>` : "", Y = (e) => `<div class="hx-line">${e}</div>`, X = (e) => `<span class="hx-name">${c(e)}</span>`;
|
|
911
911
|
function St(e, t) {
|
|
912
912
|
let n = e.browser ? " <span class=\"hx-cloud-browser\">(browser)</span>" : "", r = [t ? yt(e.type, 1) : "", e.via].filter(Boolean);
|
|
913
|
-
return Y(`<span>${X(e.label)}${n}${r.length ? `<span class="hx-faint"> · ${
|
|
913
|
+
return Y(`<span>${X(e.label)}${n}${r.length ? `<span class="hx-faint"> · ${c(r.join(" · "))}</span>` : ""}</span>`);
|
|
914
914
|
}
|
|
915
|
-
var Ct = (e) => `<button data-corn-kind="quiet" type="button" class="hx-btn hx-btn--quiet hx-cloud-play" data-action="play-outage" data-id="${
|
|
915
|
+
var Ct = (e) => `<button data-corn-kind="quiet" type="button" class="hx-btn hx-btn--quiet hx-cloud-play" data-action="play-outage" data-id="${c(e.id)}">Play: ${c(String(e.label || e.id))} is down</button>`;
|
|
916
916
|
function wt(e, t, n) {
|
|
917
917
|
let r = new Map(t.map((e) => [e.id, e])), i = (e) => String((r.get(e) || { label: e }).label || e), a = e.kind === "web", o = a ? [] : e.roles || [], s = bt(e, t, n).map((e) => {
|
|
918
918
|
let t = e.types.length > 1;
|
|
919
919
|
return J(xt[e.when], e.types.flatMap((e) => e.items.map((e) => St(e, t))));
|
|
920
|
-
}).join("") || J("Used by", [Y("<span class=\"hx-faint\">Nothing on the map uses it.</span>")]),
|
|
921
|
-
return (a ? "" : J("Plan", [Y(
|
|
920
|
+
}).join("") || J("Used by", [Y("<span class=\"hx-faint\">Nothing on the map uses it.</span>")]), l = n.filter((t) => t.kind === "calls" && t.from === e.id && (r.get(t.to) || {}).type === "external").map((e) => Y(`<span>${X(i(e.to))}${e.label ? `<span class="hx-faint"> · ${c(e.label)}</span>` : ""}</span>`)), u = n.filter((t) => t.kind === "delivers" && t.from === e.id).map((e) => Y(X(i(e.to))));
|
|
921
|
+
return (a ? "" : J("Plan", [Y(c(_t(e.plan) || q.unknown))])) + J("Roles", o.length ? [Y(c(o.join(", ")))] : []) + J("If it's down", [Y(c(e.breaks || "Not described yet."))]) + s + J("Relies on", l) + J("Pushes to", u) + (a ? "" : Ct(e));
|
|
922
922
|
}
|
|
923
923
|
// ../explorer/file-url.js
|
|
924
924
|
var Tt = {
|
|
@@ -948,7 +948,7 @@ function At(e, t, n, r = !0) {
|
|
|
948
948
|
kt(e).set(t, {
|
|
949
949
|
text: n,
|
|
950
950
|
ok: r
|
|
951
|
-
}),
|
|
951
|
+
}), C(e, n);
|
|
952
952
|
}
|
|
953
953
|
function jt(e, t) {
|
|
954
954
|
kt(e).delete(t);
|
|
@@ -971,7 +971,7 @@ var Nt = [
|
|
|
971
971
|
"runs-on",
|
|
972
972
|
"uses",
|
|
973
973
|
"extends"
|
|
974
|
-
], Pt = (e) => Object.hasOwn(
|
|
974
|
+
], Pt = (e) => Object.hasOwn(p, e) ? p[e].panel : String(e);
|
|
975
975
|
function Ft(e) {
|
|
976
976
|
let t = (e) => {
|
|
977
977
|
let t = Nt.indexOf(e);
|
|
@@ -986,7 +986,7 @@ function Ft(e) {
|
|
|
986
986
|
function It(e, t) {
|
|
987
987
|
let n = [], r = /* @__PURE__ */ new Set();
|
|
988
988
|
for (let i of e.edges) {
|
|
989
|
-
if (
|
|
989
|
+
if (w(i) !== t) continue;
|
|
990
990
|
let a = i.from === e.selectedId, o = a ? i.to : i.from;
|
|
991
991
|
r.has(o) || (r.add(o), n.push({
|
|
992
992
|
id: o,
|
|
@@ -1005,7 +1005,7 @@ var Rt = /* @__PURE__ */ e({
|
|
|
1005
1005
|
diffPillWords: () => Gt,
|
|
1006
1006
|
markup: () => Kt,
|
|
1007
1007
|
mount: () => Xt
|
|
1008
|
-
}), Z = (e) => `<code class="hx-code">${
|
|
1008
|
+
}), Z = (e) => `<code class="hx-code">${c(e)}</code>`, Q = (e) => `<div class="hx-line">${e}</div>`, zt = {
|
|
1009
1009
|
"Uses design tokens": "Tokens",
|
|
1010
1010
|
"Loaded by the server per request": "Loaded by",
|
|
1011
1011
|
"Domains served (Caddyfile → service)": "Domains",
|
|
@@ -1021,7 +1021,7 @@ var Rt = /* @__PURE__ */ e({
|
|
|
1021
1021
|
}, Bt = /^(?:Defines )?\d+ (?:CSS )?(variable|service)\(s\)$/, Vt = (e) => {
|
|
1022
1022
|
let t = e.replace(/:$/, ""), n = Bt.exec(t);
|
|
1023
1023
|
return n ? n[1] === "service" ? "Services" : t.startsWith("Defines") ? "Defines" : "Variables" : zt[t] || t;
|
|
1024
|
-
}, $ = (e, t) => t.length ? `<div class="hx-fact" data-corn="section"><div class="hx-fact-k">${
|
|
1024
|
+
}, $ = (e, t) => t.length ? `<div class="hx-fact" data-corn="section"><div class="hx-fact-k">${c(Vt(e))}</div><div class="hx-fact-v">${P(t)}</div></div>` : "", Ht = (e) => `<div class="hx-chips">${P(e.map((e) => `<code class="hx-var">${c(e)}</code>`))}</div>`;
|
|
1025
1025
|
function Ut(e) {
|
|
1026
1026
|
if (e.type === "external" && e.kind) return e.kind === "web" ? "Public web" : "Cloud";
|
|
1027
1027
|
let t = e.type.charAt(0).toUpperCase() + e.type.slice(1);
|
|
@@ -1038,7 +1038,7 @@ function Gt(e, t) {
|
|
|
1038
1038
|
if (!n || n === "none") return "";
|
|
1039
1039
|
if (n === "edit") return `${e.editOp === "removed" ? "Removed" : "Added"} by your edit`;
|
|
1040
1040
|
let r = t && typeof t.title == "string" ? t.title : "";
|
|
1041
|
-
return r ? `${
|
|
1041
|
+
return r ? `${B[n] || n} by ${r}` : `${B[n] || n} by this proposal`;
|
|
1042
1042
|
}
|
|
1043
1043
|
var Kt = () => ({
|
|
1044
1044
|
drawer: "<aside id=\"spec-drawer\" class=\"hx-drawer glass\" aria-label=\"Node details\" inert data-corn=\"node-panel\"><div class=\"hx-drawer-body\"><div class=\"hx-drawer-head\"><div class=\"hx-drawer-id\"><p class=\"hx-kicker\"><span id=\"drawer-badge\" data-corn=\"badge\">Atom</span><span id=\"drawer-host\" data-corn=\"node-host\"></span><span id=\"drawer-diff\" class=\"hx-diffpill\" data-corn=\"diff-pill\" hidden></span></p><h2 id=\"drawer-title\" class=\"hx-drawer-title\" data-corn=\"node-title\"><pop-button></h2></div><button type=\"button\" class=\"hx-close\" data-action=\"close-drawer\" aria-label=\"Close\" data-corn-kind=\"icon\">✕</button></div><p id=\"drawer-description\" class=\"hx-lead\" hidden></p><div class=\"hx-block\"><div id=\"drawer-meta-list\" class=\"hx-meta\"></div></div></div><div class=\"hx-drawer-foot\" data-corn=\"node-foot\"><a data-corn=\"open-link\" id=\"drawer-file-btn\" data-corn-kind=\"primary\" class=\"hx-open\" href=\"#\" target=\"_blank\" rel=\"noreferrer\" hidden>Open file ↗</a><a data-corn=\"open-link\" id=\"drawer-open-btn\" data-corn-kind=\"primary\" class=\"hx-open\" href=\"#\" target=\"_blank\" rel=\"noreferrer\" hidden>Open route ↗</a><button data-corn-kind=\"secondary\" type=\"button\" id=\"drawer-run-btn\" class=\"hx-btn hx-foot-btn\" data-action=\"start-run\" data-corn-string=\"startRun\" hidden>Start a run</button><button data-corn-kind=\"quiet\" type=\"button\" class=\"hx-btn hx-btn--quiet hx-foot-btn\" data-action=\"copy-spec\" data-corn-string=\"copySpec\">Copy Spec</button><p id=\"copy-spec-result\" class=\"hx-forge-result\" data-corn=\"result\" hidden></p></div></aside>",
|
|
@@ -1059,16 +1059,16 @@ async function Jt(e, t) {
|
|
|
1059
1059
|
}, Ot);
|
|
1060
1060
|
}
|
|
1061
1061
|
function Yt(e) {
|
|
1062
|
-
let { state: t } = e, n = (e) => t.nodes.find((t) => t.id === e), r = (e) => (n(e) || { label: e }).label, i = (e) => `<span class="hx-name">${
|
|
1062
|
+
let { state: t } = e, n = (e) => t.nodes.find((t) => t.id === e), r = (e) => (n(e) || { label: e }).label, i = (e) => `<span class="hx-name">${c(r(e))}</span>`, a = (e, n, r) => t.edges.filter((t) => t.kind === e && t[n] === r);
|
|
1063
1063
|
function o(e) {
|
|
1064
|
-
let o = t.edges.filter((e) => e.kind === "reads"), s = t.edges.filter((e) => e.kind === "writes"),
|
|
1064
|
+
let o = t.edges.filter((e) => e.kind === "reads"), s = t.edges.filter((e) => e.kind === "writes"), l = t.edges.filter((t) => t.kind === "uses" && t.from === e.id), u = $("Extends:", t.edges.filter((t) => t.kind === "extends" && t.from === e.id).map((e) => Q(i(e.to)))) + $("Uses design tokens:", l.map((e) => Q(`${i(e.to)} · ${e.vars.length}${Ht(e.vars)}`))) + (e.type !== "token" && e.vars ? $(`Defines ${e.vars.length} CSS variable(s):`, [Ht(e.vars)]) : "");
|
|
1065
1065
|
if (e.type === "app") {
|
|
1066
|
-
let n = e.deployed ? Q(`${/^https?:\/\//.test(e.url) ? `<a data-corn="text-link" class="hx-link" href="${
|
|
1067
|
-
return $("Served:", [n]) + $("Runs on:", r) + $("Loaded by the server per request:", o.filter((t) => t.to === e.id).map((e) => Q(i(e.from)))) +
|
|
1066
|
+
let n = e.deployed ? Q(`${/^https?:\/\//.test(e.url) ? `<a data-corn="text-link" class="hx-link" href="${c(e.url)}" target="_blank" rel="noreferrer">${c(e.url)}</a>` : Z(e.url)} → ${(e.upstreams || []).map(Z).join(" ")}${e.stack ? ` <span class="hx-faint">[${c(e.stack)}]</span>` : ""}`) : Q("Not deployed by any stack in this repo"), r = t.edges.filter((t) => t.kind === "runs-on" && t.from === e.id).map((e) => Q(`${i(e.to)}${(e.mappings || []).map((e) => `<div class="hx-faint">${Z(e.host)} → ${Z(e.upstream)}${e.service ? ` = ${Z(e.service)}` : ""}</div>`).join("")}`));
|
|
1067
|
+
return $("Served:", [n]) + $("Runs on:", r) + $("Loaded by the server per request:", o.filter((t) => t.to === e.id).map((e) => Q(i(e.from)))) + u;
|
|
1068
1068
|
}
|
|
1069
1069
|
if (e.type === "token") {
|
|
1070
1070
|
let n = t.edges.filter((t) => t.kind === "uses" && t.to === e.id);
|
|
1071
|
-
return $(`${e.vars.length} variable(s):`, [Ht(e.vars)]) + $("Used by:", n.map((e) => Q(`${i(e.from)} · ${
|
|
1071
|
+
return $(`${e.vars.length} variable(s):`, [Ht(e.vars)]) + $("Used by:", n.map((e) => Q(`${i(e.from)} · ${c(e.vars.join(" "))}`)));
|
|
1072
1072
|
}
|
|
1073
1073
|
if ([
|
|
1074
1074
|
"atom",
|
|
@@ -1076,60 +1076,60 @@ function Yt(e) {
|
|
|
1076
1076
|
"core"
|
|
1077
1077
|
].includes(e.type)) {
|
|
1078
1078
|
let n = t.edges.filter((t) => t.dashed && t.to === e.id).map((e) => Q(i(e.from)));
|
|
1079
|
-
return (e.table ? $("Record of:", [Q(`${
|
|
1079
|
+
return (e.table ? $("Record of:", [Q(`${c(e.model)} · table ${Z(e.table)}`)]) : "") + $("Rendered by:", n) + u;
|
|
1080
1080
|
}
|
|
1081
|
-
if (e.type === "stack") return $("Domains served (Caddyfile → service):", t.edges.filter((t) => t.kind === "runs-on" && t.to === e.id).flatMap((e) => (e.mappings || []).map((e) => Q(`<span class="hx-name">${
|
|
1081
|
+
if (e.type === "stack") return $("Domains served (Caddyfile → service):", t.edges.filter((t) => t.kind === "runs-on" && t.to === e.id).flatMap((e) => (e.mappings || []).map((e) => Q(`<span class="hx-name">${c(e.host)}</span> → ${Z(e.upstream)}${e.service ? ` = ${Z(e.service)}` : ""}`)))) + $(`${(e.services || []).length} service(s):`, (e.services || []).map((e) => Q(`<span class="hx-name">${c(e.name)}</span>${e.image ? ` <span class="hx-faint">${c(e.image)}</span>` : ""}${e.ports.length ? `<div>${e.ports.map(Z).join(" ")}</div>` : ""}${e.volumes.length ? `<div class="hx-faint">${e.volumes.map(c).join("<br>")}</div>` : ""}`))) + $("Compose file:", [Q(Z(e.file))]);
|
|
1082
1082
|
if (e.type === "table") {
|
|
1083
|
-
let t = o.filter((t) => t.from === e.id), a = s.filter((t) => t.to === e.id),
|
|
1084
|
-
return (e.model ? $("Model:", [Q(
|
|
1083
|
+
let t = o.filter((t) => t.from === e.id), a = s.filter((t) => t.to === e.id), l = t.filter((e) => (n(e.to) || {}).render?.rom === "bake");
|
|
1084
|
+
return (e.model ? $("Model:", [Q(c(e.model))]) : "") + $("Read by:", t.map((e) => Q(`${i(e.to)} · ${e.keys.map(Z).join(" ")}`))) + $("Written by:", a.map((e) => Q(`${i(e.from)} · ${c(e.label)}`))) + (l.length ? $("Baked pages:", [Q(`a write here re-bakes <span class="hx-rom hx-bold">${l.length}</span> file(s): ${l.map((e) => c(r(e.to))).join(", ")}`)]) : "");
|
|
1085
1085
|
}
|
|
1086
1086
|
if (e.type === "service") {
|
|
1087
|
-
let t = (e, t) => `${i(e[t])}${e.label && e.label !== "imports" ? ` · ${
|
|
1088
|
-
return (e.summary && !String(e.desc || "").includes(e.summary) ? $("Summary:", [Q(`<span class="hx-faint">${
|
|
1087
|
+
let t = (e, t) => `${i(e[t])}${e.label && e.label !== "imports" ? ` · ${c(e.label)}` : ""}`;
|
|
1088
|
+
return (e.summary && !String(e.desc || "").includes(e.summary) ? $("Summary:", [Q(`<span class="hx-faint">${c(e.summary)}</span>`)]) : "") + $("Started by:", [...(e.triggers || []).map((e) => Q(c(e))), ...a("triggers", "to", e.id).map((e) => Q(t(e, "from")))]) + $("Jobs:", (e.jobs || []).map((e) => Q(`${Z(e.name)} · cron ${Z(e.cron)}`))) + $("Runs:", a("triggers", "from", e.id).map((e) => Q(t(e, "to")))) + $("Calls:", a("calls", "from", e.id).map((e) => Q(t(e, "to")))) + $("Called by:", a("calls", "to", e.id).map((e) => Q(t(e, "from")))) + $("Reads tables:", o.filter((t) => t.to === e.id).map((e) => Q(i(e.from)))) + $("Writes tables:", s.filter((t) => t.from === e.id).map((e) => Q(i(e.to)))) + $("Mechanisms:", (e.mechanisms || []).map((e) => Q(c(e))));
|
|
1089
1089
|
}
|
|
1090
1090
|
if (e.type === "container" && e.selfHosted) {
|
|
1091
|
-
let a = (e, t) => `${i(e[t])}${e.label && e.label !== "calls" ? ` · ${
|
|
1092
|
-
return $("Self-hosted:", [Q(
|
|
1091
|
+
let a = (e, t) => `${i(e[t])}${e.label && e.label !== "calls" ? ` · ${c(e.label)}` : ""}`, o = t.edges.filter((t) => t.to === e.id && (t.kind === "calls" || t.kind === "flow" && t.flow === "api")), s = (e) => o.filter((t) => n(t.from)?.type === e).map((e) => Q(a(e, "from"))), l = new Set(t.nodes.filter((t) => t.type === "container" && t.stack === e.stack).map((e) => e.id));
|
|
1092
|
+
return $("Self-hosted:", [Q(c(e.summary || ""))]) + $("Called by services:", s("service")) + $("Called by endpoints:", s("page")) + $("Called by apps:", s("app")) + $("Pushes to (webhook):", t.edges.filter((e) => e.kind === "delivers" && l.has(e.from) && n(e.to)?.type === "page").map((t) => Q(`${i(t.to)}${t.from === e.id ? "" : ` <span class="hx-faint">from ${c(r(t.from))}</span>`}`)));
|
|
1093
1093
|
}
|
|
1094
1094
|
if (e.type === "external" && e.kind) return wt(e, t.nodes, t.edges);
|
|
1095
1095
|
if (e.type === "external") {
|
|
1096
1096
|
let t = (t) => a("calls", "to", e.id).filter((e) => n(e.from)?.type === t);
|
|
1097
|
-
return $("System:", [Q(`${
|
|
1097
|
+
return $("System:", [Q(`${c(e.summary || "")}${e.host ? `<div class="hx-faint">Runs here as ${Z(e.host)}</div>` : "<div class=\"hx-faint\">Not run by this stack</div>"}`)]) + $("Client modules:", (e.modules || []).map((e) => Q(Z(e)))) + $("Called by services:", t("service").map((e) => Q(i(e.from)))) + $("Called by endpoints:", t("page").map((e) => Q(i(e.from)))) + $("Pushes to (webhook):", a("delivers", "from", e.id).map((e) => Q(i(e.to))));
|
|
1098
1098
|
}
|
|
1099
1099
|
if (e.type === "page") {
|
|
1100
1100
|
let n = e.render, r = t.edges.filter((t) => t.dashed && t.from === e.id).map((e) => Q(i(e.to)));
|
|
1101
|
-
return (e.methods ? $("Methods:", [Q(e.methods.map(Z).join(" "))]) : "") + (e.render_fn ? $("Rendered by:", [Q(`${Z(e.render_fn)} · ${
|
|
1101
|
+
return (e.methods ? $("Methods:", [Q(e.methods.map(Z).join(" "))]) : "") + (e.render_fn ? $("Rendered by:", [Q(`${Z(e.render_fn)} · ${c(e.file)}`)]) : "") + $("Calls outside:", a("calls", "from", e.id).map((e) => Q(i(e.to)))) + $("Pushed to by:", a("delivers", "to", e.id).map((e) => Q(`${i(e.from)} · ${c(e.label)}`))) + $("Starts:", a("triggers", "from", e.id).map((e) => Q(`${i(e.to)} · ${c(e.label)}`))) + $("Renders:", r) + $("Reads:", o.filter((t) => t.to === e.id).map((e) => Q(`${i(e.from)} · ${e.keys.map(Z).join(" ")}`))) + $("Writes:", s.filter((t) => t.from === e.id).map((e) => Q(`${i(e.to)} · ${c(e.label)}`))) + (n ? $("Render:", [Q(`today: ${Z(n.now)} · ROM: ${n.rom === "bake" ? "<span class=\"hx-rom hx-bold\">bake</span>" : "<span class=\"hx-faint\">skip (per request)</span>"}${n.note ? `<div class="hx-faint">${c(n.note)}</div>` : ""}`)]) : "");
|
|
1102
1102
|
}
|
|
1103
1103
|
return "";
|
|
1104
1104
|
}
|
|
1105
1105
|
function s(t) {
|
|
1106
1106
|
let n = e.ask("threads:index", t.id);
|
|
1107
1107
|
if (!n) return "";
|
|
1108
|
-
let r = n.threads, i = n.start ? `<button data-corn-kind="quiet" type="button" class="hx-btn hx-btn--quiet hx-textact" data-thread-start="${
|
|
1108
|
+
let r = n.threads, i = n.start ? `<button data-corn-kind="quiet" type="button" class="hx-btn hx-btn--quiet hx-textact" data-thread-start="${c(t.id)}" aria-label="Start a thread about this: opens the New idea form for ${c(n.forge)}, with this node mentioned">Start a thread about this</button>` : "";
|
|
1109
1109
|
return !r || !r.length ? i : `<div class="hx-sec-block" data-corn="section"><h3 class="hx-sec-title">Threads</h3><ul class="hx-rows">${r.map((e) => {
|
|
1110
1110
|
let t = Number(e.comments) || 0;
|
|
1111
|
-
return `<li><button type="button" class="hx-row hx-thread-open" data-thread-open="${
|
|
1111
|
+
return `<li><button type="button" class="hx-row hx-thread-open" data-thread-open="${c(e.number)}" data-corn="row" aria-label="Open thread #${c(e.number)}, ${c(e.title)}, ${t} ${t === 1 ? "comment" : "comments"}, in the issues and pull requests panel"><span class="hx-row-title">${c(e.title)}</span><span class="hx-row-meta">#${c(e.number)} · ${t}</span></button></li>`;
|
|
1112
1112
|
}).join("")}</ul>${i}</div>`;
|
|
1113
1113
|
}
|
|
1114
|
-
function
|
|
1115
|
-
let n =
|
|
1114
|
+
function l(e) {
|
|
1115
|
+
let n = y(e);
|
|
1116
1116
|
if (!Gt(e, t.proposal)) return "";
|
|
1117
|
-
let r = (e, t) => `<div class="hx-diff-k">${
|
|
1118
|
-
a && i.push(r("parent",
|
|
1119
|
-
let o = t.edges.filter((t) => t.from === e.id || t.to === e.id), s = o.filter((e) =>
|
|
1120
|
-
if ((s ||
|
|
1121
|
-
return `<div class="hx-sec-block" data-proposal-mark="${
|
|
1117
|
+
let r = (e, t) => `<div class="hx-diff-k">${c(e)}</div><div class="hx-diff-v">${t}</div>`, i = [r("id", c(e.id))], a = t.edges.find((t) => !t.kind && !t.dashed && t.to === e.id);
|
|
1118
|
+
a && i.push(r("parent", c(a.from)));
|
|
1119
|
+
let o = t.edges.filter((t) => t.from === e.id || t.to === e.id), s = o.filter((e) => y(e) === "added").length, l = o.filter((e) => y(e) === "removed").length;
|
|
1120
|
+
if ((s || l) && i.push(r("edges", c([s ? `+${s}` : "", l ? `−${l}` : ""].filter(Boolean).join(" ")))), n === "changed") for (let t of we(e)) i.push(r(t.field, `<span class="hx-change-before">${c(t.before) || "<em>nothing</em>"}</span> <span aria-hidden="true">→</span><span class="hx-sr-only"> became </span> <span class="hx-change-after">${c(t.after) || "<em>nothing</em>"}</span>`));
|
|
1121
|
+
return `<div class="hx-sec-block" data-proposal-mark="${c(e.mark)}" data-corn="section"><h3 class="hx-sec-title">In this proposal</h3>${e.why ? `<p class="hx-why">${c(e.why)}</p>` : ""}<div class="hx-diff hx-diff--${c(n)}" data-corn="diff-block"${R(e.mark)}>${i.join("")}</div></div>`;
|
|
1122
1122
|
}
|
|
1123
1123
|
return {
|
|
1124
1124
|
dataSummary: o,
|
|
1125
1125
|
threadsSection: s,
|
|
1126
|
-
diffSection:
|
|
1126
|
+
diffSection: l,
|
|
1127
1127
|
nameOf: r,
|
|
1128
1128
|
nodeById: n
|
|
1129
1129
|
};
|
|
1130
1130
|
}
|
|
1131
|
-
function Xt(e,
|
|
1132
|
-
let { state: i } =
|
|
1131
|
+
function Xt(e, t, n = {}) {
|
|
1132
|
+
let { state: i } = t, o = r(t), l = Yt(t), u = n.inline === !0, d = [...a(t, e, Kt().drawer, n.slots, "drawer"), ...u ? a(t, e, `<p class="hx-panel-empty" data-corn="empty">${c(v(t, "nodePanelEmpty"))}</p>`, null, "empty") : a(t, e, Kt().backdrop, n.slots, "backdrop")], p = (e) => {
|
|
1133
1133
|
for (let t of d) {
|
|
1134
1134
|
if (t.id === e) return t;
|
|
1135
1135
|
let n = t.querySelector(`[id="${e}"]`);
|
|
@@ -1137,155 +1137,155 @@ function Xt(e, n, r = {}) {
|
|
|
1137
1137
|
}
|
|
1138
1138
|
return null;
|
|
1139
1139
|
};
|
|
1140
|
-
|
|
1141
|
-
let m = p("spec-drawer"),
|
|
1142
|
-
|
|
1143
|
-
},
|
|
1140
|
+
o.keepParts(...d);
|
|
1141
|
+
let m = p("spec-drawer"), y = u ? { hidden: !0 } : p("drawer-backdrop"), b = u ? d.find((e) => e.matches("[data-corn=\"empty\"]")) : null, w = (e) => {
|
|
1142
|
+
b && (b.hidden = !e);
|
|
1143
|
+
}, T = !1, E = () => S(i.selectedNode, t.viewEdges(), {
|
|
1144
1144
|
throughChildren: i.throughChildren,
|
|
1145
1145
|
kind: i.selectedKind
|
|
1146
1146
|
});
|
|
1147
|
-
function
|
|
1148
|
-
let
|
|
1149
|
-
if (!
|
|
1150
|
-
let r = Ft(
|
|
1151
|
-
return `<div class="hx-sec-block hx-lines" id="drawer-lines" data-corn="lines-by-kind"><h3 class="hx-sec-title">Lines</h3><div class="hx-chips" role="group" aria-label="Lit lines by kind">${r}</div>${o}${s}<div class="hx-lines-reach"><span data-lines-reach>${
|
|
1147
|
+
function D(e) {
|
|
1148
|
+
let n = E();
|
|
1149
|
+
if (!n || !n.kinds.size) return "";
|
|
1150
|
+
let r = Ft(n).map(({ kind: e, count: t, word: r }) => `<button type="button" class="hx-lines-kind" data-corn="lines-kind" data-corn-kind="quiet" data-lines-kind="${c(e)}" data-focus-key="kind:${c(e)}" aria-pressed="${n.kind === e}">${c(r)} <span class="hx-lines-count" data-corn="count">${t}</span></button>`).join(""), a = n.kind ? It(n, n.kind).map((e) => `<button type="button" class="hx-linkbtn" data-corn="node-link" data-action="select-node" data-id="${c(e.id)}"><span class="hx-sr-only">${e.out ? "to " : "from "}</span><span aria-hidden="true">${e.out ? "→" : "←"}</span> ${c(l.nameOf(e.id))}</button>`) : [], o = a.length ? `<div class="hx-lines-list">${P(a, 12)}</div>` : "", s = S(e, t.viewEdges(), { throughChildren: !1 }).childIds.size > 0 ? `<label class="hx-lines-switch"><input type="checkbox" data-corn="lines-switch" data-lines-switch data-focus-key="switch"${i.throughChildren ? " checked" : ""}> <span>${c(v(t, "throughChildren"))}</span></label>` : "", { connected: u, off: d } = _(t);
|
|
1151
|
+
return `<div class="hx-sec-block hx-lines" id="drawer-lines" data-corn="lines-by-kind"><h3 class="hx-sec-title">Lines</h3><div class="hx-chips" role="group" aria-label="Lit lines by kind">${r}</div>${o}${s}<div class="hx-lines-reach"><span data-lines-reach>${c(Lt(u, d))}</span> <button type="button" data-corn="frame-button" data-corn-kind="secondary" class="hx-btn hx-btn--secondary" data-action="frame-selection" data-focus-key="frame">${c(v(t, "frame"))}</button></div></div>`;
|
|
1152
1152
|
}
|
|
1153
|
-
function
|
|
1153
|
+
function O() {
|
|
1154
1154
|
let e = p("drawer-lines");
|
|
1155
1155
|
if (!e || !i.selectedNode) return;
|
|
1156
|
-
let
|
|
1157
|
-
|
|
1158
|
-
let
|
|
1159
|
-
if (
|
|
1160
|
-
let e = p("drawer-lines"), t = e && [...e.querySelectorAll("[data-focus-key]")].find((e) => e.dataset.focusKey ===
|
|
1156
|
+
let n = t.active(), r = n && e.contains(n) ? n.dataset.focusKey : "", a = t.doc.createElement("div");
|
|
1157
|
+
a.innerHTML = D(i.selectedNode), f(a);
|
|
1158
|
+
let o = a.firstElementChild;
|
|
1159
|
+
if (o ? e.replaceWith(o) : e.remove(), r) {
|
|
1160
|
+
let e = p("drawer-lines"), t = e && [...e.querySelectorAll("[data-focus-key]")].find((e) => e.dataset.focusKey === r);
|
|
1161
1161
|
t && t.focus();
|
|
1162
1162
|
}
|
|
1163
1163
|
}
|
|
1164
|
-
function
|
|
1165
|
-
let
|
|
1166
|
-
if (!
|
|
1167
|
-
let r =
|
|
1168
|
-
i.selectedKind = i.selectedKind === r ? null : r,
|
|
1169
|
-
let
|
|
1170
|
-
return
|
|
1164
|
+
function k(e) {
|
|
1165
|
+
let n = e.target.closest && e.target.closest("[data-lines-kind]");
|
|
1166
|
+
if (!n || !i.selectedNode) return !1;
|
|
1167
|
+
let r = n.dataset.linesKind;
|
|
1168
|
+
i.selectedKind = i.selectedKind === r ? null : r, t.touchScene(), t.map.render(), O();
|
|
1169
|
+
let a = E();
|
|
1170
|
+
return C(t, a && a.kind ? `Showing ${Pt(a.kind).toLowerCase()} only: ${a.edges.length} ${a.edges.length === 1 ? "line" : "lines"}` : "Showing every kind of line"), !0;
|
|
1171
1171
|
}
|
|
1172
|
-
function
|
|
1173
|
-
let
|
|
1174
|
-
if (!
|
|
1175
|
-
i.throughChildren = !!
|
|
1172
|
+
function A(e) {
|
|
1173
|
+
let n = e.target.closest && e.target.closest("[data-lines-switch]");
|
|
1174
|
+
if (!n || !i.selectedNode) return;
|
|
1175
|
+
i.throughChildren = !!n.checked, i.selectedKind = null, t.touchScene(), t.map.render(), O();
|
|
1176
1176
|
let r = E();
|
|
1177
|
-
|
|
1177
|
+
C(t, `${i.throughChildren ? "Including" : "Not including"} its children's lines: ${r ? r.connectedNodeIds.size - 1 : 0} connected`);
|
|
1178
1178
|
}
|
|
1179
|
-
let
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
}),
|
|
1179
|
+
let N = p("drawer-meta-list");
|
|
1180
|
+
o.listen(N, "click", (e) => {
|
|
1181
|
+
k(e) || oe(e.target);
|
|
1182
|
+
}), o.listen(N, "change", A), o.own(t.map.onPaint(() => {
|
|
1183
1183
|
if (!i.selectedNode) return;
|
|
1184
1184
|
let e = m.querySelector("[data-lines-reach]");
|
|
1185
1185
|
if (!e) return;
|
|
1186
|
-
let { connected:
|
|
1186
|
+
let { connected: n, off: r } = _(t), a = Lt(n, r);
|
|
1187
1187
|
e.textContent !== a && (e.textContent = a);
|
|
1188
1188
|
}));
|
|
1189
|
-
function
|
|
1189
|
+
function F() {
|
|
1190
1190
|
let e = p("drawer-threads");
|
|
1191
|
-
e && i.selectedNode && (e.innerHTML =
|
|
1191
|
+
e && i.selectedNode && (e.innerHTML = l.threadsSection(i.selectedNode), f(e));
|
|
1192
1192
|
}
|
|
1193
|
-
function
|
|
1194
|
-
if (!e ||
|
|
1195
|
-
let
|
|
1196
|
-
|
|
1197
|
-
let
|
|
1198
|
-
p("drawer-host").textContent =
|
|
1199
|
-
let
|
|
1200
|
-
|
|
1201
|
-
let
|
|
1202
|
-
|
|
1203
|
-
let
|
|
1204
|
-
|
|
1205
|
-
let
|
|
1206
|
-
|
|
1207
|
-
<div id="drawer-live">${
|
|
1193
|
+
function I(e, { frame: n = !1 } = {}) {
|
|
1194
|
+
if (!e || T) return;
|
|
1195
|
+
let r = p("drawer-title");
|
|
1196
|
+
r.textContent = e.tag ? `<${e.tag}>` : e.label, r.classList.toggle("hx-mono", e.type === "page" || !!e.tag), p("drawer-badge").textContent = Ut(e);
|
|
1197
|
+
let a = Wt(e);
|
|
1198
|
+
p("drawer-host").textContent = a ? ` · ${a}` : "";
|
|
1199
|
+
let o = Gt(e, i.proposal), s = p("drawer-diff");
|
|
1200
|
+
s.textContent = o, s.hidden = !o;
|
|
1201
|
+
let c = le(o ? e.mark : "");
|
|
1202
|
+
c ? s.dataset.cornState = c : delete s.dataset.cornState;
|
|
1203
|
+
let d = p("drawer-description");
|
|
1204
|
+
d.textContent = e.desc || "", d.hidden = !e.desc;
|
|
1205
|
+
let h = `${e.file ? $("File", [Z(e.file)]) : ""}${se(t, e)}${l.dataSummary(e)}`, g = t.ask("live:section", e) || "";
|
|
1206
|
+
N.innerHTML = `${D(e)}${h ? `<div class="hx-facts">${h}</div>` : ""}
|
|
1207
|
+
<div id="drawer-live">${g}</div>
|
|
1208
1208
|
${ft(i, e.id)}
|
|
1209
|
-
<div id="drawer-threads">${
|
|
1210
|
-
${
|
|
1211
|
-
let
|
|
1212
|
-
|
|
1213
|
-
let
|
|
1214
|
-
|
|
1209
|
+
<div id="drawer-threads">${l.threadsSection(e)}</div>
|
|
1210
|
+
${l.diffSection(e)}`, f(N), t.emit("threads:ensure"), t.emit("live:hydrate", p("drawer-live"));
|
|
1211
|
+
let _ = p("drawer-file-btn"), b = p("drawer-open-btn"), x = e.file && i.forge ? Dt(i.forge, e.file, i.forge.baseBranch) : null;
|
|
1212
|
+
_.hidden = !x, x ? _.href = x : _.removeAttribute("href");
|
|
1213
|
+
let S = !!(e.url && /^https?:\/\//.test(e.url));
|
|
1214
|
+
S ? b.href = e.url : b.removeAttribute("href"), b.hidden = !S, b.className = x ? "hx-btn hx-btn--quiet hx-foot-btn" : "hx-open", x ? b.dataset.cornKind = "quiet" : b.dataset.cornKind = "primary", b.textContent = `${v(t, "openRoute")} ↗`, _.textContent = `${v(t, "openFile")} ↗`, p("drawer-run-btn").hidden = !(i.proposalSlug && t.ask("forge:can-start")), m.classList.add("drawer-open"), m.inert = !1, y.hidden = !1, w(!1), u || ae(t, "drawer"), !n && !u && L(), t.emit("node:painted", { node: e });
|
|
1215
1215
|
}
|
|
1216
|
-
function
|
|
1217
|
-
if (!e ||
|
|
1218
|
-
let
|
|
1219
|
-
|
|
1220
|
-
let
|
|
1221
|
-
|
|
1216
|
+
function ce(e) {
|
|
1217
|
+
if (!e || T) return;
|
|
1218
|
+
let t = (e, t) => t ? `<div class="hx-fact" data-corn="section"><div class="hx-fact-k">${c(e)}</div><div class="hx-fact-v">${c(t)}</div></div>` : "", n = t("Kind", e.kind || (e.dashed ? "usage" : "ownership")) + t("Flow", e.flow) + t("Label", e.label) + t("Reads", Array.isArray(e.keys) ? e.keys.join(", ") : ""), r = p("drawer-title");
|
|
1219
|
+
r.textContent = `${l.nameOf(e.from)} → ${l.nameOf(e.to)}`, r.classList.remove("hx-mono"), p("drawer-badge").textContent = "Edge", p("drawer-host").textContent = "", p("drawer-diff").hidden = !0;
|
|
1220
|
+
let i = p("drawer-description");
|
|
1221
|
+
i.textContent = "", i.hidden = !0, N.innerHTML = `${n ? `<div class="hx-facts">${n}</div>` : ""}
|
|
1222
1222
|
<div class="hx-facts">
|
|
1223
|
-
<div class="hx-fact" data-corn="section"><div class="hx-fact-k">From</div><div class="hx-fact-v"><button data-corn="node-link" type="button" class="hx-linkbtn" data-action="select-node" data-id="${
|
|
1224
|
-
<div class="hx-fact" data-corn="section"><div class="hx-fact-k">To</div><div class="hx-fact-v"><button data-corn="node-link" type="button" class="hx-linkbtn" data-action="select-node" data-id="${
|
|
1225
|
-
</div>${
|
|
1223
|
+
<div class="hx-fact" data-corn="section"><div class="hx-fact-k">From</div><div class="hx-fact-v"><button data-corn="node-link" type="button" class="hx-linkbtn" data-action="select-node" data-id="${c(e.from)}">${c(l.nameOf(e.from))}</button></div></div>
|
|
1224
|
+
<div class="hx-fact" data-corn="section"><div class="hx-fact-k">To</div><div class="hx-fact-v"><button data-corn="node-link" type="button" class="hx-linkbtn" data-action="select-node" data-id="${c(e.to)}">${c(l.nameOf(e.to))}</button></div></div>
|
|
1225
|
+
</div>${Te(e)}`, f(N), p("drawer-open-btn").hidden = !0, p("drawer-file-btn").hidden = !0, p("drawer-run-btn").hidden = !0, m.classList.add("drawer-open"), m.inert = !1, y.hidden = !1, w(!1);
|
|
1226
1226
|
}
|
|
1227
|
-
function
|
|
1227
|
+
function L() {
|
|
1228
1228
|
let e = i.selectedNode;
|
|
1229
|
-
if (!e || !i.width || !
|
|
1230
|
-
let
|
|
1229
|
+
if (!e || !i.width || !h(t) || T) return;
|
|
1230
|
+
let n = g(t), r = gt(i.camera, e, {
|
|
1231
1231
|
left: 0,
|
|
1232
1232
|
top: 0,
|
|
1233
1233
|
right: i.width,
|
|
1234
|
-
bottom: i.height -
|
|
1234
|
+
bottom: i.height - n
|
|
1235
1235
|
}, e.r * i.camera.zoom + 16);
|
|
1236
|
-
r && (Object.assign(i.camera, r),
|
|
1236
|
+
r && (Object.assign(i.camera, r), t.map.render());
|
|
1237
1237
|
}
|
|
1238
|
-
function
|
|
1239
|
-
m.classList.remove("drawer-open"), m.inert = !0,
|
|
1238
|
+
function R() {
|
|
1239
|
+
m.classList.remove("drawer-open"), m.inert = !0, y.hidden = !0, w(!0), u || M(t, "drawer");
|
|
1240
1240
|
}
|
|
1241
|
-
function
|
|
1242
|
-
i.proposalSlug &&
|
|
1241
|
+
function z() {
|
|
1242
|
+
i.proposalSlug && t.emit("forge:start", {
|
|
1243
1243
|
slug: i.proposalSlug,
|
|
1244
1244
|
returnTo: "#drawer-run-btn"
|
|
1245
1245
|
});
|
|
1246
1246
|
}
|
|
1247
|
-
|
|
1248
|
-
let
|
|
1249
|
-
"close-drawer": () =>
|
|
1250
|
-
"copy-spec": () => Jt(
|
|
1251
|
-
"start-run": () =>
|
|
1252
|
-
"select-node": (e) =>
|
|
1247
|
+
o.own(() => clearTimeout(qt(t).timer));
|
|
1248
|
+
let ue = {
|
|
1249
|
+
"close-drawer": () => x(t, { source: "tap" }),
|
|
1250
|
+
"copy-spec": () => Jt(t, p("copy-spec-result")),
|
|
1251
|
+
"start-run": () => z(),
|
|
1252
|
+
"select-node": (e) => ee(t, l.nodeById(e.dataset.id), {
|
|
1253
1253
|
frame: !0,
|
|
1254
1254
|
source: "link"
|
|
1255
1255
|
}),
|
|
1256
|
-
"frame-selection": () =>
|
|
1256
|
+
"frame-selection": () => s(t)
|
|
1257
1257
|
};
|
|
1258
|
-
return
|
|
1258
|
+
return o.listen(m, "click", (e) => {
|
|
1259
1259
|
let t = e.target.closest && e.target.closest("[data-action]");
|
|
1260
1260
|
if (!t) return;
|
|
1261
|
-
let n =
|
|
1262
|
-
n && n(t), t.dataset.action === "close-drawer" && i.canvas &&
|
|
1263
|
-
}),
|
|
1264
|
-
let
|
|
1265
|
-
|
|
1266
|
-
}),
|
|
1267
|
-
|
|
1268
|
-
}, !0),
|
|
1269
|
-
e.key !== "Escape" || e.defaultPrevented || e.target.closest && e.target.closest("select, input, textarea") || (e.preventDefault(),
|
|
1270
|
-
}),
|
|
1261
|
+
let n = ue[t.dataset.action];
|
|
1262
|
+
n && n(t), t.dataset.action === "close-drawer" && i.canvas && o.timeout(() => i.canvas.focus(), 0);
|
|
1263
|
+
}), o.listen(m, "click", (e) => {
|
|
1264
|
+
let n = e.target.closest && e.target.closest("[data-thread-open]");
|
|
1265
|
+
n ? t.emit("thread:open", { number: Number(n.dataset.threadOpen) }) : e.target.closest && e.target.closest("[data-thread-start]") && i.selectedNode && t.emit("thread:start", { node: i.selectedNode });
|
|
1266
|
+
}), o.on("threads:changed", () => F()), u || o.listen(y, "click", (e) => {
|
|
1267
|
+
h(t) ? j(t, e) : x(t, { source: "tap" });
|
|
1268
|
+
}, !0), o.listen(m, "keydown", (e) => {
|
|
1269
|
+
e.key !== "Escape" || e.defaultPrevented || e.target.closest && e.target.closest("select, input, textarea") || (e.preventDefault(), x(t, { source: "keyboard" }), i.canvas && i.canvas.focus(), C(t, "Panel closed"));
|
|
1270
|
+
}), o.on("panel:present", () => !0), o.on("panel:covers", () => !u && !T && !m.hidden && m.classList.contains("drawer-open") ? { right: m.offsetWidth } : void 0), o.on("node:show", ({ node: e, frame: t }) => I(e, { frame: t })), o.on("node:close", R), o.on("node:show-edge", ({ edge: e }) => ce(e)), o.on("node:focus", () => {
|
|
1271
1271
|
let e = p("drawer-title");
|
|
1272
1272
|
if (!e) return;
|
|
1273
|
-
let
|
|
1274
|
-
|
|
1275
|
-
}),
|
|
1276
|
-
|
|
1273
|
+
let n = t.active();
|
|
1274
|
+
u && n && n !== e && typeof n.matches == "function" && n.matches("[data-corn=\"node-title\"]") || (e.setAttribute("tabindex", "-1"), e.focus());
|
|
1275
|
+
}), u || (o.own(ie(t, () => L())), re(t), te(t, "drawer", m, { stub: () => ({ title: p("drawer-title") && p("drawer-title").textContent || "Node" }) }), o.own(() => ne(t, "drawer"))), i.selectedNode && I(i.selectedNode, { frame: !1 }), o.own(() => {
|
|
1276
|
+
T = !0, d.forEach((e) => e.remove());
|
|
1277
1277
|
}), {
|
|
1278
1278
|
elements: d,
|
|
1279
|
-
show:
|
|
1280
|
-
close:
|
|
1281
|
-
repaintThreads:
|
|
1282
|
-
copySpec: () => Jt(
|
|
1283
|
-
startRun:
|
|
1284
|
-
keepSelectedInView:
|
|
1279
|
+
show: I,
|
|
1280
|
+
close: R,
|
|
1281
|
+
repaintThreads: F,
|
|
1282
|
+
copySpec: () => Jt(t, p("copy-spec-result")),
|
|
1283
|
+
startRun: z,
|
|
1284
|
+
keepSelectedInView: L,
|
|
1285
1285
|
update(e) {
|
|
1286
|
-
e && "node" in e ? e.node ?
|
|
1286
|
+
e && "node" in e ? e.node ? ee(t, e.node, { source: "api" }) : x(t, { source: "api" }) : i.selectedNode && m.classList.contains("drawer-open") && I(i.selectedNode, { frame: !1 });
|
|
1287
1287
|
},
|
|
1288
|
-
destroy: () =>
|
|
1288
|
+
destroy: () => o.destroy()
|
|
1289
1289
|
};
|
|
1290
1290
|
}
|
|
1291
|
-
export {
|
|
1291
|
+
export { R as A, V as C, de as D, Ne as E, ue as O, Me as S, ge as T, be as _, pt as a, xe as b, nt as c, at as d, pe as f, me as g, he as h, yt as i, L as k, K as l, fe as m, Rt as n, mt as o, B as p, bt as r, ht as s, Xt as t, it as u, _e as v, ke as w, Ae as x, je as y };
|