@wral/report-it 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -3
- package/dist/define.mjs +1 -1
- package/dist/define.standalone.js +1466 -1273
- package/dist/index.mjs +134 -79
- package/dist/{wral-code-input-DCemMj53.js → wral-code-input-BZTBgLk3.js} +1037 -609
- package/package.json +1 -1
|
@@ -1,6 +1,222 @@
|
|
|
1
|
-
import { css as
|
|
2
|
-
import { getAuthContext as
|
|
3
|
-
const
|
|
1
|
+
import { css as y, html as c, nothing as f, LitElement as G } from "lit";
|
|
2
|
+
import { getAuthContext as Se, createStorage as Ce, verifyCode as Te, extractTokens as Z, saveTokens as X, decodeJwtPayload as ee, refreshTokenSimple as te, sendCode as Re, createUserPool as Me, signUpIfNeeded as De, createCognitoUser as Pe, STORAGE_KEYS as S, isAuthenticatedSimple as ze } from "@wral/sdk-auth-audience";
|
|
3
|
+
const K = globalThis, re = (s) => s, B = K.trustedTypes, se = B ? B.createPolicy("lit-html", { createHTML: (s) => s }) : void 0, xe = "$lit$", v = `lit$${Math.random().toFixed(9).slice(2)}$`, ve = "?" + v, Be = `<${ve}>`, A = document, O = () => A.createComment(""), R = (s) => s === null || typeof s != "object" && typeof s != "function", Q = Array.isArray, Oe = (s) => Q(s) || typeof s?.[Symbol.iterator] == "function", H = `[
|
|
4
|
+
\f\r]`, C = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, ie = /-->/g, ne = />/g, $ = RegExp(`>|${H}(?:([^\\s"'>=/]+)(${H}*=${H}*(?:[^
|
|
5
|
+
\f\r"'\`<>=]|("|')|))|$)`, "g"), oe = /'/g, ae = /"/g, _e = /^(?:script|style|textarea|title)$/i, M = /* @__PURE__ */ Symbol.for("lit-noChange"), m = /* @__PURE__ */ Symbol.for("lit-nothing"), le = /* @__PURE__ */ new WeakMap(), k = A.createTreeWalker(A, 129);
|
|
6
|
+
function $e(s, e) {
|
|
7
|
+
if (!Q(s) || !s.hasOwnProperty("raw")) throw Error("invalid template strings array");
|
|
8
|
+
return se !== void 0 ? se.createHTML(e) : e;
|
|
9
|
+
}
|
|
10
|
+
const Ue = (s, e) => {
|
|
11
|
+
const t = s.length - 1, r = [];
|
|
12
|
+
let i, n = e === 2 ? "<svg>" : e === 3 ? "<math>" : "", o = C;
|
|
13
|
+
for (let a = 0; a < t; a++) {
|
|
14
|
+
const l = s[a];
|
|
15
|
+
let d, p, u = -1, h = 0;
|
|
16
|
+
for (; h < l.length && (o.lastIndex = h, p = o.exec(l), p !== null); ) h = o.lastIndex, o === C ? p[1] === "!--" ? o = ie : p[1] !== void 0 ? o = ne : p[2] !== void 0 ? (_e.test(p[2]) && (i = RegExp("</" + p[2], "g")), o = $) : p[3] !== void 0 && (o = $) : o === $ ? p[0] === ">" ? (o = i ?? C, u = -1) : p[1] === void 0 ? u = -2 : (u = o.lastIndex - p[2].length, d = p[1], o = p[3] === void 0 ? $ : p[3] === '"' ? ae : oe) : o === ae || o === oe ? o = $ : o === ie || o === ne ? o = C : (o = $, i = void 0);
|
|
17
|
+
const b = o === $ && s[a + 1].startsWith("/>") ? " " : "";
|
|
18
|
+
n += o === C ? l + Be : u >= 0 ? (r.push(d), l.slice(0, u) + xe + l.slice(u) + v + b) : l + v + (u === -2 ? a : b);
|
|
19
|
+
}
|
|
20
|
+
return [$e(s, n + (s[t] || "<?>") + (e === 2 ? "</svg>" : e === 3 ? "</math>" : "")), r];
|
|
21
|
+
};
|
|
22
|
+
class D {
|
|
23
|
+
constructor({ strings: e, _$litType$: t }, r) {
|
|
24
|
+
let i;
|
|
25
|
+
this.parts = [];
|
|
26
|
+
let n = 0, o = 0;
|
|
27
|
+
const a = e.length - 1, l = this.parts, [d, p] = Ue(e, t);
|
|
28
|
+
if (this.el = D.createElement(d, r), k.currentNode = this.el.content, t === 2 || t === 3) {
|
|
29
|
+
const u = this.el.content.firstChild;
|
|
30
|
+
u.replaceWith(...u.childNodes);
|
|
31
|
+
}
|
|
32
|
+
for (; (i = k.nextNode()) !== null && l.length < a; ) {
|
|
33
|
+
if (i.nodeType === 1) {
|
|
34
|
+
if (i.hasAttributes()) for (const u of i.getAttributeNames()) if (u.endsWith(xe)) {
|
|
35
|
+
const h = p[o++], b = i.getAttribute(u).split(v), w = /([.?@])?(.*)/.exec(h);
|
|
36
|
+
l.push({ type: 1, index: n, name: w[2], strings: b, ctor: w[1] === "." ? Ne : w[1] === "?" ? qe : w[1] === "@" ? He : L }), i.removeAttribute(u);
|
|
37
|
+
} else u.startsWith(v) && (l.push({ type: 6, index: n }), i.removeAttribute(u));
|
|
38
|
+
if (_e.test(i.tagName)) {
|
|
39
|
+
const u = i.textContent.split(v), h = u.length - 1;
|
|
40
|
+
if (h > 0) {
|
|
41
|
+
i.textContent = B ? B.emptyScript : "";
|
|
42
|
+
for (let b = 0; b < h; b++) i.append(u[b], O()), k.nextNode(), l.push({ type: 2, index: ++n });
|
|
43
|
+
i.append(u[h], O());
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} else if (i.nodeType === 8) if (i.data === ve) l.push({ type: 2, index: n });
|
|
47
|
+
else {
|
|
48
|
+
let u = -1;
|
|
49
|
+
for (; (u = i.data.indexOf(v, u + 1)) !== -1; ) l.push({ type: 7, index: n }), u += v.length - 1;
|
|
50
|
+
}
|
|
51
|
+
n++;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
static createElement(e, t) {
|
|
55
|
+
const r = A.createElement("template");
|
|
56
|
+
return r.innerHTML = e, r;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function E(s, e, t = s, r) {
|
|
60
|
+
if (e === M) return e;
|
|
61
|
+
let i = r !== void 0 ? t._$Co?.[r] : t._$Cl;
|
|
62
|
+
const n = R(e) ? void 0 : e._$litDirective$;
|
|
63
|
+
return i?.constructor !== n && (i?._$AO?.(!1), n === void 0 ? i = void 0 : (i = new n(s), i._$AT(s, t, r)), r !== void 0 ? (t._$Co ??= [])[r] = i : t._$Cl = i), i !== void 0 && (e = E(s, i._$AS(s, e.values), i, r)), e;
|
|
64
|
+
}
|
|
65
|
+
class Le {
|
|
66
|
+
constructor(e, t) {
|
|
67
|
+
this._$AV = [], this._$AN = void 0, this._$AD = e, this._$AM = t;
|
|
68
|
+
}
|
|
69
|
+
get parentNode() {
|
|
70
|
+
return this._$AM.parentNode;
|
|
71
|
+
}
|
|
72
|
+
get _$AU() {
|
|
73
|
+
return this._$AM._$AU;
|
|
74
|
+
}
|
|
75
|
+
u(e) {
|
|
76
|
+
const { el: { content: t }, parts: r } = this._$AD, i = (e?.creationScope ?? A).importNode(t, !0);
|
|
77
|
+
k.currentNode = i;
|
|
78
|
+
let n = k.nextNode(), o = 0, a = 0, l = r[0];
|
|
79
|
+
for (; l !== void 0; ) {
|
|
80
|
+
if (o === l.index) {
|
|
81
|
+
let d;
|
|
82
|
+
l.type === 2 ? d = new U(n, n.nextSibling, this, e) : l.type === 1 ? d = new l.ctor(n, l.name, l.strings, this, e) : l.type === 6 && (d = new je(n, this, e)), this._$AV.push(d), l = r[++a];
|
|
83
|
+
}
|
|
84
|
+
o !== l?.index && (n = k.nextNode(), o++);
|
|
85
|
+
}
|
|
86
|
+
return k.currentNode = A, i;
|
|
87
|
+
}
|
|
88
|
+
p(e) {
|
|
89
|
+
let t = 0;
|
|
90
|
+
for (const r of this._$AV) r !== void 0 && (r.strings !== void 0 ? (r._$AI(e, r, t), t += r.strings.length - 2) : r._$AI(e[t])), t++;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
class U {
|
|
94
|
+
get _$AU() {
|
|
95
|
+
return this._$AM?._$AU ?? this._$Cv;
|
|
96
|
+
}
|
|
97
|
+
constructor(e, t, r, i) {
|
|
98
|
+
this.type = 2, this._$AH = m, this._$AN = void 0, this._$AA = e, this._$AB = t, this._$AM = r, this.options = i, this._$Cv = i?.isConnected ?? !0;
|
|
99
|
+
}
|
|
100
|
+
get parentNode() {
|
|
101
|
+
let e = this._$AA.parentNode;
|
|
102
|
+
const t = this._$AM;
|
|
103
|
+
return t !== void 0 && e?.nodeType === 11 && (e = t.parentNode), e;
|
|
104
|
+
}
|
|
105
|
+
get startNode() {
|
|
106
|
+
return this._$AA;
|
|
107
|
+
}
|
|
108
|
+
get endNode() {
|
|
109
|
+
return this._$AB;
|
|
110
|
+
}
|
|
111
|
+
_$AI(e, t = this) {
|
|
112
|
+
e = E(this, e, t), R(e) ? e === m || e == null || e === "" ? (this._$AH !== m && this._$AR(), this._$AH = m) : e !== this._$AH && e !== M && this._(e) : e._$litType$ !== void 0 ? this.$(e) : e.nodeType !== void 0 ? this.T(e) : Oe(e) ? this.k(e) : this._(e);
|
|
113
|
+
}
|
|
114
|
+
O(e) {
|
|
115
|
+
return this._$AA.parentNode.insertBefore(e, this._$AB);
|
|
116
|
+
}
|
|
117
|
+
T(e) {
|
|
118
|
+
this._$AH !== e && (this._$AR(), this._$AH = this.O(e));
|
|
119
|
+
}
|
|
120
|
+
_(e) {
|
|
121
|
+
this._$AH !== m && R(this._$AH) ? this._$AA.nextSibling.data = e : this.T(A.createTextNode(e)), this._$AH = e;
|
|
122
|
+
}
|
|
123
|
+
$(e) {
|
|
124
|
+
const { values: t, _$litType$: r } = e, i = typeof r == "number" ? this._$AC(e) : (r.el === void 0 && (r.el = D.createElement($e(r.h, r.h[0]), this.options)), r);
|
|
125
|
+
if (this._$AH?._$AD === i) this._$AH.p(t);
|
|
126
|
+
else {
|
|
127
|
+
const n = new Le(i, this), o = n.u(this.options);
|
|
128
|
+
n.p(t), this.T(o), this._$AH = n;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
_$AC(e) {
|
|
132
|
+
let t = le.get(e.strings);
|
|
133
|
+
return t === void 0 && le.set(e.strings, t = new D(e)), t;
|
|
134
|
+
}
|
|
135
|
+
k(e) {
|
|
136
|
+
Q(this._$AH) || (this._$AH = [], this._$AR());
|
|
137
|
+
const t = this._$AH;
|
|
138
|
+
let r, i = 0;
|
|
139
|
+
for (const n of e) i === t.length ? t.push(r = new U(this.O(O()), this.O(O()), this, this.options)) : r = t[i], r._$AI(n), i++;
|
|
140
|
+
i < t.length && (this._$AR(r && r._$AB.nextSibling, i), t.length = i);
|
|
141
|
+
}
|
|
142
|
+
_$AR(e = this._$AA.nextSibling, t) {
|
|
143
|
+
for (this._$AP?.(!1, !0, t); e !== this._$AB; ) {
|
|
144
|
+
const r = re(e).nextSibling;
|
|
145
|
+
re(e).remove(), e = r;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
setConnected(e) {
|
|
149
|
+
this._$AM === void 0 && (this._$Cv = e, this._$AP?.(e));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
class L {
|
|
153
|
+
get tagName() {
|
|
154
|
+
return this.element.tagName;
|
|
155
|
+
}
|
|
156
|
+
get _$AU() {
|
|
157
|
+
return this._$AM._$AU;
|
|
158
|
+
}
|
|
159
|
+
constructor(e, t, r, i, n) {
|
|
160
|
+
this.type = 1, this._$AH = m, this._$AN = void 0, this.element = e, this.name = t, this._$AM = i, this.options = n, r.length > 2 || r[0] !== "" || r[1] !== "" ? (this._$AH = Array(r.length - 1).fill(new String()), this.strings = r) : this._$AH = m;
|
|
161
|
+
}
|
|
162
|
+
_$AI(e, t = this, r, i) {
|
|
163
|
+
const n = this.strings;
|
|
164
|
+
let o = !1;
|
|
165
|
+
if (n === void 0) e = E(this, e, t, 0), o = !R(e) || e !== this._$AH && e !== M, o && (this._$AH = e);
|
|
166
|
+
else {
|
|
167
|
+
const a = e;
|
|
168
|
+
let l, d;
|
|
169
|
+
for (e = n[0], l = 0; l < n.length - 1; l++) d = E(this, a[r + l], t, l), d === M && (d = this._$AH[l]), o ||= !R(d) || d !== this._$AH[l], d === m ? e = m : e !== m && (e += (d ?? "") + n[l + 1]), this._$AH[l] = d;
|
|
170
|
+
}
|
|
171
|
+
o && !i && this.j(e);
|
|
172
|
+
}
|
|
173
|
+
j(e) {
|
|
174
|
+
e === m ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, e ?? "");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
class Ne extends L {
|
|
178
|
+
constructor() {
|
|
179
|
+
super(...arguments), this.type = 3;
|
|
180
|
+
}
|
|
181
|
+
j(e) {
|
|
182
|
+
this.element[this.name] = e === m ? void 0 : e;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
class qe extends L {
|
|
186
|
+
constructor() {
|
|
187
|
+
super(...arguments), this.type = 4;
|
|
188
|
+
}
|
|
189
|
+
j(e) {
|
|
190
|
+
this.element.toggleAttribute(this.name, !!e && e !== m);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
class He extends L {
|
|
194
|
+
constructor(e, t, r, i, n) {
|
|
195
|
+
super(e, t, r, i, n), this.type = 5;
|
|
196
|
+
}
|
|
197
|
+
_$AI(e, t = this) {
|
|
198
|
+
if ((e = E(this, e, t, 0) ?? m) === M) return;
|
|
199
|
+
const r = this._$AH, i = e === m && r !== m || e.capture !== r.capture || e.once !== r.once || e.passive !== r.passive, n = e !== m && (r === m || i);
|
|
200
|
+
i && this.element.removeEventListener(this.name, this, r), n && this.element.addEventListener(this.name, this, e), this._$AH = e;
|
|
201
|
+
}
|
|
202
|
+
handleEvent(e) {
|
|
203
|
+
typeof this._$AH == "function" ? this._$AH.call(this.options?.host ?? this.element, e) : this._$AH.handleEvent(e);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
class je {
|
|
207
|
+
constructor(e, t, r) {
|
|
208
|
+
this.element = e, this.type = 6, this._$AN = void 0, this._$AM = t, this.options = r;
|
|
209
|
+
}
|
|
210
|
+
get _$AU() {
|
|
211
|
+
return this._$AM._$AU;
|
|
212
|
+
}
|
|
213
|
+
_$AI(e) {
|
|
214
|
+
E(this, e);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const We = K.litHtmlPolyfillSupport;
|
|
218
|
+
We?.(D, U), (K.litHtmlVersions ??= []).push("3.3.3");
|
|
219
|
+
const ce = (s) => s ?? m, Ve = y`
|
|
4
220
|
:host {
|
|
5
221
|
display: block;
|
|
6
222
|
box-sizing: border-box;
|
|
@@ -24,7 +240,7 @@ const ne = f`
|
|
|
24
240
|
position: absolute; width: 1px; height: 1px; overflow: hidden;
|
|
25
241
|
clip: rect(0 0 0 0); white-space: nowrap;
|
|
26
242
|
}
|
|
27
|
-
`,
|
|
243
|
+
`, Ye = y`
|
|
28
244
|
@keyframes pop-in {
|
|
29
245
|
0% { opacity: 0; transform: translateY(16px) scale(0.95); }
|
|
30
246
|
100% { opacity: 1; transform: translateY(0) scale(1); }
|
|
@@ -55,7 +271,7 @@ const ne = f`
|
|
|
55
271
|
animation: none !important;
|
|
56
272
|
}
|
|
57
273
|
}
|
|
58
|
-
`,
|
|
274
|
+
`, Ge = y`
|
|
59
275
|
.msg { max-width: 85%; padding: 12px 16px; border-radius: 14px; font-size: 15px; }
|
|
60
276
|
.msg.bot {
|
|
61
277
|
background: var(--wral-semantic-surface-default, #FFFFFF);
|
|
@@ -77,7 +293,7 @@ const ne = f`
|
|
|
77
293
|
.msg .sub { display: block; font-size: 13px; color: var(--wral-semantic-fg-muted, #64748B); margin-top: 4px; }
|
|
78
294
|
.msg.user .sub { color: rgba(255, 255, 255, 0.75); }
|
|
79
295
|
.msg.error { border-left: 3px solid var(--wral-base-red-on-light, #D1232A); }
|
|
80
|
-
`,
|
|
296
|
+
`, Ke = y`
|
|
81
297
|
.options { display: flex; flex-wrap: wrap; gap: 8px; align-self: flex-start; max-width: 92%; padding: 2px 0 6px; }
|
|
82
298
|
.chip {
|
|
83
299
|
font-family: var(--wral-base-font-ui, 'IBM Plex Sans Condensed', sans-serif);
|
|
@@ -91,7 +307,7 @@ const ne = f`
|
|
|
91
307
|
.chip:hover { background: var(--wral-base-secondary-1, #2594E3); color: #FFFFFF; }
|
|
92
308
|
.chip:focus-visible { outline: 2px solid var(--wral-base-secondary-1, #2594E3); outline-offset: 2px; }
|
|
93
309
|
.chip:active { transform: scale(0.97); }
|
|
94
|
-
`,
|
|
310
|
+
`, Qe = y`
|
|
95
311
|
.form-card {
|
|
96
312
|
align-self: stretch;
|
|
97
313
|
background: var(--wral-semantic-surface-default, #FFFFFF);
|
|
@@ -156,7 +372,7 @@ const ne = f`
|
|
|
156
372
|
.btn-ghost:hover { border-color: var(--wral-base-secondary-1, #2594E3); }
|
|
157
373
|
.btn-ghost:active { transform: scale(0.97); }
|
|
158
374
|
.btn-ghost:focus-visible { outline: 2px solid var(--wral-base-secondary-1, #2594E3); outline-offset: 2px; }
|
|
159
|
-
`,
|
|
375
|
+
`, Je = y`
|
|
160
376
|
.login-card { padding: 28px 26px; }
|
|
161
377
|
.login-card h2 {
|
|
162
378
|
font-family: var(--wral-base-font-display, 'IBM Plex Sans Condensed', sans-serif);
|
|
@@ -243,7 +459,7 @@ const ne = f`
|
|
|
243
459
|
.anon-costs .x { flex-shrink: 0; font-weight: 700; color: var(--wral-base-red-on-light, #D1232A); }
|
|
244
460
|
.anon-actions { display: flex; flex-direction: column; gap: 10px; }
|
|
245
461
|
.anon-actions .btn-ghost { width: 100%; }
|
|
246
|
-
`,
|
|
462
|
+
`, Ze = y`
|
|
247
463
|
.review-list { margin: 0; padding: 0; list-style: none; font-size: 14px; }
|
|
248
464
|
.review-list li {
|
|
249
465
|
display: grid; grid-template-columns: 130px 1fr; gap: 10px;
|
|
@@ -275,7 +491,7 @@ const ne = f`
|
|
|
275
491
|
color: var(--wral-base-primary-1, #001D68);
|
|
276
492
|
}
|
|
277
493
|
@media (max-width: 540px) { .review-list li { grid-template-columns: 1fr; gap: 2px; } }
|
|
278
|
-
`,
|
|
494
|
+
`, Xe = y`
|
|
279
495
|
.upload-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; font-size: 13.5px; }
|
|
280
496
|
.upload-row .name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
281
497
|
.upload-row .state { font-size: 12px; color: var(--wral-semantic-fg-subtle, #64748B); }
|
|
@@ -291,7 +507,7 @@ const ne = f`
|
|
|
291
507
|
border-radius: 999px; padding: 3px 12px; cursor: pointer;
|
|
292
508
|
}
|
|
293
509
|
.retry-chip:focus-visible { outline: 2px solid var(--wral-base-secondary-1, #2594E3); outline-offset: 2px; }
|
|
294
|
-
`,
|
|
510
|
+
`, et = y`
|
|
295
511
|
.confirm-card {
|
|
296
512
|
align-self: stretch;
|
|
297
513
|
background: var(--wral-base-primary-1, #001D68);
|
|
@@ -341,7 +557,7 @@ const ne = f`
|
|
|
341
557
|
.c-again:hover { background: rgba(255, 255, 255, 0.12); }
|
|
342
558
|
.c-again:focus-visible { outline: 2px solid var(--wral-base-secondary-2, #50A9E8); outline-offset: 2px; }
|
|
343
559
|
.c-again:active { transform: scale(0.97); }
|
|
344
|
-
`,
|
|
560
|
+
`, tt = y`
|
|
345
561
|
.journey {
|
|
346
562
|
align-self: stretch;
|
|
347
563
|
background: var(--wral-semantic-surface-default, #FFFFFF);
|
|
@@ -382,7 +598,7 @@ const ne = f`
|
|
|
382
598
|
color: var(--wral-base-primary-1, #001D68); margin-bottom: 2px;
|
|
383
599
|
}
|
|
384
600
|
.j-body .j-d { font-size: 13.5px; color: var(--wral-semantic-fg-muted, #475569); line-height: 1.55; }
|
|
385
|
-
`,
|
|
601
|
+
`, rt = y`
|
|
386
602
|
.bottom-bar {
|
|
387
603
|
position: sticky; bottom: 0; z-index: 20;
|
|
388
604
|
background: var(--wral-semantic-surface-default, #FFFFFF);
|
|
@@ -395,74 +611,74 @@ const ne = f`
|
|
|
395
611
|
}
|
|
396
612
|
.bottom-bar .note { margin-left: auto; font-size: 12px; color: var(--wral-semantic-fg-subtle, #64748B); }
|
|
397
613
|
@media (max-width: 540px) { .bottom-bar .note { display: none; } }
|
|
398
|
-
`,
|
|
399
|
-
function
|
|
400
|
-
return
|
|
401
|
-
<div class="msg bot ${t ? "no-anim" : ""} ${
|
|
402
|
-
<span class="lead">${
|
|
403
|
-
${e ?
|
|
614
|
+
`, st = [Ve, Ye, Ge, Ke, Qe, Je, Ze, Xe, et, tt, rt];
|
|
615
|
+
function g(s, e, { noAnim: t = !1, error: r = !1 } = {}) {
|
|
616
|
+
return c`
|
|
617
|
+
<div class="msg bot ${t ? "no-anim" : ""} ${r ? "error" : ""}">
|
|
618
|
+
<span class="lead">${s}</span>
|
|
619
|
+
${e ? c`<span class="sub">${e}</span>` : f}
|
|
404
620
|
</div>
|
|
405
621
|
`;
|
|
406
622
|
}
|
|
407
|
-
function
|
|
408
|
-
return
|
|
623
|
+
function F(s, { noAnim: e = !1 } = {}) {
|
|
624
|
+
return c`<div class="msg user ${e ? "no-anim" : ""}">${s}</div>`;
|
|
409
625
|
}
|
|
410
|
-
function
|
|
411
|
-
return
|
|
626
|
+
function j() {
|
|
627
|
+
return c`<div class="msg bot typing"><span></span><span></span><span></span></div>`;
|
|
412
628
|
}
|
|
413
|
-
function
|
|
414
|
-
return
|
|
629
|
+
function it(s) {
|
|
630
|
+
return s ? c`<span class="flag-pill ${s}">${s === "urgent" ? "Urgent" : "Moderate"}</span>` : f;
|
|
415
631
|
}
|
|
416
|
-
function
|
|
417
|
-
return
|
|
632
|
+
function nt() {
|
|
633
|
+
return c`
|
|
418
634
|
<svg viewBox="0 0 24 24" fill="none" stroke="#FFFFFF" stroke-width="3"
|
|
419
635
|
stroke-linecap="round" stroke-linejoin="round" width="20" height="20"
|
|
420
636
|
aria-hidden="true"><path d="M20 6L9 17l-5-5"/></svg>
|
|
421
637
|
`;
|
|
422
638
|
}
|
|
423
|
-
const
|
|
424
|
-
class
|
|
639
|
+
const ot = 15e3;
|
|
640
|
+
class I extends Error {
|
|
425
641
|
constructor(e, t) {
|
|
426
642
|
super(`api-forms request failed with status ${e}`), this.status = e, this.body = t;
|
|
427
643
|
}
|
|
428
644
|
}
|
|
429
|
-
const
|
|
430
|
-
function
|
|
431
|
-
baseUrl:
|
|
645
|
+
const de = Object.freeze({ enabled: !1, humanCheck: null });
|
|
646
|
+
function at({
|
|
647
|
+
baseUrl: s,
|
|
432
648
|
fetchFn: e = (...i) => fetch(...i),
|
|
433
649
|
xhrFactory: t = () => new XMLHttpRequest(),
|
|
434
|
-
getAuthHeaders:
|
|
650
|
+
getAuthHeaders: r
|
|
435
651
|
}) {
|
|
436
|
-
const i = String(
|
|
437
|
-
let n =
|
|
438
|
-
async function l
|
|
439
|
-
const
|
|
440
|
-
|
|
652
|
+
const i = String(s || "").replace(/\/+$/, "");
|
|
653
|
+
let n = de, o = null;
|
|
654
|
+
async function a(l, { method: d = "GET", body: p, auth: u = !1, timeoutMs: h } = {}) {
|
|
655
|
+
const b = { Accept: "application/json" };
|
|
656
|
+
u && Object.assign(b, o ? { Authorization: `Bearer ${o}` } : await r()), p !== void 0 && (b["Content-Type"] = "application/json");
|
|
441
657
|
let w;
|
|
442
658
|
try {
|
|
443
|
-
w = await e(`${i}${
|
|
444
|
-
method:
|
|
445
|
-
headers:
|
|
446
|
-
...
|
|
447
|
-
...
|
|
659
|
+
w = await e(`${i}${l}`, {
|
|
660
|
+
method: d,
|
|
661
|
+
headers: b,
|
|
662
|
+
...h ? { signal: AbortSignal.timeout(h) } : {},
|
|
663
|
+
...p !== void 0 ? { body: JSON.stringify(p) } : {}
|
|
448
664
|
});
|
|
449
|
-
} catch (
|
|
450
|
-
throw Object.assign(new
|
|
665
|
+
} catch (P) {
|
|
666
|
+
throw Object.assign(new I(0, null), { cause: P });
|
|
451
667
|
}
|
|
452
|
-
let
|
|
668
|
+
let _ = null;
|
|
453
669
|
try {
|
|
454
|
-
|
|
670
|
+
_ = await w.json();
|
|
455
671
|
} catch {
|
|
456
672
|
}
|
|
457
673
|
if (!w.ok)
|
|
458
|
-
throw new
|
|
459
|
-
return
|
|
674
|
+
throw new I(w.status, _);
|
|
675
|
+
return _;
|
|
460
676
|
}
|
|
461
677
|
return {
|
|
462
678
|
/** @returns {Promise<Array>} published form documents */
|
|
463
679
|
listForms: async () => {
|
|
464
|
-
const
|
|
465
|
-
return n =
|
|
680
|
+
const l = await a("/v1/forms", { timeoutMs: ot });
|
|
681
|
+
return n = l?.anonymous?.enabled === !0 ? { enabled: !0, humanCheck: l.anonymous.humanCheck || null } : de, (l?.forms || []).filter((d) => d?.formId && d?.start && Array.isArray(d?.nodes));
|
|
466
682
|
},
|
|
467
683
|
/**
|
|
468
684
|
* What the server advertised on the last listForms.
|
|
@@ -474,66 +690,91 @@ function xe({
|
|
|
474
690
|
* calls present it until endAnonSession(). Unauthenticated by design.
|
|
475
691
|
* @returns {Promise<{expiresIn: number}>}
|
|
476
692
|
*/
|
|
477
|
-
createAnonSession: async ({ formId:
|
|
478
|
-
const
|
|
693
|
+
createAnonSession: async ({ formId: l, requestId: d, humanToken: p }) => {
|
|
694
|
+
const u = await a("/v1/anon/sessions", {
|
|
479
695
|
method: "POST",
|
|
480
|
-
body: { formId:
|
|
696
|
+
body: { formId: l, requestId: d, ...p ? { humanToken: p } : {} }
|
|
481
697
|
});
|
|
482
|
-
if (o =
|
|
483
|
-
throw new
|
|
484
|
-
return { expiresIn:
|
|
698
|
+
if (o = u?.token || null, !o)
|
|
699
|
+
throw new I(502, { message: "The anonymous session had no token" });
|
|
700
|
+
return { expiresIn: u.expiresIn };
|
|
485
701
|
},
|
|
486
702
|
/** Drop the anonymous session so identity headers apply again. */
|
|
487
703
|
endAnonSession: () => {
|
|
488
704
|
o = null;
|
|
489
705
|
},
|
|
490
706
|
/** @returns {Promise<Array<{assetId,url,method,expires,assetUrl}>>} */
|
|
491
|
-
createUploads: async (
|
|
492
|
-
const { uploads:
|
|
493
|
-
return
|
|
707
|
+
createUploads: async (l) => {
|
|
708
|
+
const { uploads: d } = await a("/v1/uploads", { method: "POST", body: l, auth: !0 });
|
|
709
|
+
return d || [];
|
|
494
710
|
},
|
|
495
711
|
/**
|
|
496
712
|
* PUT one file to its presigned URL. XHR (not fetch) so upload
|
|
497
713
|
* progress is observable. Resolves on 2xx; rejects with
|
|
498
714
|
* ApiError(status) otherwise. Returns { promise, abort }.
|
|
499
715
|
*/
|
|
500
|
-
uploadFile: ({ url:
|
|
716
|
+
uploadFile: ({ url: l, file: d, contentType: p, onProgress: u = () => {
|
|
501
717
|
} }) => {
|
|
502
|
-
const
|
|
503
|
-
return { promise: new Promise((w,
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
}),
|
|
507
|
-
|
|
508
|
-
},
|
|
509
|
-
}), abort: () =>
|
|
718
|
+
const h = t();
|
|
719
|
+
return { promise: new Promise((w, _) => {
|
|
720
|
+
h.open("PUT", l), h.setRequestHeader("Content-Type", p || d.type), h.upload && (h.upload.onprogress = (P) => {
|
|
721
|
+
u({ loaded: P.loaded, total: P.total || d.size });
|
|
722
|
+
}), h.onload = () => {
|
|
723
|
+
h.status >= 200 && h.status < 300 ? w({ status: h.status }) : _(new I(h.status, null));
|
|
724
|
+
}, h.onerror = () => _(new I(0, null)), h.onabort = () => _(new I(0, { aborted: !0 })), h.send(d);
|
|
725
|
+
}), abort: () => h.abort() };
|
|
510
726
|
},
|
|
511
727
|
/** @returns {Promise<{requestId,reference,confirmation,routing}>} */
|
|
512
|
-
putRequest: async (
|
|
728
|
+
putRequest: async (l, d) => await a(`/v1/requests/${l}`, { method: "PUT", body: d, auth: !0 })
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
const ue = 60 * 1e3;
|
|
732
|
+
async function lt({ read: s, refresh: e, now: t = Date.now }) {
|
|
733
|
+
const r = (n) => {
|
|
734
|
+
const { token: o, expiry: a } = s() || {};
|
|
735
|
+
return o && Number(a) - n > t() ? o : null;
|
|
513
736
|
};
|
|
737
|
+
let i = r(ue);
|
|
738
|
+
if (!i) {
|
|
739
|
+
try {
|
|
740
|
+
await e();
|
|
741
|
+
} catch {
|
|
742
|
+
}
|
|
743
|
+
i = r(ue) || r(0);
|
|
744
|
+
}
|
|
745
|
+
if (!i)
|
|
746
|
+
throw Object.assign(new Error("Please sign in again to continue."), { status: 401, body: null });
|
|
747
|
+
return { Authorization: `Bearer ${i}` };
|
|
514
748
|
}
|
|
515
|
-
function
|
|
516
|
-
const { config:
|
|
749
|
+
function ct() {
|
|
750
|
+
const { config: s, storage: e } = Se();
|
|
517
751
|
let t = null;
|
|
518
752
|
return {
|
|
519
|
-
isAuthenticated: () =>
|
|
520
|
-
signedInEmail: () => e.get(
|
|
521
|
-
|
|
753
|
+
isAuthenticated: () => ze(),
|
|
754
|
+
signedInEmail: () => e.get(S.userEmail) || null,
|
|
755
|
+
/* The ID token, so api-forms can record the verified email (../lib/id-token.mjs). */
|
|
756
|
+
getAuthHeaders: () => lt({
|
|
757
|
+
read: () => ({
|
|
758
|
+
token: e.get(S.idToken),
|
|
759
|
+
expiry: e.get(S.idTokenExpiry)
|
|
760
|
+
}),
|
|
761
|
+
refresh: () => te()
|
|
762
|
+
}),
|
|
522
763
|
/**
|
|
523
764
|
* Email step. Keeps the challenge user in memory for verifyCode.
|
|
524
765
|
* @returns {{challengeRequired?: boolean, authenticated?: boolean}}
|
|
525
766
|
*/
|
|
526
|
-
sendCode: async (
|
|
527
|
-
const i = await
|
|
528
|
-
r,
|
|
767
|
+
sendCode: async (r) => {
|
|
768
|
+
const i = await Re(
|
|
529
769
|
s,
|
|
770
|
+
r,
|
|
530
771
|
e,
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
772
|
+
Me,
|
|
773
|
+
De,
|
|
774
|
+
Pe,
|
|
775
|
+
Z,
|
|
776
|
+
X,
|
|
777
|
+
ee
|
|
537
778
|
);
|
|
538
779
|
return t = i.cognitoUser || null, {
|
|
539
780
|
challengeRequired: !!i.challengeRequired,
|
|
@@ -544,118 +785,197 @@ function ve() {
|
|
|
544
785
|
* Code step; refreshes immediately after verify so the session
|
|
545
786
|
* starts with a full lifetime (house pattern).
|
|
546
787
|
*/
|
|
547
|
-
verifyCode: async (
|
|
788
|
+
verifyCode: async (r) => {
|
|
548
789
|
if (!t)
|
|
549
790
|
throw new Error("Please enter your email again to get a new code.");
|
|
550
791
|
try {
|
|
551
|
-
await
|
|
792
|
+
await Te(
|
|
552
793
|
t,
|
|
553
|
-
|
|
794
|
+
r,
|
|
554
795
|
e,
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
796
|
+
Z,
|
|
797
|
+
X,
|
|
798
|
+
ee
|
|
558
799
|
);
|
|
559
800
|
} catch {
|
|
560
801
|
throw new Error("Invalid or expired code. Please request a new one and try again.");
|
|
561
802
|
}
|
|
562
|
-
return await
|
|
803
|
+
return await te(), { success: !0 };
|
|
563
804
|
},
|
|
564
805
|
/** Local sign-out only ("use a different email"). */
|
|
565
806
|
signOut: () => {
|
|
566
|
-
t = null,
|
|
807
|
+
t = null, Ce().clear();
|
|
567
808
|
},
|
|
568
809
|
/**
|
|
569
810
|
* Detect a login completed in ANOTHER tab (the storage event
|
|
570
811
|
* never fires in the tab that wrote). Returns an unsubscribe.
|
|
571
812
|
*/
|
|
572
|
-
onCrossTabLogin: (
|
|
813
|
+
onCrossTabLogin: (r) => {
|
|
573
814
|
const i = (n) => {
|
|
574
|
-
(n.key ===
|
|
815
|
+
(n.key === S.accessToken || n.key === S.idToken) && r();
|
|
575
816
|
};
|
|
576
817
|
return window.addEventListener("storage", i), () => window.removeEventListener("storage", i);
|
|
577
818
|
}
|
|
578
819
|
};
|
|
579
820
|
}
|
|
580
|
-
function
|
|
581
|
-
const e =
|
|
582
|
-
return { ...
|
|
821
|
+
function dt({ baseUrl: s }) {
|
|
822
|
+
const e = ct();
|
|
823
|
+
return { ...at({ baseUrl: s, getAuthHeaders: e.getAuthHeaders }), ...e };
|
|
824
|
+
}
|
|
825
|
+
function x(s, e) {
|
|
826
|
+
return (s?.nodes || []).find((t) => t.id === e);
|
|
583
827
|
}
|
|
584
|
-
function
|
|
585
|
-
return
|
|
828
|
+
function N(s) {
|
|
829
|
+
return s?.form ? { formId: s.form, path: [...s.path || []] } : null;
|
|
586
830
|
}
|
|
587
|
-
function
|
|
831
|
+
function q(s, e = []) {
|
|
588
832
|
const t = [];
|
|
589
|
-
let
|
|
833
|
+
let r = s?.start;
|
|
590
834
|
for (const n of e) {
|
|
591
|
-
const o =
|
|
835
|
+
const o = x(s, r);
|
|
592
836
|
if (!o)
|
|
593
|
-
return { nodeId: null, node: null, flags: t, error: { step: n, reason: `unknown node: ${
|
|
837
|
+
return { nodeId: null, node: null, flags: t, error: { step: n, reason: `unknown node: ${r}` } };
|
|
594
838
|
if (o.type === "terminal" || o.type === "redirect")
|
|
595
839
|
return { nodeId: null, node: null, flags: t, error: { step: n, reason: `steps continue past ${o.type}` } };
|
|
596
|
-
if (n.nodeId !==
|
|
597
|
-
return { nodeId: null, node: null, flags: t, error: { step: n, reason: `step does not match node ${
|
|
840
|
+
if (n.nodeId !== r || n.kind !== o.type)
|
|
841
|
+
return { nodeId: null, node: null, flags: t, error: { step: n, reason: `step does not match node ${r}` } };
|
|
598
842
|
if (o.type === "choice") {
|
|
599
|
-
const
|
|
600
|
-
if (!
|
|
843
|
+
const a = (o.options || []).find((l) => l.id === n.optionId);
|
|
844
|
+
if (!a)
|
|
601
845
|
return { nodeId: null, node: null, flags: t, error: { step: n, reason: `unknown option: ${n.optionId}` } };
|
|
602
|
-
|
|
846
|
+
if (N(a))
|
|
847
|
+
return { nodeId: null, node: null, flags: t, error: { step: n, reason: `steps continue past a hand-off: ${n.optionId}` } };
|
|
848
|
+
t.push(...a.flags || []), r = a.next;
|
|
603
849
|
continue;
|
|
604
850
|
}
|
|
605
|
-
|
|
851
|
+
r = o.next;
|
|
606
852
|
}
|
|
607
|
-
const i =
|
|
608
|
-
return i ? { nodeId:
|
|
853
|
+
const i = x(s, r);
|
|
854
|
+
return i ? { nodeId: r, node: i, flags: Ae(t), error: null } : { nodeId: null, node: null, flags: t, error: { step: null, reason: `unknown node: ${r}` } };
|
|
609
855
|
}
|
|
610
|
-
function
|
|
856
|
+
function ut(s, e = []) {
|
|
611
857
|
const t = [];
|
|
612
|
-
for (const
|
|
613
|
-
if (
|
|
614
|
-
const i =
|
|
858
|
+
for (const r of e) {
|
|
859
|
+
if (r.kind !== "collect") continue;
|
|
860
|
+
const i = x(s, r.nodeId);
|
|
615
861
|
t.push(...i?.fields || []);
|
|
616
862
|
}
|
|
617
863
|
return t;
|
|
618
864
|
}
|
|
619
|
-
function
|
|
865
|
+
function pt(s = []) {
|
|
620
866
|
const e = {};
|
|
621
|
-
for (const t of
|
|
867
|
+
for (const t of s)
|
|
622
868
|
t.kind === "collect" && Object.assign(e, t.values || {});
|
|
623
869
|
return e;
|
|
624
870
|
}
|
|
625
|
-
function
|
|
626
|
-
return
|
|
871
|
+
function ht(s = []) {
|
|
872
|
+
return s.filter((e) => e.kind === "choice").map((e) => `${e.nodeId}:${e.optionId}`);
|
|
627
873
|
}
|
|
628
|
-
function
|
|
874
|
+
function ke(s, e = []) {
|
|
629
875
|
const t = [];
|
|
630
|
-
for (const
|
|
631
|
-
if (
|
|
632
|
-
const n = (
|
|
876
|
+
for (const r of e) {
|
|
877
|
+
if (r.kind !== "choice") continue;
|
|
878
|
+
const n = (x(s, r.nodeId)?.options || []).find((o) => o.id === r.optionId);
|
|
633
879
|
t.push(...n?.flags || []);
|
|
634
880
|
}
|
|
635
|
-
return
|
|
881
|
+
return Ae(t);
|
|
882
|
+
}
|
|
883
|
+
function ft(s = []) {
|
|
884
|
+
return s.includes("urgent") ? "urgent" : s.includes("moderate") ? "moderate" : null;
|
|
885
|
+
}
|
|
886
|
+
function Ae(s) {
|
|
887
|
+
return [...new Set(s)];
|
|
888
|
+
}
|
|
889
|
+
function mt(s, e = []) {
|
|
890
|
+
const t = [];
|
|
891
|
+
for (const i of e) {
|
|
892
|
+
const [n, o] = String(i).split(":"), a = x(s, n), l = a?.type === "choice" ? (a.options || []).find((d) => d.id === o) : null;
|
|
893
|
+
if (!l)
|
|
894
|
+
return { steps: [], error: `unknown preset step: ${i}` };
|
|
895
|
+
t.push({ nodeId: n, kind: "choice", optionId: o, label: l.label, preset: !0 });
|
|
896
|
+
}
|
|
897
|
+
const { error: r } = q(s, t);
|
|
898
|
+
return r ? { steps: [], error: r.reason } : { steps: t, error: null };
|
|
899
|
+
}
|
|
900
|
+
function gt(s, e) {
|
|
901
|
+
const t = N(e);
|
|
902
|
+
if (!t) return { form: null, steps: [], error: "not a hand-off" };
|
|
903
|
+
const r = (s || []).find((o) => o.formId === t.formId);
|
|
904
|
+
if (!r) return { form: null, steps: [], error: `unknown form: ${t.formId}` };
|
|
905
|
+
const { steps: i, error: n } = mt(r, t.path);
|
|
906
|
+
return n ? { form: null, steps: [], error: n } : { form: r, steps: i, error: null };
|
|
907
|
+
}
|
|
908
|
+
function bt(s, e, t, r) {
|
|
909
|
+
return {
|
|
910
|
+
form: s,
|
|
911
|
+
steps: e,
|
|
912
|
+
option: { nodeId: t.id, optionId: r.id, label: r.label }
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
function yt(s = []) {
|
|
916
|
+
return s.every((e) => e.preset === !0);
|
|
917
|
+
}
|
|
918
|
+
function wt(s, e, t) {
|
|
919
|
+
if (!Array.isArray(s) || !s.length) return [];
|
|
920
|
+
const r = [];
|
|
921
|
+
for (let i = 0; i < s.length; i++) {
|
|
922
|
+
const n = s[i], o = (e || []).find((u) => u.formId === n?.formId);
|
|
923
|
+
if (!o) return [];
|
|
924
|
+
const { node: a, error: l } = q(o, n.steps || []);
|
|
925
|
+
if (l || a?.id !== n.option?.nodeId) return [];
|
|
926
|
+
const d = (a.options || []).find((u) => u.id === n.option.optionId), p = i + 1 < s.length ? s[i + 1].formId : t;
|
|
927
|
+
if (N(d)?.formId !== p) return [];
|
|
928
|
+
r.push({ form: o, steps: n.steps || [], option: n.option });
|
|
929
|
+
}
|
|
930
|
+
return r;
|
|
636
931
|
}
|
|
637
|
-
function
|
|
638
|
-
|
|
932
|
+
function xt({ attr: s = null, search: e = "" } = {}) {
|
|
933
|
+
const t = String(s ?? "").trim();
|
|
934
|
+
if (t) return t;
|
|
935
|
+
try {
|
|
936
|
+
return new URLSearchParams(e || "").get("flow")?.trim() || null;
|
|
937
|
+
} catch {
|
|
938
|
+
return null;
|
|
939
|
+
}
|
|
639
940
|
}
|
|
640
|
-
function
|
|
641
|
-
return
|
|
941
|
+
function vt(s, e) {
|
|
942
|
+
return e && (s || []).find((t) => t.formId === e) || null;
|
|
642
943
|
}
|
|
643
|
-
|
|
944
|
+
function _t(s, e) {
|
|
945
|
+
return !e || s?.form?.formId === e ? !0 : (s?.origins || []).some((t) => t.form?.formId === e);
|
|
946
|
+
}
|
|
947
|
+
const $t = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?(\.\d+)?(Z|[+-]\d{2}:\d{2})?$/, pe = {
|
|
644
948
|
text: 500,
|
|
645
949
|
textarea: 5e3,
|
|
646
950
|
url: 2048
|
|
647
|
-
};
|
|
648
|
-
function
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
951
|
+
}, kt = "Please confirm the rights statement so we can use what you send.";
|
|
952
|
+
function Fe(s, { mediaCount: e = 0 } = {}) {
|
|
953
|
+
return s.kind === "consent" && s.requiredIf === "media" ? e > 0 : !!s.required;
|
|
954
|
+
}
|
|
955
|
+
function At(s, e) {
|
|
956
|
+
try {
|
|
957
|
+
return new RegExp(s, "u").test(e);
|
|
958
|
+
} catch {
|
|
959
|
+
return !0;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
function Ft(s) {
|
|
963
|
+
return s.key === "zip" ? "Please enter a five-digit zip code." : `Please check the format of ${s.label.toLowerCase()}.`;
|
|
964
|
+
}
|
|
965
|
+
function It(s, e, { mediaCount: t = 0 } = {}) {
|
|
966
|
+
const r = Fe(s, { mediaCount: t });
|
|
967
|
+
if (s.kind === "consent")
|
|
968
|
+
return e === !0 || !r ? null : kt;
|
|
969
|
+
if (e == null || e === "" || s.kind === "location" && Et(e))
|
|
970
|
+
return r ? `Please fill in: ${s.label.toLowerCase()}.` : null;
|
|
971
|
+
switch (s.kind) {
|
|
652
972
|
case "text":
|
|
653
973
|
case "textarea": {
|
|
654
|
-
const
|
|
655
|
-
return typeof e != "string" ? `Please enter text for ${
|
|
974
|
+
const n = s.maxLength || pe[s.kind];
|
|
975
|
+
return typeof e != "string" ? `Please enter text for ${s.label.toLowerCase()}.` : e.length > n ? `Please keep ${s.label.toLowerCase()} under ${n} characters.` : s.kind === "text" && s.pattern && !At(s.pattern, e) ? Ft(s) : null;
|
|
656
976
|
}
|
|
657
977
|
case "url": {
|
|
658
|
-
if (typeof e != "string" || e.length >
|
|
978
|
+
if (typeof e != "string" || e.length > pe.url)
|
|
659
979
|
return "Please enter a valid link.";
|
|
660
980
|
try {
|
|
661
981
|
return new URL(e), null;
|
|
@@ -664,110 +984,108 @@ function Se(r, e) {
|
|
|
664
984
|
}
|
|
665
985
|
}
|
|
666
986
|
case "datetime":
|
|
667
|
-
return
|
|
987
|
+
return $t.test(String(e)) ? null : "Please pick a date and time.";
|
|
668
988
|
case "select":
|
|
669
|
-
return (
|
|
670
|
-
case "consent":
|
|
671
|
-
return e === !0 ? null : "Please confirm the rights statement so we can use what you send.";
|
|
989
|
+
return (s.options || []).map((o) => o.id).includes(e) ? null : `Please choose one of the options for ${s.label.toLowerCase()}.`;
|
|
672
990
|
case "location":
|
|
673
|
-
return
|
|
991
|
+
return St(s, e);
|
|
674
992
|
case "media":
|
|
675
993
|
return null;
|
|
676
994
|
default:
|
|
677
|
-
return `Unsupported field: ${
|
|
995
|
+
return `Unsupported field: ${s.kind}`;
|
|
678
996
|
}
|
|
679
997
|
}
|
|
680
|
-
function
|
|
681
|
-
return
|
|
998
|
+
function Et(s) {
|
|
999
|
+
return s == null ? !0 : typeof s != "object" ? !1 : !s.county && !s.where && !(Array.isArray(s.gps) && s.gps.length);
|
|
682
1000
|
}
|
|
683
|
-
function
|
|
684
|
-
return typeof e != "object" || Array.isArray(e) ? "Please tell us where this was." : e.county !== void 0 && (typeof e.county != "string" || e.county.length > 100) ? "Please choose a county." : e.where !== void 0 && (typeof e.where != "string" || e.where.length > 500) ? "Please shorten the location description." : e.gps !== void 0 && !(Array.isArray(e.gps) && e.gps.length === 2 && e.gps.every((
|
|
1001
|
+
function St(s, e) {
|
|
1002
|
+
return typeof e != "object" || Array.isArray(e) ? "Please tell us where this was." : e.county !== void 0 && (typeof e.county != "string" || e.county.length > 100) ? "Please choose a county." : e.where !== void 0 && (typeof e.where != "string" || e.where.length > 500) ? "Please shorten the location description." : e.gps !== void 0 && !(Array.isArray(e.gps) && e.gps.length === 2 && e.gps.every((r) => typeof r == "number" && Number.isFinite(r))) ? "Location coordinates look wrong; try re-sharing your location." : s.required && !e.county && !e.where ? `Please fill in: ${s.label.toLowerCase()}.` : null;
|
|
685
1003
|
}
|
|
686
|
-
function
|
|
687
|
-
const
|
|
688
|
-
for (const
|
|
689
|
-
if (
|
|
690
|
-
const
|
|
691
|
-
|
|
692
|
-
}
|
|
693
|
-
return { ok: Object.keys(
|
|
1004
|
+
function he(s, e = {}, { mediaCount: t = 0 } = {}) {
|
|
1005
|
+
const r = {};
|
|
1006
|
+
for (const i of s) {
|
|
1007
|
+
if (i.kind === "media") continue;
|
|
1008
|
+
const n = It(i, e[i.key], { mediaCount: t });
|
|
1009
|
+
n && (r[i.key] = n);
|
|
1010
|
+
}
|
|
1011
|
+
return { ok: Object.keys(r).length === 0, errors: r };
|
|
694
1012
|
}
|
|
695
|
-
function
|
|
1013
|
+
function Y(s = [], e = {}, { required: t = !1 } = {}) {
|
|
696
1014
|
const {
|
|
697
|
-
maxFiles:
|
|
1015
|
+
maxFiles: r = 5,
|
|
698
1016
|
maxFileBytes: i = 512 * 1024 * 1024,
|
|
699
1017
|
allowedTypes: n = []
|
|
700
1018
|
} = e, o = [];
|
|
701
|
-
return t &&
|
|
1019
|
+
return t && s.length === 0 && o.push({ reason: "required", message: "Please attach at least one photo or video." }), s.length > r && o.push({
|
|
702
1020
|
reason: "count",
|
|
703
|
-
message: `This form accepts at most ${
|
|
704
|
-
}),
|
|
705
|
-
n.length && !n.includes(
|
|
706
|
-
index:
|
|
1021
|
+
message: `This form accepts at most ${r} ${r === 1 ? "file" : "files"}.`
|
|
1022
|
+
}), s.forEach((a, l) => {
|
|
1023
|
+
n.length && !n.includes(a.type) && o.push({
|
|
1024
|
+
index: l,
|
|
707
1025
|
reason: "type",
|
|
708
|
-
message: `${
|
|
709
|
-
}),
|
|
710
|
-
index:
|
|
1026
|
+
message: `${a.name || "A file"} is a type this form does not accept.`
|
|
1027
|
+
}), a.size > i && o.push({
|
|
1028
|
+
index: l,
|
|
711
1029
|
reason: "size",
|
|
712
|
-
message: `${
|
|
1030
|
+
message: `${a.name || "A file"} is larger than this form allows.`
|
|
713
1031
|
});
|
|
714
1032
|
}), { ok: o.length === 0, errors: o };
|
|
715
1033
|
}
|
|
716
|
-
function
|
|
1034
|
+
function fe({ formId: s, requestId: e, files: t }) {
|
|
717
1035
|
return {
|
|
718
|
-
formId:
|
|
1036
|
+
formId: s,
|
|
719
1037
|
requestId: e,
|
|
720
|
-
files: t.map((
|
|
1038
|
+
files: t.map((r) => ({ contentType: r.type, size: r.size }))
|
|
721
1039
|
};
|
|
722
1040
|
}
|
|
723
|
-
function
|
|
724
|
-
const
|
|
725
|
-
for (const o of
|
|
1041
|
+
function Ct({ form: s, steps: e, media: t = [] }) {
|
|
1042
|
+
const r = ut(s, e), i = pt(e), n = {};
|
|
1043
|
+
for (const o of r) {
|
|
726
1044
|
if (o.kind === "media") continue;
|
|
727
|
-
const
|
|
728
|
-
if (!(
|
|
1045
|
+
const a = i[o.key];
|
|
1046
|
+
if (!(a == null || a === "") && !(o.kind === "consent" && (a !== !0 || o.requiredIf === "media" && !t.length))) {
|
|
729
1047
|
if (o.kind === "location") {
|
|
730
|
-
const
|
|
731
|
-
|
|
1048
|
+
const l = {};
|
|
1049
|
+
a.county && (l.county = a.county), a.where && (l.where = a.where), Array.isArray(a.gps) && a.gps.length === 2 && (l.gps = a.gps), Object.keys(l).length && (n[o.key] = l);
|
|
732
1050
|
continue;
|
|
733
1051
|
}
|
|
734
|
-
n[o.key] =
|
|
1052
|
+
n[o.key] = a;
|
|
735
1053
|
}
|
|
736
1054
|
}
|
|
737
1055
|
return {
|
|
738
|
-
formId:
|
|
739
|
-
flowVersion:
|
|
740
|
-
path:
|
|
1056
|
+
formId: s.formId,
|
|
1057
|
+
flowVersion: s.flowVersion,
|
|
1058
|
+
path: ht(e),
|
|
741
1059
|
answers: n,
|
|
742
|
-
media: t.map(({ assetId: o, type:
|
|
1060
|
+
media: t.map(({ assetId: o, type: a }) => ({ assetId: o, type: a }))
|
|
743
1061
|
};
|
|
744
1062
|
}
|
|
745
|
-
function
|
|
746
|
-
if (
|
|
1063
|
+
function me(s, e) {
|
|
1064
|
+
if (s === 429)
|
|
747
1065
|
return {
|
|
748
1066
|
kind: "throttled",
|
|
749
1067
|
message: e?.message || "You have reached the submission limit; please try again later.",
|
|
750
1068
|
limit: e?.limit,
|
|
751
1069
|
retryAfter: e?.retryAfter
|
|
752
1070
|
};
|
|
753
|
-
if (
|
|
1071
|
+
if (s === 401)
|
|
754
1072
|
return { kind: "auth", message: "Please sign in again to continue." };
|
|
755
|
-
if (
|
|
1073
|
+
if (s === 403)
|
|
756
1074
|
return { kind: "forbidden", message: e?.message || "This submission belongs to another account." };
|
|
757
|
-
if (
|
|
1075
|
+
if (s === 404)
|
|
758
1076
|
return { kind: "unknown-form", message: "This form is no longer available." };
|
|
759
|
-
if (
|
|
1077
|
+
if (s === 409)
|
|
760
1078
|
return {
|
|
761
1079
|
kind: "stale",
|
|
762
1080
|
message: e?.message || "The form changed while you were filling it out; please review and resubmit."
|
|
763
1081
|
};
|
|
764
|
-
if (
|
|
1082
|
+
if (s === 400 && e?.code === "media-not-verified")
|
|
765
1083
|
return {
|
|
766
1084
|
kind: "media",
|
|
767
1085
|
message: e.message || "An attached file is missing or does not match this submission.",
|
|
768
1086
|
assetId: e.assetId
|
|
769
1087
|
};
|
|
770
|
-
if (
|
|
1088
|
+
if (s === 400 && Array.isArray(e)) {
|
|
771
1089
|
const t = e[0] || {};
|
|
772
1090
|
return {
|
|
773
1091
|
kind: "validation",
|
|
@@ -775,54 +1093,58 @@ function q(r, e) {
|
|
|
775
1093
|
fieldKey: String(t.instancePath || "").split("/").filter(Boolean)[0] || null
|
|
776
1094
|
};
|
|
777
1095
|
}
|
|
778
|
-
return
|
|
1096
|
+
return s === 0 ? { kind: "network", message: "We could not reach WRAL; check your connection and try again." } : {
|
|
779
1097
|
kind: "server",
|
|
780
1098
|
message: "Something went wrong on our end; please try again."
|
|
781
1099
|
};
|
|
782
1100
|
}
|
|
783
|
-
const
|
|
784
|
-
function
|
|
785
|
-
const t = String(
|
|
1101
|
+
const Tt = 34, Rt = 44;
|
|
1102
|
+
function ge(s, e) {
|
|
1103
|
+
const t = String(s);
|
|
786
1104
|
return t.length > e ? `${t.slice(0, e)}…` : t;
|
|
787
1105
|
}
|
|
788
|
-
function
|
|
789
|
-
|
|
1106
|
+
function Mt(s, e) {
|
|
1107
|
+
const t = (s.options || []).find((r) => r.id === e);
|
|
1108
|
+
return t ? t.label : e;
|
|
1109
|
+
}
|
|
1110
|
+
function Dt(s) {
|
|
1111
|
+
return !s || typeof s != "object" ? "" : [s.county, s.where].filter(Boolean).join(", ");
|
|
790
1112
|
}
|
|
791
|
-
function
|
|
792
|
-
const
|
|
793
|
-
for (const i of
|
|
1113
|
+
function Pt(s, e = {}, t = []) {
|
|
1114
|
+
const r = [];
|
|
1115
|
+
for (const i of s) {
|
|
794
1116
|
if (i.kind === "consent") continue;
|
|
795
1117
|
if (i.kind === "media") {
|
|
796
|
-
t.length &&
|
|
1118
|
+
t.length && r.push(`${t.length} ${t.length === 1 ? "file" : "files"}`);
|
|
797
1119
|
continue;
|
|
798
1120
|
}
|
|
799
|
-
const n = i.kind === "location" ?
|
|
800
|
-
n == null || n === "" || (i.kind === "textarea" ?
|
|
1121
|
+
const n = i.kind === "location" ? Dt(e[i.key]) : i.kind === "select" ? Mt(i, e[i.key]) : e[i.key];
|
|
1122
|
+
n == null || n === "" || (i.kind === "textarea" ? r.push(`"${ge(n, Rt)}"`) : r.push(ge(n, Tt)));
|
|
801
1123
|
}
|
|
802
|
-
return
|
|
1124
|
+
return r.join(" · ") || "Details provided";
|
|
803
1125
|
}
|
|
804
|
-
function
|
|
805
|
-
const
|
|
1126
|
+
function zt(s, e = [], t = null) {
|
|
1127
|
+
const r = [];
|
|
806
1128
|
for (const n of e) {
|
|
807
|
-
const o =
|
|
808
|
-
n.kind === "choice" && o &&
|
|
1129
|
+
const o = x(s, n.nodeId);
|
|
1130
|
+
n.kind === "choice" && o && r.push({ k: (o.prompt || "").replace(/\?$/, ""), v: n.label || n.optionId }), n.kind === "collect" && r.push({ k: "Details", v: n.summary || "Details provided" }), n.kind === "gate" && (n.anonymous ? r.push({ k: "Contact", v: "Anonymous — we will have no way to reach you" }) : (n.email || t) && r.push({ k: "Verified email", v: n.email || t }));
|
|
809
1131
|
}
|
|
810
|
-
const i =
|
|
811
|
-
return i &&
|
|
1132
|
+
const i = ft(ke(s, e));
|
|
1133
|
+
return i && r.push({ k: "Priority", v: i === "urgent" ? "Urgent" : "Moderate", pill: i }), r;
|
|
812
1134
|
}
|
|
813
|
-
function
|
|
814
|
-
const t =
|
|
1135
|
+
function Bt(s, e = []) {
|
|
1136
|
+
const t = s?.confirmation || {};
|
|
815
1137
|
return {
|
|
816
1138
|
title: t.title || "Report received.",
|
|
817
1139
|
body: t.body || "Your report is in the review queue.",
|
|
818
1140
|
urgentNote: e.includes("urgent") ? t.urgentNote : void 0
|
|
819
1141
|
};
|
|
820
1142
|
}
|
|
821
|
-
function
|
|
1143
|
+
function Ot(s, e) {
|
|
822
1144
|
const t = e === "failed" ? " The notification is queued for a delivery retry." : "";
|
|
823
|
-
return
|
|
1145
|
+
return s?.startsWith("studio+email:") ? `Sent to the Studio review queue; the desk is emailed.${t}` : s?.startsWith("studio:") ? "Sent to the Studio review queue." : s?.startsWith("jsm:") ? `A ticket is opened for tech support with your details as fields, not prose.${t}` : s?.startsWith("email:") ? `Emailed to the owning desk with a link to your report.${t}` : "Routed to the right team.";
|
|
824
1146
|
}
|
|
825
|
-
function
|
|
1147
|
+
function Ut({ routing: s = {}, flags: e = [], reference: t = "", anonymous: r = !1 }) {
|
|
826
1148
|
const i = e.includes("urgent");
|
|
827
1149
|
return [
|
|
828
1150
|
{
|
|
@@ -831,12 +1153,12 @@ function Ue({ routing: r = {}, flags: e = [], reference: t = "", anonymous: s =
|
|
|
831
1153
|
},
|
|
832
1154
|
{
|
|
833
1155
|
title: "Routed",
|
|
834
|
-
body:
|
|
1156
|
+
body: Ot(s.destination, s.state),
|
|
835
1157
|
pill: i ? "Urgent · pinned first" : void 0
|
|
836
1158
|
},
|
|
837
1159
|
{
|
|
838
1160
|
title: "Reviewed",
|
|
839
|
-
body:
|
|
1161
|
+
body: r ? "An editor reviews it in the Report It queue: accept and promote it uncredited, reject, or re-route." : "An editor reviews it in the Report It queue: accept and promote with your credit, reject, or re-route."
|
|
840
1162
|
},
|
|
841
1163
|
{
|
|
842
1164
|
title: "Monitored",
|
|
@@ -848,63 +1170,76 @@ function Ue({ routing: r = {}, flags: e = [], reference: t = "", anonymous: s =
|
|
|
848
1170
|
}
|
|
849
1171
|
];
|
|
850
1172
|
}
|
|
851
|
-
const
|
|
852
|
-
function
|
|
1173
|
+
const J = "wral-report-it:draft:v1", Ie = 1;
|
|
1174
|
+
function Lt(s, e) {
|
|
853
1175
|
try {
|
|
854
|
-
|
|
1176
|
+
s.setItem(J, JSON.stringify({ ...e, v: Ie, savedAt: Date.now() }));
|
|
855
1177
|
} catch {
|
|
856
1178
|
}
|
|
857
1179
|
}
|
|
858
|
-
function
|
|
1180
|
+
function Nt(s) {
|
|
859
1181
|
try {
|
|
860
|
-
const e =
|
|
1182
|
+
const e = s.getItem(J);
|
|
861
1183
|
if (!e) return null;
|
|
862
1184
|
const t = JSON.parse(e);
|
|
863
|
-
return t?.v !==
|
|
1185
|
+
return t?.v !== Ie ? null : t;
|
|
864
1186
|
} catch {
|
|
865
1187
|
return null;
|
|
866
1188
|
}
|
|
867
1189
|
}
|
|
868
|
-
function
|
|
1190
|
+
function be(s) {
|
|
869
1191
|
try {
|
|
870
|
-
|
|
1192
|
+
s.removeItem(J);
|
|
871
1193
|
} catch {
|
|
872
1194
|
}
|
|
873
1195
|
}
|
|
874
|
-
function
|
|
1196
|
+
function qt({
|
|
1197
|
+
apiOrigin: s,
|
|
1198
|
+
form: e,
|
|
1199
|
+
steps: t,
|
|
1200
|
+
requestId: r = null,
|
|
1201
|
+
mediaMeta: i = {},
|
|
1202
|
+
origins: n = []
|
|
1203
|
+
}) {
|
|
875
1204
|
return {
|
|
876
|
-
apiOrigin:
|
|
1205
|
+
apiOrigin: s,
|
|
877
1206
|
formId: e.formId,
|
|
878
1207
|
flowVersion: e.flowVersion,
|
|
879
|
-
requestId:
|
|
1208
|
+
requestId: r,
|
|
880
1209
|
steps: t,
|
|
881
|
-
media: i
|
|
1210
|
+
media: i,
|
|
1211
|
+
origins: n.map(({ form: o, steps: a, option: l }) => ({
|
|
1212
|
+
formId: o.formId,
|
|
1213
|
+
steps: a,
|
|
1214
|
+
option: l
|
|
1215
|
+
}))
|
|
882
1216
|
};
|
|
883
1217
|
}
|
|
884
|
-
function
|
|
885
|
-
if (!r) return { status: "discarded" };
|
|
886
|
-
if (t && r.apiOrigin && r.apiOrigin !== t)
|
|
887
|
-
return { status: "discarded" };
|
|
888
|
-
const s = (e || []).find((o) => o.formId === r.formId);
|
|
1218
|
+
function Ht(s, e, { apiOrigin: t } = {}) {
|
|
889
1219
|
if (!s) return { status: "discarded" };
|
|
890
|
-
|
|
1220
|
+
if (t && s.apiOrigin && s.apiOrigin !== t)
|
|
1221
|
+
return { status: "discarded" };
|
|
1222
|
+
const r = (e || []).find((o) => o.formId === s.formId);
|
|
1223
|
+
if (!r) return { status: "discarded" };
|
|
1224
|
+
const { error: i } = q(r, s.steps || []);
|
|
891
1225
|
if (i) return { status: "discarded" };
|
|
892
1226
|
const n = {};
|
|
893
|
-
for (const [o,
|
|
894
|
-
|
|
1227
|
+
for (const [o, a] of Object.entries(s.media || {}))
|
|
1228
|
+
a?.length && (n[o] = a.map((l) => ({ ...l, lost: !0 })));
|
|
895
1229
|
return {
|
|
896
|
-
status:
|
|
897
|
-
form:
|
|
898
|
-
steps:
|
|
899
|
-
requestId:
|
|
900
|
-
lostMedia: n
|
|
1230
|
+
status: s.flowVersion === r.flowVersion ? "ok" : "review-required",
|
|
1231
|
+
form: r,
|
|
1232
|
+
steps: s.steps || [],
|
|
1233
|
+
requestId: s.requestId || null,
|
|
1234
|
+
lostMedia: n,
|
|
1235
|
+
origins: wt(s.origins, e, r.formId)
|
|
901
1236
|
};
|
|
902
1237
|
}
|
|
903
|
-
function
|
|
1238
|
+
function z(s = []) {
|
|
904
1239
|
return {
|
|
905
1240
|
stage: "idle",
|
|
906
1241
|
resumeStage: null,
|
|
907
|
-
files:
|
|
1242
|
+
files: s.map((e) => ({
|
|
908
1243
|
name: e.name,
|
|
909
1244
|
type: e.type,
|
|
910
1245
|
size: e.size,
|
|
@@ -920,82 +1255,82 @@ function F(r = []) {
|
|
|
920
1255
|
error: null
|
|
921
1256
|
};
|
|
922
1257
|
}
|
|
923
|
-
function
|
|
1258
|
+
function jt(s, e) {
|
|
924
1259
|
switch (e.type) {
|
|
925
1260
|
case "START":
|
|
926
|
-
return { ...
|
|
1261
|
+
return { ...s, stage: s.files.length ? "minting" : "requesting", error: null };
|
|
927
1262
|
case "AUTH_REQUIRED":
|
|
928
|
-
return { ...
|
|
1263
|
+
return { ...s, resumeStage: s.stage === "auth" ? s.resumeStage : s.stage, stage: "auth" };
|
|
929
1264
|
case "AUTH_OK":
|
|
930
|
-
return { ...
|
|
1265
|
+
return { ...s, stage: s.resumeStage || "idle", resumeStage: null };
|
|
931
1266
|
case "MINTED": {
|
|
932
|
-
const t =
|
|
933
|
-
...
|
|
934
|
-
assetId: e.uploads[i]?.assetId ??
|
|
935
|
-
url: e.uploads[i]?.url ??
|
|
936
|
-
assetUrl: e.uploads[i]?.assetUrl ??
|
|
1267
|
+
const t = s.files.map((r, i) => ({
|
|
1268
|
+
...r,
|
|
1269
|
+
assetId: e.uploads[i]?.assetId ?? r.assetId,
|
|
1270
|
+
url: e.uploads[i]?.url ?? r.url,
|
|
1271
|
+
assetUrl: e.uploads[i]?.assetUrl ?? r.assetUrl,
|
|
937
1272
|
status: "uploading",
|
|
938
1273
|
progress: 0,
|
|
939
1274
|
error: null
|
|
940
1275
|
}));
|
|
941
|
-
return { ...
|
|
1276
|
+
return { ...s, stage: "uploading", files: t };
|
|
942
1277
|
}
|
|
943
1278
|
case "FILE_PROGRESS":
|
|
944
|
-
return
|
|
1279
|
+
return T(s, e.i, (t) => ({
|
|
945
1280
|
...t,
|
|
946
1281
|
progress: e.total ? e.loaded / e.total : 0
|
|
947
1282
|
}));
|
|
948
1283
|
case "FILE_DONE": {
|
|
949
|
-
const t =
|
|
950
|
-
return
|
|
1284
|
+
const t = T(s, e.i, (r) => ({ ...r, status: "done", progress: 1 }));
|
|
1285
|
+
return Wt(t);
|
|
951
1286
|
}
|
|
952
1287
|
case "FILE_FAIL":
|
|
953
|
-
return { ...
|
|
954
|
-
...
|
|
1288
|
+
return { ...T(s, e.i, (r) => ({
|
|
1289
|
+
...r,
|
|
955
1290
|
status: "failed",
|
|
956
1291
|
error: e.error || "upload failed"
|
|
957
1292
|
})), stage: "uploading-error" };
|
|
958
1293
|
case "RETRY_FILE":
|
|
959
|
-
return { ...
|
|
960
|
-
...
|
|
1294
|
+
return { ...T(s, e.i, (r) => ({
|
|
1295
|
+
...r,
|
|
961
1296
|
status: "uploading",
|
|
962
1297
|
progress: 0,
|
|
963
1298
|
error: null
|
|
964
1299
|
})), stage: "uploading" };
|
|
965
1300
|
case "REMINT_FILE":
|
|
966
|
-
return { ...
|
|
967
|
-
...
|
|
1301
|
+
return { ...T(s, e.i, (r) => ({
|
|
1302
|
+
...r,
|
|
968
1303
|
assetId: e.upload.assetId,
|
|
969
1304
|
url: e.upload.url,
|
|
970
|
-
assetUrl: e.upload.assetUrl ??
|
|
1305
|
+
assetUrl: e.upload.assetUrl ?? r.assetUrl,
|
|
971
1306
|
status: "uploading",
|
|
972
1307
|
progress: 0,
|
|
973
1308
|
error: null
|
|
974
1309
|
})), stage: "uploading" };
|
|
975
1310
|
case "REQUEST_START":
|
|
976
|
-
return { ...
|
|
1311
|
+
return { ...s, stage: "requesting", error: null };
|
|
977
1312
|
case "REQUEST_OK":
|
|
978
|
-
return { ...
|
|
1313
|
+
return { ...s, stage: "done", result: e.result, error: null };
|
|
979
1314
|
case "REQUEST_FAIL":
|
|
980
|
-
return { ...
|
|
1315
|
+
return { ...s, stage: "requesting-error", error: e.error };
|
|
981
1316
|
case "RESET":
|
|
982
|
-
return
|
|
1317
|
+
return z([]);
|
|
983
1318
|
default:
|
|
984
|
-
return
|
|
1319
|
+
return s;
|
|
985
1320
|
}
|
|
986
1321
|
}
|
|
987
|
-
function
|
|
988
|
-
const
|
|
989
|
-
return { ...
|
|
1322
|
+
function T(s, e, t) {
|
|
1323
|
+
const r = s.files.map((i, n) => n === e ? t(i) : i);
|
|
1324
|
+
return { ...s, files: r };
|
|
990
1325
|
}
|
|
991
|
-
function
|
|
992
|
-
const e =
|
|
993
|
-
return e ? { ...
|
|
1326
|
+
function Wt(s) {
|
|
1327
|
+
const e = s.files.every((r) => r.status === "done"), t = s.files.some((r) => r.status === "failed");
|
|
1328
|
+
return e ? { ...s, stage: "requesting" } : t ? { ...s, stage: "uploading-error" } : s;
|
|
994
1329
|
}
|
|
995
|
-
function
|
|
996
|
-
return
|
|
1330
|
+
function ye(s) {
|
|
1331
|
+
return s.files.map((e, t) => ({ ...e, i: t })).filter((e) => e.status === "failed");
|
|
997
1332
|
}
|
|
998
|
-
const
|
|
1333
|
+
const Vt = [
|
|
999
1334
|
"Wake",
|
|
1000
1335
|
"Durham",
|
|
1001
1336
|
"Orange",
|
|
@@ -1012,24 +1347,27 @@ const Ye = [
|
|
|
1012
1347
|
"Moore",
|
|
1013
1348
|
"Sampson",
|
|
1014
1349
|
"Other / outside the area"
|
|
1015
|
-
],
|
|
1350
|
+
], we = "(919) 821-8600", Yt = "https://www.wral.com/my-wral/", Gt = Object.freeze([
|
|
1016
1351
|
"We cannot come back to you for the detail that often turns a tip into a story.",
|
|
1017
1352
|
"We cannot credit you if we use your photos or video.",
|
|
1018
1353
|
"If you lose your reference number, we cannot look it up for you."
|
|
1019
1354
|
]);
|
|
1020
|
-
function
|
|
1021
|
-
const e = String(
|
|
1355
|
+
function Kt(s) {
|
|
1356
|
+
const e = String(s).replace(/\D/g, "");
|
|
1022
1357
|
return `tel:+1${e.length === 11 && e.startsWith("1") ? e.slice(1) : e}`;
|
|
1023
1358
|
}
|
|
1024
|
-
const
|
|
1025
|
-
class
|
|
1026
|
-
static styles =
|
|
1359
|
+
const Qt = "https://api.wral.com/forms", Jt = 480, Zt = 2, Ee = "What would you like to send to WRAL?", W = `Welcome to Report It. ${Ee}`, V = "A few quick questions route your report to the right team.", Xt = 2500, er = "I took or own this material and give WRAL permission to use it on air and online with credit to me.";
|
|
1360
|
+
class ar extends G {
|
|
1361
|
+
static styles = st;
|
|
1027
1362
|
static properties = {
|
|
1028
1363
|
api: { type: String },
|
|
1364
|
+
flow: { type: String },
|
|
1029
1365
|
_phase: { state: !0 },
|
|
1030
1366
|
_forms: { state: !0 },
|
|
1031
1367
|
_form: { state: !0 },
|
|
1032
1368
|
_steps: { state: !0 },
|
|
1369
|
+
_origins: { state: !0 },
|
|
1370
|
+
_handoffError: { state: !0 },
|
|
1033
1371
|
_typing: { state: !0 },
|
|
1034
1372
|
_loadingSlow: { state: !0 },
|
|
1035
1373
|
_cardValues: { state: !0 },
|
|
@@ -1040,36 +1378,36 @@ class at extends T {
|
|
|
1040
1378
|
_notice: { state: !0 },
|
|
1041
1379
|
_result: { state: !0 }
|
|
1042
1380
|
};
|
|
1381
|
+
#c = null;
|
|
1043
1382
|
#l = null;
|
|
1044
|
-
#a = null;
|
|
1045
1383
|
#u = null;
|
|
1046
1384
|
#t = null;
|
|
1047
1385
|
#r = {};
|
|
1048
1386
|
#s = {};
|
|
1049
|
-
#
|
|
1387
|
+
#n = /* @__PURE__ */ new Map();
|
|
1050
1388
|
#y = null;
|
|
1051
1389
|
#p = null;
|
|
1052
1390
|
#w = !1;
|
|
1053
1391
|
#d = null;
|
|
1054
|
-
#
|
|
1392
|
+
#F = 0;
|
|
1055
1393
|
constructor() {
|
|
1056
|
-
super(), this.api =
|
|
1394
|
+
super(), this.api = Qt, this.flow = null, this._phase = "loading", this._forms = [], this._form = null, this._steps = [], this._origins = [], this._handoffError = !1, this._typing = !1, this._loadingSlow = !1, this._cardValues = {}, this._fieldErrors = {}, this._gate = { stage: null, email: "", error: "", loading: !1 }, this._submit = z([]), this._banner = null, this._notice = null, this._result = null;
|
|
1057
1395
|
}
|
|
1058
1396
|
get client() {
|
|
1059
|
-
return this.#
|
|
1397
|
+
return this.#c ? this.#c : ((!this.#l || this.#u !== this.api) && (this.#l = dt({ baseUrl: this.api }), this.#u = this.api), this.#l);
|
|
1060
1398
|
}
|
|
1061
1399
|
set client(e) {
|
|
1062
|
-
this.#
|
|
1400
|
+
this.#c = e || null, this.isConnected && this.#x();
|
|
1063
1401
|
}
|
|
1064
1402
|
connectedCallback() {
|
|
1065
1403
|
super.connectedCallback(), this.#x();
|
|
1066
1404
|
}
|
|
1067
1405
|
disconnectedCallback() {
|
|
1068
1406
|
super.disconnectedCallback(), clearTimeout(this.#y), clearTimeout(this.#p), this.#d?.();
|
|
1069
|
-
for (const { abort: e } of this.#
|
|
1070
|
-
this.#
|
|
1407
|
+
for (const { abort: e } of this.#n.values()) e?.();
|
|
1408
|
+
this.#n.clear();
|
|
1071
1409
|
}
|
|
1072
|
-
get #
|
|
1410
|
+
get #O() {
|
|
1073
1411
|
try {
|
|
1074
1412
|
return matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1075
1413
|
} catch {
|
|
@@ -1091,7 +1429,7 @@ class at extends T {
|
|
|
1091
1429
|
* submission is enabled on this deployment, and a form whose desk needs
|
|
1092
1430
|
* a way to reach the viewer opts out with allowAnonymous: false.
|
|
1093
1431
|
*/
|
|
1094
|
-
get #
|
|
1432
|
+
get #U() {
|
|
1095
1433
|
return this.client.anonymousCapability?.().enabled === !0 && this._form?.allowAnonymous !== !1;
|
|
1096
1434
|
}
|
|
1097
1435
|
/* Derived from the gate step, so a reload restores the choice. */
|
|
@@ -1100,13 +1438,13 @@ class at extends T {
|
|
|
1100
1438
|
}
|
|
1101
1439
|
// ── Loading + draft restore ─────────────────────────────────────
|
|
1102
1440
|
async #x() {
|
|
1103
|
-
const e = ++this.#
|
|
1441
|
+
const e = ++this.#F, t = () => e === this.#F;
|
|
1104
1442
|
this._phase = "loading", this._banner = null, this._loadingSlow = !1, clearTimeout(this.#p), this.#p = setTimeout(() => {
|
|
1105
1443
|
this._loadingSlow = !0;
|
|
1106
|
-
},
|
|
1107
|
-
let
|
|
1444
|
+
}, Xt);
|
|
1445
|
+
let r;
|
|
1108
1446
|
try {
|
|
1109
|
-
|
|
1447
|
+
r = await this.client.listForms();
|
|
1110
1448
|
} catch {
|
|
1111
1449
|
t() && (this._phase = "load-error");
|
|
1112
1450
|
return;
|
|
@@ -1114,85 +1452,144 @@ class at extends T {
|
|
|
1114
1452
|
t() && (clearTimeout(this.#p), this._loadingSlow = !1);
|
|
1115
1453
|
}
|
|
1116
1454
|
if (!t()) return;
|
|
1117
|
-
this._forms =
|
|
1118
|
-
const i =
|
|
1119
|
-
if (
|
|
1120
|
-
this._form =
|
|
1455
|
+
this._forms = r;
|
|
1456
|
+
const i = xt({ attr: this.flow, search: globalThis.location?.search }), n = Ht(Nt(this.#h), this._forms, { apiOrigin: this.api });
|
|
1457
|
+
if ((n.status === "ok" || n.status === "review-required") && _t(n, i)) {
|
|
1458
|
+
this._form = n.form, this._steps = n.steps, this._origins = n.origins || [], this.#t = n.requestId, this.#s = n.lostMedia || {}, n.status === "review-required" ? this._notice = "This form changed since your last visit — please review your answers." : Object.keys(this.#s).length && (this._notice = "Welcome back — your answers were saved, but attachments need to be re-attached."), this.#i({ animate: !1 });
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
const o = vt(this._forms, i);
|
|
1462
|
+
if (o) {
|
|
1463
|
+
this.#I(o);
|
|
1121
1464
|
return;
|
|
1122
1465
|
}
|
|
1123
1466
|
this._phase = "pick";
|
|
1124
1467
|
}
|
|
1125
|
-
#
|
|
1468
|
+
#o() {
|
|
1126
1469
|
if (!this._form) return;
|
|
1127
1470
|
const e = {};
|
|
1128
|
-
for (const [t,
|
|
1129
|
-
|
|
1130
|
-
|
|
1471
|
+
for (const [t, r] of Object.entries(this.#r))
|
|
1472
|
+
r.length && (e[t] = r.map(({ name: i, type: n, size: o }) => ({ name: i, type: n, size: o })));
|
|
1473
|
+
Lt(this.#h, qt({
|
|
1131
1474
|
apiOrigin: this.api,
|
|
1132
1475
|
form: this._form,
|
|
1133
1476
|
steps: this._steps,
|
|
1134
1477
|
requestId: this.#t,
|
|
1135
|
-
mediaMeta: e
|
|
1478
|
+
mediaMeta: e,
|
|
1479
|
+
origins: this._origins
|
|
1136
1480
|
}));
|
|
1137
1481
|
}
|
|
1138
1482
|
// ── Walk mechanics ──────────────────────────────────────────────
|
|
1139
|
-
#
|
|
1140
|
-
this._phase = "walk", this._cardValues = {}, this._fieldErrors = {}, this._gate = { stage: null, email: "", error: "", loading: !1 }, e && !this.#
|
|
1483
|
+
#i({ animate: e = !0 } = {}) {
|
|
1484
|
+
this._phase = "walk", this._cardValues = {}, this._fieldErrors = {}, this._gate = { stage: null, email: "", error: "", loading: !1 }, e && !this.#O ? (this._typing = !0, clearTimeout(this.#y), this.#y = setTimeout(() => {
|
|
1141
1485
|
this._typing = !1;
|
|
1142
|
-
},
|
|
1486
|
+
}, Jt)) : this._typing = !1;
|
|
1143
1487
|
}
|
|
1144
1488
|
get #v() {
|
|
1145
|
-
return this._form ?
|
|
1489
|
+
return this._form ? q(this._form, this._steps) : { node: null };
|
|
1146
1490
|
}
|
|
1147
|
-
#
|
|
1148
|
-
this._form = e, this._steps = [], this.#t = null, this.#r = {}, this.#s = {}, this._notice = null, this.#
|
|
1491
|
+
#I(e) {
|
|
1492
|
+
this._form = e, this._steps = [], this._origins = [], this._handoffError = !1, this.#t = null, this.#r = {}, this.#s = {}, this._notice = null, this.#o(), this.#i();
|
|
1149
1493
|
}
|
|
1150
|
-
#
|
|
1151
|
-
this._steps = [...this._steps, e], this.#
|
|
1494
|
+
#m(e) {
|
|
1495
|
+
this._steps = [...this._steps, e], this.#o(), this.#i();
|
|
1152
1496
|
}
|
|
1153
|
-
#
|
|
1497
|
+
#L(e, t) {
|
|
1498
|
+
if (N(t)) {
|
|
1499
|
+
this.#N(e, t);
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1502
|
+
this._handoffError = !1, this.#m({
|
|
1503
|
+
nodeId: e.id,
|
|
1504
|
+
kind: "choice",
|
|
1505
|
+
optionId: t.id,
|
|
1506
|
+
label: t.label
|
|
1507
|
+
});
|
|
1508
|
+
}
|
|
1509
|
+
/*
|
|
1510
|
+
* Switch to the form a hand-off option names, replaying its preset
|
|
1511
|
+
* steps there. The form being left becomes an origin (see
|
|
1512
|
+
* ../lib/handoff.mjs); its attachments are parked with it in memory so
|
|
1513
|
+
* Back can return them. A target that is missing or no longer matches
|
|
1514
|
+
* its preset path is a config mistake: say so and stay put.
|
|
1515
|
+
*/
|
|
1516
|
+
#N(e, t) {
|
|
1517
|
+
const { form: r, steps: i, error: n } = gt(this._forms, t);
|
|
1518
|
+
if (n) {
|
|
1519
|
+
this._handoffError = !0;
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
this._handoffError = !1, this._origins = [...this._origins, {
|
|
1523
|
+
...bt(this._form, this._steps, e, t),
|
|
1524
|
+
media: this.#r,
|
|
1525
|
+
lostMedia: this.#s
|
|
1526
|
+
}], this._form = r, this._steps = i, this.#t = null, this.#r = {}, this.#s = {}, this._notice = null, this.#o(), this.#i();
|
|
1527
|
+
}
|
|
1528
|
+
/* Back past a hand-off: the originating form, on the choice card. */
|
|
1529
|
+
#q() {
|
|
1530
|
+
const e = this._origins.at(-1);
|
|
1531
|
+
this._origins = this._origins.slice(0, -1), this._form = e.form, this._steps = e.steps, this.#t = null, this.#r = e.media || {}, this.#s = e.lostMedia || {}, this._handoffError = !1, this.#o(), this.#i({ animate: !1 });
|
|
1532
|
+
}
|
|
1533
|
+
#H() {
|
|
1154
1534
|
if (this._phase === "done" || this._phase === "submitting") return;
|
|
1155
1535
|
if (this._phase === "review") {
|
|
1156
|
-
this.#
|
|
1536
|
+
this.#i({ animate: !1 });
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1539
|
+
if (this._origins.length && yt(this._steps)) {
|
|
1540
|
+
this.#q();
|
|
1157
1541
|
return;
|
|
1158
1542
|
}
|
|
1159
1543
|
if (!this._steps.length) {
|
|
1160
|
-
this.#
|
|
1544
|
+
this.#_();
|
|
1161
1545
|
return;
|
|
1162
1546
|
}
|
|
1163
1547
|
const e = this._steps.at(-1);
|
|
1164
|
-
this._steps = this._steps.slice(0, -1), e.kind === "collect" && (this._cardValues = { ...e.values }), this.#
|
|
1548
|
+
this._steps = this._steps.slice(0, -1), e.kind === "collect" && (this._cardValues = { ...e.values }), this.#o(), this.#i({ animate: !1 });
|
|
1165
1549
|
}
|
|
1166
|
-
#
|
|
1167
|
-
this.client.endAnonSession?.(), this._form = null, this._steps = [], this.#t = null, this.#r = {}, this.#s = {}, this._result = null, this._banner = null, this._notice = null, this._submit =
|
|
1550
|
+
#_() {
|
|
1551
|
+
this.client.endAnonSession?.(), this._form = null, this._steps = [], this._origins = [], this._handoffError = !1, this.#t = null, this.#r = {}, this.#s = {}, this._result = null, this._banner = null, this._notice = null, this._submit = z([]), be(this.#h), this._phase = "pick";
|
|
1168
1552
|
}
|
|
1169
1553
|
// ── Collect card ────────────────────────────────────────────────
|
|
1170
|
-
|
|
1554
|
+
#$(e, t) {
|
|
1171
1555
|
this._cardValues = { ...this._cardValues, [e]: t };
|
|
1172
1556
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1557
|
+
/* Files attached on the given collect cards (a files-only consent counts them). */
|
|
1558
|
+
#E(e) {
|
|
1559
|
+
let t = 0;
|
|
1560
|
+
for (const r of new Set(e)) t += (this.#r[r] || []).length;
|
|
1561
|
+
return t;
|
|
1562
|
+
}
|
|
1563
|
+
/* Files attached so far on this walk, the card being filled in included. */
|
|
1564
|
+
#S(e) {
|
|
1565
|
+
const t = this._steps.filter((r) => r.kind === "collect").map((r) => r.nodeId);
|
|
1566
|
+
return this.#E([...t, e]);
|
|
1567
|
+
}
|
|
1568
|
+
#j(e) {
|
|
1569
|
+
const t = e.fields || [], { ok: r, errors: i } = he(t, this._cardValues, {
|
|
1570
|
+
mediaCount: this.#S(e.id)
|
|
1571
|
+
}), n = t.find((l) => l.kind === "media");
|
|
1175
1572
|
let o = !0;
|
|
1176
1573
|
if (n) {
|
|
1177
|
-
const
|
|
1574
|
+
const l = this.#r[e.id] || [], d = Y(l, this._form.budget, {
|
|
1178
1575
|
required: !!n.required
|
|
1179
1576
|
});
|
|
1180
|
-
|
|
1577
|
+
d.ok ? l.length && (this.#s = { ...this.#s, [e.id]: [] }) : (o = !1, i[n.key] = d.errors[0].message);
|
|
1181
1578
|
}
|
|
1182
|
-
if (!
|
|
1579
|
+
if (!r || !o) {
|
|
1183
1580
|
this._fieldErrors = i;
|
|
1184
1581
|
return;
|
|
1185
1582
|
}
|
|
1186
|
-
const
|
|
1187
|
-
this.#
|
|
1583
|
+
const a = this.#r[e.id] || [];
|
|
1584
|
+
this.#m({
|
|
1188
1585
|
nodeId: e.id,
|
|
1189
1586
|
kind: "collect",
|
|
1190
1587
|
values: { ...this._cardValues },
|
|
1191
|
-
summary:
|
|
1588
|
+
summary: Pt(t, this._cardValues, a)
|
|
1192
1589
|
});
|
|
1193
1590
|
}
|
|
1194
1591
|
// ── Gate ────────────────────────────────────────────────────────
|
|
1195
|
-
async #
|
|
1592
|
+
async #C() {
|
|
1196
1593
|
if (!(this._gate.stage || this.#w)) {
|
|
1197
1594
|
this.#w = !0;
|
|
1198
1595
|
try {
|
|
@@ -1202,11 +1599,11 @@ class at extends T {
|
|
|
1202
1599
|
this.#w = !1;
|
|
1203
1600
|
}
|
|
1204
1601
|
this._gate.stage === "email" && this.client.onCrossTabLogin && !this.#d && (this.#d = this.client.onCrossTabLogin(() => {
|
|
1205
|
-
this.#d?.(), this.#d = null, this._gate = { stage: null, email: "", error: "", loading: !1 }, this.#
|
|
1602
|
+
this.#d?.(), this.#d = null, this._gate = { stage: null, email: "", error: "", loading: !1 }, this.#C();
|
|
1206
1603
|
}));
|
|
1207
1604
|
}
|
|
1208
1605
|
}
|
|
1209
|
-
async
|
|
1606
|
+
async #k() {
|
|
1210
1607
|
const e = this._gate.email.trim();
|
|
1211
1608
|
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)) {
|
|
1212
1609
|
this._gate = { ...this._gate, error: "Please enter a valid email address." };
|
|
@@ -1224,10 +1621,10 @@ class at extends T {
|
|
|
1224
1621
|
};
|
|
1225
1622
|
}
|
|
1226
1623
|
}
|
|
1227
|
-
async #
|
|
1624
|
+
async #T(e) {
|
|
1228
1625
|
this._gate = { ...this._gate, error: "", loading: !0 };
|
|
1229
1626
|
try {
|
|
1230
|
-
await this.client.verifyCode(e), this.#
|
|
1627
|
+
await this.client.verifyCode(e), this.#R(this._gate.email);
|
|
1231
1628
|
} catch (t) {
|
|
1232
1629
|
this._gate = {
|
|
1233
1630
|
...this._gate,
|
|
@@ -1236,184 +1633,186 @@ class at extends T {
|
|
|
1236
1633
|
};
|
|
1237
1634
|
}
|
|
1238
1635
|
}
|
|
1239
|
-
#
|
|
1636
|
+
#R(e) {
|
|
1240
1637
|
if (this._gate = { stage: null, email: "", error: "", loading: !1 }, this._submit.stage === "auth") {
|
|
1241
|
-
this.#e({ type: "AUTH_OK" }), this._phase = "submitting", this.#
|
|
1638
|
+
this.#e({ type: "AUTH_OK" }), this._phase = "submitting", this.#a();
|
|
1242
1639
|
return;
|
|
1243
1640
|
}
|
|
1244
1641
|
const { node: t } = this.#v;
|
|
1245
|
-
t?.type === "gate" && this.#
|
|
1642
|
+
t?.type === "gate" && this.#m({ nodeId: t.id, kind: "gate", email: e });
|
|
1246
1643
|
}
|
|
1247
|
-
#
|
|
1644
|
+
#W() {
|
|
1248
1645
|
this.client.signOut?.(), this._gate = { stage: "email", email: "", error: "", loading: !1 };
|
|
1249
1646
|
}
|
|
1250
1647
|
// ── Anonymous route ─────────────────────────────────────────────
|
|
1251
|
-
#
|
|
1648
|
+
#V() {
|
|
1252
1649
|
this._gate = { ...this._gate, stage: "anon-confirm", error: "" };
|
|
1253
1650
|
}
|
|
1254
|
-
#
|
|
1651
|
+
#Y() {
|
|
1255
1652
|
this._gate = { ...this._gate, stage: "email", error: "" };
|
|
1256
1653
|
}
|
|
1257
1654
|
/*
|
|
1258
1655
|
* Records the choice only. The session is minted at submit, against
|
|
1259
1656
|
* the requestId, so an abandoned form leaves nothing behind.
|
|
1260
1657
|
*/
|
|
1261
|
-
#
|
|
1658
|
+
#G() {
|
|
1262
1659
|
const { node: e } = this.#v;
|
|
1263
|
-
e?.type === "gate" && (this._gate = { stage: null, email: "", error: "", loading: !1 }, this.#
|
|
1660
|
+
e?.type === "gate" && (this._gate = { stage: null, email: "", error: "", loading: !1 }, this.#m({ nodeId: e.id, kind: "gate", anonymous: !0 }));
|
|
1264
1661
|
}
|
|
1265
|
-
async #
|
|
1662
|
+
async #M() {
|
|
1266
1663
|
try {
|
|
1267
1664
|
return await this.client.createAnonSession({
|
|
1268
1665
|
formId: this._form.formId,
|
|
1269
1666
|
requestId: this.#t
|
|
1270
1667
|
}), !0;
|
|
1271
1668
|
} catch (e) {
|
|
1272
|
-
return this._banner =
|
|
1669
|
+
return this._banner = me(e?.status ?? 0, e?.body ?? null), !1;
|
|
1273
1670
|
}
|
|
1274
1671
|
}
|
|
1275
1672
|
/* An anonymous session outliving the upload run re-mints in place; there
|
|
1276
1673
|
* is no identity to send back to the sign-in card. */
|
|
1277
|
-
async #
|
|
1278
|
-
if (await this.#
|
|
1279
|
-
this.#e({ type: "AUTH_OK" }), this._phase = "submitting", this.#
|
|
1674
|
+
async #K() {
|
|
1675
|
+
if (await this.#M()) {
|
|
1676
|
+
this.#e({ type: "AUTH_OK" }), this._phase = "submitting", this.#a();
|
|
1280
1677
|
return;
|
|
1281
1678
|
}
|
|
1282
1679
|
this.#e({ type: "REQUEST_FAIL", error: this._banner });
|
|
1283
1680
|
}
|
|
1284
1681
|
// ── Submit pipeline ─────────────────────────────────────────────
|
|
1285
|
-
get #
|
|
1682
|
+
get #g() {
|
|
1286
1683
|
const e = [];
|
|
1287
1684
|
for (const t of this._steps)
|
|
1288
1685
|
if (t.kind === "collect")
|
|
1289
|
-
for (const
|
|
1290
|
-
e.push(
|
|
1686
|
+
for (const r of this.#r[t.nodeId] || [])
|
|
1687
|
+
e.push(r);
|
|
1291
1688
|
return e;
|
|
1292
1689
|
}
|
|
1293
1690
|
#e(e) {
|
|
1294
|
-
this._submit =
|
|
1691
|
+
this._submit = jt(this._submit, e);
|
|
1295
1692
|
}
|
|
1296
|
-
async #
|
|
1693
|
+
async #Q() {
|
|
1297
1694
|
this._banner = null;
|
|
1298
1695
|
for (let e = 0; e < this._steps.length; e++) {
|
|
1299
1696
|
const t = this._steps[e];
|
|
1300
1697
|
if (t.kind !== "collect") continue;
|
|
1301
|
-
const
|
|
1698
|
+
const r = x(this._form, t.nodeId), i = this._steps.slice(0, e + 1).filter((d) => d.kind === "collect").map((d) => d.nodeId), { ok: n, errors: o } = he(r?.fields || [], t.values, {
|
|
1699
|
+
mediaCount: this.#E(i)
|
|
1700
|
+
}), a = (r?.fields || []).find((d) => d.kind === "media");
|
|
1302
1701
|
let l = !0;
|
|
1303
|
-
if (
|
|
1304
|
-
const d = this.#r[t.nodeId] || [],
|
|
1305
|
-
required: !!
|
|
1702
|
+
if (a) {
|
|
1703
|
+
const d = this.#r[t.nodeId] || [], p = Y(d, this._form.budget, {
|
|
1704
|
+
required: !!a.required
|
|
1306
1705
|
});
|
|
1307
|
-
|
|
1706
|
+
p.ok || (l = !1, o[a.key] = p.errors[0].message);
|
|
1308
1707
|
}
|
|
1309
|
-
if (!
|
|
1310
|
-
this._steps = this._steps.slice(0, e), this._cardValues = { ...t.values }, this._fieldErrors =
|
|
1708
|
+
if (!n || !l) {
|
|
1709
|
+
this._steps = this._steps.slice(0, e), this._cardValues = { ...t.values }, this._fieldErrors = o, this.#o(), this.#i({ animate: !1 });
|
|
1311
1710
|
return;
|
|
1312
1711
|
}
|
|
1313
1712
|
}
|
|
1314
|
-
if (this.#t = this.#t || crypto.randomUUID(), this.#
|
|
1315
|
-
if (!await this.#
|
|
1713
|
+
if (this.#t = this.#t || crypto.randomUUID(), this.#o(), this.#f) {
|
|
1714
|
+
if (!await this.#M()) return;
|
|
1316
1715
|
} else
|
|
1317
1716
|
this.client.endAnonSession?.();
|
|
1318
|
-
if (this._submit =
|
|
1319
|
-
this.#e({ type: "START" }), this.#
|
|
1717
|
+
if (this._submit = z(this.#g), this._phase = "submitting", this.#f) {
|
|
1718
|
+
this.#e({ type: "START" }), this.#a();
|
|
1320
1719
|
return;
|
|
1321
1720
|
}
|
|
1322
1721
|
if (!await this.client.isAuthenticated()) {
|
|
1323
1722
|
this.#e({ type: "START" }), this.#e({ type: "AUTH_REQUIRED" }), this._gate = { stage: "email", email: "", error: "", loading: !1 };
|
|
1324
1723
|
return;
|
|
1325
1724
|
}
|
|
1326
|
-
this.#e({ type: "START" }), this.#
|
|
1725
|
+
this.#e({ type: "START" }), this.#a();
|
|
1327
1726
|
}
|
|
1328
|
-
async #
|
|
1727
|
+
async #a() {
|
|
1329
1728
|
const e = this._submit.stage;
|
|
1330
|
-
if (e === "minting") return this.#
|
|
1331
|
-
if (e === "uploading") return this.#
|
|
1332
|
-
if (e === "requesting") return this.#
|
|
1729
|
+
if (e === "minting") return this.#J();
|
|
1730
|
+
if (e === "uploading") return this.#D();
|
|
1731
|
+
if (e === "requesting") return this.#ee();
|
|
1333
1732
|
}
|
|
1334
|
-
async #
|
|
1733
|
+
async #J() {
|
|
1335
1734
|
try {
|
|
1336
|
-
const e = await this.client.createUploads(
|
|
1735
|
+
const e = await this.client.createUploads(fe({
|
|
1337
1736
|
formId: this._form.formId,
|
|
1338
1737
|
requestId: this.#t,
|
|
1339
|
-
files: this.#
|
|
1738
|
+
files: this.#g
|
|
1340
1739
|
}));
|
|
1341
|
-
this.#e({ type: "MINTED", uploads: e }), this.#
|
|
1740
|
+
this.#e({ type: "MINTED", uploads: e }), this.#a();
|
|
1342
1741
|
} catch (e) {
|
|
1343
|
-
this.#
|
|
1742
|
+
this.#A(e);
|
|
1344
1743
|
}
|
|
1345
1744
|
}
|
|
1346
|
-
#
|
|
1347
|
-
const e = this._submit.files, t = this.#
|
|
1348
|
-
let
|
|
1349
|
-
for (let i = 0; i < e.length && t +
|
|
1350
|
-
e[i].status !== "uploading" || this.#
|
|
1745
|
+
#D() {
|
|
1746
|
+
const e = this._submit.files, t = this.#n.size;
|
|
1747
|
+
let r = 0;
|
|
1748
|
+
for (let i = 0; i < e.length && t + r < Zt; i++)
|
|
1749
|
+
e[i].status !== "uploading" || this.#n.has(i) || (r += 1, this.#Z(i));
|
|
1351
1750
|
}
|
|
1352
|
-
#
|
|
1353
|
-
const t = this._submit.files[e],
|
|
1751
|
+
#Z(e) {
|
|
1752
|
+
const t = this._submit.files[e], r = this.#g[e], { promise: i, abort: n } = this.client.uploadFile({
|
|
1354
1753
|
url: t.url,
|
|
1355
|
-
file:
|
|
1754
|
+
file: r,
|
|
1356
1755
|
contentType: t.type,
|
|
1357
|
-
onProgress: ({ loaded: o, total:
|
|
1358
|
-
this.#e({ type: "FILE_PROGRESS", i: e, loaded: o, total:
|
|
1756
|
+
onProgress: ({ loaded: o, total: a }) => {
|
|
1757
|
+
this.#e({ type: "FILE_PROGRESS", i: e, loaded: o, total: a });
|
|
1359
1758
|
}
|
|
1360
1759
|
});
|
|
1361
|
-
this.#
|
|
1362
|
-
this.#
|
|
1760
|
+
this.#n.set(e, { abort: n }), i.then(() => {
|
|
1761
|
+
this.#n.delete(e), this.#e({ type: "FILE_DONE", i: e }), this.#a();
|
|
1363
1762
|
}).catch((o) => {
|
|
1364
|
-
this.#
|
|
1763
|
+
this.#n.delete(e), this.#e({
|
|
1365
1764
|
type: "FILE_FAIL",
|
|
1366
1765
|
i: e,
|
|
1367
1766
|
error: o?.status === 403 ? "expired" : "failed"
|
|
1368
1767
|
});
|
|
1369
1768
|
});
|
|
1370
1769
|
}
|
|
1371
|
-
async #
|
|
1770
|
+
async #X(e) {
|
|
1372
1771
|
if (this._submit.files[e].error === "expired")
|
|
1373
1772
|
try {
|
|
1374
|
-
const [
|
|
1773
|
+
const [r] = await this.client.createUploads(fe({
|
|
1375
1774
|
formId: this._form.formId,
|
|
1376
1775
|
requestId: this.#t,
|
|
1377
|
-
files: [this.#
|
|
1776
|
+
files: [this.#g[e]]
|
|
1378
1777
|
}));
|
|
1379
|
-
this.#e({ type: "REMINT_FILE", i: e, upload:
|
|
1380
|
-
} catch (
|
|
1381
|
-
this.#
|
|
1778
|
+
this.#e({ type: "REMINT_FILE", i: e, upload: r });
|
|
1779
|
+
} catch (r) {
|
|
1780
|
+
this.#A(r);
|
|
1382
1781
|
return;
|
|
1383
1782
|
}
|
|
1384
1783
|
else
|
|
1385
1784
|
this.#e({ type: "RETRY_FILE", i: e });
|
|
1386
|
-
this.#
|
|
1785
|
+
this.#D();
|
|
1387
1786
|
}
|
|
1388
|
-
async #
|
|
1787
|
+
async #ee() {
|
|
1389
1788
|
try {
|
|
1390
|
-
const e = this._submit.files.map(({ assetId:
|
|
1789
|
+
const e = this._submit.files.map(({ assetId: r, type: i }) => ({ assetId: r, type: i })), t = await this.client.putRequest(this.#t, Ct({
|
|
1391
1790
|
form: this._form,
|
|
1392
1791
|
steps: this._steps,
|
|
1393
1792
|
media: e
|
|
1394
1793
|
}));
|
|
1395
|
-
this.#e({ type: "REQUEST_OK", result: t }), this._result = t,
|
|
1794
|
+
this.#e({ type: "REQUEST_OK", result: t }), this._result = t, be(this.#h), this.client.endAnonSession?.(), this._phase = "done";
|
|
1396
1795
|
} catch (e) {
|
|
1397
|
-
this.#
|
|
1796
|
+
this.#A(e);
|
|
1398
1797
|
}
|
|
1399
1798
|
}
|
|
1400
|
-
#
|
|
1401
|
-
const t =
|
|
1799
|
+
#A(e) {
|
|
1800
|
+
const t = me(e?.status ?? 0, e?.body ?? null);
|
|
1402
1801
|
if (t.kind === "auth") {
|
|
1403
1802
|
if (this.#e({ type: "AUTH_REQUIRED" }), this.#f) {
|
|
1404
|
-
this.#
|
|
1803
|
+
this.#K();
|
|
1405
1804
|
return;
|
|
1406
1805
|
}
|
|
1407
1806
|
this._gate = { stage: "email", email: "", error: "", loading: !1 };
|
|
1408
1807
|
return;
|
|
1409
1808
|
}
|
|
1410
1809
|
if (t.kind === "stale") {
|
|
1411
|
-
this._banner = t, this.#e({ type: "REQUEST_FAIL", error: t }), this.#
|
|
1810
|
+
this._banner = t, this.#e({ type: "REQUEST_FAIL", error: t }), this.#te();
|
|
1412
1811
|
return;
|
|
1413
1812
|
}
|
|
1414
1813
|
this._banner = t, this.#e({ type: "REQUEST_FAIL", error: t });
|
|
1415
1814
|
}
|
|
1416
|
-
async #
|
|
1815
|
+
async #te() {
|
|
1417
1816
|
try {
|
|
1418
1817
|
this._forms = await this.client.listForms();
|
|
1419
1818
|
const e = this._forms.find((t) => t.formId === this._form.formId);
|
|
@@ -1421,156 +1820,185 @@ class at extends T {
|
|
|
1421
1820
|
} catch {
|
|
1422
1821
|
}
|
|
1423
1822
|
}
|
|
1424
|
-
#
|
|
1425
|
-
this._banner = null, this.#e({ type: "REQUEST_START" }), this.#
|
|
1823
|
+
#re() {
|
|
1824
|
+
this._banner = null, this.#e({ type: "REQUEST_START" }), this.#a();
|
|
1426
1825
|
}
|
|
1427
1826
|
// ── Render ──────────────────────────────────────────────────────
|
|
1428
1827
|
render() {
|
|
1429
|
-
return
|
|
1828
|
+
return c`
|
|
1430
1829
|
<div class="chat" aria-live="polite">
|
|
1431
|
-
${this.#
|
|
1830
|
+
${this.#se()}
|
|
1432
1831
|
</div>
|
|
1433
|
-
${this.#
|
|
1832
|
+
${this.#ge()}
|
|
1434
1833
|
`;
|
|
1435
1834
|
}
|
|
1436
|
-
#
|
|
1835
|
+
#se() {
|
|
1437
1836
|
switch (this._phase) {
|
|
1438
1837
|
case "loading":
|
|
1439
|
-
return
|
|
1440
|
-
${
|
|
1838
|
+
return c`${g(W, this._loadingSlow ? "Loading the form list…" : V)}
|
|
1839
|
+
${j()}`;
|
|
1441
1840
|
case "load-error":
|
|
1442
|
-
return
|
|
1443
|
-
${
|
|
1841
|
+
return c`
|
|
1842
|
+
${g("We could not load the forms.", "Check your connection and try again.", { error: !0 })}
|
|
1444
1843
|
<div class="options">
|
|
1445
1844
|
<button type="button" class="chip" @click=${() => this.#x()}>Try again</button>
|
|
1446
1845
|
</div>
|
|
1447
1846
|
`;
|
|
1448
1847
|
case "pick":
|
|
1449
|
-
return this.#
|
|
1848
|
+
return this.#ie();
|
|
1450
1849
|
case "walk":
|
|
1451
|
-
return
|
|
1850
|
+
return c`${this.#b()}${this._typing ? j() : this.#ne()}`;
|
|
1452
1851
|
case "review":
|
|
1453
|
-
return
|
|
1852
|
+
return c`${this.#b()}${this.#B()}`;
|
|
1454
1853
|
case "submitting":
|
|
1455
|
-
return
|
|
1854
|
+
return c`${this.#b()}${this.#fe()}`;
|
|
1456
1855
|
case "done":
|
|
1457
|
-
return
|
|
1856
|
+
return c`${this.#b()}${this.#me()}`;
|
|
1458
1857
|
default:
|
|
1459
|
-
return
|
|
1858
|
+
return f;
|
|
1460
1859
|
}
|
|
1461
1860
|
}
|
|
1462
|
-
#
|
|
1463
|
-
const e = this._forms;
|
|
1464
|
-
return
|
|
1465
|
-
${
|
|
1466
|
-
<div class="options" role="group" aria-label
|
|
1467
|
-
${e.map((t,
|
|
1468
|
-
<button type="button" class="chip" style="animation-delay: ${60 +
|
|
1469
|
-
@click=${() => this.#
|
|
1861
|
+
#ie() {
|
|
1862
|
+
const e = this._forms.filter((t) => t.listed !== !1);
|
|
1863
|
+
return c`
|
|
1864
|
+
${g(W, V, { noAnim: !0 })}
|
|
1865
|
+
<div class="options" role="group" aria-label=${Ee}>
|
|
1866
|
+
${e.map((t, r) => c`
|
|
1867
|
+
<button type="button" class="chip" style="animation-delay: ${60 + r * 50}ms"
|
|
1868
|
+
@click=${() => this.#I(t)}>${t.title}</button>
|
|
1470
1869
|
`)}
|
|
1471
1870
|
</div>
|
|
1472
1871
|
`;
|
|
1473
1872
|
}
|
|
1873
|
+
/*
|
|
1874
|
+
* One conversation across hand-offs: the entry choice is the first
|
|
1875
|
+
* form's title, each origin replays its steps and the hand-off option
|
|
1876
|
+
* the viewer picked, and preset steps read as the viewer's own answers
|
|
1877
|
+
* (minus one that merely repeats the hand-off option).
|
|
1878
|
+
*/
|
|
1474
1879
|
#b() {
|
|
1475
1880
|
const e = [];
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1881
|
+
if (!this._form) return e;
|
|
1882
|
+
const t = this._origins[0]?.form || this._form;
|
|
1883
|
+
e.push(g(W, V, { noAnim: !0 })), e.push(F(t.title, { noAnim: !0 })), this._notice && e.push(g(this._notice, "", { noAnim: !0 }));
|
|
1884
|
+
let r = null;
|
|
1885
|
+
for (const i of this._origins) {
|
|
1886
|
+
e.push(...this.#P(i.form, i.steps, r));
|
|
1887
|
+
const n = x(i.form, i.option.nodeId);
|
|
1888
|
+
n?.prompt && e.push(g(n.prompt, n.help, { noAnim: !0 })), r = i.option.label || i.option.optionId, e.push(F(r, { noAnim: !0 }));
|
|
1889
|
+
}
|
|
1890
|
+
return e.push(...this.#P(this._form, this._steps, r)), e;
|
|
1891
|
+
}
|
|
1892
|
+
#P(e, t, r = null) {
|
|
1893
|
+
const i = [];
|
|
1894
|
+
for (const n of t) {
|
|
1895
|
+
if (n.preset) {
|
|
1896
|
+
const a = n.label || n.optionId;
|
|
1897
|
+
a !== r && i.push(F(a, { noAnim: !0 }));
|
|
1898
|
+
continue;
|
|
1899
|
+
}
|
|
1900
|
+
const o = x(e, n.nodeId);
|
|
1901
|
+
o?.prompt && i.push(g(o.prompt, o.help, { noAnim: !0 })), o?.type === "gate" && i.push(n.anonymous ? g(
|
|
1480
1902
|
"Last step: how can we reach you?",
|
|
1481
1903
|
"You chose to send this anonymously.",
|
|
1482
1904
|
{ noAnim: !0 }
|
|
1483
|
-
) :
|
|
1905
|
+
) : g(
|
|
1484
1906
|
"Last step: verify your email so we can follow up.",
|
|
1485
1907
|
"One address, one code. No password needed.",
|
|
1486
1908
|
{ noAnim: !0 }
|
|
1487
|
-
)),
|
|
1909
|
+
)), n.kind === "choice" && i.push(F(n.label || n.optionId, { noAnim: !0 })), n.kind === "collect" && i.push(F(n.summary || "Details provided", { noAnim: !0 })), n.kind === "gate" && i.push(F(n.anonymous ? "Send anonymously" : n.email, { noAnim: !0 }));
|
|
1488
1910
|
}
|
|
1489
|
-
return
|
|
1911
|
+
return i;
|
|
1490
1912
|
}
|
|
1491
|
-
#
|
|
1913
|
+
#ne() {
|
|
1492
1914
|
const { node: e, error: t } = this.#v;
|
|
1493
|
-
return t || !e ?
|
|
1915
|
+
return t || !e ? g("Something went sideways with this form.", "Please start over.", { error: !0 }) : e.type === "choice" ? this.#oe(e) : e.type === "collect" ? this.#ae(e) : e.type === "gate" ? this.#z(e) : e.type === "redirect" ? this.#he(e) : e.type === "terminal" ? this.#B() : f;
|
|
1494
1916
|
}
|
|
1495
|
-
#
|
|
1496
|
-
return
|
|
1497
|
-
${
|
|
1917
|
+
#oe(e) {
|
|
1918
|
+
return c`
|
|
1919
|
+
${g(e.prompt, e.help)}
|
|
1920
|
+
${this._handoffError ? g("We could not load the forms.", "Check your connection and try again.", { error: !0 }) : f}
|
|
1498
1921
|
<div class="options" role="group" aria-label=${e.prompt || "Choose one"}>
|
|
1499
|
-
${(e.options || []).map((t,
|
|
1500
|
-
<button type="button" class="chip" style="animation-delay: ${60 +
|
|
1501
|
-
@click=${() => this.#
|
|
1502
|
-
nodeId: e.id,
|
|
1503
|
-
kind: "choice",
|
|
1504
|
-
optionId: t.id,
|
|
1505
|
-
label: t.label
|
|
1506
|
-
})}>${t.label}</button>
|
|
1922
|
+
${(e.options || []).map((t, r) => c`
|
|
1923
|
+
<button type="button" class="chip" style="animation-delay: ${60 + r * 50}ms"
|
|
1924
|
+
@click=${() => this.#L(e, t)}>${t.label}</button>
|
|
1507
1925
|
`)}
|
|
1508
1926
|
</div>
|
|
1509
1927
|
`;
|
|
1510
1928
|
}
|
|
1511
|
-
|
|
1929
|
+
/*
|
|
1930
|
+
* A real <form>, so browsers offer the viewer's saved name, phone and
|
|
1931
|
+
* address for the autocomplete-tagged fields, and Enter continues.
|
|
1932
|
+
* novalidate: the card validates itself (native url checks would
|
|
1933
|
+
* otherwise block the submit silently).
|
|
1934
|
+
*/
|
|
1935
|
+
#ae(e) {
|
|
1512
1936
|
const t = e.fields || [];
|
|
1513
|
-
return
|
|
1514
|
-
${
|
|
1515
|
-
<
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1937
|
+
return c`
|
|
1938
|
+
${g(e.prompt, e.help)}
|
|
1939
|
+
<form class="form-card" autocomplete="on" novalidate
|
|
1940
|
+
@submit=${(r) => {
|
|
1941
|
+
r.preventDefault(), this.#j(e);
|
|
1942
|
+
}}>
|
|
1943
|
+
${t.map((r) => this.#le(e, r))}
|
|
1944
|
+
<button type="submit" class="btn-primary">Continue</button>
|
|
1945
|
+
</form>
|
|
1521
1946
|
`;
|
|
1522
1947
|
}
|
|
1523
|
-
#
|
|
1524
|
-
const
|
|
1525
|
-
|
|
1948
|
+
#le(e, t) {
|
|
1949
|
+
const r = this.#S(e.id);
|
|
1950
|
+
if (t.kind === "consent" && t.requiredIf === "media" && r === 0)
|
|
1951
|
+
return f;
|
|
1952
|
+
const i = this._cardValues[t.key], n = this._fieldErrors[t.key], o = !Fe(t, { mediaCount: r }) && t.kind !== "consent" ? c` <span class="opt">optional</span>` : f, a = t.kind === "consent" ? f : c`
|
|
1953
|
+
<label for="f-${t.key}">${t.label}${o}</label>
|
|
1526
1954
|
`;
|
|
1527
|
-
return
|
|
1955
|
+
return c`
|
|
1528
1956
|
<div class="field">
|
|
1529
|
-
${
|
|
1530
|
-
${this.#
|
|
1531
|
-
${
|
|
1957
|
+
${a}
|
|
1958
|
+
${this.#ce(e, t, i)}
|
|
1959
|
+
${n ? c`<div class="err" role="alert">${n}</div>` : f}
|
|
1532
1960
|
</div>
|
|
1533
1961
|
`;
|
|
1534
1962
|
}
|
|
1535
|
-
#
|
|
1536
|
-
const i = (n) => (o) => this
|
|
1963
|
+
#ce(e, t, r) {
|
|
1964
|
+
const i = (n) => (o) => this.#$(n, o.target.value);
|
|
1537
1965
|
switch (t.kind) {
|
|
1538
1966
|
case "text":
|
|
1539
|
-
return
|
|
1967
|
+
return c`<input type="text" id="f-${t.key}" name=${t.key} .value=${r || ""}
|
|
1968
|
+
inputmode=${ce(t.inputMode)} autocomplete=${ce(t.autocomplete)}
|
|
1540
1969
|
placeholder=${t.placeholder || ""} @input=${i(t.key)}>`;
|
|
1541
1970
|
case "url":
|
|
1542
|
-
return
|
|
1971
|
+
return c`<input type="url" id="f-${t.key}" .value=${r || ""}
|
|
1543
1972
|
placeholder=${t.placeholder || ""} @input=${i(t.key)}>`;
|
|
1544
1973
|
case "textarea":
|
|
1545
|
-
return
|
|
1974
|
+
return c`<textarea id="f-${t.key}" .value=${r || ""}
|
|
1546
1975
|
placeholder=${t.placeholder || ""} @input=${i(t.key)}></textarea>`;
|
|
1547
1976
|
case "datetime":
|
|
1548
|
-
return
|
|
1977
|
+
return c`<input type="datetime-local" id="f-${t.key}" .value=${r || ""}
|
|
1549
1978
|
@input=${i(t.key)}>`;
|
|
1550
1979
|
case "select":
|
|
1551
|
-
return
|
|
1980
|
+
return c`
|
|
1552
1981
|
<select id="f-${t.key}" @change=${i(t.key)}>
|
|
1553
1982
|
<option value="">Choose one</option>
|
|
1554
|
-
${(t.options || []).map((n) =>
|
|
1555
|
-
<option value=${n.id} ?selected=${
|
|
1983
|
+
${(t.options || []).map((n) => c`
|
|
1984
|
+
<option value=${n.id} ?selected=${r === n.id}>${n.label}</option>
|
|
1556
1985
|
`)}
|
|
1557
1986
|
</select>
|
|
1558
1987
|
`;
|
|
1559
1988
|
case "location":
|
|
1560
|
-
return this.#
|
|
1989
|
+
return this.#de(t, r || {});
|
|
1561
1990
|
case "consent":
|
|
1562
|
-
return
|
|
1991
|
+
return c`
|
|
1563
1992
|
<div class="consent-row">
|
|
1564
|
-
<input type="checkbox" id="f-${t.key}" .checked=${
|
|
1565
|
-
@change=${(n) => this
|
|
1993
|
+
<input type="checkbox" id="f-${t.key}" .checked=${r === !0}
|
|
1994
|
+
@change=${(n) => this.#$(t.key, n.target.checked)}>
|
|
1566
1995
|
<label for="f-${t.key}" style="all: unset; cursor: pointer;">
|
|
1567
|
-
|
|
1568
|
-
on air and online with credit to me.
|
|
1996
|
+
${t.text || er}
|
|
1569
1997
|
</label>
|
|
1570
1998
|
</div>
|
|
1571
1999
|
`;
|
|
1572
2000
|
case "media":
|
|
1573
|
-
return
|
|
2001
|
+
return c`
|
|
1574
2002
|
<wral-report-media
|
|
1575
2003
|
.files=${this.#r[e.id] || []}
|
|
1576
2004
|
.lostMeta=${this.#s[e.id] || []}
|
|
@@ -1582,16 +2010,16 @@ class at extends T {
|
|
|
1582
2010
|
}}></wral-report-media>
|
|
1583
2011
|
`;
|
|
1584
2012
|
default:
|
|
1585
|
-
return
|
|
2013
|
+
return f;
|
|
1586
2014
|
}
|
|
1587
2015
|
}
|
|
1588
|
-
#
|
|
1589
|
-
const
|
|
1590
|
-
return
|
|
2016
|
+
#de(e, t) {
|
|
2017
|
+
const r = e.counties || Vt, i = (n) => this.#$(e.key, { ...t, ...n });
|
|
2018
|
+
return c`
|
|
1591
2019
|
<select id="f-${e.key}" aria-label="County"
|
|
1592
2020
|
@change=${(n) => i({ county: n.target.value || void 0 })}>
|
|
1593
2021
|
<option value="">Choose a county</option>
|
|
1594
|
-
${
|
|
2022
|
+
${r.map((n) => c`
|
|
1595
2023
|
<option value=${n} ?selected=${t.county === n}>${n}</option>
|
|
1596
2024
|
`)}
|
|
1597
2025
|
</select>
|
|
@@ -1602,25 +2030,25 @@ class at extends T {
|
|
|
1602
2030
|
@input=${(n) => i({ where: n.target.value || void 0 })}>
|
|
1603
2031
|
`;
|
|
1604
2032
|
}
|
|
1605
|
-
#
|
|
1606
|
-
this.#
|
|
1607
|
-
const t = this._gate,
|
|
2033
|
+
#z(e) {
|
|
2034
|
+
this.#C();
|
|
2035
|
+
const t = this._gate, r = g(
|
|
1608
2036
|
"Last step: verify your email so we can follow up.",
|
|
1609
2037
|
"One address, one code. No password needed."
|
|
1610
2038
|
);
|
|
1611
|
-
return t.stage ? t.stage === "signedin" ?
|
|
1612
|
-
${
|
|
2039
|
+
return t.stage ? t.stage === "signedin" ? c`
|
|
2040
|
+
${r}
|
|
1613
2041
|
<div class="form-card">
|
|
1614
2042
|
<p style="margin: 0 0 12px; font-size: 14.5px;">
|
|
1615
2043
|
You are signed in as <strong>${t.email || "your My WRAL account"}</strong> on this device.
|
|
1616
2044
|
</p>
|
|
1617
2045
|
<button type="button" class="btn-primary"
|
|
1618
|
-
@click=${() => this.#
|
|
2046
|
+
@click=${() => this.#R(t.email)}>Continue</button>
|
|
1619
2047
|
<button type="button" class="btn-ghost"
|
|
1620
|
-
@click=${() => this.#
|
|
2048
|
+
@click=${() => this.#W()}>Use a different email</button>
|
|
1621
2049
|
</div>
|
|
1622
|
-
` : t.stage === "email" ?
|
|
1623
|
-
${
|
|
2050
|
+
` : t.stage === "email" ? c`
|
|
2051
|
+
${r}
|
|
1624
2052
|
<div class="form-card login-card">
|
|
1625
2053
|
<h2>Sign in or create account</h2>
|
|
1626
2054
|
<p class="login-sub">
|
|
@@ -1634,12 +2062,12 @@ class at extends T {
|
|
|
1634
2062
|
this._gate = { ...t, email: i.target.value };
|
|
1635
2063
|
}}
|
|
1636
2064
|
@keydown=${(i) => {
|
|
1637
|
-
i.key === "Enter" && this
|
|
2065
|
+
i.key === "Enter" && this.#k();
|
|
1638
2066
|
}}>
|
|
1639
2067
|
</div>
|
|
1640
|
-
${t.error ?
|
|
2068
|
+
${t.error ? c`<div class="err" role="alert">${t.error}</div>` : f}
|
|
1641
2069
|
<button type="button" class="login-btn" ?disabled=${t.loading}
|
|
1642
|
-
@click=${() => this
|
|
2070
|
+
@click=${() => this.#k()}>
|
|
1643
2071
|
${t.loading ? "Sending…" : "Continue with email"}
|
|
1644
2072
|
</button>
|
|
1645
2073
|
<div class="login-why">
|
|
@@ -1648,13 +2076,13 @@ class at extends T {
|
|
|
1648
2076
|
<li>We can follow up on your report</li>
|
|
1649
2077
|
<li>Your contact information fills in automatically next time</li>
|
|
1650
2078
|
<li>You are credited by name when we use your photos or video</li>
|
|
1651
|
-
<li><a href=${
|
|
2079
|
+
<li><a href=${Yt} target="_blank" rel="noopener">All other My WRAL account benefits</a></li>
|
|
1652
2080
|
</ul>
|
|
1653
2081
|
</div>
|
|
1654
|
-
${this._submit.stage === "auth" ?
|
|
2082
|
+
${this._submit.stage === "auth" ? f : this.#ue()}
|
|
1655
2083
|
</div>
|
|
1656
|
-
` : t.stage === "anon-confirm" ? this.#
|
|
1657
|
-
${
|
|
2084
|
+
` : t.stage === "anon-confirm" ? this.#pe(r) : c`
|
|
2085
|
+
${r}
|
|
1658
2086
|
<div class="form-card login-card">
|
|
1659
2087
|
<h2>Enter verification code</h2>
|
|
1660
2088
|
<p class="login-sub">We sent a 6-digit code to <strong>${t.email}</strong></p>
|
|
@@ -1667,48 +2095,48 @@ class at extends T {
|
|
|
1667
2095
|
<div class="field">
|
|
1668
2096
|
<label>Verification code</label>
|
|
1669
2097
|
<wral-code-input
|
|
1670
|
-
@code-complete=${(i) => this.#
|
|
2098
|
+
@code-complete=${(i) => this.#T(i.detail?.code ?? i.detail?.value ?? i.target.value)}>
|
|
1671
2099
|
</wral-code-input>
|
|
1672
2100
|
</div>
|
|
1673
|
-
${t.error ?
|
|
2101
|
+
${t.error ? c`<div class="err" role="alert">${t.error}</div>` : f}
|
|
1674
2102
|
<button type="button" class="login-btn" ?disabled=${t.loading}
|
|
1675
2103
|
@click=${() => {
|
|
1676
2104
|
const i = this.renderRoot.querySelector("wral-code-input");
|
|
1677
|
-
this.#
|
|
2105
|
+
this.#T(i?.value || "");
|
|
1678
2106
|
}}>
|
|
1679
2107
|
${t.loading ? "Checking…" : "Sign in"}
|
|
1680
2108
|
</button>
|
|
1681
2109
|
<p class="login-help">
|
|
1682
2110
|
Didn’t receive a code? Check your spam folder or
|
|
1683
|
-
<button type="button" @click=${() => this
|
|
2111
|
+
<button type="button" @click=${() => this.#k()}>resend a new code</button>.
|
|
1684
2112
|
</p>
|
|
1685
2113
|
</div>
|
|
1686
|
-
` :
|
|
2114
|
+
` : c`${r}${j()}`;
|
|
1687
2115
|
}
|
|
1688
2116
|
/* Collapsed by default: findable for whoever needs it, never the
|
|
1689
2117
|
* first thing a viewer reaches for. */
|
|
1690
|
-
#
|
|
1691
|
-
return
|
|
2118
|
+
#ue() {
|
|
2119
|
+
return c`
|
|
1692
2120
|
<details class="login-alt">
|
|
1693
2121
|
<summary>Other ways to send this</summary>
|
|
1694
2122
|
<div class="alt-body">
|
|
1695
2123
|
<p class="alt-row">
|
|
1696
2124
|
Call the newsroom desk at
|
|
1697
|
-
<a href=${
|
|
2125
|
+
<a href=${Kt(we)}>${we}</a>.
|
|
1698
2126
|
</p>
|
|
1699
|
-
${this.#
|
|
2127
|
+
${this.#U ? c`
|
|
1700
2128
|
<p class="alt-row">
|
|
1701
2129
|
<button type="button" class="alt-link"
|
|
1702
|
-
@click=${() => this.#
|
|
2130
|
+
@click=${() => this.#V()}>Send this anonymously</button>
|
|
1703
2131
|
— no follow-up, and no credit if we use your photos or video.
|
|
1704
2132
|
</p>
|
|
1705
|
-
` :
|
|
2133
|
+
` : f}
|
|
1706
2134
|
</div>
|
|
1707
2135
|
</details>
|
|
1708
2136
|
`;
|
|
1709
2137
|
}
|
|
1710
|
-
#
|
|
1711
|
-
return
|
|
2138
|
+
#pe(e) {
|
|
2139
|
+
return c`
|
|
1712
2140
|
${e}
|
|
1713
2141
|
<div class="form-card login-card">
|
|
1714
2142
|
<h2>Before you send anonymously</h2>
|
|
@@ -1716,22 +2144,22 @@ class at extends T {
|
|
|
1716
2144
|
You can send this report without an account. Here is what it costs you.
|
|
1717
2145
|
</p>
|
|
1718
2146
|
<ul class="anon-costs">
|
|
1719
|
-
${
|
|
2147
|
+
${Gt.map((t) => c`
|
|
1720
2148
|
<li><span class="x" aria-hidden="true">✕</span><span>${t}</span></li>
|
|
1721
2149
|
`)}
|
|
1722
2150
|
</ul>
|
|
1723
2151
|
<div class="anon-actions">
|
|
1724
2152
|
<button type="button" class="login-btn"
|
|
1725
|
-
@click=${() => this.#
|
|
2153
|
+
@click=${() => this.#Y()}>Sign in instead</button>
|
|
1726
2154
|
<button type="button" class="btn-ghost"
|
|
1727
|
-
@click=${() => this.#
|
|
2155
|
+
@click=${() => this.#G()}>Continue anonymously</button>
|
|
1728
2156
|
</div>
|
|
1729
2157
|
</div>
|
|
1730
2158
|
`;
|
|
1731
2159
|
}
|
|
1732
|
-
#
|
|
2160
|
+
#he(e) {
|
|
1733
2161
|
const t = e.redirect || {};
|
|
1734
|
-
return
|
|
2162
|
+
return c`
|
|
1735
2163
|
<div class="form-card">
|
|
1736
2164
|
<p style="margin: 0 0 6px; font-weight: 600; font-size: 16px;
|
|
1737
2165
|
color: var(--wral-base-primary-1, #001D68);
|
|
@@ -1748,33 +2176,33 @@ class at extends T {
|
|
|
1748
2176
|
</div>
|
|
1749
2177
|
`;
|
|
1750
2178
|
}
|
|
1751
|
-
#
|
|
1752
|
-
const e =
|
|
1753
|
-
return
|
|
1754
|
-
${
|
|
2179
|
+
#B() {
|
|
2180
|
+
const e = zt(this._form, this._steps);
|
|
2181
|
+
return c`
|
|
2182
|
+
${g("Here is what you are sending.", "Check it over, then submit.")}
|
|
1755
2183
|
<div class="form-card">
|
|
1756
2184
|
<ul class="review-list">
|
|
1757
|
-
${e.map((t) =>
|
|
2185
|
+
${e.map((t) => c`
|
|
1758
2186
|
<li>
|
|
1759
2187
|
<span class="k">${t.k}</span>
|
|
1760
|
-
<span>${t.pill ?
|
|
2188
|
+
<span>${t.pill ? it(t.pill) : t.v}</span>
|
|
1761
2189
|
</li>
|
|
1762
2190
|
`)}
|
|
1763
2191
|
</ul>
|
|
1764
|
-
${this._banner ?
|
|
2192
|
+
${this._banner ? c`
|
|
1765
2193
|
<div class="err" role="alert" style="margin-top: 12px;">${this._banner.message}</div>
|
|
1766
|
-
` :
|
|
2194
|
+
` : f}
|
|
1767
2195
|
<div style="margin-top: 16px;">
|
|
1768
|
-
<button type="button" class="btn-primary" @click=${() => this.#
|
|
2196
|
+
<button type="button" class="btn-primary" @click=${() => this.#Q()}>
|
|
1769
2197
|
Submit report
|
|
1770
2198
|
</button>
|
|
1771
2199
|
</div>
|
|
1772
2200
|
</div>
|
|
1773
2201
|
`;
|
|
1774
2202
|
}
|
|
1775
|
-
#
|
|
2203
|
+
#fe() {
|
|
1776
2204
|
const e = this._submit;
|
|
1777
|
-
if (e.stage === "auth") return this.#
|
|
2205
|
+
if (e.stage === "auth") return this.#z({ id: null, type: "gate" });
|
|
1778
2206
|
const t = {
|
|
1779
2207
|
minting: "Preparing your uploads…",
|
|
1780
2208
|
uploading: "Uploading your files…",
|
|
@@ -1782,77 +2210,77 @@ class at extends T {
|
|
|
1782
2210
|
requesting: "Sending your report…",
|
|
1783
2211
|
"requesting-error": this._banner?.message || "We could not send your report."
|
|
1784
2212
|
}[e.stage] || "Working…";
|
|
1785
|
-
return
|
|
1786
|
-
${
|
|
2213
|
+
return c`
|
|
2214
|
+
${g("Submitting your report.", t)}
|
|
1787
2215
|
<div class="form-card">
|
|
1788
|
-
${e.files.map((
|
|
2216
|
+
${e.files.map((r, i) => c`
|
|
1789
2217
|
<div class="upload-row">
|
|
1790
|
-
<span class="name">${
|
|
2218
|
+
<span class="name">${r.name}</span>
|
|
1791
2219
|
<div class="upload-bar" role="progressbar"
|
|
1792
2220
|
aria-valuemin="0" aria-valuemax="100"
|
|
1793
|
-
aria-valuenow=${Math.round((
|
|
1794
|
-
<div class="fill" style="width: ${(
|
|
2221
|
+
aria-valuenow=${Math.round((r.status === "done" ? 1 : r.progress) * 100)}>
|
|
2222
|
+
<div class="fill" style="width: ${(r.status === "done" ? 1 : r.progress) * 100}%"></div>
|
|
1795
2223
|
</div>
|
|
1796
|
-
<span class="state ${
|
|
1797
|
-
${
|
|
2224
|
+
<span class="state ${r.status === "failed" ? "failed" : ""}">
|
|
2225
|
+
${r.status === "done" ? "Done" : r.status === "failed" ? "Failed" : "Uploading"}
|
|
1798
2226
|
</span>
|
|
1799
|
-
${
|
|
1800
|
-
<button type="button" class="retry-chip" @click=${() => this.#
|
|
2227
|
+
${r.status === "failed" ? c`
|
|
2228
|
+
<button type="button" class="retry-chip" @click=${() => this.#X(i)}>
|
|
1801
2229
|
Retry
|
|
1802
2230
|
</button>
|
|
1803
|
-
` :
|
|
2231
|
+
` : f}
|
|
1804
2232
|
</div>
|
|
1805
2233
|
`)}
|
|
1806
|
-
${e.stage === "requesting-error" ?
|
|
2234
|
+
${e.stage === "requesting-error" ? c`
|
|
1807
2235
|
<div class="err" role="alert">${this._banner?.message || ""}</div>
|
|
1808
|
-
${this._banner?.retryAfter ?
|
|
2236
|
+
${this._banner?.retryAfter ? c`
|
|
1809
2237
|
<div class="file-note">You can try again in about
|
|
1810
2238
|
${Math.ceil(this._banner.retryAfter / 60)} minutes.</div>
|
|
1811
|
-
` :
|
|
2239
|
+
` : f}
|
|
1812
2240
|
<button type="button" class="btn-primary" style="margin-top: 8px;"
|
|
1813
|
-
@click=${() => this.#
|
|
1814
|
-
` :
|
|
1815
|
-
${
|
|
2241
|
+
@click=${() => this.#re()}>Try again</button>
|
|
2242
|
+
` : f}
|
|
2243
|
+
${ye(e).length && e.stage === "uploading-error" ? c`
|
|
1816
2244
|
<div class="err" role="alert">Retry the failed
|
|
1817
|
-
${
|
|
1818
|
-
` :
|
|
2245
|
+
${ye(e).length === 1 ? "file" : "files"} to continue.</div>
|
|
2246
|
+
` : f}
|
|
1819
2247
|
</div>
|
|
1820
2248
|
`;
|
|
1821
2249
|
}
|
|
1822
|
-
#
|
|
1823
|
-
const e =
|
|
2250
|
+
#me() {
|
|
2251
|
+
const e = ke(this._form, this._steps), t = Bt(this._result, e), r = Ut({
|
|
1824
2252
|
routing: this._result?.routing || {},
|
|
1825
2253
|
flags: e,
|
|
1826
2254
|
reference: this._result?.reference || "",
|
|
1827
2255
|
anonymous: this.#f
|
|
1828
2256
|
});
|
|
1829
|
-
return
|
|
2257
|
+
return c`
|
|
1830
2258
|
<div class="confirm-card">
|
|
1831
2259
|
<div class="c-head">
|
|
1832
|
-
<div class="c-check">${
|
|
2260
|
+
<div class="c-check">${nt()}</div>
|
|
1833
2261
|
<div>
|
|
1834
2262
|
<div class="eyebrow">Report received</div>
|
|
1835
2263
|
<h2>${t.title}</h2>
|
|
1836
2264
|
</div>
|
|
1837
2265
|
</div>
|
|
1838
2266
|
<p>${t.body}</p>
|
|
1839
|
-
${t.urgentNote ?
|
|
2267
|
+
${t.urgentNote ? c`<p>${t.urgentNote}</p>` : f}
|
|
1840
2268
|
<div class="refs">
|
|
1841
2269
|
<span class="ref"><span class="rk">Reference</span>${this._result?.reference || ""}</span>
|
|
1842
2270
|
</div>
|
|
1843
|
-
<button type="button" class="c-again" @click=${() => this.#
|
|
2271
|
+
<button type="button" class="c-again" @click=${() => this.#_()}>
|
|
1844
2272
|
Start a new report
|
|
1845
2273
|
</button>
|
|
1846
2274
|
</div>
|
|
1847
2275
|
<div class="journey">
|
|
1848
2276
|
<div class="j-eyebrow">Behind the scenes</div>
|
|
1849
2277
|
<div class="j-title">What happens to your report now</div>
|
|
1850
|
-
${
|
|
2278
|
+
${r.map((i, n) => c`
|
|
1851
2279
|
<div class="j-step">
|
|
1852
2280
|
<div class="j-dot">${n + 1}</div>
|
|
1853
2281
|
<div class="j-body">
|
|
1854
2282
|
<div class="j-t">${i.title}
|
|
1855
|
-
${i.pill ?
|
|
2283
|
+
${i.pill ? c` <span class="flag-pill urgent">${i.pill}</span>` : f}
|
|
1856
2284
|
</div>
|
|
1857
2285
|
<div class="j-d">${i.body}</div>
|
|
1858
2286
|
</div>
|
|
@@ -1861,15 +2289,15 @@ class at extends T {
|
|
|
1861
2289
|
</div>
|
|
1862
2290
|
`;
|
|
1863
2291
|
}
|
|
1864
|
-
#
|
|
2292
|
+
#ge() {
|
|
1865
2293
|
const e = this._phase === "submitting" || this._phase === "done" || this._phase === "loading" || this._phase === "load-error";
|
|
1866
|
-
return
|
|
2294
|
+
return c`
|
|
1867
2295
|
<div class="bottom-bar">
|
|
1868
2296
|
<div class="inner">
|
|
1869
2297
|
<button type="button" class="btn-ghost" ?disabled=${e || this._phase === "pick"}
|
|
1870
|
-
@click=${() => this.#
|
|
2298
|
+
@click=${() => this.#H()}>← Back</button>
|
|
1871
2299
|
<button type="button" class="btn-ghost" ?disabled=${this._phase === "submitting"}
|
|
1872
|
-
@click=${() => this.#
|
|
2300
|
+
@click=${() => this.#_()}>Start over</button>
|
|
1873
2301
|
<span class="note">Your report goes to a person on the right desk.</span>
|
|
1874
2302
|
</div>
|
|
1875
2303
|
</div>
|
|
@@ -1879,7 +2307,7 @@ class at extends T {
|
|
|
1879
2307
|
this.renderRoot?.querySelector(".chat")?.lastElementChild?.scrollIntoView?.({ block: "nearest" });
|
|
1880
2308
|
}
|
|
1881
2309
|
}
|
|
1882
|
-
class
|
|
2310
|
+
class lr extends G {
|
|
1883
2311
|
static properties = {
|
|
1884
2312
|
files: { attribute: !1 },
|
|
1885
2313
|
lostMeta: { attribute: !1 },
|
|
@@ -1887,7 +2315,7 @@ class ot extends T {
|
|
|
1887
2315
|
required: { type: Boolean },
|
|
1888
2316
|
label: { type: String }
|
|
1889
2317
|
};
|
|
1890
|
-
static styles =
|
|
2318
|
+
static styles = y`
|
|
1891
2319
|
:host { display: block; }
|
|
1892
2320
|
input[type=file] { font-family: inherit; font-size: 14px; }
|
|
1893
2321
|
.file-list { margin: 8px 0 0; padding: 0; list-style: none; font-size: 13.5px; }
|
|
@@ -1909,10 +2337,10 @@ class ot extends T {
|
|
|
1909
2337
|
constructor() {
|
|
1910
2338
|
super(), this.files = [], this.lostMeta = [], this.budget = {}, this.required = !1, this.label = "Photos or video";
|
|
1911
2339
|
}
|
|
1912
|
-
get #
|
|
2340
|
+
get #c() {
|
|
1913
2341
|
return (this.budget?.allowedTypes || []).join(",");
|
|
1914
2342
|
}
|
|
1915
|
-
#
|
|
2343
|
+
#l(e) {
|
|
1916
2344
|
this.dispatchEvent(new CustomEvent("files-changed", {
|
|
1917
2345
|
detail: { files: e },
|
|
1918
2346
|
bubbles: !0,
|
|
@@ -1921,76 +2349,76 @@ class ot extends T {
|
|
|
1921
2349
|
}
|
|
1922
2350
|
#u(e) {
|
|
1923
2351
|
const t = [...e.target.files || []];
|
|
1924
|
-
this.#
|
|
2352
|
+
this.#l([...this.files || [], ...t]), e.target.value = "";
|
|
1925
2353
|
}
|
|
1926
2354
|
#t(e) {
|
|
1927
2355
|
const t = [...this.files];
|
|
1928
|
-
t.splice(e, 1), this.#
|
|
2356
|
+
t.splice(e, 1), this.#l(t);
|
|
1929
2357
|
}
|
|
1930
2358
|
render() {
|
|
1931
|
-
const e = this.files || [], { errors: t } =
|
|
1932
|
-
return
|
|
2359
|
+
const e = this.files || [], { errors: t } = Y(e, this.budget, { required: !1 });
|
|
2360
|
+
return c`
|
|
1933
2361
|
<input type="file" multiple
|
|
1934
|
-
accept=${this.#
|
|
2362
|
+
accept=${this.#c || f}
|
|
1935
2363
|
aria-label=${this.label}
|
|
1936
2364
|
@change=${this.#u}>
|
|
1937
|
-
${e.length ?
|
|
2365
|
+
${e.length ? c`
|
|
1938
2366
|
<ul class="file-list">
|
|
1939
|
-
${e.map((
|
|
2367
|
+
${e.map((r, i) => c`
|
|
1940
2368
|
<li>
|
|
1941
|
-
<span>${
|
|
1942
|
-
<span class="size">${
|
|
2369
|
+
<span>${r.name}</span>
|
|
2370
|
+
<span class="size">${tr(r.size)}</span>
|
|
1943
2371
|
<button type="button" class="remove"
|
|
1944
|
-
aria-label="Remove ${
|
|
2372
|
+
aria-label="Remove ${r.name}"
|
|
1945
2373
|
@click=${() => this.#t(i)}>✕</button>
|
|
1946
2374
|
</li>
|
|
1947
2375
|
`)}
|
|
1948
2376
|
</ul>
|
|
1949
|
-
` :
|
|
1950
|
-
${(this.lostMeta || []).length ?
|
|
2377
|
+
` : f}
|
|
2378
|
+
${(this.lostMeta || []).length ? c`
|
|
1951
2379
|
<div class="lost">
|
|
1952
2380
|
Please re-attach your ${this.lostMeta.length === 1 ? "file" : "files"}
|
|
1953
|
-
(${this.lostMeta.map((
|
|
2381
|
+
(${this.lostMeta.map((r) => r.name).join(", ")}) —
|
|
1954
2382
|
attachments can't be saved between visits.
|
|
1955
2383
|
</div>
|
|
1956
|
-
` :
|
|
1957
|
-
${t.map((
|
|
2384
|
+
` : f}
|
|
2385
|
+
${t.map((r) => c`<div class="err">${r.message}</div>`)}
|
|
1958
2386
|
`;
|
|
1959
2387
|
}
|
|
1960
2388
|
}
|
|
1961
|
-
function
|
|
1962
|
-
return Number.isFinite(
|
|
2389
|
+
function tr(s) {
|
|
2390
|
+
return Number.isFinite(s) ? s >= 1024 * 1024 ? `${(s / (1024 * 1024)).toFixed(1)} MB` : s >= 1024 ? `${Math.round(s / 1024)} KB` : `${s} B` : "";
|
|
1963
2391
|
}
|
|
1964
|
-
const
|
|
2392
|
+
const rr = (s, e, t, r) => {
|
|
1965
2393
|
const i = e.target.value.replace(/\D/g, "").slice(-1), n = [...t];
|
|
1966
|
-
n[
|
|
1967
|
-
const o = n.join(""),
|
|
1968
|
-
return
|
|
1969
|
-
},
|
|
2394
|
+
n[s] = i;
|
|
2395
|
+
const o = n.join(""), a = n.every((l) => l !== "");
|
|
2396
|
+
return r("code-change", { value: o, complete: a }), i && a && r("code-complete", { value: o }), n;
|
|
2397
|
+
}, sr = (s, e, t, r) => {
|
|
1970
2398
|
if (e.key === "Backspace") {
|
|
1971
2399
|
const i = [...t];
|
|
1972
|
-
!i[
|
|
2400
|
+
!i[s] && s > 0 ? i[s - 1] = "" : i[s] && (i[s] = "");
|
|
1973
2401
|
const n = i.join("");
|
|
1974
|
-
return
|
|
2402
|
+
return r("code-change", { value: n, complete: !1 }), i;
|
|
1975
2403
|
}
|
|
1976
2404
|
return t;
|
|
1977
|
-
},
|
|
1978
|
-
|
|
1979
|
-
const
|
|
1980
|
-
if (
|
|
2405
|
+
}, ir = (s, e, t) => {
|
|
2406
|
+
s.preventDefault();
|
|
2407
|
+
const r = s.clipboardData.getData("text").replace(/\D/g, "").slice(0, 6);
|
|
2408
|
+
if (r.length === 0) return e;
|
|
1981
2409
|
const i = [...e];
|
|
1982
|
-
for (let
|
|
1983
|
-
i[
|
|
1984
|
-
const n = i.join(""), o = i.every((
|
|
1985
|
-
return t("code-change", { value: n, complete: o }),
|
|
2410
|
+
for (let a = 0; a < r.length && a < 6; a++)
|
|
2411
|
+
i[a] = r[a];
|
|
2412
|
+
const n = i.join(""), o = i.every((a) => a !== "");
|
|
2413
|
+
return t("code-change", { value: n, complete: o }), r.length === 6 && t("code-complete", { value: n }), i;
|
|
1986
2414
|
};
|
|
1987
|
-
class
|
|
2415
|
+
class cr extends G {
|
|
1988
2416
|
static formAssociated = !0;
|
|
1989
2417
|
static properties = {
|
|
1990
2418
|
_values: { type: Array, state: !0 },
|
|
1991
2419
|
disabled: { type: Boolean, reflect: !0 }
|
|
1992
2420
|
};
|
|
1993
|
-
static styles =
|
|
2421
|
+
static styles = y`
|
|
1994
2422
|
:host {
|
|
1995
2423
|
display: block;
|
|
1996
2424
|
width: 100%;
|
|
@@ -2089,7 +2517,7 @@ class lt extends T {
|
|
|
2089
2517
|
this.getInputs()[e]?.focus();
|
|
2090
2518
|
}
|
|
2091
2519
|
inputHandler(e, t) {
|
|
2092
|
-
this._values =
|
|
2520
|
+
this._values = rr(
|
|
2093
2521
|
e,
|
|
2094
2522
|
t,
|
|
2095
2523
|
this._values,
|
|
@@ -2098,22 +2526,22 @@ class lt extends T {
|
|
|
2098
2526
|
}
|
|
2099
2527
|
keydownHandler(e, t) {
|
|
2100
2528
|
if (t.key === "Backspace") {
|
|
2101
|
-
const
|
|
2102
|
-
this._values =
|
|
2529
|
+
const r = !this._values[e];
|
|
2530
|
+
this._values = sr(
|
|
2103
2531
|
e,
|
|
2104
2532
|
t,
|
|
2105
2533
|
this._values,
|
|
2106
2534
|
this.dispatchCustomEvent.bind(this)
|
|
2107
|
-
),
|
|
2535
|
+
), r && e > 0 && this.focusInput(e - 1);
|
|
2108
2536
|
}
|
|
2109
2537
|
}
|
|
2110
2538
|
pasteHandler(e) {
|
|
2111
|
-
this._values =
|
|
2539
|
+
this._values = ir(e, this._values, this.dispatchCustomEvent.bind(this));
|
|
2112
2540
|
}
|
|
2113
2541
|
render() {
|
|
2114
|
-
return
|
|
2542
|
+
return c`
|
|
2115
2543
|
<div class="code-inputs">
|
|
2116
|
-
${[0, 1, 2, 3, 4, 5].map((e) =>
|
|
2544
|
+
${[0, 1, 2, 3, 4, 5].map((e) => c`
|
|
2117
2545
|
<input
|
|
2118
2546
|
type = "text"
|
|
2119
2547
|
inputmode = "numeric"
|
|
@@ -2133,10 +2561,10 @@ class lt extends T {
|
|
|
2133
2561
|
}
|
|
2134
2562
|
}
|
|
2135
2563
|
export {
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2564
|
+
cr as W,
|
|
2565
|
+
lr as a,
|
|
2566
|
+
ar as b,
|
|
2567
|
+
ct as c,
|
|
2568
|
+
at as d,
|
|
2569
|
+
dt as e
|
|
2142
2570
|
};
|