@popcorn245/cornfield-components 0.52.1 → 0.53.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 (43) hide show
  1. package/README.md +1 -1
  2. package/dist/chunks/around-BcnegEdS.js +99 -0
  3. package/dist/chunks/connection-KDiWvV19.js +23 -0
  4. package/dist/chunks/{engine-BmXtSISH.js → engine-xmHJvQY9.js} +1188 -1186
  5. package/dist/chunks/{layers-Bj4Tluxe.js → layers-ho10a2y7.js} +48 -48
  6. package/dist/chunks/{map-BZRFOYkt.js → map-DbfPgQRe.js} +385 -385
  7. package/dist/chunks/node-panel-CC8UrSzJ.js +410 -0
  8. package/dist/chunks/panel-review-ih7RlfkH.js +884 -0
  9. package/dist/chunks/review-pieces-DtRxCDMr.js +2523 -0
  10. package/dist/chunks/{review-source-CK5tYIqk.js → review-source-CmbwaPCM.js} +1 -1
  11. package/dist/chunks/scope-2m2VmJXn.js +185 -0
  12. package/dist/chunks/scope-proposal-T06ndbin.js +116 -0
  13. package/dist/chunks/{sheets-D-sMZzSs.js → sheets-BWANwtZP.js} +7 -2
  14. package/dist/chunks/source-address-DXanAREm.js +57 -0
  15. package/dist/chunks/{status-DI5QLlAp.js → status-DM-iIEsg.js} +4 -3
  16. package/dist/corn-changes.js +43 -0
  17. package/dist/corn-decision.js +52 -0
  18. package/dist/corn-layers.js +275 -1
  19. package/dist/corn-map.js +125 -1
  20. package/dist/corn-node-panel.js +42 -1
  21. package/dist/corn-proposal.js +50 -0
  22. package/dist/corn-review.js +425 -1
  23. package/dist/corn-scope.js +33 -9
  24. package/dist/corn-search.js +484 -1
  25. package/dist/index.js +11 -8
  26. package/dist/manifest.json +95 -70
  27. package/dist/tokens.css +6 -0
  28. package/dist/types/components.d.ts +111 -5
  29. package/dist/types/corn-changes.d.ts +2 -0
  30. package/dist/types/corn-decision.d.ts +2 -0
  31. package/dist/types/corn-proposal.d.ts +2 -0
  32. package/dist/types/index.d.ts +3 -0
  33. package/dist/version.json +1 -1
  34. package/package.json +17 -5
  35. package/dist/chunks/around-BFqYTZ0K.js +0 -78
  36. package/dist/chunks/corn-layers-Cni5rISZ.js +0 -275
  37. package/dist/chunks/corn-map-B2-YxiEL.js +0 -125
  38. package/dist/chunks/corn-node-panel-BkvJThlp.js +0 -42
  39. package/dist/chunks/corn-review-5wf7AT4o.js +0 -2900
  40. package/dist/chunks/corn-search-CXs5d06S.js +0 -484
  41. package/dist/chunks/node-panel-BdvFvWCE.js +0 -1291
  42. package/dist/chunks/scope-CqPbHcKL.js +0 -137
  43. package/dist/chunks/source-address-C70zNPIj.js +0 -79
