@popcorn245/cornfield-components 0.52.1 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/chunks/around-BcnegEdS.js +99 -0
- package/dist/chunks/connection-KDiWvV19.js +23 -0
- package/dist/chunks/{engine-BmXtSISH.js → engine-xmHJvQY9.js} +1188 -1186
- package/dist/chunks/{layers-Bj4Tluxe.js → layers-ho10a2y7.js} +48 -48
- package/dist/chunks/{map-BZRFOYkt.js → map-DbfPgQRe.js} +385 -385
- package/dist/chunks/node-panel-CC8UrSzJ.js +410 -0
- package/dist/chunks/panel-review-ih7RlfkH.js +884 -0
- package/dist/chunks/review-pieces-DtRxCDMr.js +2523 -0
- package/dist/chunks/{review-source-CK5tYIqk.js → review-source-CmbwaPCM.js} +1 -1
- package/dist/chunks/scope-2m2VmJXn.js +185 -0
- package/dist/chunks/scope-proposal-T06ndbin.js +116 -0
- package/dist/chunks/{sheets-D-sMZzSs.js → sheets-BWANwtZP.js} +7 -2
- package/dist/chunks/source-address-DXanAREm.js +57 -0
- package/dist/chunks/{status-DI5QLlAp.js → status-DM-iIEsg.js} +4 -3
- package/dist/corn-changes.js +43 -0
- package/dist/corn-decision.js +52 -0
- package/dist/corn-layers.js +275 -1
- package/dist/corn-map.js +125 -1
- package/dist/corn-node-panel.js +42 -1
- package/dist/corn-proposal.js +50 -0
- package/dist/corn-review.js +425 -1
- package/dist/corn-scope.js +33 -9
- package/dist/corn-search.js +484 -1
- package/dist/index.js +11 -8
- package/dist/manifest.json +95 -70
- package/dist/tokens.css +6 -0
- package/dist/types/components.d.ts +111 -5
- package/dist/types/corn-changes.d.ts +2 -0
- package/dist/types/corn-decision.d.ts +2 -0
- package/dist/types/corn-proposal.d.ts +2 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/version.json +1 -1
- package/package.json +17 -5
- package/dist/chunks/around-BFqYTZ0K.js +0 -78
- package/dist/chunks/corn-layers-Cni5rISZ.js +0 -275
- package/dist/chunks/corn-map-B2-YxiEL.js +0 -125
- package/dist/chunks/corn-node-panel-BkvJThlp.js +0 -42
- package/dist/chunks/corn-review-5wf7AT4o.js +0 -2900
- package/dist/chunks/corn-search-CXs5d06S.js +0 -484
- package/dist/chunks/node-panel-BdvFvWCE.js +0 -1291
- package/dist/chunks/scope-CqPbHcKL.js +0 -137
- 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 };
|