@wral/report-it 0.1.0 → 0.1.2

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.
@@ -1,6 +1,6 @@
1
1
  import { css as p, html as l, nothing as c, LitElement as I } from "lit";
2
- import { getAuthContext as O, createStorage as V, verifyCode as W, extractTokens as S, saveTokens as A, decodeJwtPayload as R, refreshTokenSimple as N, sendCode as H, createUserPool as Y, signUpIfNeeded as K, createCognitoUser as Q, getAuthHeaders as G, STORAGE_KEYS as _, isAuthenticatedSimple as J } from "@wral/sdk-auth-audience";
3
- const X = p`
2
+ import { getAuthContext as W, createStorage as V, verifyCode as N, extractTokens as S, saveTokens as A, decodeJwtPayload as R, refreshTokenSimple as H, sendCode as Y, createUserPool as K, signUpIfNeeded as Q, createCognitoUser as G, getAuthHeaders as J, STORAGE_KEYS as _, isAuthenticatedSimple as X } from "@wral/sdk-auth-audience";
3
+ const Z = p`
4
4
  :host {
5
5
  display: block;
6
6
  box-sizing: border-box;
@@ -17,13 +17,14 @@ const X = p`
17
17
  display: flex;
18
18
  flex-direction: column;
19
19
  gap: 10px;
20
+ min-height: 70vh;
20
21
  }
21
22
  .chat > * { scroll-margin-bottom: 84px; }
22
23
  .sr-only {
23
24
  position: absolute; width: 1px; height: 1px; overflow: hidden;
24
25
  clip: rect(0 0 0 0); white-space: nowrap;
25
26
  }
26
- `, Z = p`
27
+ `, ee = p`
27
28
  @keyframes pop-in {
28
29
  0% { opacity: 0; transform: translateY(16px) scale(0.95); }
29
30
  100% { opacity: 1; transform: translateY(0) scale(1); }
@@ -54,7 +55,7 @@ const X = p`
54
55
  animation: none !important;
55
56
  }
56
57
  }
57
- `, ee = p`
58
+ `, te = p`
58
59
  .msg { max-width: 85%; padding: 12px 16px; border-radius: 14px; font-size: 15px; }