@@ -0,0 +1,2523 @@
1
+ import { t as e } from "./rolldown-runtime-CGnMp29N.js";
2
+ import { $ as t, Dn as n, En as r, Ft as i, It as a, K as o, Kt as s, Lt as c, Nt as l, Pt as u, Q as d, Rt as f, T as p, Tn as m, Y as h, bn as g, c as _, dn as v, et as y, hn as b, j as x, jn as S, l as C, nn as w, q as T, qt as E, rn as ee, rt as D, vn as O, yt as k, zt as A } from "./engine-xmHJvQY9.js";
3
+ import { A as j, C as M, E as N, L as P, M as F, N as I, O as L, P as R, S as z, T as B, _ as V, c as H, d as U, g as W, h as G, j as K, k as te, m as ne, n as re, o as ie, p as ae, r as q, s as J, u as oe, v as se, w as Y, x as ce, y as le } from "./panel-review-ih7RlfkH.js";
4
+ import { c as ue, d as de, i as fe, n as pe, o as me, r as he, s as ge, t as _e } from "./sheets-BWANwtZP.js";
5
+ import { c as ve, d as ye, f as be, i as xe, l as Se, m as Ce, n as we, r as Te, t as Ee } from "./layers-ho10a2y7.js";
6
+ import { n as De, t as Oe } from "./connection-KDiWvV19.js";
7
+ var ke = (e) => e === void 0 ? null : Array.isArray(e) ? e : [e], Ae = (e) => !e.kind && !e.dashed;
8
+ function je(e, t) {
9
+ if (!t) return null;
10
+ let n = k(t);
11
+ return e.find((e) => e.type === "persona" && (e.id === n || e.id === t)) || null;
12
+ }
13
+ function Me(e) {
14
+ return e.account === !1 ? { account: !1 } : {
15
+ role: e.role,
16
+ groups: Array.isArray(e.groups) ? [...e.groups] : []
17
+ };
18
+ }
19
+ var Ne = (e) => e ? e.codeLabel || e.label || e.id : "";
20
+ function Pe(e, t) {
21
+ let n = new Map(e.map((e) => [e.id, e])), r = /* @__PURE__ */ new Map();
22
+ for (let e of t) Ae(e) && !r.has(e.to) && r.set(e.to, e.from);
23
+ return {
24
+ nodes: e,
25
+ byId: n,
26
+ owner: r
27
+ };
28
+ }
29
+ function Fe(e, t) {
30
+ let n = e.byId.get(t);
31
+ return n ? n.type === "table" && (n.table || n.label) || null : typeof t == "string" && t.startsWith("table-") ? t.slice(6) : null;
32
+ }
33
+ function Ie(e, t, n) {
34
+ return !t || t.type !== "page" || !Array.isArray(t.methods) || t.methods.length === 0 ? !1 : !n || !Array.isArray(n.apps) || n.apps.includes(e.owner.get(t.id));
35
+ }
36
+ function Le(e, t, n) {
37
+ let r = ke(e && e.check);
38
+ if (r) return r.map((e) => ({ ...e }));
39
+ if (!e) return [];
40
+ if (e.node !== void 0) {
41
+ let r = t.byId.get(e.node);
42
+ if (!Ie(t, r, n)) return [];
43
+ let i = r.methods.map((e) => String(e).toUpperCase());
44
+ return [{
45
+ route: r.label,
46
+ method: i.includes("GET") ? "GET" : i[0]
47
+ }];
48
+ }
49
+ if (e.edge && e.edge.kind === "writes") {
50
+ let n = Fe(t, e.edge.to);
51
+ return n ? [{
52
+ table: n,
53
+ op: "write"
54
+ }] : [];
55
+ }
56
+ if (e.edge && e.edge.kind === "reads") {
57
+ let n = Fe(t, e.edge.from);
58
+ return n ? [{
59
+ table: n,
60
+ op: "read"
61
+ }] : [];
62
+ }
63
+ return [];
64
+ }
65
+ function Re(e, t, n, { as: r = null } = {}) {
66
+ let i = [], a = [];
67
+ return (e && Array.isArray(e.steps) ? e.steps : []).forEach((o, s) => {
68
+ let c = r || o.actor || e.actor || null, l = {
69
+ index: s,
70
+ actor: c,
71
+ actorLabel: "",
72
+ kind: "none",
73
+ checks: [],
74
+ expect: o.expect
75
+ };
76
+ if (i.push(l), !c) return;
77
+ let u = je(t.nodes, c);
78
+ if (l.actorLabel = u ? Ne(u) : c, !u) {
79
+ l.kind = "unchecked", l.why = `no persona "${c}" on the map`;
80
+ return;
81
+ }
82
+ let d = Le(o, t, n);
83
+ if (d.length === 0) {
84
+ l.kind = "unchecked", l.why = Array.isArray(o.check) ? "this step is not a permission question" : "nothing in this step to ask";
85
+ return;
86
+ }
87
+ l.kind = "ask";
88
+ let f = Me(u);
89
+ l.checks = d.map((e, t) => ({
90
+ id: `s${s + 1}-${t + 1}`,
91
+ ...e
92
+ })), l.checks.forEach((e) => a.push({
93
+ ...e,
94
+ actor: f
95
+ }));
96
+ }), {
97
+ steps: i,
98
+ items: a,
99
+ key: JSON.stringify(a)
100
+ };
101
+ }
102
+ function ze(e, t = {}) {
103
+ let n = Error(t.message || e);
104
+ return n.reason = e, Object.assign(n, t), n;
105
+ }
106
+ async function Be(e, t, { signal: n } = {}) {
107
+ let r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
108
+ if (!e) throw ze("no-checker", { message: "no permission checker" });
109
+ let a = e.max > 0 ? e.max : 100, o = t.slice();
110
+ for (; o.length;) {
111
+ let t = o.slice(0, a), s;
112
+ try {
113
+ s = await e.check(t, { signal: n });
114
+ } catch (e) {
115
+ let n = e && e.reason === "bad-check" ? e.checkId : null;
116
+ if (n && t.some((e) => e.id === n)) {
117
+ i.set(n, e.message || "the checker refused this check"), o = o.filter((e) => e.id !== n);
118
+ continue;
119
+ }
120
+ throw e;
121
+ }
122
+ for (let e of s || []) e && typeof e.id == "string" && r.set(e.id, e);
123
+ o = o.slice(t.length);
124
+ }
125
+ return {
126
+ results: r,
127
+ bad: i
128
+ };
129
+ }
130
+ function Ve(e, t) {
131
+ let n = {
132
+ mismatch: !1,
133
+ actor: e ? e.actorLabel : "",
134
+ checks: []
135
+ };
136
+ if (!e || e.kind === "none") return {
137
+ ...n,
138
+ state: "none"
139
+ };
140
+ if (e.expect && (n.expect = e.expect), e.kind === "unchecked") return {
141
+ ...n,
142
+ state: "unchecked",
143
+ why: e.why
144
+ };
145
+ if (!t || t.status === "idle" || t.status === "pending") return {
146
+ ...n,
147
+ state: "pending",
148
+ checks: e.checks
149
+ };
150
+ if (t.status === "failed") return {
151
+ ...n,
152
+ state: "unavailable",
153
+ why: He(t.error),
154
+ checks: e.checks
155
+ };
156
+ let r = e.checks.map((e) => ({
157
+ ...e,
158
+ result: t.results.get(e.id) || null
159
+ })), i = e.checks.find((e) => t.bad && t.bad.has(e.id));
160
+ if (i) return {
161
+ ...n,
162
+ state: "unchecked",
163
+ why: t.bad.get(i.id),
164
+ checks: r
165
+ };
166
+ if (r.some((e) => !e.result)) return {
167
+ ...n,
168
+ state: "unavailable",
169
+ why: "the checker gave no answer for this step",
170
+ checks: r
171
+ };
172
+ let a = r.find((e) => e.result.allowed !== !0), o = a ? "refused" : "allowed", s = {
173
+ ...n,
174
+ state: o,
175
+ checks: r
176
+ };
177
+ return a && (s.reason = a.result.reason || `refused (${a.result.status})`, a.result.rule && (s.rule = a.result.rule)), s.mismatch = !!e.expect && e.expect !== o, s;
178
+ }
179
+ function He(e) {
180
+ let t = e && e.reason;
181
+ return t === "no-checker" ? "no permission checker" : t === "no-token" ? `no token${e.hint ? ` (${e.hint})` : ""}` : t === "forbidden" ? "the token is not an admin's" : "the checker is not answering";
182
+ }
183
+ function Ue(e) {
184
+ return e.route === void 0 ? [
185
+ e.table,
186
+ e.op,
187
+ e.row
188
+ ].filter(Boolean).join(" · ") : `${String(e.method || "").toUpperCase()} ${e.route}`;
189
+ }
190
+ function We(e) {
191
+ if (!e || e.state === "none") return null;
192
+ let t = e.actor ? ` as ${e.actor}` : "", n = e.checks.map(Ue).join(", "), r = n ? `${n}${t}` : e.actor ? `As ${e.actor}` : "", i = () => `${e.reason}${e.rule ? ` (${e.rule})` : ""}`;
193
+ if (e.state === "pending") return {
194
+ tone: "pending",
195
+ pill: "Checking…",
196
+ line: `Checking${t}…`,
197
+ detail: r
198
+ };
199
+ if (e.state === "unchecked") return {
200
+ tone: "unchecked",
201
+ pill: "Not checked",
202
+ line: `Not checked: ${e.why}`,
203
+ detail: r
204
+ };
205
+ if (e.state === "unavailable") return {
206
+ tone: "unavailable",
207
+ pill: "Unavailable",
208
+ line: `Not checked: live layer unavailable (${e.why})`,
209
+ detail: r
210
+ };
211
+ if (e.mismatch) {
212
+ let t = e.state === "refused" ? `Expected allowed, but refused: ${i()}` : "Expected refused, but allowed";
213
+ return {
214
+ tone: "mismatch",
215
+ pill: `Expected ${e.expect}`,
216
+ line: t,
217
+ detail: r
218
+ };
219
+ }
220
+ return e.state === "refused" ? {
221
+ tone: "refused",
222
+ pill: "✕ Refused",
223
+ line: `Refused: ${i()}`,
224
+ detail: r
225
+ } : {
226
+ tone: "allowed",
227
+ pill: "✓ Allowed",
228
+ line: "Allowed",
229
+ detail: r
230
+ };
231
+ }
232
+ // ../explorer/engine/checks.js
233
+ var Ge = (e) => !!e && (!!e.actor || Array.isArray(e.steps) && e.steps.some((e) => e && e.actor));
234
+ function Ke(e, n = {}) {
235
+ let { state: r } = e, i = n.checker || null, a = null, o = 0, c = /* @__PURE__ */ new WeakMap(), l = [];
236
+ function u() {
237
+ a && a.controller && a.controller.abort(), a = null, o++;
238
+ }
239
+ function d(e) {
240
+ e ||= null, e !== i && u(), i = e;
241
+ }
242
+ function f() {
243
+ let e = a;
244
+ if (!e) return;
245
+ e.controller && e.controller.abort();
246
+ let t = e.plan.items;
247
+ if (t.length === 0) {
248
+ e.answer = {
249
+ status: "ok",
250
+ results: /* @__PURE__ */ new Map(),
251
+ bad: /* @__PURE__ */ new Map()
252
+ }, o++;
253
+ return;
254
+ }
255
+ let n = new AbortController();
256
+ e.controller = n, e.answer = { status: "pending" }, o++, Be(i, t, { signal: n.signal }).then(({ results: t, bad: r }) => p(e, n, {
257
+ status: "ok",
258
+ results: t,
259
+ bad: r
260
+ }), (t) => {
261
+ n.signal.aborted || p(e, n, {
262
+ status: "failed",
263
+ error: t
264
+ });
265
+ });
266
+ }
267
+ function p(e, t, n) {
268
+ a === e && e.controller === t && (e.controller = null, e.answer = n, o++, e.onChange());
269
+ }
270
+ function h(e, t = !1) {
271
+ let n = a;
272
+ if (!n || !t && n.scenario === e && n.nodes === r.nodes && n.plan) return;
273
+ let s = n.plan ? n.plan.key : null;
274
+ n.scenario = e, n.nodes = r.nodes, n.plan = Re(e, Pe(r.nodes, r.edges), i, { as: n.as }), o++, (t || n.plan.key !== s) && f();
275
+ }
276
+ function g(n, i = () => {}) {
277
+ a && a.scenario && n && a.scenario.id === n.id ? (a.onChange = i, h(n)) : (u(), a = {
278
+ scenario: null,
279
+ as: null,
280
+ nodes: null,
281
+ plan: null,
282
+ answer: { status: "idle" },
283
+ controller: null,
284
+ onChange: i
285
+ }, Ge(n) && t(r).persona !== !0 && be(e, "persona", !0, { scenario: !0 }), h(n));
286
+ }
287
+ function _(e, t) {
288
+ if (!a) return e;
289
+ h(t);
290
+ let n = a.plan.steps[e.index];
291
+ return e.verdict = Ve(n, a.answer), a.as && n && n.actor && (e.current.actor = n.actor), e;
292
+ }
293
+ function v() {
294
+ return !a || !a.plan ? [] : a.plan.steps.map((e) => Ve(e, a.answer));
295
+ }
296
+ function y(e) {
297
+ a && (a.as = e || null, h(a.scenario, !0), a.onChange());
298
+ }
299
+ function b() {
300
+ a && (h(a.scenario, !0), a.onChange());
301
+ }
302
+ function x(t) {
303
+ let n = e.doc, r = n.createElement("span");
304
+ r.className = "hx-player-verdict", r.dataset.corn = "state-pill", r.hidden = !0;
305
+ let i = t.querySelector(".hx-player-text");
306
+ i ? i.append(" ", r) : t.prepend(r);
307
+ let a = n.createElement("p");
308
+ a.className = "hx-player-check", a.dataset.corn = "scenario-check", a.hidden = !0;
309
+ let o = n.createElement("div");
310
+ o.className = "hx-player-as", o.innerHTML = "\n <label class=\"hx-player-as-label\">As <select data-corn=\"control\" class=\"hx-player-speed hx-player-as-menu\" data-check=\"as\" aria-label=\"Act every step as\"></select></label>\n <button data-corn-kind=\"secondary\" type=\"button\" class=\"hx-btn\" data-check=\"recheck\">Check again</button>\n <span class=\"hx-player-as-sum hx-faint\"></span>";
311
+ let s = t.querySelector(".hx-player-track");
312
+ s ? (s.before(a), s.before(o)) : (t.appendChild(a), t.appendChild(o));
313
+ for (let e of [
314
+ r,
315
+ a,
316
+ o
317
+ ]) e.hasAttribute("data-corn") && e.setAttribute("part", e.getAttribute("data-corn"));
318
+ m(o);
319
+ let c = o.querySelector("[data-check=as]"), u = o.querySelector("[data-check=recheck]"), d = (e) => y(e.target.value);
320
+ c.addEventListener("change", d), u.addEventListener("click", b), l.push(() => {
321
+ c.removeEventListener("change", d), u.removeEventListener("click", b);
322
+ });
323
+ }
324
+ function S() {
325
+ let e = l;
326
+ l = [], e.forEach((e) => e());
327
+ }
328
+ function C(e) {
329
+ let t = [{
330
+ value: "",
331
+ label: "As written"
332
+ }, ...r.nodes.filter((e) => e.type === "persona").map((e) => ({
333
+ value: e.id.replace(/^persona-/, ""),
334
+ label: Ne(e)
335
+ }))], n = t.map((e) => `${e.value}\u0000${e.label}`).join("");
336
+ e.dataset.key !== n && (e.innerHTML = t.map((e) => `<option value="${s(e.value)}">${s(e.label)}</option>`).join(""), e.dataset.key = n), e.value = a && a.as ? a.as : "";
337
+ }
338
+ function w() {
339
+ let e = v(), t = e.reduce((e, t) => e + t.checks.length, 0);
340
+ if (!a || a.answer.status === "pending") return t ? `Checking ${t}…` : "";
341
+ if (a.answer.status === "failed") return "";
342
+ let n = e.filter((e) => e.state === "refused").length, r = e.filter((e) => e.mismatch).length, i = [`${t} ${t === 1 ? "check" : "checks"}`];
343
+ return n && i.push(`${n} refused`), r && i.push(`${r} not as expected`), t ? i.join(" · ") : "No permission questions";
344
+ }
345
+ function T(e, t) {
346
+ if (!e || !a) return;
347
+ if (!e.querySelector(".hx-player-as")) {
348
+ if (!Ge(a.scenario)) return;
349
+ x(e);
350
+ }
351
+ let n = e.querySelector(".hx-player-verdict"), r = e.querySelector(".hx-player-check"), i = e.querySelector(".hx-player-as");
352
+ if (!n || !r || !i) return;
353
+ let o = t.done ? null : We(t.verdict);
354
+ if (n.hidden = !o, r.hidden = !o, o) {
355
+ n.dataset.tone = o.tone, R(o.tone) ? n.dataset.cornState = R(o.tone) : delete n.dataset.cornState, n.textContent = o.pill, n.title = o.line, r.dataset.tone = o.tone;
356
+ let e = `${s(o.line)}${o.detail ? ` <span class="hx-player-check-detail">${s(o.detail)}</span>` : ""}`;
357
+ c.get(r) !== e && (c.set(r, e), r.innerHTML = e);
358
+ }
359
+ C(i.querySelector("[data-check=as]")), i.querySelector("[data-check=recheck]").disabled = a.answer.status === "pending", i.querySelector(".hx-player-as-sum").textContent = w();
360
+ }
361
+ return {
362
+ setChecker: d,
363
+ open: g,
364
+ close: u,
365
+ decorate: _,
366
+ paint: T,
367
+ unmount: S,
368
+ verdicts: v,
369
+ chooseActor: y,
370
+ recheck: b,
371
+ version: () => o,
372
+ checkedScenarioId: () => a && a.scenario ? a.scenario.id : null
373
+ };
374
+ }
375
+ // ../explorer/scenario.js
376
+ var qe = 5e3, Je = "topology.scenarioSpeed", Ye = [
377
+ {
378
+ value: "2000",
379
+ label: "2 s"
380
+ },
381
+ {
382
+ value: "5000",
383
+ label: "5 s"
384
+ },
385
+ {
386
+ value: "10000",
387
+ label: "10 s"
388
+ },
389
+ {
390
+ value: "manual",
391
+ label: "Manual"
392
+ }
393
+ ];
394
+ function Xe(e) {
395
+ let t = Ye.find((t) => t.value === e);
396
+ return t ? t.value === "manual" ? "manual" : Number(t.value) : qe;
397
+ }
398
+ function Ze(e, t = qe) {
399
+ let n = e && e.ms;
400
+ return typeof n == "number" && n > 0 && Number.isFinite(n) ? n : t;
401
+ }
402
+ var Qe = (e) => e && Array.isArray(e.steps) ? e.steps : [];
403
+ function $e(e) {
404
+ let t = e && Array.isArray(e.down) ? e.down : [];
405
+ return [...new Set(t.filter((e) => typeof e == "string" && e !== ""))];
406
+ }
407
+ function et(e, t) {
408
+ return t && t.actor || e && e.actor || null;
409
+ }
410
+ function tt(e, t = {}) {
411
+ let n = e, r = t.stepMs, i = () => r === "manual", a = () => n.stepMs ?? (typeof r == "number" && r > 0 ? r : 5e3), o = t.maxFrameMs ?? Infinity, s = 0, c = !1, l = Qe(e).length === 0, u = 0, d = null, f = null, p = () => Qe(n), m = () => p().length - 1, h = (e) => Ze(p()[e], a()), g = (e) => Math.max(0, Math.min(Math.max(0, m()), e)), _ = () => {
412
+ s = 0, l = p().length === 0, u = 0, d = null, f = null;
413
+ }, v = () => {
414
+ c = !1, d = null, f = null;
415
+ };
416
+ return {
417
+ play() {
418
+ p().length === 0 || i() || (l && _(), c || (c = !0, d = null));
419
+ },
420
+ pause() {
421
+ v();
422
+ },
423
+ isPlaying: () => c,
424
+ next() {
425
+ v(), s < m() ? (s++, u = 0) : p().length && (l = !0);
426
+ },
427
+ prev() {
428
+ v(), l = !1, s > 0 && (s--, u = 0);
429
+ },
430
+ goTo(e) {
431
+ if (v(), !Number.isFinite(e)) return;
432
+ let t = g(Math.floor(e));
433
+ t !== s && (s = t, u = 0), l = !1;
434
+ },
435
+ stop() {
436
+ v(), _();
437
+ },
438
+ setSpeed(e) {
439
+ r = e, i() && v();
440
+ },
441
+ scenario: () => n,
442
+ setScenario(e) {
443
+ n = e, s = g(s), p().length === 0 && (l = !0);
444
+ },
445
+ tick(e) {
446
+ if (!c || i()) return;
447
+ if (d === null) {
448
+ d = e, f = e - u;
449
+ return;
450
+ }
451
+ let t = Math.max(0, e - d);
452
+ for (u += Math.min(t, o), t > o && (f = e - u), d = e; u >= h(s);) {
453
+ if (s >= m()) {
454
+ u = h(s), l = !0, v();
455
+ return;
456
+ }
457
+ u -= h(s), f += h(s), s++;
458
+ }
459
+ },
460
+ snapshot() {
461
+ let e = p(), t = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), a = [];
462
+ for (let n = 0; n <= s && n < e.length; n++) {
463
+ let i = e[n];
464
+ if (i.node !== void 0 && t.add(i.node), i.at !== void 0 && t.add(i.at), i.edge) {
465
+ t.add(i.edge.from), t.add(i.edge.to);
466
+ let e = U(i.edge);
467
+ r.has(e) || (r.add(e), a.push({ ...i.edge }));
468
+ }
469
+ }
470
+ let o = e[s], d = { text: o ? String(o.text ?? "") : "" };
471
+ o && o.node !== void 0 && (d.node = o.node), o && o.edge && (d.edge = { ...o.edge }, d.edgeKey = U(o.edge));
472
+ let m = et(n, o);
473
+ m && (d.actor = m), o && o.at !== void 0 && (d.at = o.at), o && o.check !== void 0 && (d.check = JSON.parse(JSON.stringify(o.check))), o && o.expect !== void 0 && (d.expect = o.expect);
474
+ let g = h(s);
475
+ return {
476
+ id: n.id,
477
+ title: n.title,
478
+ total: e.length,
479
+ index: s,
480
+ playing: c,
481
+ done: l,
482
+ visited: {
483
+ nodes: t,
484
+ edges: r,
485
+ edgeList: a
486
+ },
487
+ current: d,
488
+ progress: l ? 1 : i() ? 0 : Math.min(1, u / g),
489
+ manual: i(),
490
+ stepMs: g,
491
+ stepStartMs: f,
492
+ linkNodes: !!n.linkNodes,
493
+ down: $e(n)
494
+ };
495
+ }
496
+ };
497
+ }
498
+ function nt(e, t, n, r, i = 60, a = O) {
499
+ if (!n.width || !n.height) return null;
500
+ let o = e.node === void 0 ? e.edge ? [e.edge.from, e.edge.to] : [] : [e.node], s = o.map((e) => r.get(e));
501
+ if (s.length === 0 || s.some((e) => !e)) return null;
502
+ e.at !== void 0 && r.has(e.at) && !o.includes(e.at) && s.push(r.get(e.at));
503
+ let c = {
504
+ x: n.x || 0,
505
+ y: n.y || 0,
506
+ width: n.width,
507
+ height: n.height
508
+ }, l = g(s, c, {
509
+ padding: i,
510
+ maxZoom: Math.max(1, t.zoom),
511
+ minZoom: a
512
+ }), u = Math.min(i, c.width / 4, c.height / 4);
513
+ return J(s, t, c, u) && t.zoom >= l.zoom - .001 ? null : l;
514
+ }
515
+ // ../explorer/outage-scenario.js
516
+ function rt(e, t) {
517
+ if (!e) return [];
518
+ let n = new Map(t.map((e) => [e.id, e])), r = /* @__PURE__ */ new Set();
519
+ for (let t of [...e.down, ...e.hits.keys()]) {
520
+ let e = n.get(t);
521
+ e && r.add(e.type === "external" ? h(e) : e.type);
522
+ }
523
+ return [...r];
524
+ }
525
+ var it = 3, at = " (in the visitor's browser)";
526
+ function ot(e) {
527
+ if (e.length < 2) return e.join("");
528
+ let t = e.some((e) => e.includes(" and ")) ? ", and " : " and ";
529
+ return `${e.slice(0, -1).join(", ")}${t}${e[e.length - 1]}`;
530
+ }
531
+ function st(e) {
532
+ let t = /* @__PURE__ */ new Map();
533
+ for (let n of e) t.has(n.type) || t.set(n.type, []), t.get(n.type).push(n);
534
+ return ot([...t].sort(([e, t], [n, r]) => r.length - t.length || T(e) - T(n) || e.localeCompare(n)).map(([e, t]) => {
535
+ let n = q(e, t.length);
536
+ if (t.length > it) {
537
+ let e = t.filter((e) => e.browser).length;
538
+ return `${t.length} ${n}${e === t.length ? at : e ? ` (${e} in the visitor's browser)` : ""}`;
539
+ }
540
+ return `the ${n} ${ot(t.map((e) => `${e.label}${e.browser ? at : ""}`))}`;
541
+ }));
542
+ }
543
+ function ct(e, t, n) {
544
+ let r = new Map(t.map((e) => [e.id, e])), i = String(e.label || e.id), a = o([e.id], t, n), s = (e) => (t) => a.hits.has(t.id) && a.hits.get(t.id).when === e, c = new Map(re(e, t, n).map((e) => [e.when, e.types.flatMap((e) => e.items).filter(s(e.when)).map((e) => ({
545
+ ...e,
546
+ browser: a.hits.get(e.id).browser
547
+ }))])), l = [
548
+ `${i} is down.`,
549
+ e.breaks ? String(e.breaks) : "",
550
+ a.groups.length ? "" : "Nothing on the map uses it."
551
+ ].filter(Boolean).join(" "), u = [{
552
+ node: e.id,
553
+ text: l
554
+ }];
555
+ for (let t of a.groups) {
556
+ let n = c.get(t.when) || [], i = new Set(n.map((e) => e.id)), o = t.ids.filter((e) => !i.has(e)).map((e) => {
557
+ let t = r.get(e);
558
+ return {
559
+ id: e,
560
+ label: String(t.label || e),
561
+ type: t.type,
562
+ browser: a.hits.get(e).browser
563
+ };
564
+ }), s;
565
+ s = n.length ? `${t.title}: ${st(n)}.${o.length ? ` Through ${n.length === 1 ? "it" : "them"}: ${st(o)}.` : ""}` : `${t.title}, through what uses it: ${st(o)}.`, u.push(n.length ? {
566
+ edge: {
567
+ from: n[0].id,
568
+ to: e.id,
569
+ kind: "calls"
570
+ },
571
+ text: s
572
+ } : {
573
+ node: t.ids[0],
574
+ text: s
575
+ });
576
+ }
577
+ return {
578
+ id: `outage-${e.id}`,
579
+ title: `${i} is down`,
580
+ down: [e.id],
581
+ steps: u
582
+ };
583
+ }
584
+ // ../explorer/scenario-list-model.js
585
+ var X = (e) => Array.isArray(e) ? e : [], Z = (e, t) => `${e} ${t}${e === 1 ? "" : "s"}`, lt = (e) => String(e ?? "").replace(/[^A-Za-z0-9_-]+/g, "_") || "_", ut = (e) => String(e.id).replace(/^persona-/, ""), dt = (e) => e.codeLabel || e.label || ut(e);
586
+ function ft(e, t, n) {
587
+ let r = new Set([
588
+ "add",
589
+ "change",
590
+ "remove"
591
+ ].flatMap((e) => X(n?.edges?.[e]).map(U))), i = (t) => (e.find((e) => e.id === t) || { label: t }).label || t, a = [];
592
+ for (let n of [...G, "edit"]) {
593
+ for (let t of e.filter((e) => e.mark === n)) a.push({
594
+ kind: "node",
595
+ key: t.id,
596
+ mark: n,
597
+ word: W[n],
598
+ name: String(t.label ?? t.id),
599
+ type: String(t.type ?? "")
600
+ });
601
+ for (let e of t.filter((e) => e.mark === n && r.has(U(e)))) a.push({
602
+ kind: "edge",
603
+ key: U(e),
604
+ mark: n,
605
+ word: W[n],
606
+ name: `${i(e.from)} → ${i(e.to)}`,
607
+ type: String(e.kind || "ownership")
608
+ });
609
+ }
610
+ return a;
611
+ }
612
+ function pt(e) {
613
+ let t = [], n = (e) => {
614
+ typeof e == "string" && e && !t.includes(e) && t.push(e);
615
+ };
616
+ n(e?.actor);
617
+ for (let t of X(e?.steps)) n(t?.actor);
618
+ return t;
619
+ }
620
+ function mt(e, t = {}) {
621
+ let n = t.notChecked || "Not checked";
622
+ return !e || e.state === "none" ? null : e.state === "pending" ? {
623
+ words: "Checking…",
624
+ state: "",
625
+ tone: "pending"
626
+ } : e.state === "unchecked" ? {
627
+ words: `${n}: ${e.why || "nothing to ask"}`,
628
+ state: "",
629
+ tone: "unchecked"
630
+ } : e.state === "unavailable" ? {
631
+ words: `${n}: the checker did not answer${e.why ? ` (${e.why})` : ""}`,
632
+ state: "",
633
+ tone: "unavailable"
634
+ } : e.mismatch ? {
635
+ words: e.state === "refused" ? `Expected allowed, was refused${e.reason ? `: ${e.reason}` : ""}` : "Expected refused, was allowed",
636
+ state: "failure",
637
+ tone: "mismatch"
638
+ } : e.state === "refused" ? {
639
+ words: `Refused: ${e.reason || "no reason given"}`,
640
+ state: e.expect === "refused" ? "success" : "failure",
641
+ tone: "refused"
642
+ } : {
643
+ words: "Allowed",
644
+ state: "success",
645
+ tone: "allowed"
646
+ };
647
+ }
648
+ function ht(e, t) {
649
+ return X(e.steps).map((n, r) => {
650
+ let i = n && n.actor || e.actor || null, a = "", o = "", s = [];
651
+ if (n && n.edge) {
652
+ a = `${t.label(n.edge.from)} → ${t.label(n.edge.to)}`, s = [
653
+ `edge:${U(n.edge)}`,
654
+ `node:${n.edge.from}`,
655
+ `node:${n.edge.to}`
656
+ ];
657
+ let e = t.edges.find((e) => U(e) === U(n.edge));
658
+ e && e.mark && e.mark !== "none" && t.changeKeys.has(`edge:${U(e)}`) && (o = e.mark);
659
+ } else if (n && n.node !== void 0) {
660
+ a = t.label(n.node), s = [`node:${n.node}`];
661
+ let e = t.nodes.find((e) => e.id === n.node);
662
+ e && e.mark && e.mark !== "none" && (o = e.mark);
663
+ }
664
+ let c = t.verdicts ? mt(t.verdicts[r], t.words) : null, l = !!t.hidden && s.some((e) => e.startsWith("node:") && t.hidden(e.slice(5)));
665
+ return {
666
+ index: r,
667
+ number: r + 1,
668
+ actor: i,
669
+ actorLabel: i ? t.personaLabel(i) : "",
670
+ where: a,
671
+ mark: o,
672
+ markWord: o && W[o] || "",
673
+ text: String((n && n.text) ?? ""),
674
+ verdict: i ? c : null,
675
+ layerOff: l,
676
+ touched: s
677
+ };
678
+ });
679
+ }
680
+ function gt(e, t) {
681
+ let n = [
682
+ e.where,
683
+ e.markWord,
684
+ e.layerOff ? "on a layer that is off" : ""
685
+ ].filter(Boolean).join(", ");
686
+ return [
687
+ `Step ${e.number} of ${t}${e.actorLabel ? `, as ${e.actorLabel}` : ""}${n ? `: ${n}` : ""}.`,
688
+ e.text,
689
+ e.verdict ? `${e.verdict.words}${/[.!?…]$/.test(e.verdict.words) ? "" : "."}` : ""
690
+ ].filter(Boolean).join(" ");
691
+ }
692
+ function _t({ snap: e, nodes: t, edges: n, words: r = {} }) {
693
+ let i = e.current || {}, a = (e) => String((t.find((t) => t.id === e) || { label: e }).label ?? e), o = i.actor ? t.find((e) => e.type === "persona" && (e.id === `persona-${i.actor}` || e.id === i.actor)) : null, s = "", c = "";
694
+ if (i.edge) {
695
+ s = `${a(i.edge.from)} → ${a(i.edge.to)}`;
696
+ let e = n.find((e) => U(e) === U(i.edge));
697
+ e && e.mark && e.mark !== "none" && (c = e.mark);
698
+ } else if (i.node !== void 0) {
699
+ s = a(i.node);
700
+ let e = t.find((e) => e.id === i.node);
701
+ e && e.mark && e.mark !== "none" && (c = e.mark);
702
+ }
703
+ let l = i.actor ? mt(e.verdict, r) : null;
704
+ return gt({
705
+ number: e.index + 1,
706
+ actorLabel: i.actor ? o ? dt(o) : String(i.actor) : "",
707
+ where: s,
708
+ markWord: c && W[c] || "",
709
+ text: String(i.text ?? ""),
710
+ verdict: l
711
+ }, e.total);
712
+ }
713
+ function vt(e) {
714
+ let t = (t) => e.filter((e) => e.verdict && e.verdict.tone === t).length;
715
+ return [
716
+ [t("allowed"), "allowed"],
717
+ [t("refused"), "refused"],
718
+ [t("mismatch"), "not as expected"]
719
+ ].filter(([e]) => e > 0).map(([e, t]) => `${e} ${t}`).join(" · ");
720
+ }
721
+ function yt({ scenarios: e, nodes: t, edges: n, proposal: r = null, verdicts: i = null, seen: a = null, words: o = {}, hidden: s = null }) {
722
+ let c = X(e), l = t.filter((e) => e.type === "persona"), u = new Map(l.map((e) => [ut(e), e])), d = (e) => String((t.find((t) => t.id === e) || { label: e }).label ?? e), f = (e) => u.has(e) ? dt(u.get(e)) : String(e), p = ft(t, n, r), m = new Set(p.map((e) => `${e.kind}:${e.key}`)), h = new Set(X(a?.played)), g = new Set(X(a?.read)), _ = c.map((e, r) => {
723
+ let a = i && i.get(e.id), c = ht(e, {
724
+ nodes: t,
725
+ edges: n,
726
+ changeKeys: m,
727
+ verdicts: a || null,
728
+ words: o,
729
+ label: d,
730
+ personaLabel: f,
731
+ hidden: s
732
+ }), l = new Set(c.flatMap((e) => e.touched).filter((e) => m.has(e))), u = c.length, p = [Z(u, "step")];
733
+ m.size > 0 && p.push(`walks ${l.size} of ${Z(m.size, "change")}`);
734
+ let _ = vt(c);
735
+ return {
736
+ index: r,
737
+ id: String(e.id ?? ""),
738
+ key: `${r}-${lt(e.id)}`,
739
+ title: String(e.title ?? e.id ?? ""),
740
+ actors: pt(e),
741
+ steps: c,
742
+ stepCount: u,
743
+ summary: p.join(" · "),
744
+ verdictSummary: _,
745
+ seen: h.has(String(e.id)) ? "played" : g.has(String(e.id)) ? "read" : ""
746
+ };
747
+ }), v = [...u.keys()];
748
+ for (let e of _) for (let t of e.actors) v.includes(t) || v.push(t);
749
+ let y = [];
750
+ for (let e of v) {
751
+ let t = _.filter((t) => t.actors.includes(e));
752
+ if (!t.length) continue;
753
+ let n = f(e);
754
+ y.push({
755
+ key: lt(e),
756
+ persona: e,
757
+ label: n,
758
+ anyone: !1,
759
+ heading: `${n} · ${Z(t.length, "scenario")}`,
760
+ scenarios: t
761
+ });
762
+ }
763
+ let b = _.filter((e) => e.actors.length === 0);
764
+ b.length && y.push({
765
+ key: "anyone",
766
+ persona: null,
767
+ label: "Anyone",
768
+ anyone: !0,
769
+ heading: `Anyone · ${Z(b.length, "scenario")}`,
770
+ scenarios: b
771
+ });
772
+ let x = new Set(_.flatMap((e) => e.actors)), S = _.length ? l.filter((e) => !x.has(ut(e))).map(dt) : [], C = _.filter((e) => e.seen === "played").length;
773
+ return {
774
+ total: _.length,
775
+ personaCount: y.filter((e) => !e.anyone).length,
776
+ groups: y,
777
+ notInAny: S,
778
+ coverage: S.length ? `Not in any scenario: ${S.join(", ")}` : "",
779
+ playedLine: _.length && C ? `${C} of ${_.length} ${_.length === 1 ? "scenario" : "scenarios"} played` : ""
780
+ };
781
+ }
782
+ function bt(e, t) {
783
+ let n = [Z(e, "change")];
784
+ return t.total > 0 && n.push(`${Z(t.total, "scenario")}${t.personaCount > 0 ? ` for ${Z(t.personaCount, "persona")}` : ""}`), n.join(" · ");
785
+ }
786
+ function xt(e, t, n) {
787
+ return `Opened ${e}: ${bt(t, n).replace(" · ", ", ")}.`;
788
+ }
789
+ var St = (e, t, n = "") => `cornfield.seen.${e || "checkout"}/${t || ""}@${n || ""}`;
790
+ function Ct(e, t) {
791
+ let n = {
792
+ played: [],
793
+ read: []
794
+ };
795
+ try {
796
+ let r = e && e.getItem(t);
797
+ if (!r) return n;
798
+ let i = JSON.parse(r), a = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string").slice(0, 200) : [];
799
+ return {
800
+ played: a(i && i.played),
801
+ read: a(i && i.read)
802
+ };
803
+ } catch {
804
+ return n;
805
+ }
806
+ }
807
+ function wt(e, t, n, r, i = null) {
808
+ let a = i ? {
809
+ played: [...X(i.played)],
810
+ read: [...X(i.read)]
811
+ } : Ct(e, t), o = String(n);
812
+ r === "played" ? (a.played.includes(o) || a.played.push(o), a.read = a.read.filter((e) => e !== o)) : !a.read.includes(o) && !a.played.includes(o) && a.read.push(o);
813
+ try {
814
+ e && e.setItem(t, JSON.stringify(a));
815
+ } catch {}
816
+ return a;
817
+ }
818
+ // ../explorer/engine/player.js
819
+ var Tt = 250, Et = 140;
820
+ function Dt(e, n) {
821
+ let { state: r } = e;
822
+ if (!n || r.view === "dataflow" || r.view === "house") return [];
823
+ let i = t(r), a = (e) => i[e] !== !1, o = n.type;
824
+ if (o === "root" || D(r, n)) return [];
825
+ let s = y(r, n);
826
+ if (s) return a(s) ? [] : [s];
827
+ if (o === "core") return [...a("core") ? [] : ["core"], ...i.pkg || i.atom ? [] : ["pkg"]];
828
+ if (o === "store") return ["flow", "store"].filter((e) => !a(e));
829
+ if (o === "rom") return ["rom", "flow"].filter((e) => !a(e));
830
+ if (o === "floor" || o === "room") return a("house") ? [] : ["house"];
831
+ let c = o === "external" ? h(n) : o;
832
+ return a(c) ? [] : [c];
833
+ }
834
+ var Ot = (e) => (Array.isArray(e?.steps) ? e.steps : []).flatMap((e) => e?.edge ? [e.edge.from, e.edge.to] : e && e.node !== void 0 ? [e.node] : []), kt = "input, textarea, select, [contenteditable=\"\"], [contenteditable=\"true\"]", At = (e) => !!(e && e.closest && e.closest(kt));
835
+ function jt(e, t) {
836
+ let n = new Set(e.map((e) => e.id)), r = (t) => (e.find((e) => e.id === t) || { label: t }).label, i = t.filter((e) => (e.kind || e.dashed) && n.has(e.from) && n.has(e.to) && e.from !== e.to);
837
+ if (!i.length) return null;
838
+ let a = /* @__PURE__ */ new Map();
839
+ for (let e of i) a.has(e.from) || a.set(e.from, []), a.get(e.from).push(e);
840
+ let o = [...a.keys()].sort((e, t) => a.get(t).length - a.get(e).length || e.localeCompare(t))[0], s = [{
841
+ node: o,
842
+ text: `It starts at ${r(o)}.`
843
+ }], c = /* @__PURE__ */ new Set([o]), l = o;
844
+ for (let e = 0; e < 3; e++) {
845
+ let e = (a.get(l) || []).find((e) => !c.has(e.to));
846
+ if (!e) break;
847
+ let t = {
848
+ from: e.from,
849
+ to: e.to,
850
+ ...e.kind ? { kind: e.kind } : {},
851
+ ...e.kind === "flow" ? { flow: e.flow } : {}
852
+ };
853
+ s.push({
854
+ edge: t,
855
+ text: `${r(e.from)} ${e.label || e.kind || "uses"} ${r(e.to)}.`
856
+ }), s.push({
857
+ node: e.to,
858
+ text: `Now at ${r(e.to)}.`
859
+ }), c.add(e.to), l = e.to;
860
+ }
861
+ return s.length < 2 ? null : {
862
+ id: "demo",
863
+ title: "A walk over the map",
864
+ steps: s
865
+ };
866
+ }
867
+ function Mt(e, t, n, r = {}) {
868
+ let { state: i } = e, a = null, c = null, l = "", u = null, f = !1, p = -1, h = null, g = -1, _ = null, v = null, y = null, x = null, C = /* @__PURE__ */ new Set(), w = [], T = (t) => {
869
+ for (let e of [...C]) e(t);
870
+ e.emit("scenario:player", t);
871
+ }, ee = () => r.seat || (i.canvas ? i.canvas.parentElement : null), D = r.hear || e.root, O = () => e.map.render();
872
+ function k() {
873
+ let t = e.active();
874
+ return t && t !== e.doc.body && !t.closest?.(".hx-player") && !t.closest?.("#review-column") && t !== i.canvas ? t : null;
875
+ }
876
+ function A() {
877
+ let t = e.active();
878
+ return !!t && t !== e.doc.body && !At(t);
879
+ }
880
+ function j() {
881
+ let t = _;
882
+ _ = null;
883
+ let n = (t) => !t || !t.isConnected || t.hidden || t.disabled || t.closest("[hidden]") ? !1 : (t.focus(), e.active() === t);
884
+ n(v && v()) || n(t) || n(i.canvas);
885
+ }
886
+ function M(t) {
887
+ t && Array.isArray(t.down) && t.down.length && rt(o(t.down, i.nodes, i.edges), i.nodes).forEach((t) => {
888
+ d(i, t) || be(e, t, !0, { scenario: !0 });
889
+ });
890
+ }
891
+ function N(t) {
892
+ let n = new Map(i.nodes.map((e) => [e.id, e])), r = [];
893
+ for (let i of Ot(t)) for (let t of Dt(e, n.get(i))) r.includes(t) || r.push(t);
894
+ if (!r.length) return;
895
+ for (let t of r) be(e, t, !0, { scenario: !0 });
896
+ let a = r.map((e) => (Ee.find((t) => t.key === e) || (i.projectLayers || []).find((t) => t.key === e) || { label: e }).label);
897
+ E(e, `Turned on ${a.length > 1 ? `${a.slice(0, -1).join(", ")} and ${a[a.length - 1]}` : a[0]} to show this scenario's steps.`);
898
+ }
899
+ function P(t, r = {}) {
900
+ let i = k(), o = A() && r.focus !== !1;
901
+ I({ keepChecks: !0 }), _ = i;
902
+ let s = r.stepMs ?? W();
903
+ if (a = tt(t, {
904
+ stepMs: s,
905
+ maxFrameMs: Tt
906
+ }), Number.isFinite(r.step) && r.step > 0 && a.goTo(r.step), U(s), n.open(t, () => {
907
+ R(), O();
908
+ }), M(t), N(t), r.autoplay !== !1 && !(r.step > 0) && a.play(), R(!0), O(), e.map.ensureFlowLoop(), o && c) {
909
+ let e = c.querySelector("[data-action=scenario-toggle]");
910
+ e && !e.disabled ? e.focus() : c.querySelector("[data-action=scenario-next]")?.focus();
911
+ }
912
+ return a;
913
+ }
914
+ function F(e) {
915
+ let t = i.nodes.find((t) => t.id === e);
916
+ return !t || t.type !== "external" || t.kind !== "cloud" ? null : P(ct(t, i.nodes, i.edges));
917
+ }
918
+ function I({ keepChecks: t = !1, closing: r = !1 } = {}) {
919
+ let o = !!a || !!i.scenario;
920
+ o && Te(e), a = null, u = null, l = "", i.scenario = null, t || n.close(), h &&= (h.disconnect(), null), c &&= (de(e, "player"), w.forEach((e) => e()), w = [], n.unmount(), c.remove(), null), o && (!t || r) && T(null);
921
+ }
922
+ function L() {
923
+ if (!a && !i.scenario) return;
924
+ let t = e.active(), n = !!c && c.contains(t) || !!t?.closest?.("#review-column");
925
+ I({
926
+ keepChecks: !!a && !!y && y(a.scenario().id),
927
+ closing: !0
928
+ }), e.touchScene(), O();
929
+ let r = e.active();
930
+ n || !r || r === e.doc.body ? j() : _ = null;
931
+ }
932
+ function R(t = !1) {
933
+ if (!a) return !1;
934
+ let r = n.decorate(a.snapshot(), a.scenario());
935
+ i.scenario = r;
936
+ let o = `${r.index}|${r.playing}|${r.done}|${r.stepStartMs}|${r.stepMs}|${r.manual}|${n.version()}`, s = t || o !== l;
937
+ if (s) {
938
+ let n = t || o.split("|")[0] !== l.split("|")[0];
939
+ l = o, e.touchScene(), n && (f = !1, z(r));
940
+ }
941
+ return te(r), s && T({
942
+ id: r.id,
943
+ index: r.index,
944
+ total: r.total,
945
+ done: r.done,
946
+ playing: r.playing,
947
+ checks: n.version()
948
+ }), s;
949
+ }
950
+ function z(t) {
951
+ let n = /* @__PURE__ */ new Map();
952
+ i.nodes.forEach((t) => {
953
+ e.map.isNodeVisible(t) && n.set(t.id, t);
954
+ });
955
+ let r = b(e);
956
+ p = c ? c.offsetHeight : 0;
957
+ let a = nt({
958
+ node: t.current.node,
959
+ edge: t.current.edge,
960
+ at: t.current.at,
961
+ text: t.current.text
962
+ }, i.camera, r, n, 60, e.map.getMinZoom());
963
+ a && (e.reducedMotion ? (Object.assign(i.camera, a), u = null, O()) : (u = {
964
+ to: a,
965
+ last: null
966
+ }, e.map.ensureFlowLoop()));
967
+ }
968
+ function B(e) {
969
+ if (!u) return;
970
+ let t = u.last === null ? 16 : Math.min(e - u.last, 100);
971
+ u.last = e;
972
+ let n = 1 - Math.exp(-t / Et), r = i.camera;
973
+ r.x += (u.to.x - r.x) * n, r.y += (u.to.y - r.y) * n, r.zoom += (u.to.zoom - r.zoom) * n, Math.abs(u.to.x - r.x) < .5 && Math.abs(u.to.y - r.y) < .5 && Math.abs(u.to.zoom - r.zoom) < .002 && (Object.assign(r, u.to), u = null);
974
+ }
975
+ let V = () => !!a && (a.isPlaying() || !!u);
976
+ function H(e) {
977
+ a && (a.tick(e), R(), B(e));
978
+ }
979
+ t.own(e.map.addFrameClient({
980
+ wants: V,
981
+ tick: H
982
+ }));
983
+ function U(t) {
984
+ let n = ee();
985
+ if (!n) return;
986
+ c = e.doc.createElement("div"), c.className = "hx-player glass", c.dataset.corn = "scenario-player", c.setAttribute("part", "scenario-player"), c.setAttribute("role", "region"), c.setAttribute("aria-label", "Scenario player"), c.innerHTML = `
987
+ <span class="hx-player-title hx-sr-only"></span>
988
+ <div class="hx-player-controls" role="group">
989
+ <button data-corn-kind="secondary" type="button" class="hx-btn hx-player-prev" data-action="scenario-prev" data-peek-ok><span class="hx-player-label"></span></button>
990
+ <button type="button" class="hx-btn hx-btn--active hx-player-toggle" data-action="scenario-toggle" data-peek-ok data-corn-kind="primary"><span class="hx-player-label"></span></button>
991
+ <button data-corn-kind="secondary" type="button" class="hx-btn hx-player-next" data-action="scenario-next" data-peek-ok><span class="hx-player-label"></span></button>
992
+ <button data-corn-kind="secondary" type="button" class="hx-btn hx-player-next-scenario" data-action="scenario-next-scenario" data-peek-ok hidden></button>
993
+ </div>
994
+ <p class="hx-player-text"><span class="hx-player-count" data-corn="count"></span><span class="hx-player-sep" aria-hidden="true"> · </span><span class="hx-player-who"></span><span class="hx-player-step"></span></p>
995
+ <span class="hx-player-says hx-sr-only" role="status" aria-live="polite"></span>
996
+ <div class="hx-player-side">
997
+ <select data-corn="control" class="hx-player-speed" data-action="scenario-speed" aria-label="Time for each step" title="Time for each step">${Ye.map((e) => `<option value="${s(String(e.value))}">${s(e.label)}</option>`).join("")}</select>
998
+ <button type="button" class="hx-close" data-action="scenario-close" aria-label="Close the scenario" data-corn-kind="icon">✕</button>
999
+ </div>
1000
+ <div class="hx-player-track" data-corn="scenario-track" aria-hidden="true"><span class="hx-player-fill" data-corn="scenario-fill"></span></div>`, m(c), c.querySelector(".hx-player-controls").setAttribute("aria-label", S(e, "steps")), c.querySelector(".hx-player-prev .hx-player-label").textContent = S(e, "previousStep"), c.querySelector(".hx-player-next .hx-player-label").textContent = S(e, "nextStep"), c.querySelector(".hx-player-next-scenario").textContent = S(e, "nextScenario");
1001
+ let o = (e) => {
1002
+ let t = e.target.closest("[data-action]");
1003
+ t && K(t.dataset.action);
1004
+ }, l = c.querySelector(".hx-player-speed"), u = (e) => G(e.target.value), d = c;
1005
+ d.addEventListener("click", o), l.value = String(t), l.addEventListener("change", u), w.push(() => {
1006
+ d.removeEventListener("click", o), l.removeEventListener("change", u);
1007
+ }), r.seat ? n.appendChild(c) : (e.ask("player:seat", c) !== !0 && n.appendChild(c), ue(e, "player", c), _e(e));
1008
+ let g = e.win && e.win.ResizeObserver;
1009
+ typeof g == "function" && (h = new g(() => {
1010
+ c && a && i.scenario && !f && c.offsetHeight !== p && z(a.snapshot());
1011
+ }), h.observe(c));
1012
+ }
1013
+ let W = () => Xe(e.store.get(Je));
1014
+ function G(t) {
1015
+ let n = Xe(t);
1016
+ e.store.set(Je, String(n)), a && (a.setSpeed(n), R(), O(), e.map.ensureFlowLoop());
1017
+ }
1018
+ function K(t) {
1019
+ if (a) {
1020
+ if (t === "scenario-close") return L();
1021
+ if (t === "scenario-next-scenario") {
1022
+ let e = x ? x(a.scenario().id) : null;
1023
+ e && P(e);
1024
+ } else {
1025
+ if (t === "scenario-toggle") {
1026
+ let t = a.snapshot();
1027
+ t.playing ? a.pause() : a.play(), E(e, t.playing ? "Paused" : t.done ? "Playing again" : t.index > 0 || t.progress > 0 ? "Resumed" : "Playing");
1028
+ } else if (t === "scenario-prev") a.prev();
1029
+ else if (t === "scenario-next") a.next();
1030
+ else return;
1031
+ R(), O(), e.map.ensureFlowLoop();
1032
+ }
1033
+ }
1034
+ }
1035
+ function te(t) {
1036
+ if (!c) return;
1037
+ let r = (e) => c.querySelector(e), a = (e, t) => {
1038
+ let n = r(e);
1039
+ n.textContent !== t && (n.textContent = t);
1040
+ };
1041
+ a(".hx-player-title", t.title), c.setAttribute("aria-label", `Scenario player: ${t.title}`), a(".hx-player-count", `${Math.min(t.index + 1, Math.max(t.total, 1))} of ${t.total}`);
1042
+ let o = t.current.actor ? Ne(je(i.nodes, t.current.actor)) || t.current.actor : "";
1043
+ a(".hx-player-who", o && !t.done ? `As ${o} · ` : ""), a(".hx-player-step", t.done ? "Played to the end" : t.current.text), c.dataset.done = String(!!t.done);
1044
+ let s = r("[data-action=scenario-toggle]");
1045
+ a("[data-action=scenario-toggle] .hx-player-label", t.playing ? S(e, "pause") : t.done ? S(e, "playAgain") : S(e, "play")), s.dataset.state = t.playing ? "playing" : t.done ? "done" : "paused", s.disabled = t.total === 0 || t.manual, s.title = t.manual ? "The time for each step is Manual: use Next" : "", r("[data-action=scenario-prev]").disabled = t.index === 0 && !t.done;
1046
+ let l = r("[data-action=scenario-next]");
1047
+ l.disabled = t.done || t.total === 0;
1048
+ let u = t.done && x ? x(t.id) : null;
1049
+ r("[data-action=scenario-next-scenario]").hidden = !u, l.hidden = !!u, a(".hx-player-says", t.done ? `${t.title}: played to the end.` : _t({
1050
+ snap: t,
1051
+ nodes: i.nodes,
1052
+ edges: i.edges,
1053
+ words: { notChecked: S(e, "notChecked") }
1054
+ }));
1055
+ let d = t.total ? Math.round((t.done ? t.total : t.index + t.progress) / t.total * 1e3) / 10 : 0;
1056
+ d !== g && (g = d, r(".hx-player-fill").style.width = `${d}%`), n.paint(c, t);
1057
+ }
1058
+ function ne() {
1059
+ return e.ask("popup:open") === !0 || !!e.root.querySelector("[data-corn=\"dialog-scrim\"]:not([hidden]), .hx-mockup-dialog");
1060
+ }
1061
+ t.listen(D, "keydown", (e) => {
1062
+ if (e.key === "Escape" && !e.defaultPrevented && !e.ctrlKey && !e.metaKey && !e.altKey && a && !At(e.target) && !ne()) {
1063
+ e.preventDefault(), L();
1064
+ return;
1065
+ }
1066
+ if (!a || e.defaultPrevented || e.ctrlKey || e.metaKey || e.altKey || At(e.target) || (e.key === " " || e.code === "Space") && e.target.closest?.("#review-column")) return;
1067
+ let t = e.key === " " || e.code === "Space" ? "scenario-toggle" : e.key === "ArrowLeft" ? "scenario-prev" : e.key === "ArrowRight" ? "scenario-next" : null;
1068
+ t && (e.preventDefault(), K(t));
1069
+ }), t.listen(D, "keyup", (e) => {
1070
+ a && (e.key === " " || e.code === "Space") && !At(e.target) && e.preventDefault();
1071
+ }), t.own(me(e, () => {
1072
+ a && i.scenario && z(a.snapshot());
1073
+ }));
1074
+ for (let n of [
1075
+ "pointerdown",
1076
+ "wheel",
1077
+ "touchstart",
1078
+ "mousedown"
1079
+ ]) t.listen(e.root, n, (e) => {
1080
+ e.target === i.canvas && (u = null, f = !0);
1081
+ }, {
1082
+ passive: !0,
1083
+ capture: !0
1084
+ });
1085
+ return t.on("scenario:clear", () => I()), t.own(() => {
1086
+ I({ keepChecks: !1 }), C.clear();
1087
+ }), {
1088
+ play: P,
1089
+ stop: L,
1090
+ clear: I,
1091
+ tick: H,
1092
+ playOutage: F,
1093
+ getPlayer: () => a,
1094
+ bar: () => c,
1095
+ wantsFrames: V,
1096
+ onChange(e) {
1097
+ return C.add(e), () => C.delete(e);
1098
+ },
1099
+ setCloseFocus(e) {
1100
+ v = typeof e == "function" ? e : null;
1101
+ },
1102
+ setNextScenario(e) {
1103
+ x = typeof e == "function" ? e : null;
1104
+ },
1105
+ setKeepChecksOnClose(e) {
1106
+ y = typeof e == "function" ? e : null;
1107
+ },
1108
+ demo(e = !0) {
1109
+ if (!e) return !1;
1110
+ let t = jt(i.nodes, i.edges);
1111
+ return t ? (P(t), !0) : (console.warn("scenario-demo: the map has none of the nodes the demo walks over"), !1);
1112
+ }
1113
+ };
1114
+ }
1115
+ // ../explorer/engine/proposal.js
1116
+ var Q = (e) => e.slot("proposal", () => ({
1117
+ pinnedSource: !1,
1118
+ listing: null,
1119
+ listingProblem: null,
1120
+ forgeProblem: null,
1121
+ listingAt: 0,
1122
+ watchers: /* @__PURE__ */ new Set(),
1123
+ openToken: 0,
1124
+ message: null
1125
+ })), Nt = (e) => e.proposal && typeof e.proposal.title == "string" && e.proposal.title || e.proposalSlug || "Proposal", Pt = (e) => e.ask("proposal:specs-list") === !1 ? null : {
1126
+ label: S(e, "openSpecsList"),
1127
+ way: "specs"
1128
+ };
1129
+ function Ft(e) {
1130
+ let t = Q(e);
1131
+ return {
1132
+ entries: t.listing,
1133
+ problem: t.listingProblem,
1134
+ forgeProblem: t.forgeProblem,
1135
+ at: t.listingAt
1136
+ };
1137
+ }
1138
+ async function It(e) {
1139
+ let t = Q(e), n = Oe(e);
1140
+ try {
1141
+ let r;
1142
+ try {
1143
+ r = await n("/proposals", { cache: "no-store" });
1144
+ } catch {
1145
+ throw Error(e.offline() ? "You are offline." : "cornfield could not be reached. Check that it is still running.");
1146
+ }
1147
+ if (!r.ok) throw Error(`The server could not list them (error ${r.status}).`);
1148
+ let i;
1149
+ try {
1150
+ i = await r.json();
1151
+ } catch {
1152
+ throw Error("cornfield sent a list this page could not read.");
1153
+ }
1154
+ if (!Array.isArray(i)) throw Error("cornfield sent something that is not a list of proposals.");
1155
+ t.listing = i, t.listingProblem = null;
1156
+ let a = r.headers.get("X-Proposals-Forge-Error");
1157
+ t.forgeProblem = a ? decodeURIComponent(a) : null;
1158
+ } catch (e) {
1159
+ t.listing = null, t.forgeProblem = null, t.listingProblem = e.message || "cornfield did not answer.";
1160
+ }
1161
+ t.listingAt = Date.now(), e.emit("proposal:listing");
1162
+ for (let e of [...t.watchers]) e();
1163
+ return t.listing;
1164
+ }
1165
+ function $(e, t, n = !1, r = []) {
1166
+ let i = Q(e);
1167
+ i.message = {
1168
+ text: t,
1169
+ isError: n,
1170
+ ways: r
1171
+ }, e.emit("proposal:message", i.message);
1172
+ }
1173
+ var Lt = (e) => Q(e).message;
1174
+ async function Rt(e, t, n = null) {
1175
+ let r = Q(e), i = ++r.openToken;
1176
+ if (!ce(t)) {
1177
+ let r = Y(t);
1178
+ return $(e, r, !0, []), e.emit("proposal:failed", {
1179
+ slug: t,
1180
+ source: n,
1181
+ status: 0,
1182
+ notFound: !1,
1183
+ message: r
1184
+ }), !1;
1185
+ }
1186
+ $(e, `Opening ${t} …`);
1187
+ try {
1188
+ let r;
1189
+ try {
1190
+ r = await Oe(e)(`/proposals/${encodeURIComponent(t)}.json${n ? `?source=${encodeURIComponent(n)}` : ""}`, { cache: "no-store" });
1191
+ } catch {
1192
+ throw Error(e.offline() ? `${t} could not be opened: you are offline.` : `${t} could not be opened: cornfield could not be reached.`);
1193
+ }
1194
+ if (!r.ok) {
1195
+ let i = "";
1196
+ try {
1197
+ i = (await r.json()).error || "";
1198
+ } catch {}
1199
+ let a = r.status === 401 || r.status === 403;
1200
+ a && e.emit("auth", {
1201
+ status: r.status,
1202
+ during: "proposal"
1203
+ });
1204
+ let o = a ? r.status === 403 ? "this is for the project's maintainers." : "you are not signed in." : `the server had a problem (error ${r.status}).`, s = Error(r.status === 404 ? B(t, n) : `${t} could not be opened: ${typeof i == "string" && i ? i : o}`);
1205
+ throw s.notFound = r.status === 404, s.status = r.status, s;
1206
+ }
1207
+ let i = r.headers.get("X-Proposal-Source"), a;
1208
+ try {
1209
+ a = await r.json();
1210
+ } catch {
1211
+ throw Error(`${t} could not be opened: cornfield sent a file this page could not read.`);
1212
+ }
1213
+ let o = r.headers.get("X-Proposal-Sha256");
1214
+ return !e.ended && (zt(e, a, {
1215
+ slug: t,
1216
+ source: n || (i ? decodeURIComponent(i) : null),
1217
+ pinSource: !!n,
1218
+ view: "diff",
1219
+ fit: !0,
1220
+ sha256: o
1221
+ }), E(e, [e.ask("changes:opened-line", Nt(e.state)), ye(e)].filter(Boolean).join(" ")), !0);
1222
+ } catch (a) {
1223
+ if (e.ended) return !1;
1224
+ console.error("Opening the proposal failed", a);
1225
+ let o = a.message || `${t} could not be opened.`;
1226
+ if ($(e, o, !0, a.notFound ? [Pt(e)].filter(Boolean) : [{
1227
+ label: "Retry",
1228
+ way: "retry",
1229
+ slug: t,
1230
+ source: n
1231
+ }, {
1232
+ label: "Close",
1233
+ way: "close"
1234
+ }]), a.notFound && i === r.openToken) {
1235
+ await It(e);
1236
+ let a = new Set((Array.isArray(r.listing) ? r.listing : []).map((e) => e && e.source));
1237
+ i === r.openToken && (o = B(t, n, a), $(e, o, !0, [...N(r.listing, t, n).map((e) => ({
1238
+ label: e.label,
1239
+ way: "open",
1240
+ slug: e.slug,
1241
+ source: e.source
1242
+ })), Pt(e)].filter(Boolean)));
1243
+ }
1244
+ return i === r.openToken && e.emit("proposal:failed", {
1245
+ slug: t,
1246
+ source: n,
1247
+ status: a.status || 0,
1248
+ notFound: !!a.notFound,
1249
+ message: o
1250
+ }), !1;
1251
+ }
1252
+ }
1253
+ function zt(e, t, { slug: n = null, source: r = null, pinSource: i = !1, view: a, fit: o = !0, sha256: s = null } = {}) {
1254
+ let { state: c } = e;
1255
+ c.proposal = t, we(e), c.proposalSlug = n, c.proposalSource = r, c.proposalSha256 = typeof s == "string" && /^[0-9a-f]{64}$/.test(s) ? s : null, Q(e).pinnedSource = i, a ? c.proposalView = a : V.includes(c.proposalView) || (c.proposalView = "diff");
1256
+ let l = e.ask("proposal:effective", t);
1257
+ Ht(e, l === void 0 ? t : l, { fit: o }), Bt(e, "opened");
1258
+ }
1259
+ function Bt(e, t) {
1260
+ let { state: n } = e;
1261
+ e.emit("proposal", {
1262
+ change: t,
1263
+ slug: n.proposalSlug || null,
1264
+ source: n.proposalSource || null,
1265
+ pinSource: Q(e).pinnedSource,
1266
+ view: n.proposalView,
1267
+ proposal: n.proposal || null
1268
+ });
1269
+ }
1270
+ function Vt(e) {
1271
+ let t = !!e.state.proposal;
1272
+ e.emit("proposal:draw", { open: t }), e.emit("proposal:bar", { open: t });
1273
+ }
1274
+ function Ht(e, t, { fit: n = !1 } = {}) {
1275
+ let { state: r } = e;
1276
+ if (t === void 0) {
1277
+ let n = e.ask("proposal:effective", r.proposal);
1278
+ t = n === void 0 ? r.proposal : n;
1279
+ }
1280
+ let i = {
1281
+ nodes: r.baseNodes,
1282
+ edges: r.baseEdges
1283
+ }, a;
1284
+ r.effectiveProposal = t;
1285
+ try {
1286
+ r.proposalErrors = ae(i, t).errors, a = oe(i, t), e.emit("proposal:mark", {
1287
+ applied: a,
1288
+ effective: t,
1289
+ proposal: r.proposal
1290
+ });
1291
+ } catch (e) {
1292
+ r.proposalErrors = [{
1293
+ path: "",
1294
+ message: `This proposal could not be read: ${e.message}`
1295
+ }], a = {
1296
+ nodes: r.baseNodes.map((e) => ({
1297
+ ...e,
1298
+ mark: "none"
1299
+ })),
1300
+ edges: r.baseEdges.map((e) => ({
1301
+ ...e,
1302
+ mark: "none"
1303
+ }))
1304
+ };
1305
+ }
1306
+ Gt(e, a.nodes, a.edges), Vt(e), Se(e), n && Kt(e), e.map.render(), e.map.ensureFlowLoop();
1307
+ }
1308
+ function Ut(e) {
1309
+ let { state: t } = e;
1310
+ return e.ask("proposal:before-close") !== !1 && (t.proposal = null, t.effectiveProposal = null, t.proposalSlug = null, t.proposalSource = null, t.proposalSha256 = null, t.proposalErrors = [], xe(e), Gt(e, t.baseNodes.map((e) => ({ ...e })), t.baseEdges), e.map.fitGraphToViewport(e.map.fitPadding()), e.map.render(), e.map.ensureFlowLoop(), Vt(e), Bt(e, "closed"), !0);
1311
+ }
1312
+ function Wt(e, t, { quiet: n = !1 } = {}) {
1313
+ let { state: r } = e;
1314
+ r.proposal && V.includes(t) && r.proposalView !== t && (r.proposalView = t, e.touchScene(), r.selectedNode && !e.map.isNodeVisible(r.selectedNode) && w(e, { source: "api" }), t === "diff" && Kt(e), e.map.render(), Vt(e), Bt(e, "view"), n || E(e, j(t)));
1315
+ }
1316
+ function Gt(e, t, n) {
1317
+ let { state: r } = e, i = r.selectedNode ? r.selectedNode.id : null;
1318
+ if (e.ask("map:set", {
1319
+ nodes: t,
1320
+ edges: n
1321
+ }) || (r.mapNodes = t, r.mapEdges = n, r.nodes = t, r.edges = n), r.selectedEdge = null, i) {
1322
+ let t = r.nodes.find((e) => e.id === i);
1323
+ t ? r.selectedNode = t : w(e, { source: "api" });
1324
+ }
1325
+ e.touchScene();
1326
+ }
1327
+ function Kt(e) {
1328
+ let { state: t, map: n } = e, { touched: r } = l(t.nodes, e.viewEdges()), i = t.nodes.filter((e) => r.has(e.id) && n.isNodeVisible(e)), a = b(e), o = {
1329
+ padding: n.fitPadding(),
1330
+ maxZoom: 1,
1331
+ minZoom: n.getMinZoom()
1332
+ }, s = H(i, a, {
1333
+ ...o,
1334
+ minZoom: Math.max(o.minZoom, ie)
1335
+ }), c = i.length ? g(s, a, o) : null;
1336
+ c ? (Object.assign(t.camera, c), n.render()) : n.fitGraphToViewport(n.fitPadding());
1337
+ }
1338
+ var qt = (e, t) => (e.nodes.find((e) => e.id === t) || { label: t }).label, Jt = (e) => e.kind || (e.dashed ? "usage" : "ownership");
1339
+ function Yt(e, t, n, { select: r = !0 } = {}) {
1340
+ let { state: i, map: a } = e, o = t === "edge" ? i.edges.find((e) => U(e) === n) : i.nodes.find((e) => e.id === n);
1341
+ if (!o) return;
1342
+ let s = (t === "edge" ? [i.nodes.find((e) => e.id === o.from), i.nodes.find((e) => e.id === o.to)] : [o]).filter(Boolean);
1343
+ if (!s.length) return;
1344
+ i.proposalView !== "diff" && s.some((e) => !a.isNodeVisible(e)) && Wt(e, "diff", { quiet: !0 }), r && (t === "edge" ? Zt(e, o) : ee(e, o));
1345
+ let c = g(s, b(e), {
1346
+ padding: a.fitPadding(),
1347
+ maxZoom: Math.max(1, i.camera.zoom),
1348
+ minZoom: a.getMinZoom()
1349
+ });
1350
+ c && Object.assign(i.camera, c), a.render(), E(e, z(W[o.mark] || o.mark, t === "edge" ? `${qt(i, o.from)} to ${qt(i, o.to)}` : o.label));
1351
+ }
1352
+ function Xt(e, t, n, r) {
1353
+ let i = null, a = r;
1354
+ for (let r of e.map.getScene().edges) if (r.mark !== "none") for (let e = 0; e <= 1; e += 1 / 20) {
1355
+ let o = p(r, e), s = Math.hypot(o.x - t, o.y - n);
1356
+ s <= a && (i = r, a = s);
1357
+ }
1358
+ return i && e.viewEdges().find((e) => e.from === i.from && e.to === i.to && Jt(e) === i.kind) || null;
1359
+ }
1360
+ function Zt(e, t) {
1361
+ w(e, { source: "api" }), e.state.selectedEdge = t, e.emit("node:show-edge", { edge: t }), e.touchScene(), e.map.render();
1362
+ }
1363
+ function Qt(e, t) {
1364
+ let n = e.state.canvas;
1365
+ if (!n) return () => {};
1366
+ let r = null, i = [t(n, "mousedown", (e) => {
1367
+ r = {
1368
+ x: e.clientX,
1369
+ y: e.clientY
1370
+ };
1371
+ }), t(n, "click", (t) => {
1372
+ let { state: i } = e;
1373
+ if (!i.proposal || i.proposalView === "before" || r && Math.hypot(t.clientX - r.x, t.clientY - r.y) > 5) return;
1374
+ let a = n.getBoundingClientRect(), o = e.map.screenToWorld(t.clientX - a.left, t.clientY - a.top), s = i.camera.zoom;
1375
+ if (i.nodes.some((t) => e.map.isNodeVisible(t) && Math.hypot(t.x - o.x, t.y - o.y) <= t.r + 6 / s)) return;
1376
+ let c = Xt(e, o.x, o.y, 8 / s);
1377
+ c && Zt(e, c);
1378
+ })];
1379
+ return () => i.forEach((e) => e());
1380
+ }
1381
+ var $t = (e) => Q(e).pinnedSource, en = /* @__PURE__ */ e({
1382
+ markup: () => rn,
1383
+ mount: () => sn
1384
+ }), tn = "cornfield.reviewTab", nn = 1360, rn = ({ inline: e = !1 } = {}) => ({ column: "<aside id=\"review-column\" class=\"hx-review-column glass\" aria-label=\"Review\" data-corn=\"review-column\" hidden><div class=\"hx-rc-scroll\"><p id=\"proposal-summary\" class=\"hx-proposal-summary\" hidden></p><div id=\"review-lists\" class=\"hx-rc-lists\"></div></div>" + (e ? "<div class=\"hx-player-seat\"></div>" : "<!--corn-piece:decision/foot-->") + "</aside>" }), an = (e, t) => `${s(e)}<span aria-hidden="true"> · </span><span class="hx-sr-only">, </span><span data-corn="count">${t}</span>`;
1385
+ function on(e) {
1386
+ let t = `${e.word} ${e.name}, ${e.type}`;
1387
+ return `<li><button type="button" class="hx-change-row" data-action="proposal-focus" data-kind="${e.kind}" data-key="${s(e.key)}" data-focus-key="ch:${s(e.kind)}:${s(e.key)}" data-corn="row" aria-label="${s(t)}"><span class="hx-mark-dot hx-mark-dot--${e.mark}" data-corn="mark-dot"${P(e.mark)} aria-hidden="true"></span><span class="hx-change-what">${s(e.word)}</span><span class="hx-name">${s(e.name)}</span><span class="hx-faint">${s(e.type)}</span></button></li>`;
1388
+ }
1389
+ function sn(e, t, i = {}) {
1390
+ let { state: a } = t, o = n(t), c = !!i.inline, l = () => !c && v(t), u = r(t, e, rn({ inline: c }).column, i.slots, "column"), d = (e) => {
1391
+ for (let t of u) {
1392
+ if (t.id === e) return t;
1393
+ let n = t.querySelector(`[id="${e}"]`);
1394
+ if (n) return n;
1395
+ }
1396
+ return null;
1397
+ };
1398
+ o.keepParts(...u);
1399
+ let f = d("review-column"), p = !1, h = Ke(t, { checker: i.checker }), g = Mt(t, o, h, c ? {
1400
+ seat: f.querySelector(".hx-player-seat"),
1401
+ hear: e
1402
+ } : {});
1403
+ o.own(() => h.close());
1404
+ let _ = {
1405
+ checks: 0,
1406
+ open: null,
1407
+ tab: null,
1408
+ tabNow: null,
1409
+ tabFor: "",
1410
+ openFor: "",
1411
+ head: "",
1412
+ headFor: "",
1413
+ current: null,
1414
+ lastStep: null,
1415
+ seen: {
1416
+ played: [],
1417
+ read: []
1418
+ },
1419
+ seenFor: "",
1420
+ pending: []
1421
+ }, y = {
1422
+ getItem: (e) => t.store.get(e),
1423
+ setItem: (e, n) => t.store.set(e, n)
1424
+ }, b = t.store.get(tn);
1425
+ (b === "changes" || b === "scenarios") && (_.tab = b);
1426
+ let x = () => {
1427
+ let e = a.effectiveProposal || a.proposal;
1428
+ return e && Array.isArray(e.scenarios) ? e.scenarios : [];
1429
+ }, C = () => `${a.proposalSource || ""}/${a.proposalSlug || ""}`;
1430
+ function T() {
1431
+ return L(a.proposalSource) ? _.headFor === C() && _.head ? St(a.proposalSource, a.proposalSlug, _.head) : null : St(a.proposalSource, a.proposalSlug, "");
1432
+ }
1433
+ function E() {
1434
+ let e = T(), t = e || `pending:${C()}`;
1435
+ if (_.seenFor === t) return;
1436
+ let n = _.seenFor;
1437
+ if (_.seenFor = t, !e) _.seen = {
1438
+ played: [],
1439
+ read: []
1440
+ }, _.pending = [];
1441
+ else {
1442
+ if (_.seen = Ct(y, e), n === `pending:${C()}`) for (let [t, n] of _.pending) _.seen = wt(y, e, t, n);
1443
+ _.pending = [];
1444
+ }
1445
+ }
1446
+ function ee(e, t) {
1447
+ E(), _.seenFor.startsWith("pending:") ? (_.pending.push([String(e), t]), _.seen = wt(null, "", e, t, _.seen)) : _.seen = wt(y, _.seenFor, e, t);
1448
+ }
1449
+ function D(e) {
1450
+ let t = typeof e == "string" ? e : "";
1451
+ (t !== _.head || _.headFor !== C()) && (_.head = t, _.headFor = C(), a.proposal && H());
1452
+ }
1453
+ function O() {
1454
+ E();
1455
+ let e = /* @__PURE__ */ new Map(), n = h.checkedScenarioId();
1456
+ n !== null && e.set(n, h.verdicts());
1457
+ let r = a.effectiveProposal || a.proposal, i = { notChecked: S(t, "notChecked") }, o = new Map(a.nodes.map((e) => [e.id, e]));
1458
+ return yt({
1459
+ scenarios: x(),
1460
+ nodes: a.nodes,
1461
+ edges: a.edges,
1462
+ proposal: r,
1463
+ verdicts: e,
1464
+ seen: _.seen,
1465
+ words: i,
1466
+ hidden: (e) => o.has(e) && Dt(t, o.get(e)).length > 0
1467
+ });
1468
+ }
1469
+ let k = (e) => ft(a.nodes, a.edges, e).filter((e) => e.mark !== "edit");
1470
+ function A(e) {
1471
+ let t = a.effectiveProposal || a.proposal;
1472
+ return xt(e, k(t).length, O());
1473
+ }
1474
+ function j() {
1475
+ let e = a.effectiveProposal || a.proposal;
1476
+ return bt(k(e).length, O());
1477
+ }
1478
+ function M(e, t, n, r) {
1479
+ let i = _.current && _.current.index === e.index && _.current.step === t.index && _.current.id === e.id, a = t.verdict ? `<span class="hx-step-verdict" data-corn="state-pill" data-tone="${s(t.verdict.tone)}"${t.verdict.state ? ` data-corn-state="${t.verdict.state}"` : ""}>${s(t.verdict.words)}</span>` : "", o = t.mark ? `<span class="hx-step-mark"><span class="hx-mark-dot hx-mark-dot--${t.mark}" data-corn="mark-dot"${P(t.mark)} aria-hidden="true"></span>${s(t.markWord)}</span>` : "", c = t.actorLabel ? `<span class="hx-step-who">As ${s(t.actorLabel)}</span>` : "";
1480
+ return `<li><button type="button" class="hx-step" data-corn="step" data-action="scenario-step" data-scenario-index="${e.index}" data-step-index="${t.index}" data-focus-key="st:${n.key}:${e.key}:${t.index}" aria-label="${s(gt(t, r))}"${i ? " aria-current=\"step\"" : ""}><span class="hx-step-n" aria-hidden="true">${t.number}</span><span class="hx-step-body"><span class="hx-step-line">${c}<span class="hx-step-where">${s(t.where)}</span>${o}${t.layerOff ? "<span class=\"hx-step-off\">Layer off: shown when played</span>" : ""}</span><span class="hx-step-text">${s(t.text)}</span></span>${a}</button></li>`;
1481
+ }
1482
+ function N(e, n) {
1483
+ let r = _.open === e.id, i = `rc-steps-${n.key}-${e.key}`, a = e.seen ? `<span class="hx-sc-seen" data-seen="${e.seen}">${e.seen === "played" ? "✓ Played" : "✓ Read"}</span>` : "", o = e.verdictSummary ? ` · ${s(e.verdictSummary)}` : "", c = r && W(e.id) && e.steps.some((e) => e.actor) ? "<p class=\"hx-faint hx-rc-note hx-sc-waits\" data-corn=\"notice\">Not checked while another scenario plays. Close the player, or choose a step here to play this one.</p>" : "";
1484
+ return `<li class="hx-sc" data-open="${r}"><button type="button" class="hx-sc-row" data-corn="row" data-action="scenario-open" data-scenario-index="${e.index}" data-focus-key="sc:${n.key}:${e.key}" aria-expanded="${r}" aria-controls="${i}"><span class="hx-sc-caret" aria-hidden="true">${r ? "▾" : "▸"}</span><span class="hx-sc-main"><span class="hx-sc-title">${s(e.title)}</span><span class="hx-sc-meta">${s(e.summary)}${o}</span></span>${a}</button>${c}<ol class="hx-steps" id="${i}" data-corn="step-list" aria-label="${s(S(t, "steps"))}: ${s(e.title)}"${r ? "" : " hidden"}>${r ? e.steps.map((t) => M(e, t, n, e.steps.length)).join("") : ""}</ol></li>`;
1485
+ }
1486
+ function F(e) {
1487
+ let n = e.scenarios.length, r = e.anyone ? S(t, "anyone") : e.label, i = `${s(r)}<span aria-hidden="true"> · </span><span class="hx-sr-only">, </span>${n} ${n === 1 ? "scenario" : "scenarios"}`;
1488
+ return `<div class="hx-persona" data-corn="persona-group" data-persona="${s(e.key)}"><h4 class="hx-persona-name">${i}</h4><ul class="hx-sc-list">${e.scenarios.map((t) => N(t, e)).join("")}</ul></div>`;
1489
+ }
1490
+ function I() {
1491
+ let e = a.effectiveProposal || a.proposal, n = ft(a.nodes, a.edges, e), r = n.filter((e) => e.mark !== "edit"), i = n.filter((e) => e.mark === "edit"), o = O(), c = l();
1492
+ _.tabFor !== C() && (_.tabFor = C(), _.tabNow = o.total ? _.tab || "scenarios" : "changes");
1493
+ let u = _.tabNow || "changes", d = a.nodes.some((e) => e.type === "persona"), f = `<div class="hx-rc-tabs" role="tablist" aria-label="Review" data-corn="tabs"${c ? "" : " hidden"}><button type="button" role="tab" id="rc-tab-changes" class="hx-rc-tab" data-corn="tab" data-action="review-tab" data-tab="changes" aria-selected="${u === "changes"}" aria-controls="rc-changes" tabindex="${u === "changes" ? 0 : -1}">${s(S(t, "changes"))} · ${r.length}</button><button type="button" role="tab" id="rc-tab-scenarios" class="hx-rc-tab" data-corn="tab" data-action="review-tab" data-tab="scenarios" aria-selected="${u === "scenarios"}" aria-controls="rc-scenarios" tabindex="${u === "scenarios" ? 0 : -1}">${s(S(t, "scenarios"))} · ${o.total}</button></div>`, p = `<section id="rc-changes" class="hx-rc-section" data-corn="proposal-changes"${c ? ` role="tabpanel" aria-labelledby="rc-tab-changes"${u === "changes" ? "" : " hidden"}` : " aria-labelledby=\"rc-changes-h\""}><h3 id="rc-changes-h" class="hx-rc-h" tabindex="-1">${an(S(t, "changes"), r.length)}</h3>` + (i.length ? `<h4 class="hx-rc-sub">${an(S(t, "yourEdits"), i.length)}</h4><ul class="hx-change-list">${i.map(on).join("")}</ul>` : "") + (r.length ? `<ul class="hx-change-list">${r.map(on).join("")}</ul>` : "<p class=\"hx-faint hx-rc-empty\">This proposal changes nothing on the map.</p>") + "</section>", m;
1494
+ return o.total ? (m = o.groups.map(F).join(""), d || (m += `<p class="hx-faint hx-rc-note">This map has no personas (topology.personas.json), so every scenario is listed under ${s(S(t, "anyone"))}.</p>`), o.coverage && (m += `<p class="hx-rc-coverage" data-corn="notice">${s(S(t, "notInAnyScenario"))}: ${o.notInAny.map(s).join(", ")}</p>`)) : m = "<p class=\"hx-faint hx-rc-empty\">This proposal has no scenarios: there is nothing to walk through, and its changes are all it shows.</p>", `${f}${p}${`<section id="rc-scenarios" class="hx-rc-section" data-corn="scenario-list"${c ? ` role="tabpanel" aria-labelledby="rc-tab-scenarios"${u === "scenarios" ? "" : " hidden"}` : " aria-labelledby=\"rc-scenarios-h\""}><h3 id="rc-scenarios-h" class="hx-rc-h" tabindex="-1">${an(S(t, "personasAndScenarios"), o.total)}</h3><div class="hx-rc-sbody">${m}</div></section>`}`;
1495
+ }
1496
+ function R() {
1497
+ return c || t.ask("proposal:seat-column", {
1498
+ column: f,
1499
+ phone: l()
1500
+ }), f;
1501
+ }
1502
+ function z() {
1503
+ if (c || l()) return;
1504
+ let e = t.ask("proposal:bar-bottom");
1505
+ typeof e == "number" && f.style.setProperty("--hx-column-top", `${e}px`);
1506
+ }
1507
+ function B() {
1508
+ if (p) return;
1509
+ R();
1510
+ let e = !!a.proposal;
1511
+ if (f.hidden = !e, !e) {
1512
+ _.open = null, _.current = null, _.lastStep = null, G();
1513
+ let e = d("review-lists");
1514
+ e && (e.innerHTML = "");
1515
+ } else H(), z();
1516
+ }
1517
+ function V() {
1518
+ let e = d("review-lists"), n = d("rc-scenarios");
1519
+ if (!e || !n || f.hidden || l()) return;
1520
+ let r = e.clientHeight;
1521
+ if (!r) return;
1522
+ let i = parseFloat(t.win.getComputedStyle(e).rowGap) || 0, a = n.querySelector(".hx-rc-h"), o = n.querySelector(".hx-rc-sbody"), s = Math.ceil((a ? a.offsetHeight + (parseFloat(t.win.getComputedStyle(a).marginBottom) || 0) : 0) + (o ? o.scrollHeight : 0));
1523
+ f.style.setProperty("--hx-scenarios-need", `${s}px`), f.style.setProperty("--hx-changes-max", `${Math.floor(Math.max(.4 * r, r - s - i))}px`);
1524
+ }
1525
+ function H() {
1526
+ let e = d("review-lists");
1527
+ if (p || !e || !a.proposal) return;
1528
+ _.openFor !== C() && (_.openFor = C(), g.getPlayer() || (_.open = null, _.current = null, _.lastStep = null)), _.open !== null && !x().some((e) => e.id === _.open) && (_.open = null);
1529
+ let n = _.open !== null && !g.getPlayer() ? x().find((e) => e.id === _.open) : null;
1530
+ n && h.checkedScenarioId() === n.id && h.open(n, () => H());
1531
+ let r = t.active(), i = r && e.contains(r) && r.getAttribute ? r.getAttribute("data-focus-key") : null, o = e.scrollTop;
1532
+ e.innerHTML = I(), m(e);
1533
+ let s = a.proposal, c = d("proposal-summary");
1534
+ if (c.textContent = s && typeof s.summary == "string" && s.summary || "", c.hidden = !c.textContent, e.scrollTop = o, t.emit("changes:peek", j()), i) {
1535
+ let t = [...e.querySelectorAll("[data-focus-key]")].find((e) => e.getAttribute("data-focus-key") === i);
1536
+ t && t.focus();
1537
+ }
1538
+ V(), t.emit("changes:paint");
1539
+ }
1540
+ let U = (e) => x()[Number(e.dataset.scenarioIndex)] || null, W = (e) => {
1541
+ let t = g.getPlayer();
1542
+ return !!t && t.scenario().id !== e;
1543
+ };
1544
+ function G() {
1545
+ g.getPlayer() || h.close();
1546
+ }
1547
+ function K(e) {
1548
+ _.open === e.id ? (_.open = null, g.getPlayer() || h.close()) : (_.open = e.id, ee(e.id, "read"), W(e.id) || h.open(e, () => H())), H();
1549
+ }
1550
+ function te(e, n) {
1551
+ _.open = e.id;
1552
+ let r = a.canvas && a.canvas.parentElement;
1553
+ !c && !l() && t.ask("panel:covers") && r && r.clientWidth < nn && w(t, { source: "api" }), g.play(e, {
1554
+ autoplay: !1,
1555
+ step: n,
1556
+ focus: l()
1557
+ }), H();
1558
+ }
1559
+ function ne(e, { focus: n = !1 } = {}) {
1560
+ _.tab = e, _.tabNow = e, _.tabFor = C(), t.store.set(tn, e), H(), n && d(`rc-tab-${e}`)?.focus();
1561
+ }
1562
+ function re(e) {
1563
+ if (!a.proposal) return;
1564
+ l() && (ne(e), he(t, "proposal"));
1565
+ let n = d(e === "scenarios" ? "rc-scenarios" : "rc-changes"), r = d(e === "scenarios" ? "rc-scenarios-h" : "rc-changes-h");
1566
+ n && typeof n.scrollIntoView == "function" && n.scrollIntoView({ block: "start" }), r && r.focus();
1567
+ }
1568
+ o.listen(f, "click", (e) => {
1569
+ let n = e.target.closest ? e.target.closest("[data-action]") : null;
1570
+ if (!n) return;
1571
+ let r = n.dataset.action;
1572
+ if (r === "scenario-open") {
1573
+ let e = U(n);
1574
+ e && K(e);
1575
+ } else if (r === "scenario-step") {
1576
+ let e = U(n);
1577
+ e && te(e, Number(n.dataset.stepIndex));
1578
+ } else r === "review-tab" ? ne(n.dataset.tab, { focus: !1 }) : r === "proposal-focus" && Yt(t, n.dataset.kind, n.dataset.key);
1579
+ }), o.listen(f, "keydown", (e) => {
1580
+ let t = e.target.closest ? e.target.closest("[role=\"tab\"]") : null;
1581
+ t && [
1582
+ "ArrowLeft",
1583
+ "ArrowRight",
1584
+ "Home",
1585
+ "End"
1586
+ ].includes(e.key) && (e.preventDefault(), ne(t.dataset.tab === "changes" ? "scenarios" : "changes", { focus: !0 }));
1587
+ });
1588
+ function ie(e) {
1589
+ if (!e) {
1590
+ let e = _.open !== null && a.proposal && _.openFor === C() ? x().find((e) => e.id === _.open) : null;
1591
+ e && h.open(e, () => H()), (_.current || e) && (_.current = null, H());
1592
+ return;
1593
+ }
1594
+ let t = x().findIndex((t) => t.id === e.id), n = {
1595
+ id: e.id,
1596
+ index: t,
1597
+ step: Math.min(e.index, Math.max(e.total - 1, 0))
1598
+ };
1599
+ _.lastStep = n, e.done && (E(), _.seen.played.includes(e.id) || ee(e.id, "played"));
1600
+ let r = _.current && _.current.id === n.id && _.current.step === n.step;
1601
+ _.current = n, _.open !== e.id && (_.open = e.id), (!r || e.done || e.checks !== _.checks) && (_.checks = e.checks, H());
1602
+ }
1603
+ function ae() {
1604
+ let e = _.lastStep;
1605
+ if (!e) return null;
1606
+ l() && he(t, "proposal");
1607
+ let n = d("review-lists");
1608
+ return n ? n.querySelector(`[data-action="scenario-step"][data-scenario-index="${e.index}"][data-step-index="${e.step}"]`) : null;
1609
+ }
1610
+ function q(e) {
1611
+ let t = [];
1612
+ for (let e of O().groups) for (let n of e.scenarios) t.includes(n.id) || t.push(n.id);
1613
+ let n = t.indexOf(e), r = n >= 0 ? t[n + 1] : void 0;
1614
+ return r === void 0 ? null : x().find((e) => String(e.id) === r) || null;
1615
+ }
1616
+ o.own(g.onChange(ie)), g.setCloseFocus(ae), g.setNextScenario(q), g.setKeepChecksOnClose((e) => _.open === e && !!a.proposal), o.own(ve(t, () => {
1617
+ a.proposal && H();
1618
+ })), o.on("proposal:draw", () => B()), o.on("proposal:pull-head", (e) => D(e)), o.on("changes:show", (e) => re(e));
1619
+ let J = t.win && t.win.ResizeObserver;
1620
+ if (o.on("proposal:bar-resize", () => z()), ((e, t) => {
1621
+ if (e && typeof J == "function") {
1622
+ let n = new J(t);
1623
+ n.observe(e), o.own(() => n.disconnect());
1624
+ }
1625
+ })(f, () => V()), !c) {
1626
+ o.own(ge(t, () => {
1627
+ a.proposal && B();
1628
+ }));
1629
+ let e = (e) => !!e && !e.hidden && e.isConnected;
1630
+ o.on("changes:covers", () => e(f) ? { right: f.getBoundingClientRect().right } : void 0), o.on("player:covers", () => {
1631
+ let t = g.bar();
1632
+ return e(t) ? { top: t.getBoundingClientRect().top } : void 0;
1633
+ });
1634
+ }
1635
+ return o.own(() => {
1636
+ p = !0, u.forEach((e) => e.remove());
1637
+ }), B(), o.on("changes:opened-line", (e) => a.proposal ? A(e) : void 0), o.on("changes:played-line", () => a.proposal ? O().playedLine : ""), {
1638
+ elements: u,
1639
+ playScenario: g.play,
1640
+ stopScenario: g.stop,
1641
+ clearScenario: g.clear,
1642
+ playOutage: g.playOutage,
1643
+ getPlayer: g.getPlayer,
1644
+ wantsFrames: g.wantsFrames,
1645
+ setCloseFocus: g.setCloseFocus,
1646
+ setNextScenario: g.setNextScenario,
1647
+ setKeepChecksOnClose: g.setKeepChecksOnClose,
1648
+ tickScenario: g.tick,
1649
+ demo: g.demo,
1650
+ layersHiding: (e) => Dt(t, e),
1651
+ checks: h,
1652
+ renderColumn: B,
1653
+ shareRoom: V,
1654
+ setPullHead: D,
1655
+ openedLine: A,
1656
+ peekLine: j,
1657
+ update(e) {
1658
+ e && "checker" in e && h.setChecker(e.checker), a.proposal && H();
1659
+ },
1660
+ destroy: () => o.destroy()
1661
+ };
1662
+ }
1663
+ // ../explorer/decision-model.js
1664
+ var cn = 5e3, ln = 3, un = 40, dn = (e, t) => `${e} ${t}${e === 1 ? "" : "s"}`, fn = (e) => String(e).replace(/\s+/g, " ").trim(), pn = (e) => {
1665
+ let t = fn(e);
1666
+ return t.length > un ? `${t.slice(0, 39)}…` : t;
1667
+ };
1668
+ function mn(e) {
1669
+ let t = e.slice(0, ln).map(pn), n = e.length - t.length;
1670
+ return n > 0 ? `${t.join(", ")} and ${n} more` : t.length < 2 ? t.join("") : `${t.slice(0, -1).join(", ")} and ${t[t.length - 1]}`;
1671
+ }
1672
+ var hn = (e) => e && e.checks && Array.isArray(e.checks.failed) ? e.checks.failed : [], gn = (e) => e && e.checks && e.checks.running || 0, _n = (e) => `${mn(e)} failed`;
1673
+ function vn(e, t) {
1674
+ if (!e) return "";
1675
+ let n = [
1676
+ "code",
1677
+ "summary",
1678
+ "brief",
1679
+ "proposal"
1680
+ ].includes(e.kind) ? e.kind : "code", r = n === "code" ? "a code run" : `a ${n} run`;
1681
+ if (e.open) return `No new run is asked for: ${typeof e.open == "string" ? `run ${fn(e.open).slice(0, 40)} is` : "one is"} still open on it.`;
1682
+ if (e.fired) return `No new run is asked for: ${r} was asked for at this head already.`;
1683
+ let i = `Then ${r} is asked for.`;
1684
+ if (e.transport !== "pull") return `${i} The request is posted for your runner.`;
1685
+ if (e.runner === "online") return `${i} A runner is online.`;
1686
+ let a = typeof e.lastSeen == "string" ? Date.parse(e.lastSeen) : NaN;
1687
+ return e.runner === "quiet" && Number.isFinite(a) ? `${i} No runner has polled for ${I(t - a)}: the run will wait.` : `${i} No runner has polled yet: the run will wait.`;
1688
+ }
1689
+ var yn = (e) => e > 0 ? `Your ${dn(e, "edit")} ${e === 1 ? "goes" : "go"} in the comment, for the agent to fold in.` : "";
1690
+ function bn(e) {
1691
+ let t = e.pull.number, n = !!e.lands;
1692
+ if (e.pull.draft) return n ? `PR #${t} is a draft. Approve posts an approval; it lands only if the PR is marked ready within 60 minutes.` : `PR #${t} is a draft. Approve posts an approval on it.`;
1693
+ let r = `Approve posts an approval on PR #${t}.`, i = e.checks, a = hn(e), o = gn(e);
1694
+ return a.length ? n ? `${r} It will not land: ${_n(a)}.` : `${r} ${_n(a)}.` : i && i.total === 0 ? n ? `${r} It will not land: the PR has no checks.` : `${r} It does not land it.` : o ? n ? `${r} It lands once ${o === 1 ? "1 running check passes" : `${o} running checks pass`}.` : `${r} ${o === 1 ? "1 check is" : `${o} checks are`} still running.` : i && !i.passed ? n ? `${r} It will not land: no check has passed.` : `${r} It does not land it.` : n ? `Approve posts an approval on PR #${t} and lands it.` : `${r} It does not land it.`;
1695
+ }
1696
+ function xn(e, t) {
1697
+ return `An approval of this version of PR #${e} stands.${t && t.landing ? " Its landing waits for the checks." : ""} A push makes Approve live again.`;
1698
+ }
1699
+ function Sn({ facts: e, edits: t = 0, form: n = null }) {
1700
+ let r = [];
1701
+ if (e && e.pull) {
1702
+ let t = hn(e);
1703
+ t.length && r.push({
1704
+ key: "failed",
1705
+ text: `${_n(t)} on PR #${e.pull.number}.`
1706
+ }), e.pull.draft && r.push({
1707
+ key: "draft",
1708
+ text: `PR #${e.pull.number} is a draft: its author has not marked it ready.`
1709
+ });
1710
+ }
1711
+ return n && r.push({
1712
+ key: "form",
1713
+ text: `Your ${fn(n.name)} form is not added.`
1714
+ }), e && e.pull && e.lands && t > 0 && r.push({
1715
+ key: "edits",
1716
+ text: `PR #${e.pull.number} lands as written; your ${dn(t, "edit")} only go${t === 1 ? "es" : ""} in the comment.`
1717
+ }), r;
1718
+ }
1719
+ function Cn(e, t = "Approve") {
1720
+ if (!e.length) return "";
1721
+ let n = e.length === 1 ? e[0] : null, r = n && n.key === "form" ? `${t} without it?` : `${t} anyway?`;
1722
+ return `${e.map((e) => e.text).join(" ")} ${r}`;
1723
+ }
1724
+ var wn = (e, t) => e.filter((e) => !t.includes(e.key)), Tn = "Shown to read only: there is no cornfield server here to send an approval or a send back to.", En = "Shown to read only: this proposal has no name, so there is nothing to send an approval or a send back about.";
1725
+ function Dn({ source: e, facts: t, factsState: n, review: r = null, edits: i = 0, form: a = null, played: o = "", now: s = Date.now() }) {
1726
+ let c = L(e), l = (...e) => e.filter(Boolean).join(" ");
1727
+ if (!c) return {
1728
+ line: `Draft in ${!e || e === "checkout" ? "the checkout" : `worktree ${fn(e)}`}: push it as a spec PR to review it here.`,
1729
+ approve: "refused",
1730
+ reasons: [],
1731
+ ask: ""
1732
+ };
1733
+ let u = !!r && r.verdict === "approved" && r.current === !0;
1734
+ if (n === "loading" || !t && n !== "unread") return {
1735
+ line: l(`Reading PR #${c} …`, o),
1736
+ approve: u ? "done" : "reading",
1737
+ reasons: [],
1738
+ ask: ""
1739
+ };
1740
+ if (!t || n === "unread") return {
1741
+ line: l(`Could not read PR #${c}'s checks. Approve posts an approval on it.`, yn(i), o),
1742
+ approve: u ? "done" : "allowed",
1743
+ reasons: Sn({
1744
+ facts: null,
1745
+ edits: i,
1746
+ form: a
1747
+ }),
1748
+ ask: ""
1749
+ };
1750
+ let d = Sn({
1751
+ facts: t,
1752
+ edits: i,
1753
+ form: a
1754
+ }), f = t.run ? vn(t.run, s) : "", p = l(bn(t), f, yn(i), o);
1755
+ return u ? {
1756
+ line: l(xn(c, t), o),
1757
+ approve: "done",
1758
+ reasons: d,
1759
+ ask: ""
1760
+ } : {
1761
+ line: p,
1762
+ approve: d.length ? "asks" : "allowed",
1763
+ reasons: d,
1764
+ ask: Cn(d)
1765
+ };
1766
+ }
1767
+ function On({ source: e, edits: t = 0 }) {
1768
+ let n = L(e);
1769
+ return n ? `Posts ${t > 0 ? `your note and ${dn(t, "edit")}` : "your note"} on PR #${n} for the drafting agent. No run is asked for.` : "";
1770
+ }
1771
+ function kn({ form: e = null }) {
1772
+ let t = Sn({
1773
+ facts: null,
1774
+ edits: 0,
1775
+ form: e
1776
+ });
1777
+ return {
1778
+ asks: t.length > 0,
1779
+ reasons: t,
1780
+ ask: Cn(t, "Send back")
1781
+ };
1782
+ }
1783
+ function An(e, t = "") {
1784
+ if (e === 401) return "Your sign-in has ended. Sign in again: your edits are kept here.";
1785
+ let n = fn(t);
1786
+ return e === 403 || e === 409 ? n || "The review was not posted." : `The review was not posted. ${n || `The server answered ${e}.`}`;
1787
+ }
1788
+ var jn = (e, t) => `${e === "approved" ? "Approving" : "Sending back"} in ${Math.max(0, Math.ceil(t))} s`, Mn = (e, t) => `${e === "approved" ? "Approving" : "Sending back"} in ${dn(Math.ceil(t), "second")}. Undo to stop it; nothing has been sent.`;
1789
+ function Nn(e, t) {
1790
+ let n = e === "approved" ? "The approval" : "The send back";
1791
+ return `${{
1792
+ undo: `${n} was undone.`,
1793
+ escape: `${n} was undone.`,
1794
+ closed: `${n} was stopped: the proposal was closed.`,
1795
+ other: `${n} was stopped: another proposal was opened.`,
1796
+ hidden: `${n} was stopped: this tab was hidden.`,
1797
+ offline: `${n} was stopped: you are offline.`,
1798
+ edits: `${n} was stopped: your edits changed.`,
1799
+ pushed: `${n} was stopped: the PR was pushed to while it was held, so it is not what you looked at. Look again before you decide.`
1800
+ }[t] || `${n} was stopped.`} Nothing was sent.`;
1801
+ }
1802
+ var Pn = (e) => `Sent with ${dn(e, "edit")}`, Fn = /* @__PURE__ */ e({
1803
+ FACTS_MS: () => Ln,
1804
+ markup: () => zn,
1805
+ mount: () => Bn
1806
+ }), In = 3e4, Ln = 3e4, Rn = "cornfield.reviewNote.", zn = () => ({ foot: "<div id=\"review-decision\" class=\"hx-rc-foot\" data-corn=\"decision\" role=\"group\" aria-label=\"Decision\"><div id=\"review\" class=\"hx-review\" data-corn=\"review-bar\"><p class=\"hx-review-status\" data-review-status hidden><span data-review-verdict role=\"status\"></span><span data-review-when></span></p><div class=\"hx-review-form\" id=\"review-form\" data-review-form hidden><label class=\"hx-review-label\" for=\"review-note\" data-corn=\"review-label\"></label><textarea data-corn=\"review-note\" id=\"review-note\" class=\"hx-review-note\" rows=\"2\" maxlength=\"20000\"></textarea><p class=\"hx-review-line\" id=\"review-sendback-line\" data-review-sendback-line></p><div class=\"hx-review-row\"><button type=\"button\" class=\"hx-btn hx-btn--quiet\" data-review-cancel data-corn-kind=\"quiet\">Cancel</button></div></div><p class=\"hx-review-msg\" data-review-loadfail role=\"alert\" hidden data-corn=\"message\" data-corn-state=\"failure\"><span data-review-loadfail-text></span> <button type=\"button\" class=\"hx-btn hx-btn--quiet\" data-review-retry data-corn-kind=\"quiet\">Retry</button></p><p class=\"hx-review-msg\" data-review-msg role=\"alert\" hidden></p><p class=\"hx-review-line\" id=\"review-hint\" data-review-hint role=\"status\" hidden></p><details class=\"hx-sent-edits\" data-corn=\"sent-edits\" data-review-sent hidden><summary data-corn=\"summary\" data-review-sent-summary></summary><ul class=\"hx-whatif-list\" data-review-sent-list></ul></details><div class=\"hx-review-landing\" data-corn=\"notice\" data-corn-state=\"waiting\" data-review-landing hidden><p data-review-landing-text></p><button type=\"button\" class=\"hx-btn hx-btn--quiet\" data-review-cancel-landing data-corn-kind=\"quiet\"></button></div><p class=\"hx-review-ask\" id=\"review-ask\" data-corn=\"message\" data-corn-state=\"waiting\" data-review-ask role=\"alert\" hidden></p><p class=\"hx-decision-line\" id=\"review-line\" data-review-line></p><div class=\"hx-hold\" data-review-hold hidden aria-hidden=\"true\"><span class=\"hx-hold-fill\" data-review-hold-fill></span></div><p class=\"hx-sr-only\" data-review-hold-live role=\"status\"></p></div><div class=\"hx-proposal-actions\"><button data-corn-kind=\"secondary\" type=\"button\" class=\"hx-btn\" data-review=\"notes\" data-peek-ok title=\"Send it back to the drafting agent with a note and your edits\" data-corn-string=\"sendBack\">Send back</button><button type=\"button\" class=\"hx-btn hx-review-undo\" data-review-undo data-corn-kind=\"secondary\" hidden></button><button type=\"button\" class=\"hx-btn hx-btn--approve\" data-review=\"approved\" data-peek-ok title=\"Sign this proposal off\" data-corn-kind=\"approve\" data-corn-string=\"approve\">Approve</button></div></div>" });
1807
+ function Bn(e, t, o = {}) {
1808
+ let { state: s } = t, l = n(t), d = typeof o.now == "function" ? o.now : () => Date.now(), f = !!o.inline, p = () => !f && v(t), m = f ? e : t.root, h = typeof o.unnamed == "string" && o.unnamed ? o.unnamed : f ? En : "", g = Oe(t), _ = r(t, e, zn().foot, o.slots, "foot");
1809
+ l.keepParts(..._);
1810
+ let y = _[0], b = y.querySelector("#review"), x = y.querySelector(".hx-proposal-actions"), C = !1, w = {
1811
+ key: null,
1812
+ reviewable: !1,
1813
+ review: null,
1814
+ loadFailed: !1,
1815
+ busy: !1,
1816
+ noting: !1,
1817
+ message: "",
1818
+ hint: "",
1819
+ facts: null,
1820
+ factsState: "loading",
1821
+ factsAt: 0,
1822
+ asking: null,
1823
+ hold: null,
1824
+ sent: null
1825
+ }, T = () => s.proposalSlug || null, ee = () => s.proposal && T() ? `${s.proposalSource || ""}/${T()}` : null, D = () => s.proposalSource ? `?source=${encodeURIComponent(s.proposalSource)}` : "", O = () => `/proposals/${encodeURIComponent(T())}/review${D()}`, k = (e) => `/proposals/${encodeURIComponent(T())}/decision${D()}${e ? "&fresh=1" : ""}`, j = (e) => b.querySelector(e), M = (e) => y.querySelector(`[data-review="${e}"]`), N = () => y.querySelector("[data-review-undo]"), P = () => {
1826
+ let e = t.ask("whatif:edits");
1827
+ return Array.isArray(e) ? e : [];
1828
+ }, F = () => {
1829
+ let e = t.ask("whatif:form");
1830
+ return e === void 0 ? null : e;
1831
+ }, I = () => {
1832
+ let e = t.ask("changes:played-line");
1833
+ return typeof e == "string" ? e : "";
1834
+ }, R = () => s.whatIf ? s.whatIf.edits.length : 0;
1835
+ function z() {
1836
+ return Dn({
1837
+ source: s.proposalSource,
1838
+ facts: w.facts,
1839
+ factsState: w.factsState,
1840
+ review: w.review,
1841
+ edits: R(),
1842
+ form: F(),
1843
+ played: I(),
1844
+ now: d()
1845
+ });
1846
+ }
1847
+ function B() {
1848
+ if (C) return;
1849
+ let e = j("[data-review-status]"), { verdict: n, when: r } = c(w.review, d()), i = j("[data-review-verdict]");
1850
+ i.textContent !== n && (i.textContent = n), j("[data-review-when]").textContent = r ? ` ${r}` : "", e.hidden = !n;
1851
+ let a = j("[data-review-loadfail]");
1852
+ a.hidden = !w.loadFailed, j("[data-review-loadfail-text]").textContent = w.loadFailed ? `Could not load this proposal's reviews.${t.offline() ? " You are offline." : ""} It may already be approved or sent back; try again before you decide.` : "";
1853
+ let o = z(), l = "";
1854
+ if (w.asking && !w.hold) {
1855
+ if (w.asking.verdict === "approved") l = o.reasons.length ? Cn(o.reasons) : "";
1856
+ else {
1857
+ let e = kn({ form: F() });
1858
+ l = e.asks ? e.ask : "";
1859
+ }
1860
+ l || (w.asking = null);
1861
+ }
1862
+ let u = w.hold, f = M("approved"), p = M("notes"), m = w.asking && w.asking.verdict === "approved" ? "anyway" : u && u.verdict === "approved" ? "hold" : o.approve === "done" ? "done" : "plain", g = w.asking && w.asking.verdict === "notes" ? "anyway" : u && u.verdict === "notes" ? "hold" : "plain", _ = j("[data-review-line]"), v = !w.key && !!s.proposal && !!h;
1863
+ _.textContent = w.key ? o.line : v ? h : "", _.hidden = !w.key && !v || !!l, x.hidden = v;
1864
+ let b = j("[data-review-ask]");
1865
+ b.textContent !== l && (b.textContent = l), b.hidden = !l, j("[data-review-sendback-line]").textContent = On({
1866
+ source: s.proposalSource,
1867
+ edits: R()
1868
+ });
1869
+ let T = w.key && o.approve === "refused";
1870
+ for (let e of y.querySelectorAll("[data-review]")) !w.reviewable || w.busy || u || e === f && (o.approve === "done" || o.approve === "reading") ? e.setAttribute("aria-disabled", "true") : e.removeAttribute("aria-disabled"), e.disabled = !1, w.key && e === f ? e.setAttribute("aria-describedby", l ? "review-ask" : "review-line") : w.key && !w.noting && e === p && T ? e.setAttribute("aria-describedby", "review-line") : w.key && w.noting && e === p ? e.setAttribute("aria-describedby", "review-sendback-line") : e.removeAttribute("aria-describedby");
1871
+ f && (f.textContent = m === "hold" ? jn("approved", u.left) : m === "anyway" ? S(t, "approveAnyway") : m === "done" ? S(t, "approved") : S(t, "approve"), f.dataset.holding = m === "hold" ? "true" : "false"), p && (p.textContent = g === "hold" ? jn("notes", u.left) : g === "anyway" ? S(t, "sendBackAnyway") : w.noting ? S(t, "sendBackWithNote") : S(t, "sendBack"), p.setAttribute("aria-expanded", String(w.noting)), p.setAttribute("aria-controls", "review-form"), p.dataset.holding = g === "hold" ? "true" : "false");
1872
+ let E = N();
1873
+ E && (E.hidden = !u, E.textContent = S(t, "undo"));
1874
+ let ee = j("[data-review-hold]");
1875
+ ee.hidden = !u, j("[data-review-form]").hidden = !w.noting, j("[data-review-cancel]").disabled = w.busy || !!u;
1876
+ let D = j("#review-note");
1877
+ D.disabled = !w.reviewable, D.readOnly = !!u;
1878
+ for (let [e, t] of [["[data-review-msg]", w.message], ["[data-review-hint]", w.reviewable ? w.hint : ""]]) {
1879
+ let n = j(e);
1880
+ n.hidden = !t, n.textContent = t;
1881
+ }
1882
+ let O = j("[data-review-sent]");
1883
+ if (O.hidden = !w.sent, w.sent) {
1884
+ j("[data-review-sent-summary]").textContent = Pn(w.sent.lines.length);
1885
+ let e = j("[data-review-sent-list]");
1886
+ e.dataset.for !== w.sent.key && (e.dataset.for = w.sent.key, e.replaceChildren(...w.sent.lines.map((e) => {
1887
+ let n = t.doc.createElement("li");
1888
+ return n.className = "hx-whatif-edit", n.textContent = e, n;
1889
+ })));
1890
+ }
1891
+ let k = j("[data-review-landing]"), A = w.reviewable && w.facts && w.facts.landing ? w.facts.landing : null;
1892
+ k.hidden = !A, A && (j("[data-review-landing-text]").textContent = `Landing on approval waits for PR #${w.facts.pull.number} to be ready and green.`);
1893
+ }
1894
+ j(".hx-review-label").textContent = S(t, "reviewNoteLabel"), j("#review-note").setAttribute("placeholder", S(t, "reviewNotePlaceholder")), j("[data-review-cancel-landing]").textContent = S(t, "cancelLanding"), N().textContent = S(t, "undo");
1895
+ function V() {
1896
+ w.noting = !0, w.message = "", B(), p() && he(t, "proposal"), j("#review-note").focus();
1897
+ let e = M("notes");
1898
+ p() && e && typeof e.scrollIntoView == "function" && e.scrollIntoView({ block: "nearest" });
1899
+ }
1900
+ function H() {
1901
+ w.noting = !1, w.asking = null, w.message = "", j("#review-note").value = "", re(w.key), B();
1902
+ let e = M("notes");
1903
+ e && e.focus();
1904
+ }
1905
+ function U({ open: e }) {
1906
+ let t = e ? ee() : null;
1907
+ if (b.hidden = !(t || e && h), f && (y.hidden = !e), t === w.key) {
1908
+ B();
1909
+ return;
1910
+ }
1911
+ w.hold && Y(e ? "other" : "closed", { quiet: !1 }), w.key = t, w.reviewable = !!t && i(s.proposalSource), w.review = null, w.loadFailed = !1, w.busy = !1, w.noting = !1, w.asking = null, w.sent = null, w.facts = null, w.factsState = w.reviewable ? "loading" : "ready", w.message = w.hint = "";
1912
+ let n = j("#review-note"), r = t && w.reviewable ? ne(t) : "";
1913
+ n && (n.value = r), r && (w.noting = !0), B(), t && w.reviewable && (q(t), G());
1914
+ }
1915
+ let W = (e, n) => {
1916
+ (e === 401 || e === 403) && t.emit("auth", {
1917
+ status: e,
1918
+ during: n
1919
+ });
1920
+ };
1921
+ async function G({ fresh: e = !1 } = {}) {
1922
+ let t = w.key;
1923
+ if (!t || !w.reviewable || !L(s.proposalSource)) return;
1924
+ w.factsAt = d();
1925
+ let n = null;
1926
+ try {
1927
+ let t = await g(k(e), { cache: "no-store" });
1928
+ t.ok ? n = await t.json() : W(t.status, "facts");
1929
+ } catch {
1930
+ n = null;
1931
+ }
1932
+ if (C || t !== w.key) return;
1933
+ let r = n && n.pull ? n.pull.head : null, i = w.facts && w.facts.pull ? w.facts.pull.head : null;
1934
+ w.facts = n && n.pull ? n : null, w.factsState = w.facts ? "ready" : "unread", r && i && r !== i && q(t), B();
1935
+ }
1936
+ let K = () => {
1937
+ try {
1938
+ return t.win.sessionStorage;
1939
+ } catch {
1940
+ return null;
1941
+ }
1942
+ };
1943
+ function te(e, t) {
1944
+ if (e) try {
1945
+ t && t.trim() ? K().setItem(Rn + e, t.slice(0, 2e4)) : K().removeItem(Rn + e);
1946
+ } catch {}
1947
+ }
1948
+ function ne(e) {
1949
+ try {
1950
+ return K().getItem(Rn + e) || "";
1951
+ } catch {
1952
+ return "";
1953
+ }
1954
+ }
1955
+ function re(e) {
1956
+ if (e) try {
1957
+ K().removeItem(Rn + e);
1958
+ } catch {}
1959
+ }
1960
+ function ie(e = 0) {
1961
+ w.key && w.reviewable && !w.hold && !w.busy && (t.hidden() || d() - w.factsAt < e || G());
1962
+ }
1963
+ function ae() {
1964
+ let e = t.active(), n = !!e && b.contains(e) && e.matches("[data-review-retry]");
1965
+ w.loadFailed = !1, B(), n && t.emit("proposal:focus-title");
1966
+ }
1967
+ async function q(e) {
1968
+ try {
1969
+ let t = await g(O(), { cache: "no-store" });
1970
+ if (C || e !== w.key) return;
1971
+ if (t.status === 404) {
1972
+ w.review = null, ae();
1973
+ return;
1974
+ }
1975
+ if (!t.ok) throw W(t.status, "review"), Error(`The server answered ${t.status}.`);
1976
+ let n = await t.json();
1977
+ if (C || e !== w.key) return;
1978
+ n && typeof n.verdict == "string" && (w.review = {
1979
+ verdict: n.verdict,
1980
+ at: n.at,
1981
+ current: n.current === !0
1982
+ }), ae();
1983
+ } catch {
1984
+ !C && e === w.key && (w.loadFailed = !0, B());
1985
+ }
1986
+ }
1987
+ function J(e) {
1988
+ if (!e.target.closest || e.detail > 1 && e.target.closest("[data-review], [data-review-undo]")) return;
1989
+ if (e.target.closest("[data-review-undo]")) {
1990
+ w.hold && Y("undo");
1991
+ return;
1992
+ }
1993
+ if (w.hold || w.busy) return;
1994
+ if (e.target.closest("[data-review-cancel-landing]")) {
1995
+ le();
1996
+ return;
1997
+ }
1998
+ if (e.target.closest("[data-review-cancel]")) {
1999
+ H();
2000
+ return;
2001
+ }
2002
+ if (e.target.closest("[data-review-retry]")) {
2003
+ j("[data-review-loadfail-text]").textContent = "Reading the reviews again …", q(w.key);
2004
+ return;
2005
+ }
2006
+ let t = e.target.closest("[data-review]");
2007
+ if (!t) return;
2008
+ let n = t.dataset.review;
2009
+ w.asking && w.asking.verdict !== n && (w.asking = null, B()), t.getAttribute("aria-disabled") !== "true" && w.reviewable && (n === "notes" && !w.noting ? V() : oe(n));
2010
+ }
2011
+ function oe(e) {
2012
+ if (w.message = "", w.hint = "", w.sent = null, t.offline()) {
2013
+ w.asking = null, w.message = De(t, e === "approved" ? "Your approval" : "Your send back"), B();
2014
+ return;
2015
+ }
2016
+ let n = [];
2017
+ if (e === "notes") {
2018
+ let e = A(j("#review-note").value);
2019
+ if (e) {
2020
+ w.message = e, w.noting = !0, B(), p() && he(t, "proposal"), j("#review-note").focus();
2021
+ return;
2022
+ }
2023
+ let r = kn({ form: F() });
2024
+ if (r.asks && !(w.asking && w.asking.verdict === "notes")) {
2025
+ w.asking = {
2026
+ verdict: "notes",
2027
+ answered: []
2028
+ }, B(), E(t, r.ask);
2029
+ return;
2030
+ }
2031
+ n = r.reasons.map((e) => e.key);
2032
+ } else {
2033
+ let e = z();
2034
+ if (e.approve === "refused" || e.approve === "done" || e.approve === "reading") {
2035
+ B();
2036
+ return;
2037
+ }
2038
+ if (e.approve === "asks" && !(w.asking && w.asking.verdict === "approved")) {
2039
+ w.asking = {
2040
+ verdict: "approved",
2041
+ answered: []
2042
+ }, B();
2043
+ return;
2044
+ }
2045
+ n = e.reasons.map((e) => e.key);
2046
+ }
2047
+ se(e, n);
2048
+ }
2049
+ function se(e, t) {
2050
+ let n = {
2051
+ ...s.proposalSha256 ? { sha256: s.proposalSha256 } : {},
2052
+ ...w.facts && w.facts.pull && w.facts.pull.head ? { headSha: w.facts.pull.head } : {}
2053
+ }, r = {
2054
+ ...a(e, e === "notes" ? j("#review-note").value : "", P()),
2055
+ ...n
2056
+ };
2057
+ w.asking = null;
2058
+ let i = {
2059
+ verdict: e,
2060
+ body: r,
2061
+ answered: t,
2062
+ left: cn / 1e3,
2063
+ tick: null,
2064
+ end: null
2065
+ };
2066
+ w.hold = i, i.tick = setInterval(() => {
2067
+ i.left = Math.max(0, i.left - 1), B();
2068
+ }, 1e3), i.end = setTimeout(() => {
2069
+ ce(i);
2070
+ }, cn), j("[data-review-hold-fill]").style.animationDuration = `${cn}ms`, B(), j("[data-review-hold-live]").textContent = Mn(e, cn / 1e3);
2071
+ let o = N();
2072
+ o && o.focus();
2073
+ }
2074
+ function Y(e, { quiet: n = !1 } = {}) {
2075
+ let r = w.hold;
2076
+ if (!r) return;
2077
+ clearInterval(r.tick), clearTimeout(r.end), w.hold = null;
2078
+ let i = Nn(r.verdict, e);
2079
+ if (e === "closed" || e === "other" ? n || E(t, i) : w.message = i, C) return;
2080
+ B();
2081
+ let a = j("[data-review-hold-live]");
2082
+ a && (a.textContent = e === "closed" || e === "other" ? "" : i), e !== "closed" && e !== "other" && M(r.verdict)?.focus();
2083
+ }
2084
+ async function ce(e) {
2085
+ if (w.hold !== e) return;
2086
+ if (clearInterval(e.tick), t.offline()) {
2087
+ Y("offline");
2088
+ return;
2089
+ }
2090
+ if (t.hidden()) {
2091
+ Y("hidden");
2092
+ return;
2093
+ }
2094
+ let n = w.key;
2095
+ if (e.verdict === "approved" && w.reviewable && await G({ fresh: !0 }), C || w.hold !== e || n !== w.key) return;
2096
+ let r = w.facts && w.facts.pull ? w.facts.pull.head : null;
2097
+ if (e.verdict === "approved" && e.body.headSha && r && r !== e.body.headSha) {
2098
+ Y("pushed");
2099
+ return;
2100
+ }
2101
+ if (e.verdict === "approved" && wn(Sn({
2102
+ facts: w.facts,
2103
+ edits: e.body.edits.length,
2104
+ form: F()
2105
+ }), e.answered).length) {
2106
+ w.hold = null, w.asking = {
2107
+ verdict: "approved",
2108
+ answered: e.answered
2109
+ }, B(), M("approved")?.focus();
2110
+ return;
2111
+ }
2112
+ w.hold = null;
2113
+ let i = j("[data-review-hold-live]");
2114
+ i && (i.textContent = ""), await ue(e.verdict, { body: e.body });
2115
+ }
2116
+ async function le() {
2117
+ let e = L(s.proposalSource);
2118
+ if (!e) return;
2119
+ w.busy = !0, B();
2120
+ let n = "";
2121
+ try {
2122
+ let t = await g(`/api/forge/pulls/${e}/landing/cancel`, {
2123
+ method: "POST",
2124
+ headers: { "Content-Type": "application/json" },
2125
+ body: "{}"
2126
+ });
2127
+ if (!t.ok) {
2128
+ W(t.status, "landing");
2129
+ let e = "";
2130
+ try {
2131
+ e = (await t.json()).error || "";
2132
+ } catch {}
2133
+ n = An(t.status, e);
2134
+ }
2135
+ } catch {
2136
+ n = De(t, "Cancelling the landing");
2137
+ }
2138
+ C || (w.busy = !1, w.message = n, await G({ fresh: !0 }), C || (B(), n || E(t, "Landing cancelled. The approval stands and the PR stays open."), (M("approved") || M("notes"))?.focus()));
2139
+ }
2140
+ async function ue(e, n = {}) {
2141
+ if (C || !s.proposal || !T() || !w.reviewable) return !1;
2142
+ let r = j("#review-note"), i = e === "notes" ? r.value : "";
2143
+ if (w.hint = "", e === "notes" && !n.body) {
2144
+ let e = A(i);
2145
+ if (e) return w.message = e, w.noting = !0, B(), p() && he(t, "proposal"), r.focus(), !1;
2146
+ }
2147
+ w.message = "", w.busy = !0, B();
2148
+ let o = w.key, c = T(), l = s.proposalSource || null, d = n.body || a(e, i, P()), f = t.ask("whatif:describe"), m = e === "notes" && Array.isArray(f) ? f : [], h, _ = e === "approved" ? "Your approval" : "Your send back", v;
2149
+ try {
2150
+ v = await g(O(), {
2151
+ method: "PUT",
2152
+ headers: { "Content-Type": "application/json" },
2153
+ body: JSON.stringify(d)
2154
+ });
2155
+ } catch {
2156
+ return C || (w.busy = !1, w.message = De(t, _), B()), !1;
2157
+ }
2158
+ if (C) return !1;
2159
+ try {
2160
+ let e = null;
2161
+ try {
2162
+ e = await v.json();
2163
+ } catch {}
2164
+ if (v.status === 401 || v.redirected) throw Object.assign(/* @__PURE__ */ Error(""), { status: 401 });
2165
+ if (!v.ok) throw Object.assign(Error(e && e.error || ""), { status: v.status });
2166
+ h = e;
2167
+ } catch (e) {
2168
+ return C || (w.busy = !1, w.message = An(e.status || v.status, e.message), B(), W(e.status || v.status, "send"), (v.status === 409 || v.status === 429) && o === w.key && (q(o), G({ fresh: !0 }))), !1;
2169
+ }
2170
+ if (w.busy = !1, o !== w.key) return t.emit("decision", {
2171
+ outcome: e,
2172
+ review: h,
2173
+ slug: c,
2174
+ source: l,
2175
+ open: !1
2176
+ }), !0;
2177
+ w.review = {
2178
+ verdict: h.verdict,
2179
+ at: h.at,
2180
+ current: h.verdict === "approved"
2181
+ }, w.hint = e === "approved" ? u(e, d.edits.length) : "", h.posted === !1 && (w.hint = `It was approved already${h.by ? ` by ${h.by}` : ""}; nothing new was posted.`), re(o), e === "notes" && m.length && (w.sent = {
2182
+ key: `${h.at}`,
2183
+ lines: m
2184
+ }), r.value = "";
2185
+ let y = w.noting;
2186
+ w.noting = !1, B();
2187
+ let b = t.active(), x = !b || b === t.doc.body || !b.isConnected || b.hidden;
2188
+ return e === "approved" ? x && M("approved")?.focus() : (y || x) && M("notes")?.focus(), t.emit("decision", {
2189
+ outcome: e,
2190
+ review: h,
2191
+ slug: c,
2192
+ source: l,
2193
+ open: !0
2194
+ }), t.emit("mockups:refresh"), e === "notes" && t.emit("whatif:clear"), G({ fresh: !0 }), !0;
2195
+ }
2196
+ l.listen(y, "click", J), l.listen(b, "input", (e) => {
2197
+ e.target && e.target.id === "review-note" && te(w.key, e.target.value), w.message && (w.message = "", B());
2198
+ }), l.listen(b, "keydown", (e) => {
2199
+ e.key === "Escape" && w.noting && !w.asking && !w.hold && (e.stopPropagation(), H());
2200
+ }), l.listen(m, "keydown", (e) => {
2201
+ e.repeat && (e.key === "Enter" || e.key === " ") && e.target && e.target.closest && e.target.closest("#review-decision [data-review], #review-decision [data-review-undo]") ? (e.preventDefault(), e.stopPropagation()) : e.key === "Escape" && w.key && (w.hold ? (e.stopPropagation(), e.preventDefault(), Y("escape")) : w.asking && (e.stopPropagation(), e.preventDefault(), w.asking = null, B()));
2202
+ }, !0), l.own(t.onNetwork((e) => {
2203
+ e ? w.hold && Y("offline") : w.loadFailed && w.key && q(w.key);
2204
+ })), l.own(t.onWindowFocus(() => ie(5e3))), l.own(t.onPageHide(() => {
2205
+ w.hold && Y("closed", { quiet: !0 });
2206
+ })), l.own(t.onHide(() => {
2207
+ w.hold && Y("hidden");
2208
+ })), l.own(t.onShown(() => ie(5e3))), l.on("proposal:bar", U), l.on("whatif:edits-changed", () => {
2209
+ w.hold && Y("edits"), B();
2210
+ }), l.on("changes:paint", () => B());
2211
+ let de = setInterval(() => {
2212
+ w.review && B();
2213
+ }, In), fe = setInterval(() => ie(), Ln);
2214
+ return l.own(() => {
2215
+ clearInterval(de), clearInterval(fe);
2216
+ }), l.own(() => {
2217
+ C = !0, w.hold &&= (clearInterval(w.hold.tick), clearTimeout(w.hold.end), null), _.forEach((e) => e.remove());
2218
+ }), U({ open: !!s.proposal }), {
2219
+ elements: _,
2220
+ sendReview: ue,
2221
+ loadFacts: G,
2222
+ paint: B,
2223
+ update() {
2224
+ U({ open: !!s.proposal });
2225
+ },
2226
+ destroy: () => l.destroy()
2227
+ };
2228
+ }
2229
+ // ../explorer/pieces/proposal.js
2230
+ var Vn = /* @__PURE__ */ e({
2231
+ markup: () => Hn,
2232
+ mount: () => Jn,
2233
+ problemsHtml: () => Un,
2234
+ proposalRowHtml: () => qn
2235
+ }), Hn = ({ edit: e = !0 } = {}) => ({
2236
+ bar: "<section id=\"proposal-bar\" class=\"hx-proposal-bar glass\" aria-label=\"Open proposal\" hidden data-corn=\"proposal-bar\"><p id=\"proposal-message\" class=\"hx-proposal-message\" data-corn=\"message\" role=\"status\" hidden></p><div id=\"proposal-ways\" class=\"hx-proposal-ways\" role=\"group\" aria-label=\"Ways on\" data-corn=\"proposal-ways\" hidden></div><div id=\"proposal-body\"><div class=\"hx-proposal-head\" data-corn=\"proposal-head\" role=\"group\" aria-label=\"Proposal actions\"><h2 id=\"proposal-title\" class=\"hx-proposal-name\" data-corn=\"proposal-title\"></h2><a id=\"proposal-source\" class=\"hx-proposal-source\" data-corn=\"proposal-source\" hidden></a><div class=\"hx-proposal-counts\"><div id=\"proposal-chip\" class=\"hx-proposal-chip\" data-corn=\"proposal-counts\"></div><p id=\"proposal-peek\" class=\"hx-proposal-peek\"></p><button type=\"button\" id=\"proposal-mode\" class=\"hx-proposal-mode\" data-corn=\"proposal-mode\" data-action=\"toggle-proposal-mode\" data-peek-ok aria-expanded=\"false\" aria-controls=\"proposal-seg\" title=\"Before, Diff or After\"></button></div><div id=\"proposal-seg\" class=\"hx-seg\" data-corn=\"compare\" role=\"group\" aria-label=\"Compare\"><button data-corn=\"compare-option\" type=\"button\" class=\"hx-seg-btn\" data-action=\"proposal-view\" data-view=\"before\" aria-pressed=\"false\" data-corn-string=\"before\">Before</button><button data-corn=\"compare-option\" type=\"button\" class=\"hx-seg-btn\" data-action=\"proposal-view\" data-view=\"diff\" aria-pressed=\"true\" data-corn-string=\"diff\">Diff</button><button data-corn=\"compare-option\" type=\"button\" class=\"hx-seg-btn\" data-action=\"proposal-view\" data-view=\"after\" aria-pressed=\"false\" data-corn-string=\"after\">After</button></div><div class=\"hx-proposal-tools\"><button data-corn=\"whole-map\" data-corn-kind=\"secondary\" type=\"button\" id=\"proposal-whole\" class=\"hx-btn\" data-action=\"proposal-whole\" aria-pressed=\"false\" aria-label=\"Show the whole map\" title=\"Show the whole map\" data-peek-ok data-corn-string=\"wholeMap\" data-corn-string-aria-label=\"showWholeMap\">Whole map</button>" + (e ? "<button data-corn-kind=\"secondary\" type=\"button\" id=\"proposal-myedits\" class=\"hx-btn\" aria-pressed=\"true\" data-peek-ok data-corn-string=\"myEdits\" hidden>My edits</button><button data-corn-kind=\"secondary\" type=\"button\" id=\"proposal-edit\" class=\"hx-btn\" aria-expanded=\"false\" aria-controls=\"whatif\" title=\"Try a change: add a node or an edge, reword a scenario\">Edit</button>" : "") + "</div><div class=\"hx-proposal-more\"><button type=\"button\" id=\"proposal-more\" class=\"hx-btn hx-btn--icon\" data-action=\"toggle-proposal-more\" aria-haspopup=\"menu\" aria-expanded=\"false\" aria-controls=\"proposal-more-menu\" aria-label=\"More\" data-corn-kind=\"icon\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><circle cx=\"3\" cy=\"8\" r=\"1.5\"/><circle cx=\"8\" cy=\"8\" r=\"1.5\"/><circle cx=\"13\" cy=\"8\" r=\"1.5\"/></svg></button><div id=\"proposal-more-menu\" class=\"hx-proposal-more-menu glass\" data-corn=\"proposal-menu\" role=\"menu\" aria-label=\"More\" hidden><button type=\"button\" role=\"menuitem\" class=\"hx-btn hx-btn--quiet\" data-action=\"close-proposal\" title=\"Close the proposal and go back to the map\" data-corn-kind=\"quiet\" data-corn-string=\"closeProposal\">Close</button></div></div></div><details id=\"proposal-errors\" class=\"hx-proposal-errors\" data-corn=\"proposal-errors\" hidden><summary data-corn=\"summary\" id=\"proposal-errors-count\"></summary><ul id=\"proposal-errors-list\"></ul><p class=\"hx-faint\">The map shows what it can.</p></details></div></section>",
2237
+ menu: "<div id=\"proposal-wrap\"><button type=\"button\" id=\"proposal-btn\" class=\"hx-account-item\" data-action=\"toggle-proposals-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" title=\"Open a proposal: what a change would add, change and remove\" data-corn=\"proposals-button\"><span data-corn-string=\"proposals\">Proposals</span><span class=\"hx-faint\" aria-hidden=\"true\">▾</span></button><div id=\"proposal-menu\" class=\"hx-menu hx-menu--proposals\" hidden data-corn=\"proposals-menu\"></div></div>"
2238
+ });
2239
+ function Un(e, t = 8) {
2240
+ let n = e.slice(0, t).map((e) => `<li>${e.path ? `<code class="hx-code">${s(e.path)}</code> ` : ""}${s(e.message)}</li>`);
2241
+ return e.length > t && n.push(`<li class="hx-faint">and ${e.length - t} more</li>`), n.join("");
2242
+ }
2243
+ var Wn = (e, t) => `${e} ${t}${e === 1 ? "" : "s"}`, Gn = (e) => typeof e == "string" && /^https?:\/\//i.test(e) ? e : null;
2244
+ function Kn(e) {
2245
+ return e.pull ? `Spec PR #${e.pull.number}${e.pull.draft ? " (draft)" : ""}${e.pull.author ? ` by ${e.pull.author}` : ""}` : e.source === "checkout" ? "In the checkout" : `In worktree ${e.source}`;
2246
+ }
2247
+ function qn(e, t) {
2248
+ let n = t && t.slug === e.slug && t.source === e.source, r = `<span class="hx-proposal-title">${s(e.title || e.slug)}</span>`, i = [`<span class="hx-proposal-where">${s(Kn(e))}</span>`];
2249
+ if (e.spec && i.push(`<span>spec ${s(e.spec)}</span>`), e.error) return `<div class="hx-proposal-item is-broken" data-corn="row">${r}<span class="hx-proposal-sum hx-error-text">${s(e.error)}</span><span class="hx-proposal-meta">${i.join("")}</span></div>`;
2250
+ e.counts && i.push(`<span>${s(le(e.counts))}</span>`);
2251
+ let a = f(e.review, Date.now());
2252
+ return a && i.push(`<span class="hx-proposal-reviewed">${s(a)}</span>`), e.errors && i.push(`<span class="hx-warn">${s(Wn(e.errors, "problem"))}</span>`), `<button type="button" class="hx-proposal-item${n ? " is-current" : ""}" data-action="open-proposal" data-slug="${s(e.slug)}" data-source="${s(e.source)}" data-corn="row">${r}${e.summary ? `<span class="hx-proposal-sum">${s(e.summary)}</span>` : ""}<span class="hx-proposal-meta">${i.join("")}</span></button>`;
2253
+ }
2254
+ function Jn(e, t, i = {}) {
2255
+ let { state: a } = t, o = n(t), c = !!i.inline, l = Hn({ edit: i.edit !== !1 && !c }), u = [...r(t, e, l.bar, i.slots, "bar"), ...c ? [] : r(t, e, l.menu, i.slots, "menu")], d = c ? e : t.root, f = (e) => {
2256
+ for (let t of u) {
2257
+ if (t.id === e) return t;
2258
+ let n = t.querySelector(`[id="${e}"]`);
2259
+ if (n) return n;
2260
+ }
2261
+ return null;
2262
+ };
2263
+ o.keepParts(...u);
2264
+ let p = f("proposal-bar"), h = null, g = null, v = !1;
2265
+ function y({ text: e, isError: t, ways: n }) {
2266
+ p.hidden = !1, p.classList.toggle("is-error", t), f("proposal-body").hidden = !0;
2267
+ let r = f("proposal-message");
2268
+ r.hidden = !1, r.textContent = e;
2269
+ let i = f("proposal-ways");
2270
+ i.hidden = n.length === 0, i.innerHTML = n.map((e) => `<button type="button" class="hx-btn" data-action="proposal-way" data-way="${s(e.way)}"${e.slug ? ` data-slug="${s(e.slug)}"` : ""}${e.source ? ` data-source="${s(e.source)}"` : ""} data-peek-ok data-corn-kind="quiet">${s(e.label)}</button>`).join(""), m(i);
2271
+ }
2272
+ let b = t.slot("proposal-pulls", () => /* @__PURE__ */ new Map()), w = null;
2273
+ function T() {
2274
+ let e = f("proposal-source"), n = a.proposal ? a.proposalSource : null;
2275
+ if (e.hidden = !n, !n) return;
2276
+ let r = L(n), i = r ? b.get(r) : null, o = Ft(t).entries, s = r && Array.isArray(o) ? o.find((e) => e.slug === a.proposalSlug && e.source === n) : null, c = te(n, i && i.pull || s && s.pull || null, i ? i.checks : null);
2277
+ e.textContent = c.text, c.state ? e.dataset.cornState = c.state : delete e.dataset.cornState;
2278
+ let l = Gn(c.href);
2279
+ l ? (e.setAttribute("href", l), e.setAttribute("target", "_blank"), e.setAttribute("rel", "noreferrer"), e.title = "Open this pull request") : (e.removeAttribute("href"), e.removeAttribute("target"), e.removeAttribute("rel"), e.title = c.label);
2280
+ let u = `${n}/${a.proposalSlug}`;
2281
+ r && w !== u && (w = u, ee(r));
2282
+ }
2283
+ async function ee(e) {
2284
+ try {
2285
+ let n = await Oe(t)(`/api/forge/pulls/${e}`), r = n.ok ? await n.json() : null;
2286
+ if (v) return;
2287
+ r && r.ok !== !1 && r.pull && b.set(e, {
2288
+ pull: r.pull,
2289
+ checks: Array.isArray(r.checks) ? r.checks : null
2290
+ }), r && r.pull && L(a.proposalSource) === e && t.emit("proposal:pull-head", r.pull.head && typeof r.pull.head.sha == "string" ? r.pull.head.sha : "");
2291
+ } catch {}
2292
+ !v && a.proposal && L(a.proposalSource) === e && T();
2293
+ }
2294
+ function D({ open: e = !!a.proposal } = {}) {
2295
+ if (p.hidden = !e, !e) {
2296
+ N(), R(!1), c || pe(t, "proposal");
2297
+ return;
2298
+ }
2299
+ p.classList.remove("is-error"), f("proposal-message").hidden = !0, f("proposal-body").hidden = !1;
2300
+ let n = a.proposal, r = f("proposal-title");
2301
+ r.textContent = n && typeof n.title == "string" && n.title || a.proposalSlug || "Proposal", T(), r.title = n && typeof n.summary == "string" && n.summary || "";
2302
+ let i = f("proposal-chip");
2303
+ i.innerHTML = se(ne(n)).map((e) => {
2304
+ let t = e.mark ? `<span class="hx-mark-dot hx-mark-dot--${e.mark}" data-corn="mark-dot"${P(e.mark)} aria-hidden="true"></span>` : "";
2305
+ return !e.mark && /scenarios?$/.test(e.text) ? `<button type="button" class="hx-proposal-count" data-action="review-show-scenarios" data-corn-kind="quiet" title="Show the personas and their scenarios">${s(e.text)}</button>` : `<button type="button" class="hx-proposal-count" data-action="review-show-changes" data-corn-kind="quiet" title="Show the list of changes">${t}${s(e.text)}</button>`;
2306
+ }).join("<span class=\"hx-proposal-sep\" aria-hidden=\"true\"> · </span>");
2307
+ let o = K(a.whatIf && a.whatIf.edits, !!a.whatIfOff);
2308
+ o && i.insertAdjacentHTML("beforeend", `<span class="hx-proposal-sep" aria-hidden="true"> · </span><span class="hx-proposal-count hx-proposal-yours"><span class="hx-mark-dot hx-mark-dot--edit" data-corn="mark-dot" data-corn-state="edit" aria-hidden="true"></span>${s(o)}</span>`), m(i), f("proposal-mode").textContent = S(t, a.proposalView);
2309
+ for (let e of p.querySelectorAll("[data-action=\"proposal-view\"]")) {
2310
+ let t = e.dataset.view === a.proposalView;
2311
+ e.setAttribute("aria-pressed", String(t)), e.classList.toggle("is-on", t);
2312
+ }
2313
+ let l = f("proposal-whole"), u = !!(a.review && a.review.whole);
2314
+ l.setAttribute("aria-pressed", String(u)), l.title = S(t, "showWholeMap"), l.classList.toggle("hx-btn--active", u);
2315
+ let d = a.proposalErrors || [], h = f("proposal-errors");
2316
+ h.hidden = d.length === 0, d.length && (f("proposal-errors-count").textContent = `${Wn(d.length, "problem")} in this proposal`, f("proposal-errors-list").innerHTML = Un(d));
2317
+ }
2318
+ function O() {
2319
+ let e = f("proposal-body");
2320
+ if (h && h.isConnected) return h;
2321
+ h = t.doc.createElement("p"), h.className = "hx-waiting-line", h.dataset.corn = "waiting-line", h.setAttribute("part", "waiting-line"), h.dataset.cornState = "waiting", h.hidden = !0, h.innerHTML = "<span data-waiting-words></span> <button type=\"button\" class=\"hx-btn hx-forge-act\" data-waiting-answer data-peek-ok data-corn-kind=\"secondary\"></button>";
2322
+ let n = e.querySelector(".hx-proposal-head");
2323
+ return n ? n.after(h) : e.append(h), h;
2324
+ }
2325
+ function k(e, n) {
2326
+ let r = O();
2327
+ if (r.hidden = !e, !e) {
2328
+ g = null;
2329
+ return;
2330
+ }
2331
+ let i = F(e);
2332
+ r.querySelector("[data-waiting-words]").textContent = i;
2333
+ let a = r.querySelector("[data-waiting-answer]");
2334
+ a.textContent = S(t, "answer"), a.dataset.waitingAnswer = e.runId, a.setAttribute("aria-label", `${S(t, "answer")}: ${i}`);
2335
+ let o = `${n}|${e.runId}`;
2336
+ g !== o && (g = o, E(t, i));
2337
+ }
2338
+ let A = () => [...p.querySelectorAll("#proposal-more-menu [role=\"menuitem\"]")], j = () => {
2339
+ let e = f("proposal-more-menu");
2340
+ return !!e && !e.hidden;
2341
+ };
2342
+ function N(e = !1) {
2343
+ f("proposal-more-menu").hidden = !0;
2344
+ let t = f("proposal-more");
2345
+ t.setAttribute("aria-expanded", "false"), e && t.focus();
2346
+ }
2347
+ function I(e = "first") {
2348
+ f("proposal-more-menu").hidden = !1, f("proposal-more").setAttribute("aria-expanded", "true");
2349
+ let t = A();
2350
+ (e === "last" ? t[t.length - 1] : t[0])?.focus();
2351
+ }
2352
+ function R(e) {
2353
+ let t = typeof e == "boolean" ? e : p.dataset.modeOpen !== "true";
2354
+ p.dataset.modeOpen = String(t), f("proposal-mode").setAttribute("aria-expanded", String(t));
2355
+ }
2356
+ function z(e) {
2357
+ let n = f("proposal-more");
2358
+ if (e.target === n && (e.key === "ArrowDown" || e.key === "ArrowUp")) {
2359
+ e.preventDefault(), I(e.key === "ArrowUp" ? "last" : "first");
2360
+ return;
2361
+ }
2362
+ if (!j()) return;
2363
+ if (e.key === "Escape") {
2364
+ e.preventDefault(), N(!0);
2365
+ return;
2366
+ }
2367
+ if (e.key === "Tab") {
2368
+ N();
2369
+ return;
2370
+ }
2371
+ let r = A(), i = r.indexOf(t.active());
2372
+ if (i < 0) return;
2373
+ let a = {
2374
+ ArrowDown: (i + 1) % r.length,
2375
+ ArrowUp: (i - 1 + r.length) % r.length,
2376
+ Home: 0,
2377
+ End: r.length - 1
2378
+ }[e.key];
2379
+ a !== void 0 && (e.preventDefault(), r[a].focus());
2380
+ }
2381
+ let B = () => {
2382
+ let e = f("proposal-menu");
2383
+ return !!e && !e.hidden;
2384
+ };
2385
+ function H() {
2386
+ let e = f("proposal-menu");
2387
+ e && (e.hidden = !0, f("proposal-btn").setAttribute("aria-expanded", "false"));
2388
+ }
2389
+ async function U() {
2390
+ let e = f("proposal-menu");
2391
+ if (e) {
2392
+ if (B()) return H();
2393
+ e.hidden = !1, f("proposal-btn").setAttribute("aria-expanded", "true"), Ft(t).entries || W(!0), await It(t);
2394
+ }
2395
+ }
2396
+ function W(e = !1) {
2397
+ let n = f("proposal-menu");
2398
+ if (!n) return;
2399
+ let { entries: r, problem: i, forgeProblem: o } = Ft(t), c = a.proposal ? {
2400
+ slug: a.proposalSlug,
2401
+ source: a.proposalSource
2402
+ } : null, l;
2403
+ l = e && !r ? "<p class=\"hx-faint hx-proposal-empty\">Looking for proposals …</p>" : i ? `<p class="hx-error-text hx-proposal-empty">The list could not be loaded: ${s(i)}</p>` : !r || r.length === 0 ? "<p class=\"hx-faint hx-proposal-empty\">No proposals</p>" : `<div class="hx-proposal-list" role="list">${r.map((e) => `<div role="listitem">${qn(e, c)}</div>`).join("")}</div>`;
2404
+ let u = o && !i ? `<p class="hx-error-text hx-proposal-empty">The spec PRs could not be listed: ${s(o)}</p>` : "";
2405
+ n.innerHTML = `<div class="hx-menu-title hx-menu-head" data-corn="menu-title"><span>${s(S(t, "proposals"))}</span></div>${u}${l}`, m(n);
2406
+ }
2407
+ async function G(e, n) {
2408
+ let r = await Rt(t, e, n);
2409
+ if (v) return;
2410
+ let i = r ? f("proposal-title") : p.querySelector("#proposal-ways [data-way=\"retry\"]");
2411
+ i && (r && (i.tabIndex = -1), i.focus());
2412
+ }
2413
+ function re() {
2414
+ Ut(t), a.canvas && a.canvas.focus();
2415
+ }
2416
+ function ie() {
2417
+ t.ask("work:open-specs") !== !0 && (B() || U());
2418
+ }
2419
+ let ae = {
2420
+ "toggle-proposals-menu": () => U(),
2421
+ "open-proposal": (e) => Rt(t, e.dataset.slug, e.dataset.source || null),
2422
+ "close-proposal": () => {
2423
+ Ut(t), c && a.canvas && a.canvas.focus();
2424
+ },
2425
+ "proposal-whole": () => {
2426
+ Ce(t, !(a.review && a.review.whole)), Vt(t);
2427
+ },
2428
+ "proposal-view": (e) => {
2429
+ Wt(t, e.dataset.view), R(!1);
2430
+ },
2431
+ "toggle-proposal-mode": () => R(),
2432
+ "toggle-proposal-more": () => j() ? N() : I(),
2433
+ "review-show-changes": () => t.emit("changes:show", "changes"),
2434
+ "review-show-scenarios": () => t.emit("changes:show", "scenarios"),
2435
+ "proposal-way": (e) => e.dataset.way === "open" ? Rt(t, e.dataset.slug, e.dataset.source || null) : e.dataset.way === "retry" ? G(e.dataset.slug, e.dataset.source || null) : e.dataset.way === "close" ? re() : ie()
2436
+ };
2437
+ o.listen(d, "click", (e) => {
2438
+ let t = e.target.closest ? e.target.closest("[data-action]") : null, n = t && Object.hasOwn(ae, t.dataset.action) && ae[t.dataset.action];
2439
+ n && n(t), j() && !(t && t.dataset.action === "toggle-proposal-more") && N(!!(t && t.closest("#proposal-more-menu")));
2440
+ let r = f("proposal-wrap");
2441
+ B() && r && !r.contains(e.target) && !(t && t.dataset.action === "proposal-way") && H();
2442
+ }), c && o.listen(p, "focusout", (e) => {
2443
+ j() && !(e.relatedTarget && p.contains(e.relatedTarget)) && N();
2444
+ }), o.listen(p, "click", (e) => {
2445
+ let n = e.target.closest && e.target.closest("[data-waiting-answer]");
2446
+ n && (e.preventDefault(), e.stopPropagation(), t.emit("work:answer", { run: n.dataset.waitingAnswer }));
2447
+ }, !0);
2448
+ let q = (e) => {
2449
+ let t = f("proposal-wrap");
2450
+ t && (t.hidden = !!e);
2451
+ };
2452
+ o.on("work:available", ({ on: e }) => q(e)), t.ask("work:on") && q(!0), o.listen(d, "keydown", (e) => {
2453
+ e.key === "Escape" && B() && H(), z(e);
2454
+ });
2455
+ function J() {
2456
+ let e = t.tokenElement();
2457
+ if (!e || !e.style) return;
2458
+ let { mark: n } = _(x(a.theme), C(t).get());
2459
+ for (let t of Object.keys(n)) e.style.setProperty(`--hx-mark-${t}`, n[t].color);
2460
+ }
2461
+ if (J(), o.on("theme", J), o.own(C(t).onChange(() => J())), o.on("proposal:draw", ({ open: e }) => D({ open: e })), o.on("changes:peek", (e) => {
2462
+ f("proposal-peek").textContent = e;
2463
+ }), o.on("proposal:focus-title", () => {
2464
+ let e = f("proposal-title");
2465
+ e.tabIndex = -1, e.focus();
2466
+ }), o.on("proposal:message", (e) => y(e)), o.on("proposal:listing", () => {
2467
+ W(), a.proposal && T();
2468
+ }), o.on("proposal:waiting", ({ run: e, key: t }) => k(e, t)), o.on("proposal:waiting-reset", () => {
2469
+ g = null, h = null;
2470
+ }), o.on("proposal", ({ change: e }) => {
2471
+ e === "opened" && H();
2472
+ }), !c) {
2473
+ o.own(Qt(t, (e, t, n) => o.listen(e, t, n))), fe(t), ue(t, "proposal", p, { stub: () => ({ title: f("proposal-title") && f("proposal-title").textContent || "Proposal" }) }), o.own(() => de(t, "proposal")), o.on("proposal:covers", () => p.hidden || !p.isConnected ? void 0 : { bottom: p.getBoundingClientRect().bottom }), o.on("proposal:bar-bottom", () => p.hidden ? void 0 : Math.round(p.offsetTop + p.offsetHeight + 8)), o.on("proposal:seat-column", ({ column: e, phone: t }) => {
2474
+ let n = f("proposal-body");
2475
+ return t && n ? (e.parentElement !== n && n.appendChild(e), !0) : (p.parentElement && e.parentElement !== p.parentElement && p.after(e), !0);
2476
+ });
2477
+ let e = t.win && t.win.ResizeObserver;
2478
+ if (typeof e == "function") {
2479
+ let n = new e(() => t.emit("proposal:bar-resize"));
2480
+ n.observe(p), o.own(() => n.disconnect());
2481
+ }
2482
+ }
2483
+ o.on("popup:open", () => j() ? !0 : void 0), o.own(() => {
2484
+ v = !0, u.forEach((e) => e.remove());
2485
+ }), D();
2486
+ let oe = Lt(t);
2487
+ return oe && !a.proposal && y(oe), {
2488
+ elements: u,
2489
+ renderBar: () => Vt(t),
2490
+ paintWaitingLine: k,
2491
+ toggleMenu: U,
2492
+ closeMenu: H,
2493
+ setMessage: (e, n, r) => $(t, e, n, r),
2494
+ sayBadLink: (e) => {
2495
+ let n = M(e);
2496
+ return n && $(t, n, !0, [{
2497
+ label: S(t, "openSpecsList"),
2498
+ way: "specs"
2499
+ }]), !!n;
2500
+ },
2501
+ update(e) {
2502
+ if (!e || !("proposal" in e || "view" in e)) {
2503
+ Vt(t);
2504
+ return;
2505
+ }
2506
+ let n;
2507
+ if ("proposal" in e) {
2508
+ let r = e.proposal;
2509
+ r === null ? Ut(t) : typeof r == "string" ? n = a.proposal && a.proposalSlug === r && (e.source || null) === (a.proposalSource || null) && a.proposal ? Promise.resolve(!0) : Rt(t, r, e.source || null) : r && typeof r == "object" && zt(t, r, {
2510
+ slug: e.slug || null,
2511
+ source: e.source || null,
2512
+ pinSource: !!e.source,
2513
+ view: V.includes(e.view) ? e.view : "diff",
2514
+ sha256: e.sha256 || null
2515
+ });
2516
+ }
2517
+ return "view" in e && V.includes(e.view) && !(typeof e.proposal == "string" && n) ? Wt(t, e.view, { quiet: !0 }) : "view" in e && n && (n = n.then((n) => (n && V.includes(e.view) && Wt(t, e.view, { quiet: !0 }), n))), n;
2518
+ },
2519
+ pinnedSource: () => $t(t),
2520
+ destroy: () => o.destroy()
2521
+ };
2522
+ }
2523
+ export { Tn as a, Qt as c, Ht as d, $ as f, Bn as i, Ut as l, zt as m, Vn as n, en as o, Wt as p, Fn as r, sn as s, Jn as t, Rt as u };