59
60
  .msg.bot {
60
61
  background: var(--wral-semantic-surface-default, #FFFFFF);
@@ -76,7 +77,7 @@ const X = p`
76
77
  .msg .sub { display: block; font-size: 13px; color: var(--wral-semantic-fg-muted, #64748B); margin-top: 4px; }
77
78
  .msg.user .sub { color: rgba(255, 255, 255, 0.75); }
78
79
  .msg.error { border-left: 3px solid var(--wral-base-red-on-light, #D1232A); }
79
- `, te = p`
80
+ `, re = p`
80
81
  .options { display: flex; flex-wrap: wrap; gap: 8px; align-self: flex-start; max-width: 92%; padding: 2px 0 6px; }
81
82
  .chip {
82
83
  font-family: var(--wral-base-font-ui, 'IBM Plex Sans Condensed', sans-serif);
@@ -90,7 +91,7 @@ const X = p`
90
91
  .chip:hover { background: var(--wral-base-secondary-1, #2594E3); color: #FFFFFF; }
91
92
  .chip:focus-visible { outline: 2px solid var(--wral-base-secondary-1, #2594E3); outline-offset: 2px; }
92
93
  .chip:active { transform: scale(0.97); }
93
- `, re = p`
94
+ `, se = p`
94
95
  .form-card {
95
96
  align-self: stretch;
96
97
  background: var(--wral-semantic-surface-default, #FFFFFF);
@@ -155,7 +156,7 @@ const X = p`
155
156
  .btn-ghost:hover { border-color: var(--wral-base-secondary-1, #2594E3); }
156
157
  .btn-ghost:active { transform: scale(0.97); }
157
158
  .btn-ghost:focus-visible { outline: 2px solid var(--wral-base-secondary-1, #2594E3); outline-offset: 2px; }
158
- `, se = p`
159
+ `, ie = p`
159
160
  .login-card { padding: 28px 26px; }
160
161
  .login-card h2 {
161
162
  font-family: var(--wral-base-font-display, 'IBM Plex Sans Condensed', sans-serif);
@@ -200,7 +201,14 @@ const X = p`
200
201
  }
201
202
  .login-why ul { margin: 0; padding-left: 20px; font-size: 14px; color: var(--color-gray-6, #565454); }
202
203
  .login-why li { margin-bottom: 4px; line-height: 1.5; }
203
- `, ie = p`
204
+ .login-why a { color: var(--color-secondary, #2594E3); font-weight: 600; text-decoration: underline; }
205
+ .login-anon {
206
+ border-top: 1px solid var(--color-gray-2, #E7E5E4); margin: 16px 0 0; padding-top: 14px;
207
+ font-size: 14px; color: var(--color-gray-6, #565454); line-height: 1.5;
208
+ }
209
+ .login-anon a { color: var(--color-primary-dark, #00144A); font-weight: 600; text-decoration: none; white-space: nowrap; }
210
+ .login-anon a:hover { text-decoration: underline; }
211
+ `, ae = p`
204
212
  .review-list { margin: 0; padding: 0; list-style: none; font-size: 14px; }
205
213
  .review-list li {
206
214
  display: grid; grid-template-columns: 130px 1fr; gap: 10px;
@@ -232,7 +240,7 @@ const X = p`
232
240
  color: var(--wral-base-primary-1, #001D68);
233
241
  }
234
242
  @media (max-width: 540px) { .review-list li { grid-template-columns: 1fr; gap: 2px; } }
235
- `, ae = p`
243
+ `, ne = p`
236
244
  .upload-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; font-size: 13.5px; }
237
245
  .upload-row .name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
238
246
  .upload-row .state { font-size: 12px; color: var(--wral-semantic-fg-subtle, #64748B); }
@@ -248,7 +256,7 @@ const X = p`
248
256
  border-radius: 999px; padding: 3px 12px; cursor: pointer;
249
257
  }
250
258
  .retry-chip:focus-visible { outline: 2px solid var(--wral-base-secondary-1, #2594E3); outline-offset: 2px; }
251
- `, ne = p`
259
+ `, oe = p`
252
260
  .confirm-card {
253
261
  align-self: stretch;
254
262
  background: var(--wral-base-primary-1, #001D68);
@@ -298,7 +306,7 @@ const X = p`
298
306
  .c-again:hover { background: rgba(255, 255, 255, 0.12); }
299
307
  .c-again:focus-visible { outline: 2px solid var(--wral-base-secondary-2, #50A9E8); outline-offset: 2px; }
300
308
  .c-again:active { transform: scale(0.97); }
301
- `, oe = p`
309
+ `, le = p`
302
310
  .journey {
303
311
  align-self: stretch;
304
312
  background: var(--wral-semantic-surface-default, #FFFFFF);
@@ -339,7 +347,7 @@ const X = p`
339
347
  color: var(--wral-base-primary-1, #001D68); margin-bottom: 2px;
340
348
  }
341
349
  .j-body .j-d { font-size: 13.5px; color: var(--wral-semantic-fg-muted, #475569); line-height: 1.55; }
342
- `, le = p`
350
+ `, de = p`
343
351
  .bottom-bar {
344
352
  position: sticky; bottom: 0; z-index: 20;
345
353
  background: var(--wral-semantic-surface-default, #FFFFFF);
@@ -352,7 +360,7 @@ const X = p`
352
360
  }
353
361
  .bottom-bar .note { margin-left: auto; font-size: 12px; color: var(--wral-semantic-fg-subtle, #64748B); }
354
362
  @media (max-width: 540px) { .bottom-bar .note { display: none; } }
355
- `, de = [X, Z, ee, te, re, se, ie, ae, ne, oe, le];
363
+ `, ce = [Z, ee, te, re, se, ie, ae, ne, oe, le, de];
356
364
  function h(r, e, { noAnim: t = !1, error: s = !1 } = {}) {
357
365
  return l`
358
366
  <div class="msg bot ${t ? "no-anim" : ""} ${s ? "error" : ""}">
@@ -367,10 +375,10 @@ function v(r, { noAnim: e = !1 } = {}) {
367
375
  function $() {
368
376
  return l`<div class="msg bot typing"><span></span><span></span><span></span></div>`;
369
377
  }
370
- function ce(r) {
378
+ function ue(r) {
371
379
  return r ? l`<span class="flag-pill ${r}">${r === "urgent" ? "Urgent" : "Moderate"}</span>` : c;
372
380
  }
373
- function ue() {
381
+ function pe() {
374
382
  return l`
375
383
  <svg viewBox="0 0 24 24" fill="none" stroke="#FFFFFF" stroke-width="3"
376
384
  stroke-linecap="round" stroke-linejoin="round" width="20" height="20"
@@ -382,7 +390,7 @@ class w extends Error {
382
390
  super(`api-forms request failed with status ${e}`), this.status = e, this.body = t;
383
391
  }
384
392
  }
385
- function pe({
393
+ function he({
386
394
  baseUrl: r,
387
395
  fetchFn: e = (...i) => fetch(...i),
388
396
  xhrFactory: t = () => new XMLHttpRequest(),
@@ -442,25 +450,25 @@ function pe({
442
450
  putRequest: async (n, o) => await a(`/v1/requests/${n}`, { method: "PUT", body: o, auth: !0 })
443
451
  };
444
452
  }
445
- function he() {
446
- const { config: r, storage: e } = O();
453
+ function fe() {
454
+ const { config: r, storage: e } = W();
447
455
  let t = null;
448
456
  return {
449
- isAuthenticated: () => J(),
457
+ isAuthenticated: () => X(),
450
458
  signedInEmail: () => e.get(_.userEmail) || null,
451
- getAuthHeaders: () => G(r, e),
459
+ getAuthHeaders: () => J(r, e),
452
460
  /**
453
461
  * Email step. Keeps the challenge user in memory for verifyCode.
454
462
  * @returns {{challengeRequired?: boolean, authenticated?: boolean}}
455
463
  */
456
464
  sendCode: async (s) => {
457
- const i = await H(
465
+ const i = await Y(
458
466
  r,
459
467
  s,
460
468
  e,
461
- Y,
462
469
  K,
463
470
  Q,
471
+ G,
464
472
  S,
465
473
  A,
466
474
  R
@@ -478,7 +486,7 @@ function he() {
478
486
  if (!t)
479
487
  throw new Error("Please enter your email again to get a new code.");
480
488
  try {
481
- await W(
489
+ await N(
482
490
  t,
483
491
  s,
484
492
  e,
@@ -489,7 +497,7 @@ function he() {
489
497
  } catch {
490
498
  throw new Error("Invalid or expired code. Please request a new one and try again.");
491
499
  }
492
- return await N(), { success: !0 };
500
+ return await H(), { success: !0 };
493
501
  },
494
502
  /** Local sign-out only ("use a different email"). */
495
503
  signOut: () => {
@@ -507,14 +515,14 @@ function he() {
507
515
  }
508
516
  };
509
517
  }
510
- function fe({ baseUrl: r }) {
511
- const e = he();
512
- return { ...pe({ baseUrl: r, getAuthHeaders: e.getAuthHeaders }), ...e };
518
+ function ge({ baseUrl: r }) {
519
+ const e = fe();
520
+ return { ...he({ baseUrl: r, getAuthHeaders: e.getAuthHeaders }), ...e };
513
521
  }
514
522
  function g(r, e) {
515
523
  return (r?.nodes || []).find((t) => t.id === e);
516
524
  }
517
- function M(r, e = []) {
525
+ function U(r, e = []) {
518
526
  const t = [];
519
527
  let s = r?.start;
520
528
  for (const a of e) {
@@ -535,9 +543,9 @@ function M(r, e = []) {
535
543
  s = n.next;
536
544
  }
537
545
  const i = g(r, s);
538
- return i ? { nodeId: s, node: i, flags: j(t), error: null } : { nodeId: null, node: null, flags: t, error: { step: null, reason: `unknown node: ${s}` } };
546
+ return i ? { nodeId: s, node: i, flags: L(t), error: null } : { nodeId: null, node: null, flags: t, error: { step: null, reason: `unknown node: ${s}` } };
539
547
  }
540
- function ge(r, e = []) {
548
+ function me(r, e = []) {
541
549
  const t = [];
542
550
  for (const s of e) {
543
551
  if (s.kind !== "collect") continue;
@@ -546,37 +554,37 @@ function ge(r, e = []) {
546
554
  }
547
555
  return t;
548
556
  }
549
- function me(r = []) {
557
+ function be(r = []) {
550
558
  const e = {};
551
559
  for (const t of r)
552
560
  t.kind === "collect" && Object.assign(e, t.values || {});
553
561
  return e;
554
562
  }
555
- function be(r = []) {
563
+ function ye(r = []) {
556
564
  return r.filter((e) => e.kind === "choice").map((e) => `${e.nodeId}:${e.optionId}`);
557
565
  }
558
- function U(r, e = []) {
566
+ function j(r, e = []) {
559
567
  const t = [];
560
568
  for (const s of e) {
561
569
  if (s.kind !== "choice") continue;
562
570
  const a = (g(r, s.nodeId)?.options || []).find((n) => n.id === s.optionId);
563
571
  t.push(...a?.flags || []);
564
572
  }
565
- return j(t);
573
+ return L(t);
566
574
  }
567
- function ye(r = []) {
575
+ function we(r = []) {
568
576
  return r.includes("urgent") ? "urgent" : r.includes("moderate") ? "moderate" : null;
569
577
  }
570
- function j(r) {
578
+ function L(r) {
571
579
  return [...new Set(r)];
572
580
  }
573
- const we = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?(\.\d+)?(Z|[+-]\d{2}:\d{2})?$/, D = {
581
+ const xe = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?(\.\d+)?(Z|[+-]\d{2}:\d{2})?$/, D = {
574
582
  text: 500,
575
583
  textarea: 5e3,
576
584
  url: 2048
577
585
  };
578
- function xe(r, e) {
579
- if (e == null || e === "" || r.kind === "location" && ve(e))
586
+ function ve(r, e) {
587
+ if (e == null || e === "" || r.kind === "location" && ke(e))
580
588
  return r.required ? `Please fill in: ${r.label.toLowerCase()}.` : null;
581
589
  switch (r.kind) {
582
590
  case "text":
@@ -594,30 +602,30 @@ function xe(r, e) {
594
602
  }
595
603
  }
596
604
  case "datetime":
597
- return we.test(String(e)) ? null : "Please pick a date and time.";
605
+ return xe.test(String(e)) ? null : "Please pick a date and time.";
598
606
  case "select":
599
607
  return (r.options || []).map((i) => i.id).includes(e) ? null : `Please choose one of the options for ${r.label.toLowerCase()}.`;
600
608
  case "consent":
601
609
  return e === !0 ? null : "Please confirm the rights statement so we can use what you send.";
602
610
  case "location":
603
- return ke(r, e);
611
+ return _e(r, e);
604
612
  case "media":
605
613
  return null;
606
614
  default:
607
615
  return `Unsupported field: ${r.kind}`;
608
616
  }
609
617
  }
610
- function ve(r) {
618
+ function ke(r) {
611
619
  return r == null ? !0 : typeof r != "object" ? !1 : !r.county && !r.where && !(Array.isArray(r.gps) && r.gps.length);
612
620
  }
613
- function ke(r, e) {
621
+ function _e(r, e) {
614
622
  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((s) => typeof s == "number" && Number.isFinite(s))) ? "Location coordinates look wrong; try re-sharing your location." : r.required && !e.county && !e.where ? `Please fill in: ${r.label.toLowerCase()}.` : null;
615
623
  }
616
624
  function T(r, e = {}) {
617
625
  const t = {};
618
626
  for (const s of r) {
619
627
  if (s.kind === "media") continue;
620
- const i = xe(s, e[s.key]);
628
+ const i = ve(s, e[s.key]);
621
629
  i && (t[s.key] = i);
622
630
  }
623
631
  return { ok: Object.keys(t).length === 0, errors: t };
@@ -650,8 +658,8 @@ function z({ formId: r, requestId: e, files: t }) {
650
658
  files: t.map((s) => ({ contentType: s.type, size: s.size }))
651
659
  };
652
660
  }
653
- function _e({ form: r, steps: e, media: t = [] }) {
654
- const s = ge(r, e), i = me(e), a = {};
661
+ function $e({ form: r, steps: e, media: t = [] }) {
662
+ const s = me(r, e), i = be(e), a = {};
655
663
  for (const n of s) {
656
664
  if (n.kind === "media") continue;
657
665
  const o = i[n.key];
@@ -667,12 +675,12 @@ function _e({ form: r, steps: e, media: t = [] }) {
667
675
  return {
668
676
  formId: r.formId,
669
677
  flowVersion: r.flowVersion,
670
- path: be(e),
678
+ path: ye(e),
671
679
  answers: a,
672
680
  media: t.map(({ assetId: n, type: o }) => ({ assetId: n, type: o }))
673
681
  };
674
682
  }
675
- function $e(r, e) {
683
+ function Fe(r, e) {
676
684
  if (r === 429)
677
685
  return {
678
686
  kind: "throttled",
@@ -710,15 +718,15 @@ function $e(r, e) {
710
718
  message: "Something went wrong on our end; please try again."
711
719
  };
712
720
  }
713
- const Fe = 34, Ie = 44;
721
+ const Ie = 34, Ee = 44;
714
722
  function P(r, e) {
715
723
  const t = String(r);
716
724
  return t.length > e ? `${t.slice(0, e)}…` : t;
717
725
  }
718
- function Ee(r) {
726
+ function Ce(r) {
719
727
  return !r || typeof r != "object" ? "" : [r.county, r.where].filter(Boolean).join(", ");
720
728
  }
721
- function Ce(r, e = {}, t = []) {
729
+ function Se(r, e = {}, t = []) {
722
730
  const s = [];
723
731
  for (const i of r) {
724
732
  if (i.kind === "consent") continue;
@@ -726,21 +734,21 @@ function Ce(r, e = {}, t = []) {
726
734
  t.length && s.push(`${t.length} ${t.length === 1 ? "file" : "files"}`);
727
735
  continue;
728
736
  }
729
- const a = i.kind === "location" ? Ee(e[i.key]) : e[i.key];
730
- a == null || a === "" || (i.kind === "textarea" ? s.push(`"${P(a, Ie)}"`) : s.push(P(a, Fe)));
737
+ const a = i.kind === "location" ? Ce(e[i.key]) : e[i.key];
738
+ a == null || a === "" || (i.kind === "textarea" ? s.push(`"${P(a, Ee)}"`) : s.push(P(a, Ie)));
731
739
  }
732
740
  return s.join(" · ") || "Details provided";
733
741
  }
734
- function Se(r, e = [], t = null) {
742
+ function Ae(r, e = [], t = null) {
735
743
  const s = [];
736
744
  for (const a of e) {
737
745
  const n = g(r, a.nodeId);
738
746
  a.kind === "choice" && n && s.push({ k: (n.prompt || "").replace(/\?$/, ""), v: a.label || a.optionId }), a.kind === "collect" && s.push({ k: "Details", v: a.summary || "Details provided" }), a.kind === "gate" && (a.email || t) && s.push({ k: "Verified email", v: a.email || t });
739
747
  }
740
- const i = ye(U(r, e));
748
+ const i = we(j(r, e));
741
749
  return i && s.push({ k: "Priority", v: i === "urgent" ? "Urgent" : "Moderate", pill: i }), s;
742
750
  }
743
- function Ae(r, e = []) {
751
+ function Re(r, e = []) {
744
752
  const t = r?.confirmation || {};
745
753
  return {
746
754
  title: t.title || "Report received.",
@@ -748,11 +756,11 @@ function Ae(r, e = []) {
748
756
  urgentNote: e.includes("urgent") ? t.urgentNote : void 0
749
757
  };
750
758
  }
751
- function Re(r, e) {
759
+ function De(r, e) {
752
760
  const t = e === "failed" ? " The notification is queued for a delivery retry." : "";
753
761
  return r?.startsWith("studio+email:") ? `Sent to the Studio review queue; the desk is emailed.${t}` : r?.startsWith("studio:") ? "Sent to the Studio review queue." : r?.startsWith("jsm:") ? `A ticket is opened for tech support with your details as fields, not prose.${t}` : r?.startsWith("email:") ? `Emailed to the owning desk with a link to your report.${t}` : "Routed to the right team.";
754
762
  }
755
- function De({ routing: r = {}, flags: e = [], reference: t = "" }) {
763
+ function Te({ routing: r = {}, flags: e = [], reference: t = "" }) {
756
764
  const s = e.includes("urgent");
757
765
  return [
758
766
  {
@@ -761,7 +769,7 @@ function De({ routing: r = {}, flags: e = [], reference: t = "" }) {
761
769
  },
762
770
  {
763
771
  title: "Routed",
764
- body: Re(r.destination, r.state),
772
+ body: De(r.destination, r.state),
765
773
  pill: s ? "Urgent · pinned first" : void 0
766
774
  },
767
775
  {
@@ -778,19 +786,19 @@ function De({ routing: r = {}, flags: e = [], reference: t = "" }) {
778
786
  }
779
787
  ];
780
788
  }
781
- const E = "wral-report-it:draft:v1", L = 1;
782
- function Te(r, e) {
789
+ const E = "wral-report-it:draft:v1", O = 1;
790
+ function ze(r, e) {
783
791
  try {
784
- r.setItem(E, JSON.stringify({ ...e, v: L, savedAt: Date.now() }));
792
+ r.setItem(E, JSON.stringify({ ...e, v: O, savedAt: Date.now() }));
785
793
  } catch {
786
794
  }
787
795
  }
788
- function ze(r) {
796
+ function Pe(r) {
789
797
  try {
790
798
  const e = r.getItem(E);
791
799
  if (!e) return null;
792
800
  const t = JSON.parse(e);
793
- return t?.v !== L ? null : t;
801
+ return t?.v !== O ? null : t;
794
802
  } catch {
795
803
  return null;
796
804
  }
@@ -801,7 +809,7 @@ function B(r) {
801
809
  } catch {
802
810
  }
803
811
  }
804
- function Pe({ apiOrigin: r, form: e, steps: t, requestId: s = null, mediaMeta: i = {} }) {
812
+ function Be({ apiOrigin: r, form: e, steps: t, requestId: s = null, mediaMeta: i = {} }) {
805
813
  return {
806
814
  apiOrigin: r,
807
815
  formId: e.formId,
@@ -811,13 +819,13 @@ function Pe({ apiOrigin: r, form: e, steps: t, requestId: s = null, mediaMeta: i
811
819
  media: i
812
820
  };
813
821
  }
814
- function Be(r, e, { apiOrigin: t } = {}) {
822
+ function qe(r, e, { apiOrigin: t } = {}) {
815
823
  if (!r) return { status: "discarded" };
816
824
  if (t && r.apiOrigin && r.apiOrigin !== t)
817
825
  return { status: "discarded" };
818
826
  const s = (e || []).find((n) => n.formId === r.formId);
819
827
  if (!s) return { status: "discarded" };
820
- const { error: i } = M(s, r.steps || []);
828
+ const { error: i } = U(s, r.steps || []);
821
829
  if (i) return { status: "discarded" };
822
830
  const a = {};
823
831
  for (const [n, o] of Object.entries(r.media || {}))
@@ -850,7 +858,7 @@ function k(r = []) {
850
858
  error: null
851
859
  };
852
860
  }
853
- function qe(r, e) {
861
+ function Me(r, e) {
854
862
  switch (e.type) {
855
863
  case "START":
856
864
  return { ...r, stage: r.files.length ? "minting" : "requesting", error: null };
@@ -877,7 +885,7 @@ function qe(r, e) {
877
885
  }));
878
886
  case "FILE_DONE": {
879
887
  const t = x(r, e.i, (s) => ({ ...s, status: "done", progress: 1 }));
880
- return Me(t);
888
+ return Ue(t);
881
889
  }
882
890
  case "FILE_FAIL":
883
891
  return { ...x(r, e.i, (s) => ({
@@ -918,14 +926,14 @@ function x(r, e, t) {
918
926
  const s = r.files.map((i, a) => a === e ? t(i) : i);
919
927
  return { ...r, files: s };
920
928
  }
921
- function Me(r) {
929
+ function Ue(r) {
922
930
  const e = r.files.every((s) => s.status === "done"), t = r.files.some((s) => s.status === "failed");
923
931
  return e ? { ...r, stage: "requesting" } : t ? { ...r, stage: "uploading-error" } : r;
924
932
  }
925
933
  function q(r) {
926
934
  return r.files.map((e, t) => ({ ...e, i: t })).filter((e) => e.status === "failed");
927
935
  }
928
- const Ue = [
936
+ const je = [
929
937
  "Wake",
930
938
  "Durham",
931
939
  "Orange",
@@ -942,9 +950,14 @@ const Ue = [
942
950
  "Moore",
943
951
  "Sampson",
944
952
  "Other / outside the area"
945
- ], je = "https://api.wral.com/forms", Le = 480, Oe = 2;
946
- class Qe extends I {
947
- static styles = de;
953
+ ], M = "(919) 821-8600", Le = "https://www.wral.com/my-wral/";
954
+ function Oe(r) {
955
+ const e = String(r).replace(/\D/g, "");
956
+ return `tel:+1${e.length === 11 && e.startsWith("1") ? e.slice(1) : e}`;
957
+ }
958
+ const We = "https://api.wral.com/forms", Ve = 480, Ne = 2;
959
+ class Xe extends I {
960
+ static styles = ce;
948
961
  static properties = {
949
962
  api: { type: String },
950
963
  _phase: { state: !0 },
@@ -971,10 +984,10 @@ class Qe extends I {
971
984
  #m = !1;
972
985
  #l = null;
973
986
  constructor() {
974
- super(), this.api = je, this._phase = "loading", this._forms = [], this._form = null, this._steps = [], this._typing = !1, this._cardValues = {}, this._fieldErrors = {}, this._gate = { stage: null, email: "", error: "", loading: !1 }, this._submit = k([]), this._banner = null, this._notice = null, this._result = null;
987
+ super(), this.api = We, this._phase = "loading", this._forms = [], this._form = null, this._steps = [], this._typing = !1, this._cardValues = {}, this._fieldErrors = {}, this._gate = { stage: null, email: "", error: "", loading: !1 }, this._submit = k([]), this._banner = null, this._notice = null, this._result = null;
975
988
  }
976
989
  get client() {
977
- return this.#o ? this.#o : ((!this.#a || this.#u !== this.api) && (this.#a = fe({ baseUrl: this.api }), this.#u = this.api), this.#a);
990
+ return this.#o ? this.#o : ((!this.#a || this.#u !== this.api) && (this.#a = ge({ baseUrl: this.api }), this.#u = this.api), this.#a);
978
991
  }
979
992
  set client(e) {
980
993
  this.#o = e || null, this.isConnected && this.#b();
@@ -1012,7 +1025,7 @@ class Qe extends I {
1012
1025
  this._phase = "load-error";
1013
1026
  return;
1014
1027
  }
1015
- const e = Be(ze(this.#p), this._forms, { apiOrigin: this.api });
1028
+ const e = qe(Pe(this.#p), this._forms, { apiOrigin: this.api });
1016
1029
  if (e.status === "ok" || e.status === "review-required") {
1017
1030
  this._form = e.form, this._steps = e.steps, this.#t = e.requestId, this.#s = e.lostMedia || {}, e.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.#n({ animate: !1 });
1018
1031
  return;
@@ -1024,7 +1037,7 @@ class Qe extends I {
1024
1037
  const e = {};
1025
1038
  for (const [t, s] of Object.entries(this.#r))
1026
1039
  s.length && (e[t] = s.map(({ name: i, type: a, size: n }) => ({ name: i, type: a, size: n })));
1027
- Te(this.#p, Pe({
1040
+ ze(this.#p, Be({
1028
1041
  apiOrigin: this.api,
1029
1042
  form: this._form,
1030
1043
  steps: this._steps,
@@ -1036,10 +1049,10 @@ class Qe extends I {
1036
1049
  #n({ animate: e = !0 } = {}) {
1037
1050
  this._phase = "walk", this._cardValues = {}, this._fieldErrors = {}, this._gate = { stage: null, email: "", error: "", loading: !1 }, e && !this.#A ? (this._typing = !0, clearTimeout(this.#g), this.#g = setTimeout(() => {
1038
1051
  this._typing = !1;
1039
- }, Le)) : this._typing = !1;
1052
+ }, Ve)) : this._typing = !1;
1040
1053
  }
1041
1054
  get #_() {
1042
- return this._form ? M(this._form, this._steps) : { node: null };
1055
+ return this._form ? U(this._form, this._steps) : { node: null };
1043
1056
  }
1044
1057
  #R(e) {
1045
1058
  this._form = e, this._steps = [], this.#t = null, this.#r = {}, this.#s = {}, this._notice = null, this.#d(), this.#n();
@@ -1085,7 +1098,7 @@ class Qe extends I {
1085
1098
  nodeId: e.id,
1086
1099
  kind: "collect",
1087
1100
  values: { ...this._cardValues },
1088
- summary: Ce(t, this._cardValues, o)
1101
+ summary: Se(t, this._cardValues, o)
1089
1102
  });
1090
1103
  }
1091
1104
  // ── Gate ────────────────────────────────────────────────────────
@@ -1154,7 +1167,7 @@ class Qe extends I {
1154
1167
  return e;
1155
1168
  }
1156
1169
  #e(e) {
1157
- this._submit = qe(this._submit, e);
1170
+ this._submit = Me(this._submit, e);
1158
1171
  }
1159
1172
  async #P() {
1160
1173
  this._banner = null;
@@ -1201,7 +1214,7 @@ class Qe extends I {
1201
1214
  #E() {
1202
1215
  const e = this._submit.files, t = this.#i.size;
1203
1216
  let s = 0;
1204
- for (let i = 0; i < e.length && t + s < Oe; i++)
1217
+ for (let i = 0; i < e.length && t + s < Ne; i++)
1205
1218
  e[i].status !== "uploading" || this.#i.has(i) || (s += 1, this.#q(i));
1206
1219
  }
1207
1220
  #q(e) {
@@ -1242,7 +1255,7 @@ class Qe extends I {
1242
1255
  }
1243
1256
  async #U() {
1244
1257
  try {
1245
- const e = this._submit.files.map(({ assetId: s, type: i }) => ({ assetId: s, type: i })), t = await this.client.putRequest(this.#t, _e({
1258
+ const e = this._submit.files.map(({ assetId: s, type: i }) => ({ assetId: s, type: i })), t = await this.client.putRequest(this.#t, $e({
1246
1259
  form: this._form,
1247
1260
  steps: this._steps,
1248
1261
  media: e
@@ -1253,7 +1266,7 @@ class Qe extends I {
1253
1266
  }
1254
1267
  }
1255
1268
  #k(e) {
1256
- const t = $e(e?.status ?? 0, e?.body ?? null);
1269
+ const t = Fe(e?.status ?? 0, e?.body ?? null);
1257
1270
  if (t.kind === "auth") {
1258
1271
  this.#e({ type: "AUTH_REQUIRED" }), this._gate = { stage: "email", email: "", error: "", loading: !1 };
1259
1272
  return;
@@ -1296,9 +1309,9 @@ class Qe extends I {
1296
1309
  </div>
1297
1310
  `;
1298
1311
  case "pick":
1299
- return this.#V();
1312
+ return this.#W();
1300
1313
  case "walk":
1301
- return l`${this.#f()}${this._typing ? $() : this.#W()}`;
1314
+ return l`${this.#f()}${this._typing ? $() : this.#V()}`;
1302
1315
  case "review":
1303
1316
  return l`${this.#f()}${this.#S()}`;
1304
1317
  case "submitting":
@@ -1309,7 +1322,7 @@ class Qe extends I {
1309
1322
  return c;
1310
1323
  }
1311
1324
  }
1312
- #V() {
1325
+ #W() {
1313
1326
  const e = this._forms;
1314
1327
  return l`
1315
1328
  ${h(
@@ -1341,7 +1354,7 @@ class Qe extends I {
1341
1354
  }
1342
1355
  return e;
1343
1356
  }
1344
- #W() {
1357
+ #V() {
1345
1358
  const { node: e, error: t } = this.#_;
1346
1359
  return t || !e ? h("Something went sideways with this form.", "Please start over.", { error: !0 }) : e.type === "choice" ? this.#N(e) : e.type === "collect" ? this.#H(e) : e.type === "gate" ? this.#C(e) : e.type === "redirect" ? this.#G(e) : e.type === "terminal" ? this.#S() : c;
1347
1360
  }
@@ -1439,7 +1452,7 @@ class Qe extends I {
1439
1452
  }
1440
1453
  }
1441
1454
  #Q(e, t) {
1442
- const s = e.counties || Ue, i = (a) => this.#x(e.key, { ...t, ...a });
1455
+ const s = e.counties || je, i = (a) => this.#x(e.key, { ...t, ...a });
1443
1456
  return l`
1444
1457
  <select id="f-${e.key}" aria-label="County"
1445
1458
  @change=${(a) => i({ county: a.target.value || void 0 })}>
@@ -1501,8 +1514,13 @@ class Qe extends I {
1501
1514
  <li>We can follow up on your report</li>
1502
1515
  <li>Your contact information fills in automatically next time</li>
1503
1516
  <li>You are credited by name when we use your photos or video</li>
1517
+ <li><a href=${Le} target="_blank" rel="noopener">All other My WRAL account benefits</a></li>
1504
1518
  </ul>
1505
1519
  </div>
1520
+ <p class="login-anon">
1521
+ Want to remain anonymous? Call us at
1522
+ <a href=${Oe(M)}>${M}</a>.
1523
+ </p>
1506
1524
  </div>
1507
1525
  ` : l`
1508
1526
  ${s}
@@ -1556,7 +1574,7 @@ class Qe extends I {
1556
1574
  `;
1557
1575
  }
1558
1576
  #S() {
1559
- const e = Se(this._form, this._steps);
1577
+ const e = Ae(this._form, this._steps);
1560
1578
  return l`
1561
1579
  ${h("Here is what you are sending.", "Check it over, then submit.")}
1562
1580
  <div class="form-card">
@@ -1564,7 +1582,7 @@ class Qe extends I {
1564
1582
  ${e.map((t) => l`
1565
1583
  <li>
1566
1584
  <span class="k">${t.k}</span>
1567
- <span>${t.pill ? ce(t.pill) : t.v}</span>
1585
+ <span>${t.pill ? ue(t.pill) : t.v}</span>
1568
1586
  </li>
1569
1587
  `)}
1570
1588
  </ul>
@@ -1624,7 +1642,7 @@ class Qe extends I {
1624
1642
  `;
1625
1643
  }
1626
1644
  #X() {
1627
- const e = U(this._form, this._steps), t = Ae(this._result, e), s = De({
1645
+ const e = j(this._form, this._steps), t = Re(this._result, e), s = Te({
1628
1646
  routing: this._result?.routing || {},
1629
1647
  flags: e,
1630
1648
  reference: this._result?.reference || ""
@@ -1632,7 +1650,7 @@ class Qe extends I {
1632
1650
  return l`
1633
1651
  <div class="confirm-card">
1634
1652
  <div class="c-head">
1635
- <div class="c-check">${ue()}</div>
1653
+ <div class="c-check">${pe()}</div>
1636
1654
  <div>
1637
1655
  <div class="eyebrow">Report received</div>
1638
1656
  <h2>${t.title}</h2>
@@ -1682,7 +1700,7 @@ class Qe extends I {
1682
1700
  this.renderRoot?.querySelector(".chat")?.lastElementChild?.scrollIntoView?.({ block: "nearest" });
1683
1701
  }
1684
1702
  }
1685
- class Ge extends I {
1703
+ class Ze extends I {
1686
1704
  static properties = {
1687
1705
  files: { attribute: !1 },
1688
1706
  lostMeta: { attribute: !1 },
@@ -1742,7 +1760,7 @@ class Ge extends I {
1742
1760
  ${e.map((s, i) => l`
1743
1761
  <li>
1744
1762
  <span>${s.name}</span>
1745
- <span class="size">${Ve(s.size)}</span>
1763
+ <span class="size">${He(s.size)}</span>
1746
1764
  <button type="button" class="remove"
1747
1765
  aria-label="Remove ${s.name}"
1748
1766
  @click=${() => this.#t(i)}>✕</button>
@@ -1761,15 +1779,15 @@ class Ge extends I {
1761
1779
  `;
1762
1780
  }
1763
1781
  }
1764
- function Ve(r) {
1782
+ function He(r) {
1765
1783
  return Number.isFinite(r) ? r >= 1024 * 1024 ? `${(r / (1024 * 1024)).toFixed(1)} MB` : r >= 1024 ? `${Math.round(r / 1024)} KB` : `${r} B` : "";
1766
1784
  }
1767
- const We = (r, e, t, s) => {
1785
+ const Ye = (r, e, t, s) => {
1768
1786
  const i = e.target.value.replace(/\D/g, "").slice(-1), a = [...t];
1769
1787
  a[r] = i;
1770
1788
  const n = a.join(""), o = a.every((d) => d !== "");
1771
1789
  return s("code-change", { value: n, complete: o }), i && o && s("code-complete", { value: n }), a;
1772
- }, Ne = (r, e, t, s) => {
1790
+ }, Ke = (r, e, t, s) => {
1773
1791
  if (e.key === "Backspace") {
1774
1792
  const i = [...t];
1775
1793
  !i[r] && r > 0 ? i[r - 1] = "" : i[r] && (i[r] = "");
@@ -1777,7 +1795,7 @@ const We = (r, e, t, s) => {
1777
1795
  return s("code-change", { value: a, complete: !1 }), i;
1778
1796
  }
1779
1797
  return t;
1780
- }, He = (r, e, t) => {
1798
+ }, Qe = (r, e, t) => {
1781
1799
  r.preventDefault();
1782
1800
  const s = r.clipboardData.getData("text").replace(/\D/g, "").slice(0, 6);
1783
1801
  if (s.length === 0) return e;
@@ -1787,7 +1805,7 @@ const We = (r, e, t, s) => {
1787
1805
  const a = i.join(""), n = i.every((o) => o !== "");
1788
1806
  return t("code-change", { value: a, complete: n }), s.length === 6 && t("code-complete", { value: a }), i;
1789
1807
  };
1790
- class Je extends I {
1808
+ class et extends I {
1791
1809
  static formAssociated = !0;
1792
1810
  static properties = {
1793
1811
  _values: { type: Array, state: !0 },
@@ -1892,7 +1910,7 @@ class Je extends I {
1892
1910
  this.getInputs()[e]?.focus();
1893
1911
  }
1894
1912
  inputHandler(e, t) {
1895
- this._values = We(
1913
+ this._values = Ye(
1896
1914
  e,
1897
1915
  t,
1898
1916
  this._values,
@@ -1902,7 +1920,7 @@ class Je extends I {
1902
1920
  keydownHandler(e, t) {
1903
1921
  if (t.key === "Backspace") {
1904
1922
  const s = !this._values[e];
1905
- this._values = Ne(
1923
+ this._values = Ke(
1906
1924
  e,
1907
1925
  t,
1908
1926
  this._values,
@@ -1911,7 +1929,7 @@ class Je extends I {
1911
1929
  }
1912
1930
  }
1913
1931
  pasteHandler(e) {
1914
- this._values = He(e, this._values, this.dispatchCustomEvent.bind(this));
1932
+ this._values = Qe(e, this._values, this.dispatchCustomEvent.bind(this));
1915
1933
  }
1916
1934
  render() {
1917
1935
  return l`
@@ -1936,10 +1954,10 @@ class Je extends I {
1936
1954
  }
1937
1955
  }
1938
1956
  export {
1939
- Je as W,
1940
- Ge as a,
1941
- Qe as b,
1942
- he as c,
1943
- pe as d,
1944
- fe as e
1957
+ et as W,
1958
+ Ze as a,
1959
+ Xe as b,
1960
+ fe as c,
1961
+ he as d,
1962
+ ge as e
1945
1963
  };