@sphoro/bugcatch-web-sdk 0.20.0 → 0.21.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 +39 -1
- package/dist/bugcatch-call.umd.js +1 -1
- package/dist/bugcatch-core.es.js +652 -497
- package/dist/bugcatch-core.es.js.map +1 -1
- package/dist/bugcatch-panel.es.js +1140 -938
- package/dist/bugcatch-panel.es.js.map +1 -1
- package/dist/bugcatch-panel.umd.js +237 -145
- package/dist/bugcatch-panel.umd.js.map +1 -1
- package/dist/bugcatch.standalone.umd.js +243 -151
- package/dist/bugcatch.standalone.umd.js.map +1 -1
- package/dist/bugcatch.umd.js +8 -8
- package/dist/bugcatch.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/feedback.js +94 -0
- package/src/identity.js +1 -1
- package/src/index.d.ts +56 -6
- package/src/index.js +111 -7
- package/src/panel/compose.js +1 -1
- package/src/panel/feedback.js +205 -0
- package/src/panel/icons.js +6 -0
- package/src/panel/index.js +83 -13
- package/src/panel/styles.js +47 -0
- package/src/widget.js +14 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { s as
|
|
2
|
-
const Ne = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>', Be = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>', fe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>', pe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>', ge = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>', Ye = '<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>', We = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>', re = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>', Pe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>', Fe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 6l6 6-6 6"/></svg>', me = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.9l2.75 5.82 6.37.76-4.7 4.37 1.24 6.3L12 17.03l-5.66 3.12 1.24-6.3-4.7-4.37 6.37-.76z"/></svg>', Ke = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 13.5l2.6-7.2A1.5 1.5 0 0 1 7.5 5.3h9a1.5 1.5 0 0 1 1.4 1L20.5 13.5V18a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 18z"/><path d="M3.5 13.5h4.8l1.2 2.2h5l1.2-2.2h4.8"/></svg>', Ue = '<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>', Ze = `
|
|
1
|
+
import { s as qe, m as Ee, a as Me, c as pe, b as ze, d as Ce, R as me, h as K, n as Ae, e as He, f as Ie, g as ae, i as P, j as F, r as Re, v as De, k as je, S as Ve, U as Oe, l as Be, o as Ne, p as Fe, M as We, F as Ye } from "./bugcatch-core.es.js";
|
|
2
|
+
const Ke = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>', Pe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>', ve = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>', he = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>', ce = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>', Ue = '<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>', _e = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>', oe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>', Ze = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6a4 4 0 0 1 8 0"/><rect x="7" y="7.5" width="10" height="12" rx="5"/><path d="M7 11H3.5M7 15.5H4M17 11h3.5M17 15.5h3M12 8v11.5"/></svg>', Ge = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>', Xe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 6l6 6-6 6"/></svg>', ye = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.9l2.75 5.82 6.37.76-4.7 4.37 1.24 6.3L12 17.03l-5.66 3.12 1.24-6.3-4.7-4.37 6.37-.76z"/></svg>', Je = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 13.5l2.6-7.2A1.5 1.5 0 0 1 7.5 5.3h9a1.5 1.5 0 0 1 1.4 1L20.5 13.5V18a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 18z"/><path d="M3.5 13.5h4.8l1.2 2.2h5l1.2-2.2h4.8"/></svg>', et = '<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>', tt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 5.5h15a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1h-8l-4.3 3.2a.5.5 0 0 1-.8-.4v-2.8H4.5a1 1 0 0 1-1-1v-9a1 1 0 0 1 1-1z"/><path d="M12 8.4l.9 1.9 2 .3-1.5 1.4.4 2-1.8-1-1.8 1 .4-2-1.5-1.4 2-.3z"/></svg>', at = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 17.5h6M10 21h4"/><path d="M12 3a6 6 0 0 0-3.6 10.8c.6.5 1 1.2 1 2V17h5.2v-1.2c0-.8.4-1.5 1-2A6 6 0 0 0 12 3z"/></svg>', rt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20s-7.5-4.6-7.5-10.2A4.3 4.3 0 0 1 12 7.2a4.3 4.3 0 0 1 7.5 2.6C19.5 15.4 12 20 12 20z"/></svg>', ot = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M9.6 9.4a2.5 2.5 0 0 1 4.8.9c0 1.7-2.4 2.2-2.4 3.6M12 17h.01"/></svg>', nt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.8" stroke-linecap="round"><path d="M6.5 12h.01M12 12h.01M17.5 12h.01"/></svg>', it = `
|
|
3
3
|
@keyframes bc-fade-in { from { opacity: 0 } to { opacity: 1 } }
|
|
4
4
|
@keyframes bc-fade-out { to { opacity: 0 } }
|
|
5
5
|
@keyframes bc-panel-in { from { opacity: 0; transform: translateY(14px) scale(.965) } to { opacity: 1; transform: none } }
|
|
@@ -297,6 +297,53 @@ textarea { min-height: 76px; resize: vertical; }
|
|
|
297
297
|
.seg button[aria-pressed=true]::before { opacity: 1; }
|
|
298
298
|
.seg button:focus-visible { outline-offset: -2px; }
|
|
299
299
|
|
|
300
|
+
/* ---------- report a bug, or give feedback ----------
|
|
301
|
+
The same stone track as the severity control, two wide segments, under the
|
|
302
|
+
header so it stays put while the form scrolls. Each form's own parts carry
|
|
303
|
+
bug-only or fb-only; the other screens (history, a conversation, a call)
|
|
304
|
+
carry neither, so a mode left on the panel cannot hide anything of theirs. */
|
|
305
|
+
.modes {
|
|
306
|
+
flex: none; display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
|
|
307
|
+
margin: 12px var(--bc-pad) 0; padding: 3px; background: var(--bc-stone); border-radius: 999px;
|
|
308
|
+
}
|
|
309
|
+
.modes button {
|
|
310
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-width: 0;
|
|
311
|
+
height: 32px; padding: 0 8px; font: inherit; font-size: var(--bc-fs-sm); font-weight: 520; line-height: 1; white-space: nowrap;
|
|
312
|
+
color: var(--bc-muted); background: none; border: none; border-radius: 999px;
|
|
313
|
+
cursor: pointer; transition: background 180ms var(--bc-ease), color 180ms, box-shadow 180ms;
|
|
314
|
+
}
|
|
315
|
+
.modes button svg { font-size: 15px; flex: none; }
|
|
316
|
+
.modes button:hover { color: var(--bc-fg); }
|
|
317
|
+
.modes button[aria-pressed=true] {
|
|
318
|
+
background: var(--bc-raised); color: var(--bc-fg); font-weight: 600;
|
|
319
|
+
box-shadow: 0 1px 2px rgba(20,18,14,.10), 0 0 0 .5px rgba(20,18,14,.08);
|
|
320
|
+
}
|
|
321
|
+
.modes button:focus-visible { outline-offset: -2px; }
|
|
322
|
+
.panel[data-mode="feedback"] .bug-only,
|
|
323
|
+
.panel:not([data-mode="feedback"]) .fb-only { display: none !important; }
|
|
324
|
+
|
|
325
|
+
/* ---------- feedback ---------- */
|
|
326
|
+
.feedback { animation: bc-fade-in 200ms ease both; }
|
|
327
|
+
.feedback textarea { min-height: 96px; }
|
|
328
|
+
.feedback .kinds { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
329
|
+
.feedback .kinds .tool[aria-pressed=true] { background: var(--bc-accent); border-color: var(--bc-accent); color: var(--bc-on-accent); }
|
|
330
|
+
.feedback .kinds .tool[aria-pressed=true] svg { color: currentColor; }
|
|
331
|
+
.faces { display: flex; gap: 6px; }
|
|
332
|
+
.face {
|
|
333
|
+
flex: 1 1 0; display: grid; place-items: center; height: 42px; padding: 0;
|
|
334
|
+
font: inherit; font-size: 24px; color: var(--bc-muted); background: var(--bc-stone);
|
|
335
|
+
border: 1px solid transparent; border-radius: var(--bc-r-md); cursor: pointer;
|
|
336
|
+
transition: background 160ms, color 160ms, transform 160ms var(--bc-ease);
|
|
337
|
+
}
|
|
338
|
+
.face:hover { color: var(--bc-fg); background: color-mix(in srgb, var(--bc-fg) 8%, var(--bc-stone)); }
|
|
339
|
+
.face:active { transform: scale(.94); }
|
|
340
|
+
.face[aria-pressed=true] { color: var(--bc-on-accent); background: var(--bc-accent); }
|
|
341
|
+
.face:focus-visible { outline-offset: 2px; }
|
|
342
|
+
.face-word { font-weight: 560; color: var(--bc-muted); }
|
|
343
|
+
.fb-as { margin: 0; font-size: var(--bc-fs-xs); line-height: 1.45; color: var(--bc-muted); }
|
|
344
|
+
.fb-as strong { color: var(--bc-fg); font-weight: 600; word-break: break-all; }
|
|
345
|
+
.fb-who:empty { display: none; }
|
|
346
|
+
|
|
300
347
|
/* ---------- attachments ----------
|
|
301
348
|
Three ring pills in a row: optional, so they take one line, not a band of
|
|
302
349
|
dashed drop zones. */
|
|
@@ -1033,31 +1080,31 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1033
1080
|
.tool:hover:not(:disabled) { transform: none; }
|
|
1034
1081
|
}
|
|
1035
1082
|
`;
|
|
1036
|
-
function
|
|
1083
|
+
function de({ title: e, sub: t, id: o = "", back: d = !1, theme: l = "" }) {
|
|
1037
1084
|
return `
|
|
1038
1085
|
<div class="head">
|
|
1039
|
-
${d ? `<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${
|
|
1086
|
+
${d ? `<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${_e}</button>` : ""}
|
|
1040
1087
|
<span class="orb mark" aria-hidden="true"></span>
|
|
1041
1088
|
<div class="titles">
|
|
1042
|
-
<h2${
|
|
1089
|
+
<h2${o ? ` id="${o}"` : ""}>${v(e)}</h2>
|
|
1043
1090
|
<p>${v(t)}</p>
|
|
1044
1091
|
</div>
|
|
1045
|
-
${
|
|
1046
|
-
aria-label="Theme: ${v(
|
|
1047
|
-
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${
|
|
1092
|
+
${l ? `<button class="icon-btn theme" type="button" data-act="theme" title="Theme: ${v(l)}"
|
|
1093
|
+
aria-label="Theme: ${v(l)}. Change theme"><span class="m-light">${qe}</span><span class="m-dark">${Ee}</span><span class="m-auto">${Me}</span></button>` : ""}
|
|
1094
|
+
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${pe}</button>
|
|
1048
1095
|
</div>`;
|
|
1049
1096
|
}
|
|
1050
|
-
function
|
|
1097
|
+
function ie(e, t) {
|
|
1051
1098
|
return `<div class="empty"><span class="empty-ico" aria-hidden="true">${t}</span>${v(e)}</div>`;
|
|
1052
1099
|
}
|
|
1053
|
-
function
|
|
1100
|
+
function st(e) {
|
|
1054
1101
|
return Array.from({ length: e }, () => `
|
|
1055
1102
|
<div class="row" aria-hidden="true">
|
|
1056
1103
|
<span class="row-ico"></span>
|
|
1057
1104
|
<span class="who"><span class="skel" style="width:70%"></span><span class="skel" style="width:40%;height:9px"></span></span>
|
|
1058
1105
|
</div>`).join("") + '<span class="sr-only">Loading…</span>';
|
|
1059
1106
|
}
|
|
1060
|
-
function
|
|
1107
|
+
function lt() {
|
|
1061
1108
|
return `
|
|
1062
1109
|
<div aria-hidden="true" style="display:flex;flex-direction:column;gap:10px;padding-top:6px">
|
|
1063
1110
|
<span class="skel" style="width:42%;height:34px;border-radius:16px;align-self:center"></span>
|
|
@@ -1066,7 +1113,7 @@ function Ge() {
|
|
|
1066
1113
|
</div>
|
|
1067
1114
|
<span class="sr-only">Loading…</span>`;
|
|
1068
1115
|
}
|
|
1069
|
-
function
|
|
1116
|
+
function ct(e) {
|
|
1070
1117
|
const t = String(e).trim().split(/\s+/).filter(Boolean);
|
|
1071
1118
|
return t.length ? (t[0][0] + (t.length > 1 ? t[t.length - 1][0] : "")).toUpperCase() : "?";
|
|
1072
1119
|
}
|
|
@@ -1074,22 +1121,22 @@ function Z(e) {
|
|
|
1074
1121
|
const t = new Date(e);
|
|
1075
1122
|
return Number.isFinite(t.getTime()) ? `${t.getFullYear()}-${t.getMonth()}-${t.getDate()}` : null;
|
|
1076
1123
|
}
|
|
1077
|
-
function
|
|
1078
|
-
const t = new Date(e),
|
|
1079
|
-
if (Z(t) === Z(
|
|
1124
|
+
function dt(e) {
|
|
1125
|
+
const t = new Date(e), o = /* @__PURE__ */ new Date(), d = new Date(o.getFullYear(), o.getMonth(), o.getDate() - 1);
|
|
1126
|
+
if (Z(t) === Z(o)) return "Today";
|
|
1080
1127
|
if (Z(t) === Z(d)) return "Yesterday";
|
|
1081
1128
|
try {
|
|
1082
1129
|
return t.toLocaleDateString(void 0, {
|
|
1083
1130
|
weekday: "short",
|
|
1084
1131
|
day: "numeric",
|
|
1085
1132
|
month: "short",
|
|
1086
|
-
...t.getFullYear() !==
|
|
1133
|
+
...t.getFullYear() !== o.getFullYear() ? { year: "numeric" } : {}
|
|
1087
1134
|
});
|
|
1088
1135
|
} catch {
|
|
1089
|
-
return
|
|
1136
|
+
return X(e);
|
|
1090
1137
|
}
|
|
1091
1138
|
}
|
|
1092
|
-
function
|
|
1139
|
+
function xe(e) {
|
|
1093
1140
|
const t = new Date(e);
|
|
1094
1141
|
if (!Number.isFinite(t.getTime())) return "";
|
|
1095
1142
|
try {
|
|
@@ -1098,14 +1145,14 @@ function ve(e) {
|
|
|
1098
1145
|
return "";
|
|
1099
1146
|
}
|
|
1100
1147
|
}
|
|
1101
|
-
function
|
|
1148
|
+
function be(e) {
|
|
1102
1149
|
return e.scrollHeight - e.scrollTop - e.clientHeight < 40;
|
|
1103
1150
|
}
|
|
1104
|
-
function
|
|
1105
|
-
const
|
|
1106
|
-
t && !
|
|
1151
|
+
function G(e, { smooth: t = !1 } = {}) {
|
|
1152
|
+
const o = typeof matchMedia == "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1153
|
+
t && !o && e.scrollTo ? e.scrollTo({ top: e.scrollHeight, behavior: "smooth" }) : e.scrollTop = e.scrollHeight;
|
|
1107
1154
|
}
|
|
1108
|
-
function
|
|
1155
|
+
function se(e) {
|
|
1109
1156
|
return {
|
|
1110
1157
|
OPEN: "Open",
|
|
1111
1158
|
IN_PROGRESS: "In progress",
|
|
@@ -1113,54 +1160,54 @@ function ie(e) {
|
|
|
1113
1160
|
CLOSED: "Closed"
|
|
1114
1161
|
}[e] || String(e || "").toLowerCase();
|
|
1115
1162
|
}
|
|
1116
|
-
function
|
|
1163
|
+
function X(e) {
|
|
1117
1164
|
const t = new Date(e).getTime();
|
|
1118
1165
|
if (!Number.isFinite(t)) return "";
|
|
1119
|
-
const
|
|
1120
|
-
if (
|
|
1121
|
-
if (
|
|
1122
|
-
if (
|
|
1123
|
-
const d = Math.floor(
|
|
1166
|
+
const o = Math.floor((Date.now() - t) / 864e5);
|
|
1167
|
+
if (o <= 0) return "today";
|
|
1168
|
+
if (o === 1) return "yesterday";
|
|
1169
|
+
if (o < 30) return `${o} days ago`;
|
|
1170
|
+
const d = Math.floor(o / 30);
|
|
1124
1171
|
return d === 1 ? "a month ago" : `${d} months ago`;
|
|
1125
1172
|
}
|
|
1126
1173
|
function v(e) {
|
|
1127
1174
|
return String(e).replace(/[&<>"']/g, (t) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[t]);
|
|
1128
1175
|
}
|
|
1129
|
-
const
|
|
1176
|
+
const pt = 7 * 24 * 60 * 60 * 1e3;
|
|
1130
1177
|
let ee;
|
|
1131
|
-
function
|
|
1178
|
+
function ut() {
|
|
1132
1179
|
return ee || (ee = new Promise((e, t) => {
|
|
1133
|
-
const
|
|
1134
|
-
|
|
1180
|
+
const o = indexedDB.open("bugcatch-drafts", 1);
|
|
1181
|
+
o.onupgradeneeded = () => o.result.createObjectStore("drafts"), o.onsuccess = () => e(o.result), o.onerror = () => t(o.error), o.onblocked = () => t(new Error("Draft storage is blocked."));
|
|
1135
1182
|
}).catch((e) => {
|
|
1136
1183
|
throw ee = null, e;
|
|
1137
1184
|
})), ee;
|
|
1138
1185
|
}
|
|
1139
|
-
function
|
|
1140
|
-
var
|
|
1141
|
-
return JSON.stringify([e.apiBase, e.projectId, t || ((
|
|
1186
|
+
function ht(e, t) {
|
|
1187
|
+
var o, d;
|
|
1188
|
+
return JSON.stringify([e.apiBase, e.projectId, t || ((o = e.user) == null ? void 0 : o.email) || ((d = e.user) == null ? void 0 : d.id) || "anonymous"]);
|
|
1142
1189
|
}
|
|
1143
|
-
async function
|
|
1144
|
-
const
|
|
1145
|
-
return new Promise((d,
|
|
1146
|
-
const S =
|
|
1147
|
-
S.oncomplete = () => d(
|
|
1190
|
+
async function re(e, t) {
|
|
1191
|
+
const o = await ut();
|
|
1192
|
+
return new Promise((d, l) => {
|
|
1193
|
+
const S = o.transaction("drafts", t === void 0 ? "readonly" : "readwrite"), m = S.objectStore("drafts"), f = t === void 0 ? m.get(e) : t === null ? m.delete(e) : m.put({ ...t, savedAt: Date.now() }, e);
|
|
1194
|
+
S.oncomplete = () => d(f.result), S.onerror = () => l(S.error), S.onabort = () => l(S.error || new Error("Draft was not saved."));
|
|
1148
1195
|
});
|
|
1149
1196
|
}
|
|
1150
|
-
async function
|
|
1151
|
-
const t = await
|
|
1152
|
-
return t && Date.now() - t.savedAt >
|
|
1197
|
+
async function bt(e) {
|
|
1198
|
+
const t = await re(e);
|
|
1199
|
+
return t && Date.now() - t.savedAt > pt ? (await re(e, null), null) : t || null;
|
|
1153
1200
|
}
|
|
1154
|
-
const
|
|
1201
|
+
const we = [
|
|
1155
1202
|
{ value: "LOW", label: "Low" },
|
|
1156
1203
|
{ value: "MEDIUM", label: "Medium" },
|
|
1157
1204
|
{ value: "HIGH", label: "High" },
|
|
1158
1205
|
{ value: "CRITICAL", label: "Critical" }
|
|
1159
|
-
],
|
|
1160
|
-
function
|
|
1161
|
-
const t = e.attachments !== !1,
|
|
1206
|
+
], ke = "MEDIUM";
|
|
1207
|
+
function ft(e) {
|
|
1208
|
+
const t = e.attachments !== !1, o = t && ze(), d = t && Ce();
|
|
1162
1209
|
return `
|
|
1163
|
-
<div class="compose">
|
|
1210
|
+
<div class="compose bug-only">
|
|
1164
1211
|
<div class="field">
|
|
1165
1212
|
<label for="bc-title">What went wrong?</label>
|
|
1166
1213
|
<input id="bc-title" type="text" placeholder="e.g. The checkout button does nothing" autocomplete="off"
|
|
@@ -1179,8 +1226,8 @@ function nt(e) {
|
|
|
1179
1226
|
<div class="field">
|
|
1180
1227
|
<label id="bc-prio-l">How much is it getting in your way?</label>
|
|
1181
1228
|
<div class="seg" role="group" aria-labelledby="bc-prio-l">
|
|
1182
|
-
${
|
|
1183
|
-
<button type="button" data-prio="${
|
|
1229
|
+
${we.map((l) => `
|
|
1230
|
+
<button type="button" data-prio="${l.value}" aria-pressed="${l.value === ke}">${l.label}</button>
|
|
1184
1231
|
`).join("")}
|
|
1185
1232
|
</div>
|
|
1186
1233
|
</div>
|
|
@@ -1191,842 +1238,842 @@ function nt(e) {
|
|
|
1191
1238
|
<span class="count" aria-live="polite"></span>
|
|
1192
1239
|
</div>
|
|
1193
1240
|
<div class="tools" role="group" aria-labelledby="bc-att-l">
|
|
1194
|
-
${
|
|
1195
|
-
${d ? `<button class="tool" type="button" data-act="rec">${
|
|
1196
|
-
<button class="tool" type="button" data-act="file">${
|
|
1241
|
+
${o ? `<button class="tool" type="button" data-act="shot">${Ke}Screenshot</button>` : ""}
|
|
1242
|
+
${d ? `<button class="tool" type="button" data-act="rec">${Pe}Record screen</button>` : ""}
|
|
1243
|
+
<button class="tool" type="button" data-act="file">${ve}Upload file</button>
|
|
1197
1244
|
</div>
|
|
1198
1245
|
<div class="thumbs"></div>
|
|
1199
|
-
<input type="file" accept="${
|
|
1246
|
+
<input type="file" accept="${me.join(",")}" multiple hidden />
|
|
1200
1247
|
</div>` : ""}
|
|
1201
1248
|
</div>`;
|
|
1202
1249
|
}
|
|
1203
|
-
function
|
|
1204
|
-
var ne,
|
|
1250
|
+
function gt(e) {
|
|
1251
|
+
var ne, U, _, C;
|
|
1205
1252
|
const {
|
|
1206
1253
|
client: t,
|
|
1207
|
-
cfg:
|
|
1254
|
+
cfg: o,
|
|
1208
1255
|
root: d,
|
|
1209
|
-
host:
|
|
1256
|
+
host: l,
|
|
1210
1257
|
dock: S,
|
|
1211
|
-
scrim:
|
|
1212
|
-
$:
|
|
1213
|
-
say:
|
|
1214
|
-
titleInput:
|
|
1215
|
-
descInput:
|
|
1216
|
-
compose:
|
|
1217
|
-
sendBtn:
|
|
1218
|
-
note:
|
|
1219
|
-
} = e, x =
|
|
1220
|
-
let n =
|
|
1221
|
-
const
|
|
1222
|
-
|
|
1223
|
-
const
|
|
1224
|
-
let
|
|
1225
|
-
function
|
|
1226
|
-
if (clearTimeout(
|
|
1227
|
-
const
|
|
1228
|
-
title:
|
|
1229
|
-
description:
|
|
1258
|
+
scrim: m,
|
|
1259
|
+
$: f,
|
|
1260
|
+
say: c,
|
|
1261
|
+
titleInput: h,
|
|
1262
|
+
descInput: b,
|
|
1263
|
+
compose: k,
|
|
1264
|
+
sendBtn: s,
|
|
1265
|
+
note: y
|
|
1266
|
+
} = e, x = f(".thumbs"), T = m.querySelector("input[type=file]"), a = [];
|
|
1267
|
+
let n = ke, i = null;
|
|
1268
|
+
const r = document.createElement("div");
|
|
1269
|
+
r.setAttribute("role", "status"), r.className = "note", k.prepend(r);
|
|
1270
|
+
const $ = ht(o, (ne = t.signedInAs()) == null ? void 0 : ne.email);
|
|
1271
|
+
let q = o.drafts === !1, w = !1, p = Promise.resolve(), L;
|
|
1272
|
+
function g() {
|
|
1273
|
+
if (clearTimeout(L), !q || w || o.drafts === !1) return p;
|
|
1274
|
+
const u = h.value || b.value || a.length ? {
|
|
1275
|
+
title: h.value,
|
|
1276
|
+
description: b.value,
|
|
1230
1277
|
priority: n,
|
|
1231
|
-
items:
|
|
1278
|
+
items: a.map(({ blob: E, mime: R, kind: D }) => ({ blob: E, mime: R, kind: D }))
|
|
1232
1279
|
} : null;
|
|
1233
|
-
return
|
|
1234
|
-
}).then(() =>
|
|
1235
|
-
|
|
1280
|
+
return p = p.catch(() => {
|
|
1281
|
+
}).then(() => re($, u)).then(() => {
|
|
1282
|
+
r.textContent = u ? "Draft saved on this device" : "";
|
|
1236
1283
|
}).catch(() => {
|
|
1237
|
-
|
|
1238
|
-
}),
|
|
1284
|
+
r.textContent = "Draft could not be saved. Keep this tab open.";
|
|
1285
|
+
}), p;
|
|
1239
1286
|
}
|
|
1240
|
-
function
|
|
1241
|
-
clearTimeout(
|
|
1287
|
+
function z() {
|
|
1288
|
+
clearTimeout(L), L = setTimeout(g, 250);
|
|
1242
1289
|
}
|
|
1243
|
-
|
|
1244
|
-
const
|
|
1245
|
-
|
|
1290
|
+
k.addEventListener("input", z), k.addEventListener("change", z);
|
|
1291
|
+
const M = () => {
|
|
1292
|
+
g();
|
|
1246
1293
|
};
|
|
1247
|
-
window.addEventListener("pagehide",
|
|
1248
|
-
function
|
|
1249
|
-
|
|
1250
|
-
}
|
|
1251
|
-
window.addEventListener("online",
|
|
1252
|
-
e.closed || !
|
|
1253
|
-
|
|
1254
|
-
for (const E of (
|
|
1255
|
-
|
|
1256
|
-
},
|
|
1257
|
-
|
|
1294
|
+
window.addEventListener("pagehide", M);
|
|
1295
|
+
function A() {
|
|
1296
|
+
a.filter((u) => u.status === "failed").forEach(B);
|
|
1297
|
+
}
|
|
1298
|
+
window.addEventListener("online", A), o.drafts !== !1 && (k.inert = !0, bt($).then((u) => {
|
|
1299
|
+
e.closed || !u || (r.innerHTML = '<span>You have an unfinished report on this device.</span> <button type="button" data-resume>Resume report</button> <button type="button" data-discard>Discard</button>', r.querySelector("[data-resume]").onclick = () => {
|
|
1300
|
+
h.value = u.title || "", b.value = u.description || "", n = we.some((E) => E.value === u.priority) ? u.priority : "MEDIUM", m.querySelectorAll("[data-prio]").forEach((E) => E.setAttribute("aria-pressed", String(E.dataset.prio === n)));
|
|
1301
|
+
for (const E of (u.items || []).slice(0, o.maxAttachments ?? 5)) W(E);
|
|
1302
|
+
q = !0, g();
|
|
1303
|
+
}, r.querySelector("[data-discard]").onclick = () => {
|
|
1304
|
+
q = !0, g();
|
|
1258
1305
|
});
|
|
1259
1306
|
}).catch(() => {
|
|
1260
|
-
|
|
1307
|
+
r.textContent = "Draft storage is unavailable. Keep this tab open.";
|
|
1261
1308
|
}).finally(() => {
|
|
1262
|
-
|
|
1309
|
+
k.inert = e.mustRate(), r.querySelector("[data-resume]") || (q = !0);
|
|
1263
1310
|
})), e.onDestroy(() => {
|
|
1264
|
-
var
|
|
1265
|
-
|
|
1266
|
-
}),
|
|
1267
|
-
|
|
1268
|
-
n =
|
|
1269
|
-
E.setAttribute("aria-pressed", String(E ===
|
|
1311
|
+
var u;
|
|
1312
|
+
g(), clearTimeout(L), window.removeEventListener("pagehide", M), window.removeEventListener("online", A), i == null || i.cancel(), a.forEach((E) => E.previewUrl && URL.revokeObjectURL(E.previewUrl)), (u = d.querySelector(".recbar")) == null || u.remove();
|
|
1313
|
+
}), m.querySelectorAll("[data-prio]").forEach((u) => {
|
|
1314
|
+
u.addEventListener("click", () => {
|
|
1315
|
+
n = u.dataset.prio, z(), m.querySelectorAll("[data-prio]").forEach((E) => {
|
|
1316
|
+
E.setAttribute("aria-pressed", String(E === u));
|
|
1270
1317
|
});
|
|
1271
1318
|
});
|
|
1272
1319
|
});
|
|
1273
|
-
const
|
|
1274
|
-
function Q(
|
|
1275
|
-
|
|
1320
|
+
const O = f("#bc-title-err");
|
|
1321
|
+
function Q(u) {
|
|
1322
|
+
O.hidden = !u, O.innerHTML = u ? `${P}<span>${v(u)}</span>` : "", h.classList.toggle("invalid", !!u), h.setAttribute("aria-invalid", String(!!u));
|
|
1276
1323
|
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1324
|
+
h.addEventListener("input", () => {
|
|
1325
|
+
h.value.trim() && Q("");
|
|
1279
1326
|
});
|
|
1280
|
-
function
|
|
1281
|
-
const
|
|
1282
|
-
|
|
1283
|
-
const
|
|
1284
|
-
|
|
1285
|
-
|
|
1327
|
+
function I() {
|
|
1328
|
+
const u = a.some((j) => j.status === "uploading"), E = e.mustRate();
|
|
1329
|
+
s.disabled = e.sending || u || E || a.some((j) => j.status === "failed"), y.textContent = E ? "Rate your last report to send a new one." : u ? "Waiting for the upload to finish…" : a.some((j) => j.status === "failed") ? "Retry or remove failed attachments before sending." : "";
|
|
1330
|
+
const R = o.maxAttachments ?? 5;
|
|
1331
|
+
m.querySelectorAll(".tool").forEach((j) => {
|
|
1332
|
+
j.disabled = e.sending || a.length >= R;
|
|
1286
1333
|
});
|
|
1287
|
-
const
|
|
1288
|
-
|
|
1289
|
-
}
|
|
1290
|
-
e.refreshSendState =
|
|
1291
|
-
function
|
|
1292
|
-
var
|
|
1293
|
-
const E =
|
|
1294
|
-
let
|
|
1295
|
-
|
|
1296
|
-
${
|
|
1297
|
-
<span class="kind">${
|
|
1298
|
-
<button class="drop" type="button" data-act="drop" aria-label="Remove ${
|
|
1299
|
-
${
|
|
1300
|
-
}
|
|
1301
|
-
function
|
|
1302
|
-
const E =
|
|
1303
|
-
E >= 0 &&
|
|
1304
|
-
}
|
|
1305
|
-
async function
|
|
1306
|
-
|
|
1334
|
+
const D = f(".field-head .count");
|
|
1335
|
+
D && (D.textContent = a.length ? `${a.length} of ${R}` : "");
|
|
1336
|
+
}
|
|
1337
|
+
e.refreshSendState = I;
|
|
1338
|
+
function H(u) {
|
|
1339
|
+
var Y;
|
|
1340
|
+
const E = u.el, R = u.kind === "VIDEO" ? "Video" : "Shot", D = u.kind === "VIDEO" ? `<video src="${u.previewUrl}" muted playsinline preload="metadata"></video>` : `<img src="${u.previewUrl}" alt="" />`;
|
|
1341
|
+
let j = "";
|
|
1342
|
+
u.status === "uploading" ? j = `<div class="veil"><div class="spinner"></div><div class="bar"><i style="width:${Math.round(u.progress * 100)}%"></i></div></div>` : u.status === "failed" && (j = `<div class="veil err"><button type="button" data-act="retry" aria-label="Retry upload">${Ge}</button>Failed</div>`), E.innerHTML = `
|
|
1343
|
+
${D}
|
|
1344
|
+
<span class="kind">${R} · ${K(u.size)}</span>
|
|
1345
|
+
<button class="drop" type="button" data-act="drop" aria-label="Remove ${R.toLowerCase()}">${pe}</button>
|
|
1346
|
+
${j}`, E.querySelector('[data-act="drop"]').addEventListener("click", () => V(u)), (Y = E.querySelector('[data-act="retry"]')) == null || Y.addEventListener("click", () => B(u));
|
|
1347
|
+
}
|
|
1348
|
+
function V(u) {
|
|
1349
|
+
const E = a.indexOf(u);
|
|
1350
|
+
E >= 0 && a.splice(E, 1), u.previewUrl && URL.revokeObjectURL(u.previewUrl), u.el.remove(), g(), I();
|
|
1351
|
+
}
|
|
1352
|
+
async function B(u) {
|
|
1353
|
+
u.status = "uploading", u.progress = 0, H(u), I();
|
|
1307
1354
|
try {
|
|
1308
|
-
const { storageKey: E, mime:
|
|
1309
|
-
|
|
1310
|
-
const
|
|
1311
|
-
|
|
1355
|
+
const { storageKey: E, mime: R } = await t.uploadAttachment(u.blob, u.mime, (D) => {
|
|
1356
|
+
u.progress = D;
|
|
1357
|
+
const j = u.el.querySelector(".bar i");
|
|
1358
|
+
j && (j.style.width = `${Math.round(D * 100)}%`);
|
|
1312
1359
|
});
|
|
1313
|
-
|
|
1360
|
+
u.storageKey = E, u.mime = R, u.status = "ready";
|
|
1314
1361
|
} catch (E) {
|
|
1315
|
-
|
|
1362
|
+
u.status = "failed", c(E.message.replace("[BugCatch] ", ""));
|
|
1316
1363
|
}
|
|
1317
|
-
|
|
1364
|
+
H(u), I();
|
|
1318
1365
|
}
|
|
1319
|
-
function
|
|
1320
|
-
const
|
|
1321
|
-
if (
|
|
1322
|
-
|
|
1366
|
+
function W({ blob: u, mime: E, kind: R }) {
|
|
1367
|
+
const D = o.maxAttachmentBytes ?? 26214400;
|
|
1368
|
+
if (u.size > D) {
|
|
1369
|
+
c(`That file is ${K(u.size)} — the limit is ${K(D)}.`);
|
|
1323
1370
|
return;
|
|
1324
1371
|
}
|
|
1325
|
-
const
|
|
1326
|
-
if (!
|
|
1327
|
-
|
|
1372
|
+
const j = Ae(E || u.type, me);
|
|
1373
|
+
if (!j) {
|
|
1374
|
+
c("Only PNG, JPEG, WebP, WebM and MP4 files can be attached to a report.");
|
|
1328
1375
|
return;
|
|
1329
1376
|
}
|
|
1330
|
-
const
|
|
1331
|
-
blob:
|
|
1332
|
-
kind:
|
|
1333
|
-
mime:
|
|
1334
|
-
size:
|
|
1335
|
-
previewUrl: URL.createObjectURL(
|
|
1377
|
+
const Y = {
|
|
1378
|
+
blob: u,
|
|
1379
|
+
kind: R,
|
|
1380
|
+
mime: j,
|
|
1381
|
+
size: u.size,
|
|
1382
|
+
previewUrl: URL.createObjectURL(u),
|
|
1336
1383
|
status: "uploading",
|
|
1337
1384
|
progress: 0,
|
|
1338
1385
|
storageKey: null,
|
|
1339
1386
|
el: document.createElement("div")
|
|
1340
1387
|
};
|
|
1341
|
-
|
|
1388
|
+
Y.el.className = "thumb", a.push(Y), x.appendChild(Y.el), c(""), g(), B(Y);
|
|
1342
1389
|
}
|
|
1343
|
-
async function
|
|
1344
|
-
|
|
1390
|
+
async function J(u) {
|
|
1391
|
+
l.style.opacity = "0", l.style.pointerEvents = "none", await new Promise((E) => requestAnimationFrame(() => requestAnimationFrame(E)));
|
|
1345
1392
|
try {
|
|
1346
|
-
return await
|
|
1393
|
+
return await u();
|
|
1347
1394
|
} finally {
|
|
1348
|
-
|
|
1395
|
+
l.style.opacity = "", l.style.pointerEvents = "";
|
|
1349
1396
|
}
|
|
1350
1397
|
}
|
|
1351
|
-
(
|
|
1398
|
+
(U = m.querySelector('[data-act="shot"]')) == null || U.addEventListener("click", async () => {
|
|
1352
1399
|
try {
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
} catch (
|
|
1356
|
-
(
|
|
1400
|
+
const u = await J(He);
|
|
1401
|
+
W(u);
|
|
1402
|
+
} catch (u) {
|
|
1403
|
+
(u == null ? void 0 : u.name) !== "NotAllowedError" && c(`Screenshot failed: ${u.message}`);
|
|
1357
1404
|
}
|
|
1358
|
-
}), (
|
|
1359
|
-
const
|
|
1360
|
-
[...T.files].slice(0, Math.max(
|
|
1361
|
-
|
|
1405
|
+
}), (_ = m.querySelector('[data-act="file"]')) == null || _.addEventListener("click", () => T.click()), T == null || T.addEventListener("change", () => {
|
|
1406
|
+
const u = (o.maxAttachments ?? 5) - a.length;
|
|
1407
|
+
[...T.files].slice(0, Math.max(u, 0)).forEach((E) => {
|
|
1408
|
+
W({
|
|
1362
1409
|
blob: E,
|
|
1363
1410
|
mime: E.type,
|
|
1364
1411
|
kind: E.type.startsWith("video/") ? "VIDEO" : "SCREENSHOT"
|
|
1365
1412
|
});
|
|
1366
1413
|
}), T.value = "";
|
|
1367
|
-
}), (
|
|
1368
|
-
const
|
|
1414
|
+
}), (C = m.querySelector('[data-act="rec"]')) == null || C.addEventListener("click", async () => {
|
|
1415
|
+
const u = o.maxRecordingMs ?? 12e4;
|
|
1369
1416
|
let E;
|
|
1370
1417
|
try {
|
|
1371
|
-
|
|
1372
|
-
maxMs:
|
|
1373
|
-
onTick: (
|
|
1374
|
-
E && (E.querySelector(".time").textContent =
|
|
1418
|
+
i = await Ie({
|
|
1419
|
+
maxMs: u,
|
|
1420
|
+
onTick: (R) => {
|
|
1421
|
+
E && (E.querySelector(".time").textContent = ae(R));
|
|
1375
1422
|
},
|
|
1376
1423
|
onAutoStop: () => {
|
|
1377
|
-
|
|
1424
|
+
i && N({ keep: !0 });
|
|
1378
1425
|
}
|
|
1379
1426
|
});
|
|
1380
|
-
} catch (
|
|
1381
|
-
(
|
|
1427
|
+
} catch (R) {
|
|
1428
|
+
(R == null ? void 0 : R.name) !== "NotAllowedError" && c(`Recording failed: ${R.message}`);
|
|
1382
1429
|
return;
|
|
1383
1430
|
}
|
|
1384
|
-
|
|
1431
|
+
m.style.display = "none", S.hidden = !0, E = document.createElement("div"), E.className = "recbar", E.innerHTML = `
|
|
1385
1432
|
<span class="dot"></span>
|
|
1386
1433
|
<span class="time">0:00</span>
|
|
1387
|
-
<span class="hint">Recording — up to ${
|
|
1434
|
+
<span class="hint">Recording — up to ${ae(Math.round(u / 1e3))}</span>
|
|
1388
1435
|
<button class="stop" type="button">Stop</button>
|
|
1389
|
-
<button class="ghost" type="button">Discard</button>`, E.querySelector(".stop").addEventListener("click", () =>
|
|
1436
|
+
<button class="ghost" type="button">Discard</button>`, E.querySelector(".stop").addEventListener("click", () => N({ keep: !0 })), E.querySelector(".ghost").addEventListener("click", () => N({ keep: !1 })), d.appendChild(E), E.querySelector(".stop").focus();
|
|
1390
1437
|
});
|
|
1391
|
-
async function
|
|
1392
|
-
var
|
|
1393
|
-
const E =
|
|
1438
|
+
async function N({ keep: u }) {
|
|
1439
|
+
var R;
|
|
1440
|
+
const E = i;
|
|
1394
1441
|
if (E) {
|
|
1395
|
-
if (
|
|
1396
|
-
E.cancel(),
|
|
1442
|
+
if (i = null, (R = d.querySelector(".recbar")) == null || R.remove(), m.style.display = "", S.hidden = !1, !u) {
|
|
1443
|
+
E.cancel(), h.focus();
|
|
1397
1444
|
return;
|
|
1398
1445
|
}
|
|
1399
1446
|
try {
|
|
1400
|
-
const
|
|
1401
|
-
|
|
1402
|
-
} catch (
|
|
1403
|
-
|
|
1447
|
+
const D = await E.stop();
|
|
1448
|
+
D.blob.size ? W(D) : c("That recording came back empty — nothing was captured.");
|
|
1449
|
+
} catch (D) {
|
|
1450
|
+
c(`Recording failed: ${D.message}`);
|
|
1404
1451
|
}
|
|
1405
|
-
|
|
1452
|
+
h.focus();
|
|
1406
1453
|
}
|
|
1407
1454
|
}
|
|
1408
|
-
e.isRecording = () => !!
|
|
1409
|
-
var
|
|
1410
|
-
const
|
|
1411
|
-
if (!
|
|
1412
|
-
Q("Add a few words about what went wrong — a short sentence is plenty."),
|
|
1455
|
+
e.isRecording = () => !!i, e.stopRecording = N, s.addEventListener("click", async () => {
|
|
1456
|
+
var R;
|
|
1457
|
+
const u = h.value;
|
|
1458
|
+
if (!u.trim()) {
|
|
1459
|
+
Q("Add a few words about what went wrong — a short sentence is plenty."), h.focus();
|
|
1413
1460
|
return;
|
|
1414
1461
|
}
|
|
1415
1462
|
if (e.holdForReference()) return;
|
|
1416
|
-
e.sending = !0,
|
|
1417
|
-
const E =
|
|
1418
|
-
|
|
1463
|
+
e.sending = !0, c(""), I();
|
|
1464
|
+
const E = s.innerHTML;
|
|
1465
|
+
s.innerHTML = '<span class="spinner" aria-hidden="true"></span>Sending…';
|
|
1419
1466
|
try {
|
|
1420
|
-
const
|
|
1421
|
-
title:
|
|
1422
|
-
description:
|
|
1467
|
+
const D = await t.report({
|
|
1468
|
+
title: u,
|
|
1469
|
+
description: b.value,
|
|
1423
1470
|
priority: n,
|
|
1424
1471
|
references: e.answeredReference(),
|
|
1425
|
-
issue: ((
|
|
1426
|
-
attachments:
|
|
1472
|
+
issue: ((R = e.pickedIssue()) == null ? void 0 : R.key) || null,
|
|
1473
|
+
attachments: a.filter((j) => j.status === "ready").map((j) => ({ type: j.kind, storageKey: j.storageKey, mime: j.mime }))
|
|
1427
1474
|
});
|
|
1428
|
-
if (
|
|
1429
|
-
e.sending = !1,
|
|
1475
|
+
if (D != null && D.cancelled) {
|
|
1476
|
+
e.sending = !1, s.innerHTML = E, I();
|
|
1430
1477
|
return;
|
|
1431
1478
|
}
|
|
1432
|
-
|
|
1433
|
-
}), e.succeed(
|
|
1434
|
-
} catch (
|
|
1435
|
-
e.sending = !1,
|
|
1479
|
+
w = !0, clearTimeout(L), await p, o.drafts !== !1 && await re($, null).catch(() => {
|
|
1480
|
+
}), e.succeed(D);
|
|
1481
|
+
} catch (D) {
|
|
1482
|
+
e.sending = !1, s.innerHTML = E, c(D.message.replace("[BugCatch] ", "")), I(), e.recheckSignIn();
|
|
1436
1483
|
}
|
|
1437
1484
|
});
|
|
1438
1485
|
}
|
|
1439
|
-
function
|
|
1486
|
+
function mt(e) {
|
|
1440
1487
|
const {
|
|
1441
1488
|
client: t,
|
|
1442
|
-
say:
|
|
1489
|
+
say: o,
|
|
1443
1490
|
titleInput: d,
|
|
1444
|
-
descInput:
|
|
1491
|
+
descInput: l,
|
|
1445
1492
|
sendBtn: S,
|
|
1446
|
-
refsBox:
|
|
1493
|
+
refsBox: m
|
|
1447
1494
|
} = e;
|
|
1448
|
-
let
|
|
1495
|
+
let f = { policy: "off", fields: [] }, c = !1, h = null, b = "", k = "", s = [], y = "ask", x = !1, T = !1;
|
|
1449
1496
|
t.referenceFields().then((Q) => {
|
|
1450
|
-
|
|
1497
|
+
f = Q, q();
|
|
1451
1498
|
}).catch(() => {
|
|
1452
1499
|
});
|
|
1453
|
-
function
|
|
1454
|
-
return
|
|
1500
|
+
function a() {
|
|
1501
|
+
return f.policy === "off" || !f.fields.length ? { found: [], conflicts: [], loose: [] } : Re(f.fields, [d.value, l.value]);
|
|
1455
1502
|
}
|
|
1456
|
-
function n(Q =
|
|
1503
|
+
function n(Q = a()) {
|
|
1457
1504
|
return Q.found.length > 0 && Q.conflicts.length === 0;
|
|
1458
1505
|
}
|
|
1459
|
-
function
|
|
1460
|
-
return !
|
|
1506
|
+
function i() {
|
|
1507
|
+
return !h || !b.trim() ? [] : [{ key: h, value: b.trim().slice(0, 120) }];
|
|
1461
1508
|
}
|
|
1462
|
-
const
|
|
1463
|
-
|
|
1464
|
-
let
|
|
1465
|
-
function
|
|
1466
|
-
const Q =
|
|
1509
|
+
const r = document.createElement("p");
|
|
1510
|
+
r.className = "ref-found", r.setAttribute("aria-live", "polite"), r.hidden = !0, l.closest(".field").after(r);
|
|
1511
|
+
let $;
|
|
1512
|
+
function q() {
|
|
1513
|
+
const Q = a();
|
|
1467
1514
|
if (n(Q)) {
|
|
1468
|
-
const
|
|
1469
|
-
|
|
1515
|
+
const I = Q.found.slice(0, 2).map((H) => `${v(H.label)} <b>${v(p(H.value))}</b>`).join(", ");
|
|
1516
|
+
r.innerHTML = `${F}<span>Found your ${I} — no need to add it again.</span>`, r.hidden = !1, c && !i().length && (c = !1, z());
|
|
1470
1517
|
} else
|
|
1471
|
-
|
|
1518
|
+
r.hidden = !0, r.innerHTML = "";
|
|
1472
1519
|
}
|
|
1473
|
-
const
|
|
1474
|
-
clearTimeout(
|
|
1520
|
+
const w = () => {
|
|
1521
|
+
clearTimeout($), $ = setTimeout(q, 250);
|
|
1475
1522
|
};
|
|
1476
|
-
d.addEventListener("input",
|
|
1477
|
-
function
|
|
1523
|
+
d.addEventListener("input", w), l.addEventListener("input", w);
|
|
1524
|
+
function p(Q) {
|
|
1478
1525
|
return Q.length > 20 ? `${Q.slice(0, 8)}…${Q.slice(-4)}` : Q;
|
|
1479
1526
|
}
|
|
1480
|
-
function
|
|
1481
|
-
const
|
|
1482
|
-
return
|
|
1527
|
+
function L(Q) {
|
|
1528
|
+
const I = Q.trim().toLowerCase();
|
|
1529
|
+
return s.find((H) => H.value.toLowerCase() === I) || null;
|
|
1483
1530
|
}
|
|
1484
|
-
function
|
|
1485
|
-
|
|
1531
|
+
function g(Q) {
|
|
1532
|
+
b = Q.value, Q.kinds.length === 1 ? h = Q.kinds[0].key : Q.kinds.some((I) => I.key === h) || (h = null), k = "", T = !1;
|
|
1486
1533
|
}
|
|
1487
|
-
function
|
|
1488
|
-
var
|
|
1489
|
-
if (!
|
|
1490
|
-
|
|
1534
|
+
function z() {
|
|
1535
|
+
var U, _;
|
|
1536
|
+
if (!c) {
|
|
1537
|
+
m.hidden = !0, m.innerHTML = "";
|
|
1491
1538
|
return;
|
|
1492
1539
|
}
|
|
1493
|
-
const Q =
|
|
1494
|
-
confirm:
|
|
1540
|
+
const Q = f.fields.find((C) => C.key === h) || null, I = f.policy !== "required", H = L(b), V = H && H.kinds.length > 1 ? f.fields.filter((C) => H.kinds.some((u) => u.key === C.key)) : f.fields, B = s.length > 1 && s.every((C) => C.kinds.length === 1 && C.kinds[0].key === s[0].kinds[0].key), W = {
|
|
1541
|
+
confirm: s.length > 1 ? ["Which one is this about?", "We found more than one ID in your message. Pick the one this problem is about."] : ["Is this the right ID?", "This could be more than one kind of ID. Tell us which it is."],
|
|
1495
1542
|
suggest: ["Is this your ID?", "We spotted this in your message. Tell us what it is so we can find your record."],
|
|
1496
|
-
ask:
|
|
1497
|
-
}[
|
|
1498
|
-
|
|
1499
|
-
const
|
|
1500
|
-
|
|
1543
|
+
ask: I ? ["One more thing", "So we can find your record — this helps us answer faster."] : ["We need one detail", "We need one of these to look this up."]
|
|
1544
|
+
}[y];
|
|
1545
|
+
m.hidden = !1;
|
|
1546
|
+
const J = V.length > 6;
|
|
1547
|
+
m.innerHTML = `
|
|
1501
1548
|
<div class="ask-head">
|
|
1502
1549
|
<span class="avatar orb" aria-hidden="true"></span>
|
|
1503
1550
|
<div>
|
|
1504
|
-
<strong>${v(
|
|
1505
|
-
<p class="why">${v(
|
|
1551
|
+
<strong>${v(W[0])}</strong>
|
|
1552
|
+
<p class="why">${v(W[1])}</p>
|
|
1506
1553
|
</div>
|
|
1507
1554
|
</div>
|
|
1508
|
-
${
|
|
1555
|
+
${s.length > 1 ? `
|
|
1509
1556
|
<div class="chips cands" role="group" aria-label="IDs found in your message">
|
|
1510
|
-
${
|
|
1511
|
-
<button type="button" data-ref-cand="${
|
|
1512
|
-
aria-pressed="${!!
|
|
1557
|
+
${s.map((C, u) => `
|
|
1558
|
+
<button type="button" data-ref-cand="${u}" title="${v(C.value)}"
|
|
1559
|
+
aria-pressed="${!!H && H === C}">${v(p(C.value))}</button>
|
|
1513
1560
|
`).join("")}
|
|
1514
1561
|
</div>` : ""}
|
|
1515
|
-
${
|
|
1562
|
+
${V.length > 1 && !J && !B ? `
|
|
1516
1563
|
<div class="chips" role="group" aria-label="Which detail you are giving">
|
|
1517
|
-
${
|
|
1518
|
-
<button type="button" data-ref-kind="${v(
|
|
1564
|
+
${V.map((C) => `
|
|
1565
|
+
<button type="button" data-ref-kind="${v(C.key)}" aria-pressed="${!!Q && C.key === Q.key}">${v(C.label)}</button>
|
|
1519
1566
|
`).join("")}
|
|
1520
1567
|
</div>` : ""}
|
|
1521
1568
|
<div class="row">
|
|
1522
|
-
${
|
|
1569
|
+
${J ? `
|
|
1523
1570
|
<select class="ref-kind" aria-label="Which detail you are giving">
|
|
1524
1571
|
${Q ? "" : '<option value="" selected disabled>What is it?</option>'}
|
|
1525
|
-
${
|
|
1526
|
-
<option value="${v(
|
|
1572
|
+
${V.map((C) => `
|
|
1573
|
+
<option value="${v(C.key)}" ${Q && C.key === Q.key ? "selected" : ""}>${v(C.label)}</option>
|
|
1527
1574
|
`).join("")}
|
|
1528
1575
|
</select>` : ""}
|
|
1529
|
-
<input class="ref-value${
|
|
1576
|
+
<input class="ref-value${k ? " invalid" : ""}" type="${(Q == null ? void 0 : Q.inputMode) === "email" ? "email" : "text"}"
|
|
1530
1577
|
inputmode="${v((Q == null ? void 0 : Q.inputMode) === "numeric" || (Q == null ? void 0 : Q.inputMode) === "tel" ? "numeric" : "text")}"
|
|
1531
|
-
value="${v(
|
|
1578
|
+
value="${v(b)}"
|
|
1532
1579
|
placeholder="${v(Q ? Q.placeholder || Q.label : "Your ID")}"
|
|
1533
|
-
aria-label="${v(Q ? Q.label : "Your ID")}" ${
|
|
1580
|
+
aria-label="${v(Q ? Q.label : "Your ID")}" ${k ? 'aria-invalid="true"' : ""} />
|
|
1534
1581
|
</div>
|
|
1535
1582
|
${Q != null && Q.hint ? `<p class="hint">${v(Q.hint)}</p>` : ""}
|
|
1536
|
-
${
|
|
1537
|
-
${
|
|
1538
|
-
|
|
1539
|
-
|
|
1583
|
+
${k ? `<p class="field-err" role="alert">${P}<span>${v(k)}</span></p>` : ""}
|
|
1584
|
+
${I ? `<button type="button" class="link" data-act="ref-skip">${y === "ask" ? "I don't have this — send without it" : "Not sure — send as it is"}</button>` : ""}`, m.querySelectorAll("[data-ref-cand]").forEach((C) => {
|
|
1585
|
+
C.addEventListener("click", () => {
|
|
1586
|
+
g(s[Number(C.dataset.refCand)]), z();
|
|
1540
1587
|
});
|
|
1541
|
-
}),
|
|
1542
|
-
|
|
1543
|
-
|
|
1588
|
+
}), m.querySelectorAll("[data-ref-kind]").forEach((C) => {
|
|
1589
|
+
C.addEventListener("click", () => {
|
|
1590
|
+
h = C.dataset.refKind, k = "", T = !1, z();
|
|
1544
1591
|
});
|
|
1545
1592
|
});
|
|
1546
|
-
const
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
}),
|
|
1550
|
-
|
|
1551
|
-
}), (
|
|
1552
|
-
var
|
|
1553
|
-
|
|
1554
|
-
}), (
|
|
1555
|
-
x = !0,
|
|
1556
|
-
}), ((!Q &&
|
|
1557
|
-
}
|
|
1558
|
-
function
|
|
1559
|
-
if (
|
|
1560
|
-
if (
|
|
1593
|
+
const N = m.querySelector(".ref-value");
|
|
1594
|
+
N.addEventListener("input", () => {
|
|
1595
|
+
b = N.value, k = "", T = !1;
|
|
1596
|
+
}), N.addEventListener("keydown", (C) => {
|
|
1597
|
+
C.key === "Enter" && (C.preventDefault(), S.click());
|
|
1598
|
+
}), (U = m.querySelector(".ref-kind")) == null || U.addEventListener("change", (C) => {
|
|
1599
|
+
var u;
|
|
1600
|
+
h = C.target.value, k = "", z(), (u = m.querySelector(".ref-value")) == null || u.focus();
|
|
1601
|
+
}), (_ = m.querySelector('[data-act="ref-skip"]')) == null || _.addEventListener("click", () => {
|
|
1602
|
+
x = !0, c = !1, h = null, b = "", k = "", T = !1, z(), o("");
|
|
1603
|
+
}), ((!Q && b ? m.querySelector("[data-ref-kind], .ref-kind") : null) || N).focus();
|
|
1604
|
+
}
|
|
1605
|
+
function M(Q) {
|
|
1606
|
+
if (s = Q.conflicts.length ? Q.conflicts : Q.loose.slice(0, 4), y = Q.conflicts.length ? "confirm" : Q.loose.length ? "suggest" : "ask", c = !0, s.length)
|
|
1607
|
+
if (s.length === 1) g(s[0]);
|
|
1561
1608
|
else {
|
|
1562
|
-
|
|
1563
|
-
const [
|
|
1564
|
-
|
|
1609
|
+
b = "";
|
|
1610
|
+
const [I] = s;
|
|
1611
|
+
h = s.every((V) => V.kinds.length === 1 && V.kinds[0].key === I.kinds[0].key) ? I.kinds[0].key : null;
|
|
1565
1612
|
}
|
|
1566
1613
|
else
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
}
|
|
1570
|
-
function
|
|
1571
|
-
if (
|
|
1572
|
-
const Q =
|
|
1573
|
-
return n(Q) || x &&
|
|
1574
|
-
}
|
|
1575
|
-
function
|
|
1576
|
-
if (
|
|
1577
|
-
return
|
|
1578
|
-
const Q =
|
|
1614
|
+
h = h || f.fields[0].key;
|
|
1615
|
+
z();
|
|
1616
|
+
}
|
|
1617
|
+
function A() {
|
|
1618
|
+
if (f.policy === "off" || !f.fields.length || i().length) return !1;
|
|
1619
|
+
const Q = a();
|
|
1620
|
+
return n(Q) || x && f.policy !== "required" ? !1 : Q;
|
|
1621
|
+
}
|
|
1622
|
+
function O() {
|
|
1623
|
+
if (c && b.trim() && !h)
|
|
1624
|
+
return k = "Pick what this ID is.", z(), !0;
|
|
1625
|
+
const Q = A();
|
|
1579
1626
|
if (Q)
|
|
1580
|
-
return
|
|
1581
|
-
if (
|
|
1582
|
-
const
|
|
1583
|
-
if (!T &&
|
|
1584
|
-
return
|
|
1627
|
+
return c ? z() : M(Q), o(""), !0;
|
|
1628
|
+
if (h && b.trim()) {
|
|
1629
|
+
const I = f.fields.find((H) => H.key === h);
|
|
1630
|
+
if (!T && I && !De(I, b))
|
|
1631
|
+
return k = `That does not look like a ${I.label.toLowerCase()}. Press Send again to use it anyway.`, T = !0, z(), !0;
|
|
1585
1632
|
}
|
|
1586
1633
|
return !1;
|
|
1587
1634
|
}
|
|
1588
|
-
e.holdForReference =
|
|
1635
|
+
e.holdForReference = O, e.answeredReference = i;
|
|
1589
1636
|
}
|
|
1590
|
-
const
|
|
1591
|
-
function
|
|
1592
|
-
const { client: t, cfg:
|
|
1593
|
-
let
|
|
1637
|
+
const vt = 3;
|
|
1638
|
+
function yt(e) {
|
|
1639
|
+
const { client: t, cfg: o, notices: d } = e;
|
|
1640
|
+
let l = [];
|
|
1594
1641
|
function S() {
|
|
1595
|
-
const
|
|
1596
|
-
d.replaceChildren(...
|
|
1642
|
+
const f = l.slice(0, vt);
|
|
1643
|
+
d.replaceChildren(...f.map((c) => je(c, { where: "panel", onDismiss: m }))), d.hidden = f.length === 0;
|
|
1597
1644
|
}
|
|
1598
|
-
function
|
|
1599
|
-
t.dismissAnnouncement(
|
|
1645
|
+
function m(f) {
|
|
1646
|
+
t.dismissAnnouncement(f), l = l.filter((c) => c !== f), S(), e.titleInput.focus();
|
|
1600
1647
|
}
|
|
1601
|
-
|
|
1602
|
-
e.closed || (
|
|
1648
|
+
o.announcements !== !1 && typeof t.announcements == "function" && t.announcements().then((f) => {
|
|
1649
|
+
e.closed || (l = f, S());
|
|
1603
1650
|
}).catch(() => {
|
|
1604
1651
|
});
|
|
1605
1652
|
}
|
|
1606
|
-
function
|
|
1653
|
+
function xt(e) {
|
|
1607
1654
|
const {
|
|
1608
1655
|
client: t,
|
|
1609
|
-
cfg:
|
|
1656
|
+
cfg: o,
|
|
1610
1657
|
titleInput: d,
|
|
1611
|
-
known:
|
|
1658
|
+
known: l
|
|
1612
1659
|
} = e;
|
|
1613
|
-
let S = [],
|
|
1614
|
-
function
|
|
1615
|
-
|
|
1616
|
-
S = x,
|
|
1660
|
+
let S = [], m = "", f = null, c = null;
|
|
1661
|
+
function h() {
|
|
1662
|
+
o.knownIssues !== !1 && t.knownIssues().then((x) => {
|
|
1663
|
+
S = x, s();
|
|
1617
1664
|
}).catch(() => {
|
|
1618
1665
|
});
|
|
1619
1666
|
}
|
|
1620
|
-
let
|
|
1621
|
-
function
|
|
1622
|
-
if (
|
|
1623
|
-
clearTimeout(
|
|
1667
|
+
let b = null;
|
|
1668
|
+
function k(x) {
|
|
1669
|
+
if (o.knownIssues === !1) return;
|
|
1670
|
+
clearTimeout(b), c == null || c.abort();
|
|
1624
1671
|
const T = (x || "").trim();
|
|
1625
1672
|
if (T.length < 3) {
|
|
1626
|
-
|
|
1673
|
+
h();
|
|
1627
1674
|
return;
|
|
1628
1675
|
}
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1676
|
+
b = setTimeout(() => {
|
|
1677
|
+
c = new AbortController(), t.matchKnownIssues(T, { signal: c.signal }).then((a) => {
|
|
1678
|
+
a.length && (S = a, s());
|
|
1632
1679
|
}).catch(() => {
|
|
1633
1680
|
});
|
|
1634
1681
|
}, 250);
|
|
1635
1682
|
}
|
|
1636
|
-
function
|
|
1683
|
+
function s() {
|
|
1637
1684
|
if (!S.length) {
|
|
1638
|
-
|
|
1685
|
+
l.hidden = !0, l.innerHTML = "";
|
|
1639
1686
|
return;
|
|
1640
1687
|
}
|
|
1641
|
-
|
|
1688
|
+
l.hidden = !1, l.innerHTML = `
|
|
1642
1689
|
<p class="known-h">Already reported</p>
|
|
1643
1690
|
${S.map((x) => `
|
|
1644
1691
|
<div class="issue ${x.joined ? "is-joined" : ""}">
|
|
1645
1692
|
<span class="who">
|
|
1646
1693
|
<span class="t">${v(x.title)}</span>
|
|
1647
|
-
<span class="meta">${v(
|
|
1694
|
+
<span class="meta">${v(y(x))}</span>
|
|
1648
1695
|
</span>
|
|
1649
1696
|
<button class="join" type="button" data-join="${v(x.id)}"
|
|
1650
1697
|
${x.joined ? "disabled" : ""}>${x.joined ? "Following" : "Me too"}</button>
|
|
1651
1698
|
</div>
|
|
1652
|
-
${
|
|
1699
|
+
${f === x.id ? `
|
|
1653
1700
|
<div class="ask">
|
|
1654
1701
|
<input type="email" class="join-email" placeholder="you@example.com"
|
|
1655
1702
|
aria-label="Your email, so we can tell you when this is fixed" />
|
|
1656
1703
|
<button class="ghost" type="button" data-join-confirm="${v(x.id)}">Follow</button>
|
|
1657
1704
|
</div>` : ""}
|
|
1658
1705
|
`).join("")}
|
|
1659
|
-
${
|
|
1660
|
-
}
|
|
1661
|
-
function
|
|
1662
|
-
const T = x.status === "IN_PROGRESS" ? "Being worked on now" : "Not fixed yet",
|
|
1663
|
-
return `${T} · reported ${
|
|
1664
|
-
}
|
|
1665
|
-
|
|
1666
|
-
var
|
|
1667
|
-
const T = x.target.closest("[data-join]"),
|
|
1668
|
-
if (!T && !
|
|
1669
|
-
const n = (
|
|
1670
|
-
|
|
1671
|
-
const
|
|
1672
|
-
if (!
|
|
1673
|
-
|
|
1706
|
+
${m ? `<p class="err">${v(m)}</p>` : ""}`;
|
|
1707
|
+
}
|
|
1708
|
+
function y(x) {
|
|
1709
|
+
const T = x.status === "IN_PROGRESS" ? "Being worked on now" : "Not fixed yet", a = x.affectedCount === 0 ? "" : ` · ${x.affectedCount} ${x.affectedCount === 1 ? "person has" : "people have"} said this is happening to them`;
|
|
1710
|
+
return `${T} · reported ${X(x.since)}${a}`;
|
|
1711
|
+
}
|
|
1712
|
+
l.addEventListener("click", async (x) => {
|
|
1713
|
+
var r, $, q, w, p;
|
|
1714
|
+
const T = x.target.closest("[data-join]"), a = x.target.closest("[data-join-confirm]");
|
|
1715
|
+
if (!T && !a) return;
|
|
1716
|
+
const n = (a || T).getAttribute(a ? "data-join-confirm" : "data-join");
|
|
1717
|
+
m = "";
|
|
1718
|
+
const i = (($ = (r = l.querySelector(".join-email")) == null ? void 0 : r.value) == null ? void 0 : $.trim()) || ((q = t.signedInAs()) == null ? void 0 : q.email) || ((w = t.config.user) == null ? void 0 : w.email);
|
|
1719
|
+
if (!i) {
|
|
1720
|
+
f = n, s(), (p = l.querySelector(".join-email")) == null || p.focus();
|
|
1674
1721
|
return;
|
|
1675
1722
|
}
|
|
1676
1723
|
try {
|
|
1677
|
-
const
|
|
1678
|
-
|
|
1679
|
-
} catch (
|
|
1680
|
-
|
|
1724
|
+
const L = await t.meToo(n, { email: i });
|
|
1725
|
+
f = null, S = S.map((g) => g.id === n ? { ...g, joined: !0, affectedCount: L.affectedCount ?? g.affectedCount } : g), s();
|
|
1726
|
+
} catch (L) {
|
|
1727
|
+
m = L.message.replace("[BugCatch] ", ""), s();
|
|
1681
1728
|
}
|
|
1682
|
-
}),
|
|
1729
|
+
}), h(), d.addEventListener("input", () => k(d.value));
|
|
1683
1730
|
}
|
|
1684
|
-
function
|
|
1731
|
+
function wt(e) {
|
|
1685
1732
|
const {
|
|
1686
1733
|
client: t,
|
|
1687
|
-
cfg:
|
|
1734
|
+
cfg: o,
|
|
1688
1735
|
titleInput: d,
|
|
1689
|
-
descInput:
|
|
1736
|
+
descInput: l,
|
|
1690
1737
|
picks: S
|
|
1691
1738
|
} = e;
|
|
1692
|
-
let
|
|
1693
|
-
function
|
|
1694
|
-
if (!
|
|
1739
|
+
let m = [], f = null;
|
|
1740
|
+
function c() {
|
|
1741
|
+
if (!m.length) {
|
|
1695
1742
|
S.hidden = !0, S.innerHTML = "";
|
|
1696
1743
|
return;
|
|
1697
1744
|
}
|
|
1698
1745
|
S.hidden = !1, S.innerHTML = `
|
|
1699
1746
|
<p class="picks-h">Get an answer right away</p>
|
|
1700
1747
|
<div class="picks-grid" role="group" aria-label="Common questions">
|
|
1701
|
-
${
|
|
1702
|
-
<button type="button" class="pick" data-pick="${v(
|
|
1703
|
-
${
|
|
1704
|
-
aria-pressed="${(
|
|
1705
|
-
<span class="t">${v(
|
|
1706
|
-
${
|
|
1748
|
+
${m.map((h, b) => `
|
|
1749
|
+
<button type="button" class="pick" data-pick="${v(h.key)}"
|
|
1750
|
+
${h.hint ? `title="${v(h.hint)}" aria-describedby="bc-pick-h${b}"` : ""}
|
|
1751
|
+
aria-pressed="${(f == null ? void 0 : f.key) === h.key}">
|
|
1752
|
+
<span class="t">${v(h.title)}</span>
|
|
1753
|
+
${h.hint ? `<span class="h sr-only" id="bc-pick-h${b}">${v(h.hint)}</span>` : ""}
|
|
1707
1754
|
</button>`).join("")}
|
|
1708
1755
|
</div>
|
|
1709
|
-
${
|
|
1710
|
-
}
|
|
1711
|
-
S.addEventListener("click", (
|
|
1712
|
-
const
|
|
1713
|
-
if (!
|
|
1714
|
-
const
|
|
1715
|
-
if (!
|
|
1716
|
-
const
|
|
1717
|
-
(
|
|
1718
|
-
}),
|
|
1719
|
-
|
|
1756
|
+
${f ? `<p class="picks-note">${F}<span>Our assistant will check your account and reply here. Add anything else below, then send.</span></p>` : ""}`;
|
|
1757
|
+
}
|
|
1758
|
+
S.addEventListener("click", (h) => {
|
|
1759
|
+
const b = h.target.closest("[data-pick]");
|
|
1760
|
+
if (!b) return;
|
|
1761
|
+
const k = m.find((y) => y.key === b.dataset.pick);
|
|
1762
|
+
if (!k) return;
|
|
1763
|
+
const s = f && d.value.trim() === f.title;
|
|
1764
|
+
(f == null ? void 0 : f.key) === k.key ? (f = null, s && (d.value = "")) : (f = k, (!d.value.trim() || s) && (d.value = k.title)), d.dispatchEvent(new Event("input", { bubbles: !0 })), c(), f && l.focus();
|
|
1765
|
+
}), o.agentIssues !== !1 && typeof t.agentIssues == "function" && t.agentIssues().then((h) => {
|
|
1766
|
+
m = h, c();
|
|
1720
1767
|
}).catch(() => {
|
|
1721
|
-
}), e.pickedIssue = () =>
|
|
1768
|
+
}), e.pickedIssue = () => f;
|
|
1722
1769
|
}
|
|
1723
|
-
function
|
|
1770
|
+
function kt(e) {
|
|
1724
1771
|
const {
|
|
1725
1772
|
client: t,
|
|
1726
|
-
scrim:
|
|
1773
|
+
scrim: o,
|
|
1727
1774
|
say: d,
|
|
1728
|
-
callBtn:
|
|
1775
|
+
callBtn: l,
|
|
1729
1776
|
close: S
|
|
1730
1777
|
} = e;
|
|
1731
|
-
let
|
|
1732
|
-
function
|
|
1733
|
-
t.callKind().then((
|
|
1734
|
-
|
|
1778
|
+
let m = !1;
|
|
1779
|
+
function f() {
|
|
1780
|
+
t.callKind().then((b) => {
|
|
1781
|
+
b && (m = !0, e.preloadCall(), l.hidden = e.mustSignIn() || e.mustRate());
|
|
1735
1782
|
}).catch(() => {
|
|
1736
1783
|
});
|
|
1737
1784
|
}
|
|
1738
|
-
|
|
1739
|
-
e.sending = !0, d(""), e.refreshSendState(),
|
|
1785
|
+
f(), l.addEventListener("click", async () => {
|
|
1786
|
+
e.sending = !0, d(""), e.refreshSendState(), l.disabled = !0, l.innerHTML = '<span class="spinner"></span>Ringing…';
|
|
1740
1787
|
try {
|
|
1741
|
-
const
|
|
1742
|
-
|
|
1743
|
-
} catch (
|
|
1744
|
-
e.sending = !1,
|
|
1788
|
+
const b = await t.startCall();
|
|
1789
|
+
c(b);
|
|
1790
|
+
} catch (b) {
|
|
1791
|
+
e.sending = !1, l.disabled = !1, l.innerHTML = `${oe}Talk to the team`, e.refreshSendState(), b.filed ? e.succeed(b.filed, { callFailed: b.reason || "The call could not be started." }) : (d(b.message.replace("[BugCatch] ", "")), e.recheckSignIn());
|
|
1745
1792
|
}
|
|
1746
1793
|
});
|
|
1747
|
-
function
|
|
1748
|
-
const
|
|
1749
|
-
|
|
1794
|
+
function c(b) {
|
|
1795
|
+
const k = o.querySelector(".panel"), s = b != null && b.bugId ? String(b.bugId).slice(0, 8) : null;
|
|
1796
|
+
k.innerHTML = `
|
|
1750
1797
|
<div class="call">
|
|
1751
1798
|
<div class="call-head">
|
|
1752
1799
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1753
1800
|
<strong class="call-state">Ringing…</strong>
|
|
1754
1801
|
</div>
|
|
1755
1802
|
<p class="call-note">
|
|
1756
|
-
We're ringing the team now. Someone will pick up if they're free — your report${
|
|
1803
|
+
We're ringing the team now. Someone will pick up if they're free — your report${s ? ` <code>${v(s)}</code>` : ""} is already filed either way, so nothing is lost if nobody answers.
|
|
1757
1804
|
</p>
|
|
1758
1805
|
<div class="foot">
|
|
1759
1806
|
<span class="spacer"></span>
|
|
1760
1807
|
<button class="primary" type="button" data-act="hangup">Cancel</button>
|
|
1761
1808
|
</div>
|
|
1762
1809
|
</div>`;
|
|
1763
|
-
const
|
|
1810
|
+
const y = k.querySelector(".call-state"), x = k.querySelector(".call-dot"), T = {
|
|
1764
1811
|
ringing: "Ringing the team…",
|
|
1765
1812
|
connecting: "Someone answered — connecting…",
|
|
1766
1813
|
connected: "Connected",
|
|
1767
1814
|
missed: "Nobody was free",
|
|
1768
1815
|
ended: "Call ended",
|
|
1769
1816
|
failed: "The call dropped"
|
|
1770
|
-
},
|
|
1771
|
-
if (
|
|
1772
|
-
const
|
|
1773
|
-
|
|
1817
|
+
}, a = ["ended", "failed", "missed"], n = t.on("call", ({ state: i }) => {
|
|
1818
|
+
if (y.textContent = T[i] || i, x.classList.toggle("off", a.includes(i)), a.includes(i) && (k.querySelector('[data-act="hangup"]').textContent = "Close", i === "missed")) {
|
|
1819
|
+
const r = k.querySelector(".call-note");
|
|
1820
|
+
r && (r.textContent = "Nobody was free to pick up just now. Your report is filed and the team will reply in the chat.");
|
|
1774
1821
|
}
|
|
1775
1822
|
});
|
|
1776
|
-
|
|
1823
|
+
k.querySelector('[data-act="hangup"]').addEventListener("click", () => {
|
|
1777
1824
|
n(), t.endCall(), S();
|
|
1778
1825
|
});
|
|
1779
1826
|
}
|
|
1780
|
-
function
|
|
1781
|
-
const
|
|
1782
|
-
|
|
1827
|
+
function h(b, k, s) {
|
|
1828
|
+
const y = document.createElement("div");
|
|
1829
|
+
y.className = "livecall", y.innerHTML = `
|
|
1783
1830
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1784
1831
|
<span class="who" role="status" aria-live="polite">Calling the team…</span>
|
|
1785
1832
|
<span class="secs" hidden></span>
|
|
1786
|
-
${
|
|
1833
|
+
${s != null && s.recorded ? '<span class="call-kept">This call is recorded.</span>' : ""}
|
|
1787
1834
|
<button class="act" type="button" data-act="mute" hidden>Mute</button>
|
|
1788
|
-
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,
|
|
1789
|
-
const x =
|
|
1790
|
-
let
|
|
1791
|
-
const
|
|
1792
|
-
|
|
1793
|
-
},
|
|
1794
|
-
|
|
1795
|
-
},
|
|
1796
|
-
if (
|
|
1835
|
+
<button class="act danger" type="button" data-act="hangup">Cancel</button>`, b.insertBefore(y, k);
|
|
1836
|
+
const x = y.querySelector(".who"), T = y.querySelector(".secs"), a = y.querySelector(".call-dot"), n = y.querySelector('[data-act="mute"]'), i = y.querySelector('[data-act="hangup"]');
|
|
1837
|
+
let r = null;
|
|
1838
|
+
const $ = () => {
|
|
1839
|
+
r && (clearInterval(r), r = null);
|
|
1840
|
+
}, q = (p) => {
|
|
1841
|
+
$(), a.classList.add("off"), y.classList.add("over"), x.textContent = p, T.hidden = !0, n.hidden = !0, i.textContent = "Dismiss", i.classList.remove("danger");
|
|
1842
|
+
}, w = t.on("call", ({ state: p }) => {
|
|
1843
|
+
if (p === "ringing" && (x.textContent = "Calling the team…"), p === "connecting" && (x.textContent = "Someone answered — connecting…"), p === "connected") {
|
|
1797
1844
|
x.textContent = "You're on a call with the team", n.hidden = !1, T.hidden = !1;
|
|
1798
|
-
const
|
|
1799
|
-
|
|
1800
|
-
T.textContent =
|
|
1845
|
+
const L = Date.now();
|
|
1846
|
+
$(), r = setInterval(() => {
|
|
1847
|
+
T.textContent = ae(Math.floor((Date.now() - L) / 1e3));
|
|
1801
1848
|
}, 1e3), T.textContent = "0s";
|
|
1802
1849
|
}
|
|
1803
|
-
|
|
1850
|
+
p === "missed" && q("Nobody was free. Send a message instead and the team will pick it up."), p === "ended" && q("Call ended."), p === "failed" && q("The call dropped.");
|
|
1804
1851
|
});
|
|
1805
1852
|
n.addEventListener("click", () => {
|
|
1806
|
-
const
|
|
1807
|
-
n.textContent =
|
|
1808
|
-
}),
|
|
1809
|
-
|
|
1853
|
+
const p = s.setMuted(!s.isMuted());
|
|
1854
|
+
n.textContent = p ? "Unmute" : "Mute", x.textContent = p ? "You're muted" : "You're on a call with the team";
|
|
1855
|
+
}), i.addEventListener("click", () => {
|
|
1856
|
+
w(), $(), t.endCall(), y.remove(), e.refreshThread(e.openReportId());
|
|
1810
1857
|
});
|
|
1811
1858
|
}
|
|
1812
|
-
e.offerCall =
|
|
1859
|
+
e.offerCall = f, e.callOffered = () => m, e.showLiveCall = h;
|
|
1813
1860
|
}
|
|
1814
|
-
function
|
|
1815
|
-
var
|
|
1861
|
+
function $t(e) {
|
|
1862
|
+
var w;
|
|
1816
1863
|
const {
|
|
1817
1864
|
client: t,
|
|
1818
|
-
say:
|
|
1865
|
+
say: o,
|
|
1819
1866
|
compose: d,
|
|
1820
|
-
sendBtn:
|
|
1867
|
+
sendBtn: l,
|
|
1821
1868
|
historyBtn: S,
|
|
1822
|
-
callBtn:
|
|
1823
|
-
whoami:
|
|
1869
|
+
callBtn: m,
|
|
1870
|
+
whoami: f
|
|
1824
1871
|
} = e;
|
|
1825
|
-
let
|
|
1826
|
-
const x = () =>
|
|
1872
|
+
let c = { mode: t.lastLoginMode || "off", signedIn: null }, h = "idle", b = ((w = t.config.user) == null ? void 0 : w.email) || "", k = "", s = !1, y = "";
|
|
1873
|
+
const x = () => c.mode === "required" && !c.signedIn;
|
|
1827
1874
|
function T() {
|
|
1828
|
-
const
|
|
1829
|
-
d.hidden =
|
|
1875
|
+
const p = x();
|
|
1876
|
+
d.hidden = p, l.hidden = p, S && (S.hidden = p), p ? m.hidden = !0 : e.callOffered() && !e.mustRate() && (m.hidden = !1);
|
|
1830
1877
|
}
|
|
1831
|
-
function
|
|
1832
|
-
var
|
|
1833
|
-
if (
|
|
1834
|
-
|
|
1878
|
+
function a() {
|
|
1879
|
+
var L;
|
|
1880
|
+
if (c.mode === "off") {
|
|
1881
|
+
f.hidden = !0, f.innerHTML = "";
|
|
1835
1882
|
return;
|
|
1836
1883
|
}
|
|
1837
|
-
|
|
1838
|
-
const
|
|
1839
|
-
if (
|
|
1840
|
-
if (
|
|
1841
|
-
|
|
1884
|
+
f.hidden = !1, f.classList.toggle("asking", h !== "idle");
|
|
1885
|
+
const p = y ? `<div class="after err">${v(y)}</div>` : "";
|
|
1886
|
+
if (h === "idle") {
|
|
1887
|
+
if (c.signedIn) {
|
|
1888
|
+
f.innerHTML = `<span class="who">Signed in as <strong>${v(c.signedIn.email)}</strong></span><button type="button" class="link" data-act="signout">Sign out</button>`;
|
|
1842
1889
|
return;
|
|
1843
1890
|
}
|
|
1844
|
-
const
|
|
1845
|
-
|
|
1891
|
+
const g = (L = t.config.user) == null ? void 0 : L.email;
|
|
1892
|
+
f.innerHTML = `<span class="who">${c.mode === "required" ? "Sign in to report a bug here." : g ? `Reporting as <strong>${v(g)}</strong>.` : "Reporting anonymously — sign in and we can tell you what happens next."}</span><button type="button" class="link" data-act="signin">Sign in</button>`;
|
|
1846
1893
|
return;
|
|
1847
1894
|
}
|
|
1848
|
-
if (
|
|
1849
|
-
|
|
1895
|
+
if (h === "email") {
|
|
1896
|
+
f.innerHTML = `
|
|
1850
1897
|
<p class="why">Sign in with any email address — we'll send you a code.
|
|
1851
|
-
It's how you hear back about this report${
|
|
1898
|
+
It's how you hear back about this report${c.mode === "required" ? ", and this project asks for it" : ""}.</p>
|
|
1852
1899
|
<div class="row">
|
|
1853
|
-
<input type="email" data-fld="email" value="${v(
|
|
1900
|
+
<input type="email" data-fld="email" value="${v(b)}"
|
|
1854
1901
|
placeholder="you@example.com" autocomplete="email" spellcheck="false"
|
|
1855
|
-
aria-label="Your email address" ${
|
|
1856
|
-
<button type="button" class="primary" data-act="code" ${
|
|
1857
|
-
${
|
|
1902
|
+
aria-label="Your email address" ${s ? "disabled" : ""} />
|
|
1903
|
+
<button type="button" class="primary" data-act="code" ${s ? "disabled" : ""}>
|
|
1904
|
+
${s ? "Sending…" : "Send code"}
|
|
1858
1905
|
</button>
|
|
1859
1906
|
</div>
|
|
1860
|
-
${
|
|
1861
|
-
${
|
|
1907
|
+
${p}
|
|
1908
|
+
${c.mode === "optional" ? '<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>' : ""}`;
|
|
1862
1909
|
return;
|
|
1863
1910
|
}
|
|
1864
|
-
|
|
1865
|
-
<p class="why">We sent a code to <strong>${v(
|
|
1911
|
+
f.innerHTML = `
|
|
1912
|
+
<p class="why">We sent a code to <strong>${v(b)}</strong>. It expires in ten minutes.</p>
|
|
1866
1913
|
<div class="row">
|
|
1867
|
-
<input type="text" class="code" data-fld="code" value="${v(
|
|
1914
|
+
<input type="text" class="code" data-fld="code" value="${v(k)}"
|
|
1868
1915
|
placeholder="123456" inputmode="numeric" autocomplete="one-time-code"
|
|
1869
|
-
maxlength="8" aria-label="The code we emailed you" ${
|
|
1870
|
-
<button type="button" class="primary" data-act="confirm" ${
|
|
1871
|
-
${
|
|
1916
|
+
maxlength="8" aria-label="The code we emailed you" ${s ? "disabled" : ""} />
|
|
1917
|
+
<button type="button" class="primary" data-act="confirm" ${s ? "disabled" : ""}>
|
|
1918
|
+
${s ? "Checking…" : "Sign in"}
|
|
1872
1919
|
</button>
|
|
1873
1920
|
</div>
|
|
1874
|
-
${
|
|
1921
|
+
${p}
|
|
1875
1922
|
<div class="after">
|
|
1876
|
-
<button type="button" class="link" data-act="resend" ${
|
|
1877
|
-
<button type="button" class="link" data-act="signin-back" ${
|
|
1923
|
+
<button type="button" class="link" data-act="resend" ${s ? "disabled" : ""}>Send it again</button>
|
|
1924
|
+
<button type="button" class="link" data-act="signin-back" ${s ? "disabled" : ""}>Use another address</button>
|
|
1878
1925
|
</div>`;
|
|
1879
1926
|
}
|
|
1880
|
-
function n({ focus:
|
|
1881
|
-
var
|
|
1882
|
-
if (
|
|
1883
|
-
const
|
|
1884
|
-
|
|
1885
|
-
}
|
|
1886
|
-
|
|
1887
|
-
const
|
|
1888
|
-
|
|
1889
|
-
}),
|
|
1890
|
-
|
|
1927
|
+
function n({ focus: p = !1 } = {}) {
|
|
1928
|
+
var g;
|
|
1929
|
+
if (a(), T(), !p || s) return;
|
|
1930
|
+
const L = f.querySelector("[data-fld]");
|
|
1931
|
+
L && (L.focus(), (g = L.setSelectionRange) == null || g.call(L, L.value.length, L.value.length));
|
|
1932
|
+
}
|
|
1933
|
+
f.addEventListener("input", (p) => {
|
|
1934
|
+
const L = p.target.closest("[data-fld]");
|
|
1935
|
+
L && (L.dataset.fld === "email" ? b = L.value : k = L.value);
|
|
1936
|
+
}), f.addEventListener("keydown", (p) => {
|
|
1937
|
+
p.key !== "Enter" || !p.target.closest("[data-fld]") || (p.preventDefault(), h === "email" ? i() : r());
|
|
1891
1938
|
});
|
|
1892
|
-
async function
|
|
1893
|
-
const
|
|
1894
|
-
if (
|
|
1895
|
-
|
|
1939
|
+
async function i({ resent: p = !1 } = {}) {
|
|
1940
|
+
const L = b.trim();
|
|
1941
|
+
if (!L) {
|
|
1942
|
+
y = "Enter the address to send the code to.", n({ focus: !0 });
|
|
1896
1943
|
return;
|
|
1897
1944
|
}
|
|
1898
|
-
|
|
1945
|
+
s = !0, y = "", n();
|
|
1899
1946
|
try {
|
|
1900
|
-
await t.signIn(
|
|
1901
|
-
} catch (
|
|
1902
|
-
|
|
1947
|
+
await t.signIn(L), b = L, p || (k = ""), h = "code";
|
|
1948
|
+
} catch (g) {
|
|
1949
|
+
y = g.message;
|
|
1903
1950
|
} finally {
|
|
1904
|
-
|
|
1951
|
+
s = !1, n({ focus: !0 });
|
|
1905
1952
|
}
|
|
1906
1953
|
}
|
|
1907
|
-
async function
|
|
1908
|
-
const
|
|
1909
|
-
if (!
|
|
1910
|
-
|
|
1954
|
+
async function r() {
|
|
1955
|
+
const p = k.trim();
|
|
1956
|
+
if (!p) {
|
|
1957
|
+
y = "Enter the code we emailed you.", n({ focus: !0 });
|
|
1911
1958
|
return;
|
|
1912
1959
|
}
|
|
1913
|
-
|
|
1960
|
+
s = !0, y = "", n();
|
|
1914
1961
|
try {
|
|
1915
|
-
const
|
|
1916
|
-
|
|
1917
|
-
} catch (
|
|
1918
|
-
|
|
1962
|
+
const L = await t.confirmSignIn(b.trim(), p);
|
|
1963
|
+
c.signedIn = L, h = "idle", k = "", o(""), e.offerCall();
|
|
1964
|
+
} catch (L) {
|
|
1965
|
+
y = L.message;
|
|
1919
1966
|
} finally {
|
|
1920
|
-
|
|
1967
|
+
s = !1, n({ focus: h !== "idle" });
|
|
1921
1968
|
}
|
|
1922
1969
|
}
|
|
1923
|
-
|
|
1924
|
-
const
|
|
1925
|
-
if (
|
|
1926
|
-
const
|
|
1927
|
-
if (
|
|
1928
|
-
|
|
1970
|
+
f.addEventListener("click", async (p) => {
|
|
1971
|
+
const L = p.target.closest("button[data-act]");
|
|
1972
|
+
if (!L) return;
|
|
1973
|
+
const g = L.dataset.act;
|
|
1974
|
+
if (g === "signin") {
|
|
1975
|
+
h = "email", y = "", n({ focus: !0 });
|
|
1929
1976
|
return;
|
|
1930
1977
|
}
|
|
1931
|
-
if (
|
|
1932
|
-
|
|
1978
|
+
if (g === "skip") {
|
|
1979
|
+
h = "idle", y = "", n();
|
|
1933
1980
|
return;
|
|
1934
1981
|
}
|
|
1935
|
-
if (
|
|
1936
|
-
|
|
1982
|
+
if (g === "signin-back") {
|
|
1983
|
+
h = "email", y = "", k = "", n({ focus: !0 });
|
|
1937
1984
|
return;
|
|
1938
1985
|
}
|
|
1939
|
-
if (
|
|
1940
|
-
|
|
1986
|
+
if (g === "code") {
|
|
1987
|
+
i();
|
|
1941
1988
|
return;
|
|
1942
1989
|
}
|
|
1943
|
-
if (
|
|
1944
|
-
|
|
1990
|
+
if (g === "resend") {
|
|
1991
|
+
i({ resent: !0 });
|
|
1945
1992
|
return;
|
|
1946
1993
|
}
|
|
1947
|
-
if (
|
|
1948
|
-
|
|
1994
|
+
if (g === "confirm") {
|
|
1995
|
+
r();
|
|
1949
1996
|
return;
|
|
1950
1997
|
}
|
|
1951
|
-
if (
|
|
1952
|
-
|
|
1998
|
+
if (g === "signout") {
|
|
1999
|
+
s = !0, n();
|
|
1953
2000
|
try {
|
|
1954
2001
|
await t.signOut();
|
|
1955
2002
|
} finally {
|
|
1956
|
-
|
|
2003
|
+
c.signedIn = null, s = !1, h = c.mode === "required" ? "email" : "idle", n({ focus: h !== "idle" });
|
|
1957
2004
|
}
|
|
1958
2005
|
}
|
|
1959
2006
|
});
|
|
1960
|
-
async function
|
|
1961
|
-
const
|
|
1962
|
-
|
|
2007
|
+
async function $({ announce: p = !1 } = {}) {
|
|
2008
|
+
const L = await t.loginState();
|
|
2009
|
+
c = { mode: L.mode, signedIn: L.signedIn }, t.lastLoginMode = L.mode, x() && h === "idle" && (h = "email"), c.signedIn && (h = "idle"), p && L.signedOutReason && o(L.signedOutReason, "info"), n();
|
|
1963
2010
|
}
|
|
1964
|
-
|
|
2011
|
+
$({ announce: !0 }).catch(() => {
|
|
1965
2012
|
});
|
|
1966
|
-
function
|
|
1967
|
-
|
|
2013
|
+
function q() {
|
|
2014
|
+
c.mode !== "off" && $().catch(() => {
|
|
1968
2015
|
});
|
|
1969
2016
|
}
|
|
1970
|
-
e.mustSignIn = x, e.recheckSignIn =
|
|
2017
|
+
e.mustSignIn = x, e.recheckSignIn = q;
|
|
1971
2018
|
}
|
|
1972
|
-
function
|
|
2019
|
+
function fe(e) {
|
|
1973
2020
|
const t = e || [];
|
|
1974
2021
|
if (!t.length) return "";
|
|
1975
|
-
let
|
|
1976
|
-
return t.map((
|
|
1977
|
-
var
|
|
1978
|
-
const S = Z(
|
|
1979
|
-
if (
|
|
1980
|
-
return d = null,
|
|
1981
|
-
const
|
|
1982
|
-
from:
|
|
1983
|
-
author: (
|
|
1984
|
-
automated: (
|
|
1985
|
-
body: (
|
|
1986
|
-
at:
|
|
1987
|
-
attachments: (
|
|
1988
|
-
},
|
|
1989
|
-
return d = { who:
|
|
2022
|
+
let o = null, d = null;
|
|
2023
|
+
return t.map((l) => {
|
|
2024
|
+
var b, k, s, y;
|
|
2025
|
+
const S = Z(l.at), m = S && S !== o ? `<div class="day-sep" role="separator">${v(dt(l.at))}</div>` : "";
|
|
2026
|
+
if (m && (o = S, d = null), !l.from)
|
|
2027
|
+
return d = null, m + Lt(l);
|
|
2028
|
+
const f = {
|
|
2029
|
+
from: l.from,
|
|
2030
|
+
author: (b = l.reply) == null ? void 0 : b.author,
|
|
2031
|
+
automated: (k = l.reply) == null ? void 0 : k.automated,
|
|
2032
|
+
body: (s = l.reply) == null ? void 0 : s.body,
|
|
2033
|
+
at: l.at,
|
|
2034
|
+
attachments: (y = l.reply) == null ? void 0 : y.attachments
|
|
2035
|
+
}, c = St(f), h = d && d.who === c && Math.abs(new Date(l.at).getTime() - new Date(d.at).getTime()) < 5 * 6e4;
|
|
2036
|
+
return d = { who: c, at: l.at }, m + $e(f, h ? "cont" : "");
|
|
1990
2037
|
}).join("");
|
|
1991
2038
|
}
|
|
1992
|
-
function
|
|
2039
|
+
function St(e) {
|
|
1993
2040
|
return e.from === "reporter" ? "me" : e.automated ? "assistant" : `team:${e.author || ""}`;
|
|
1994
2041
|
}
|
|
1995
|
-
function
|
|
1996
|
-
const t =
|
|
2042
|
+
function Lt(e) {
|
|
2043
|
+
const t = xe(e.at);
|
|
1997
2044
|
return `
|
|
1998
2045
|
<div class="sys k-${v(e.kind)}">
|
|
1999
2046
|
<span class="dot" aria-hidden="true"></span>${v(e.summary || "")}${t ? `
|
|
2000
2047
|
<span class="t">· ${v(t)}</span>` : ""}
|
|
2001
2048
|
</div>`;
|
|
2002
2049
|
}
|
|
2003
|
-
function
|
|
2004
|
-
const
|
|
2005
|
-
let
|
|
2050
|
+
function $e(e, t = "") {
|
|
2051
|
+
const o = e.from === "reporter", d = e.body || "", l = e.attachments || [], S = !o && !!e.automated, m = d ? `<span class="msg-text">${v(d)}</span>` : "", f = l.length ? `<div class="att">${l.map(Tt).join("")}</div>` : "";
|
|
2052
|
+
let c = "", h = "";
|
|
2006
2053
|
if (S)
|
|
2007
|
-
|
|
2008
|
-
else if (!
|
|
2009
|
-
const
|
|
2010
|
-
|
|
2011
|
-
}
|
|
2012
|
-
t.includes("cont") && (
|
|
2013
|
-
const
|
|
2014
|
-
<button type="button" data-quick="Yes, this is the problem">${
|
|
2054
|
+
c = '<span class="msg-who auto">Assistant <span class="tag">AI</span></span>', h = '<span class="av bot orb" aria-hidden="true"></span>';
|
|
2055
|
+
else if (!o) {
|
|
2056
|
+
const k = e.author || "Support team";
|
|
2057
|
+
c = `<span class="msg-who">${v(k)}</span>`, h = `<span class="av" aria-hidden="true">${v(ct(k))}</span>`;
|
|
2058
|
+
}
|
|
2059
|
+
t.includes("cont") && (c = "");
|
|
2060
|
+
const b = S && /it goes to the same person/i.test(d) ? `<div class="quick" role="group" aria-label="Answer">
|
|
2061
|
+
<button type="button" data-quick="Yes, this is the problem">${F}That's right</button>
|
|
2015
2062
|
<button type="button" data-quick="No, that is not the problem">That's not it</button>
|
|
2016
|
-
</div>` : S &&
|
|
2017
|
-
<button type="button" data-quick="Yes, that answers it">${
|
|
2063
|
+
</div>` : S && Ve.test(d) ? `<div class="quick" role="group" aria-label="Did this answer your question?">
|
|
2064
|
+
<button type="button" data-quick="Yes, that answers it">${F}Yes, that answers it</button>
|
|
2018
2065
|
<button type="button" data-quick="No, I still need help">No, I still need help</button>
|
|
2019
2066
|
</div>` : "";
|
|
2020
2067
|
return `
|
|
2021
|
-
<div class="msg-row ${
|
|
2022
|
-
${
|
|
2023
|
-
${f}
|
|
2024
|
-
<div class="bubble ${d ? "" : "silent"}">${b}${h}</div>
|
|
2068
|
+
<div class="msg-row ${o ? "mine" : "theirs"} ${S ? "auto" : ""} ${t}">
|
|
2069
|
+
${h}
|
|
2025
2070
|
${c}
|
|
2026
|
-
<
|
|
2071
|
+
<div class="bubble ${d ? "" : "silent"}">${m}${f}</div>
|
|
2072
|
+
${b}
|
|
2073
|
+
<span class="msg-when">${v(xe(e.at) || X(e.at))}</span>
|
|
2027
2074
|
</div>`;
|
|
2028
2075
|
}
|
|
2029
|
-
function
|
|
2076
|
+
function Qt() {
|
|
2030
2077
|
return `
|
|
2031
2078
|
<div class="typing-row">
|
|
2032
2079
|
<span class="av bot orb" aria-hidden="true"></span>
|
|
@@ -2034,561 +2081,700 @@ function ft() {
|
|
|
2034
2081
|
<div class="bubble typing" role="img" aria-label="The assistant is working on it"><i></i><i></i><i></i></div>
|
|
2035
2082
|
</div>`;
|
|
2036
2083
|
}
|
|
2037
|
-
function
|
|
2084
|
+
function Tt(e) {
|
|
2038
2085
|
const t = v(e.name || "attachment");
|
|
2039
2086
|
if (!e.url) return `<span class="file"><span class="nm">${t}</span></span>`;
|
|
2040
|
-
const
|
|
2041
|
-
return e.type === "SCREENSHOT" ? `<a href="${
|
|
2042
|
-
<a class="file" href="${
|
|
2087
|
+
const o = v(e.url);
|
|
2088
|
+
return e.type === "SCREENSHOT" ? `<a href="${o}" target="_blank" rel="noopener noreferrer"><img src="${o}" alt="${t}" loading="lazy"></a>` : e.type === "AUDIO" ? `<audio controls preload="metadata" src="${o}"></audio>` : e.type === "VIDEO" ? `<video controls preload="metadata" src="${o}"></video>` : `
|
|
2089
|
+
<a class="file" href="${o}" target="_blank" rel="noopener noreferrer" download>
|
|
2043
2090
|
<span class="nm">${t}</span>
|
|
2044
|
-
${e.size ? `<span class="sz">${v(
|
|
2091
|
+
${e.size ? `<span class="sz">${v(K(e.size))}</span>` : ""}
|
|
2045
2092
|
</a>`;
|
|
2046
2093
|
}
|
|
2047
|
-
function
|
|
2048
|
-
var
|
|
2049
|
-
const { client:
|
|
2050
|
-
|
|
2094
|
+
function qt(e, t, o, d) {
|
|
2095
|
+
var q;
|
|
2096
|
+
const { client: l, cfg: S } = e, m = document.createElement("div");
|
|
2097
|
+
m.className = "composer", m.innerHTML = `
|
|
2051
2098
|
<div class="staged" hidden></div>
|
|
2052
2099
|
<div class="row">
|
|
2053
2100
|
<div class="tools">
|
|
2054
2101
|
${S.attachments === !1 ? "" : `
|
|
2055
|
-
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${
|
|
2056
|
-
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${
|
|
2057
|
-
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${
|
|
2102
|
+
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${ve}</button>
|
|
2103
|
+
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${he}</button>`}
|
|
2104
|
+
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${oe}</button>
|
|
2058
2105
|
</div>
|
|
2059
2106
|
<textarea rows="1" placeholder="Write a reply…" aria-label="Write a reply"></textarea>
|
|
2060
|
-
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${
|
|
2107
|
+
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${ce}</button>
|
|
2061
2108
|
</div>
|
|
2062
2109
|
<div class="note" hidden></div>
|
|
2063
|
-
<input type="file" hidden multiple accept="${
|
|
2064
|
-
const
|
|
2065
|
-
let T = null,
|
|
2066
|
-
function n(
|
|
2067
|
-
|
|
2068
|
-
}
|
|
2069
|
-
function
|
|
2070
|
-
const
|
|
2071
|
-
|
|
2072
|
-
<span class="chip ${
|
|
2073
|
-
<span class="nm">${v(
|
|
2074
|
-
<span class="sz">${
|
|
2075
|
-
<button type="button" data-drop="${
|
|
2110
|
+
<input type="file" hidden multiple accept="${Oe.join(",")}">`, t.appendChild(m);
|
|
2111
|
+
const f = m.querySelector(".staged"), c = m.querySelector("textarea"), h = m.querySelector('[data-act="send"]'), b = m.querySelector('[data-act="voice"]'), k = m.querySelector('[data-act="livecall"]'), s = m.querySelector("input[type=file]"), y = m.querySelector(".note"), x = [];
|
|
2112
|
+
let T = null, a = !1;
|
|
2113
|
+
function n(w, p = "") {
|
|
2114
|
+
y.hidden = !w, y.className = `note ${p}`, y.textContent = w || "";
|
|
2115
|
+
}
|
|
2116
|
+
function i() {
|
|
2117
|
+
const w = x.filter((p) => p.storageKey);
|
|
2118
|
+
h.disabled = a || !c.value.trim() && !w.length, f.hidden = !x.length, f.innerHTML = x.map((p, L) => `
|
|
2119
|
+
<span class="chip ${p.storageKey ? "" : "uploading"}">
|
|
2120
|
+
<span class="nm">${v(p.name)}</span>
|
|
2121
|
+
<span class="sz">${p.storageKey ? K(p.size) : "sending…"}</span>
|
|
2122
|
+
<button type="button" data-drop="${L}" aria-label="Remove ${v(p.name)}">${pe}</button>
|
|
2076
2123
|
</span>`).join("");
|
|
2077
|
-
for (const
|
|
2078
|
-
|
|
2079
|
-
x.splice(Number(
|
|
2124
|
+
for (const p of f.querySelectorAll("[data-drop]"))
|
|
2125
|
+
p.addEventListener("click", () => {
|
|
2126
|
+
x.splice(Number(p.dataset.drop), 1), i();
|
|
2080
2127
|
});
|
|
2081
2128
|
}
|
|
2082
|
-
async function
|
|
2083
|
-
const
|
|
2084
|
-
x.push(
|
|
2129
|
+
async function r(w, p, L) {
|
|
2130
|
+
const g = { name: L, size: w.size, storageKey: null };
|
|
2131
|
+
x.push(g), i();
|
|
2085
2132
|
try {
|
|
2086
|
-
const { storageKey:
|
|
2087
|
-
|
|
2088
|
-
} catch (
|
|
2089
|
-
x.splice(x.indexOf(
|
|
2133
|
+
const { storageKey: z, mime: M } = await l.uploadAttachment(w, p);
|
|
2134
|
+
g.storageKey = z, g.mime = M;
|
|
2135
|
+
} catch (z) {
|
|
2136
|
+
x.splice(x.indexOf(g), 1), n(z.message || "That file could not be sent.", "err");
|
|
2090
2137
|
}
|
|
2091
|
-
|
|
2138
|
+
i();
|
|
2092
2139
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
}),
|
|
2096
|
-
|
|
2097
|
-
}), (
|
|
2140
|
+
c.addEventListener("input", () => {
|
|
2141
|
+
c.style.height = "auto", c.style.height = `${Math.min(c.scrollHeight, 120)}px`, i();
|
|
2142
|
+
}), c.addEventListener("keydown", (w) => {
|
|
2143
|
+
w.key === "Enter" && !w.shiftKey && !w.isComposing && (w.preventDefault(), $());
|
|
2144
|
+
}), (q = m.querySelector('[data-act="attach"]')) == null || q.addEventListener("click", () => s.click()), s.addEventListener("change", () => {
|
|
2098
2145
|
n("");
|
|
2099
|
-
for (const
|
|
2100
|
-
if (
|
|
2101
|
-
n(`${
|
|
2146
|
+
for (const w of s.files) {
|
|
2147
|
+
if (w.size > l.config.maxAttachmentBytes) {
|
|
2148
|
+
n(`${w.name} is larger than ${K(l.config.maxAttachmentBytes)}.`, "err");
|
|
2102
2149
|
continue;
|
|
2103
2150
|
}
|
|
2104
|
-
|
|
2151
|
+
r(w, w.type, w.name);
|
|
2105
2152
|
}
|
|
2106
|
-
|
|
2107
|
-
}),
|
|
2153
|
+
s.value = "";
|
|
2154
|
+
}), b && !Be() && (b.disabled = !0, b.title = "This browser cannot record audio"), b == null || b.addEventListener("click", async () => {
|
|
2108
2155
|
if (T) {
|
|
2109
|
-
const
|
|
2110
|
-
T = null,
|
|
2111
|
-
const { blob:
|
|
2112
|
-
|
|
2156
|
+
const w = T;
|
|
2157
|
+
T = null, b.classList.remove("recording"), b.innerHTML = he, n("");
|
|
2158
|
+
const { blob: p, mime: L } = await w.stop();
|
|
2159
|
+
p.size && r(p, L, "Voice note");
|
|
2113
2160
|
return;
|
|
2114
2161
|
}
|
|
2115
2162
|
try {
|
|
2116
|
-
n(""), T = await
|
|
2117
|
-
maxMs:
|
|
2118
|
-
onTick: (
|
|
2119
|
-
onAutoStop: () =>
|
|
2120
|
-
}),
|
|
2163
|
+
n(""), T = await Ne({
|
|
2164
|
+
maxMs: l.config.maxRecordingMs,
|
|
2165
|
+
onTick: (w) => n(`Recording — ${ae(w)}. Tap the mic to stop.`),
|
|
2166
|
+
onAutoStop: () => b.click()
|
|
2167
|
+
}), b.classList.add("recording"), b.innerHTML = Ue;
|
|
2121
2168
|
} catch {
|
|
2122
2169
|
T = null, n("The microphone is not available — check the browser permission.", "err");
|
|
2123
2170
|
}
|
|
2124
|
-
}),
|
|
2125
|
-
|
|
2171
|
+
}), l.canCallTeam(d).then((w) => {
|
|
2172
|
+
w && (k.hidden = !1, e.preloadCall());
|
|
2126
2173
|
}).catch(() => {
|
|
2127
|
-
}),
|
|
2128
|
-
|
|
2174
|
+
}), k.addEventListener("click", async () => {
|
|
2175
|
+
k.disabled = !0, n("");
|
|
2129
2176
|
try {
|
|
2130
|
-
const
|
|
2131
|
-
e.showLiveCall(t,
|
|
2132
|
-
} catch (
|
|
2133
|
-
n(
|
|
2177
|
+
const w = await l.startLiveCall(d);
|
|
2178
|
+
e.showLiveCall(t, o, w);
|
|
2179
|
+
} catch (w) {
|
|
2180
|
+
n(w.message.replace("[BugCatch] ", ""), "err");
|
|
2134
2181
|
} finally {
|
|
2135
|
-
|
|
2182
|
+
k.disabled = !1;
|
|
2136
2183
|
}
|
|
2137
|
-
}),
|
|
2138
|
-
var
|
|
2139
|
-
const
|
|
2140
|
-
!
|
|
2184
|
+
}), h.addEventListener("click", $), o.addEventListener("click", (w) => {
|
|
2185
|
+
var L, g;
|
|
2186
|
+
const p = (g = (L = w.target).closest) == null ? void 0 : g.call(L, "[data-quick]");
|
|
2187
|
+
!p || a || (c.value = p.dataset.quick, $());
|
|
2141
2188
|
});
|
|
2142
|
-
async function
|
|
2143
|
-
var
|
|
2144
|
-
const
|
|
2145
|
-
if (!(
|
|
2146
|
-
|
|
2189
|
+
async function $() {
|
|
2190
|
+
var L;
|
|
2191
|
+
const w = c.value.trim(), p = x.filter((g) => g.storageKey);
|
|
2192
|
+
if (!(a || !w && !p.length)) {
|
|
2193
|
+
a = !0, i(), n(""), o.insertAdjacentHTML("beforeend", $e({
|
|
2147
2194
|
from: "reporter",
|
|
2148
|
-
body:
|
|
2195
|
+
body: w,
|
|
2149
2196
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2150
|
-
attachments:
|
|
2151
|
-
}, "pending")),
|
|
2197
|
+
attachments: p.map((g) => ({ type: "FILE", name: g.name, size: g.size }))
|
|
2198
|
+
}, "pending")), G(o, { smooth: !0 });
|
|
2152
2199
|
try {
|
|
2153
|
-
await
|
|
2154
|
-
body:
|
|
2155
|
-
attachments:
|
|
2156
|
-
storageKey:
|
|
2157
|
-
mime:
|
|
2158
|
-
name:
|
|
2159
|
-
size:
|
|
2200
|
+
await l.replyToReport(d, {
|
|
2201
|
+
body: w,
|
|
2202
|
+
attachments: p.map((g) => ({
|
|
2203
|
+
storageKey: g.storageKey,
|
|
2204
|
+
mime: g.mime,
|
|
2205
|
+
name: g.name,
|
|
2206
|
+
size: g.size
|
|
2160
2207
|
}))
|
|
2161
|
-
}),
|
|
2162
|
-
} catch (
|
|
2163
|
-
(
|
|
2208
|
+
}), c.value = "", c.style.height = "auto", x.length = 0, await e.refreshThread(d);
|
|
2209
|
+
} catch (g) {
|
|
2210
|
+
(L = o.querySelector(".msg-row.pending")) == null || L.classList.replace("pending", "failed"), n(g.message || "That could not be sent — try again.", "err");
|
|
2164
2211
|
} finally {
|
|
2165
|
-
|
|
2212
|
+
a = !1, i();
|
|
2166
2213
|
}
|
|
2167
2214
|
}
|
|
2168
2215
|
}
|
|
2169
|
-
|
|
2216
|
+
i();
|
|
2170
2217
|
}
|
|
2171
|
-
function
|
|
2218
|
+
function Se(e) {
|
|
2172
2219
|
return JSON.stringify(e ? [e.score, e.current, e.comment || null] : null);
|
|
2173
2220
|
}
|
|
2174
|
-
function
|
|
2221
|
+
function ue(e, {
|
|
2175
2222
|
client: t,
|
|
2176
|
-
report:
|
|
2223
|
+
report: o,
|
|
2177
2224
|
rating: d,
|
|
2178
|
-
justRated:
|
|
2225
|
+
justRated: l = !1,
|
|
2179
2226
|
question: S = null,
|
|
2180
|
-
onRated:
|
|
2181
|
-
onError:
|
|
2227
|
+
onRated: m = null,
|
|
2228
|
+
onError: f = null
|
|
2182
2229
|
}) {
|
|
2183
|
-
var
|
|
2184
|
-
e.dataset.key =
|
|
2185
|
-
const
|
|
2230
|
+
var a;
|
|
2231
|
+
e.dataset.key = Se(d);
|
|
2232
|
+
const c = d != null && d.current ? d.score : 0, h = d ? d.current ? l ? "Thanks — the team will see that." : `You rated this ${d.score} out of 5.` : `You rated an earlier fix ${d.score} out of 5. How did this one go?` : S || "How did we do?", b = l && (d == null ? void 0 : d.current) && !d.comment;
|
|
2186
2233
|
e.innerHTML = `
|
|
2187
|
-
<p class="fr-q">${v(
|
|
2234
|
+
<p class="fr-q">${v(h)}</p>
|
|
2188
2235
|
<div class="stars" role="group" aria-label="Rate how this was handled, 1 to 5">${[1, 2, 3, 4, 5].map((n) => `
|
|
2189
|
-
<button type="button" data-score="${n}" aria-pressed="${n ===
|
|
2236
|
+
<button type="button" data-score="${n}" aria-pressed="${n === c}" aria-label="${n} out of 5${n === 1 ? ", poor" : n === 5 ? ", great" : ""}" class="${n <= c ? "on" : ""}">${ye}</button>`).join("")}
|
|
2190
2237
|
</div>
|
|
2191
2238
|
${d != null && d.current && d.comment ? `<p class="fr-said">“${v(d.comment)}”</p>` : ""}
|
|
2192
|
-
${
|
|
2239
|
+
${b ? `
|
|
2193
2240
|
<div class="fr-note">
|
|
2194
2241
|
<textarea maxlength="2000" aria-label="Add a note to your rating" placeholder="${d.score <= 2 ? "What went wrong? (optional)" : "Anything to add? (optional)"}"></textarea>
|
|
2195
2242
|
<button type="button" data-act="rating-note">Add note</button>
|
|
2196
2243
|
</div>` : ""}
|
|
2197
2244
|
${d ? "" : '<p class="fr-hint">1 is poor, 5 is great.</p>'}
|
|
2198
2245
|
<p class="feedback-status" role="status"></p>`;
|
|
2199
|
-
const
|
|
2200
|
-
|
|
2246
|
+
const k = [...e.querySelectorAll("[data-score]")], s = (n) => k.forEach((i) => i.classList.toggle("on", Number(i.dataset.score) <= n)), y = (n) => e.querySelectorAll("button, textarea").forEach((i) => {
|
|
2247
|
+
i.disabled = n;
|
|
2201
2248
|
}), x = e.querySelector(".feedback-status");
|
|
2202
|
-
async function T(n,
|
|
2203
|
-
var
|
|
2204
|
-
|
|
2249
|
+
async function T(n, i) {
|
|
2250
|
+
var r;
|
|
2251
|
+
y(!0), x.textContent = "";
|
|
2205
2252
|
try {
|
|
2206
|
-
const
|
|
2207
|
-
|
|
2253
|
+
const $ = await t.rate(o.id, { score: n, comment: i });
|
|
2254
|
+
ue(e, {
|
|
2208
2255
|
client: t,
|
|
2209
|
-
report:
|
|
2210
|
-
rating:
|
|
2256
|
+
report: o,
|
|
2257
|
+
rating: $,
|
|
2211
2258
|
justRated: !0,
|
|
2212
2259
|
question: S,
|
|
2213
|
-
onRated:
|
|
2214
|
-
onError:
|
|
2215
|
-
}), (
|
|
2216
|
-
} catch (
|
|
2217
|
-
x.textContent =
|
|
2260
|
+
onRated: m,
|
|
2261
|
+
onError: f
|
|
2262
|
+
}), (r = e.querySelector(".fr-note textarea")) == null || r.focus(), m == null || m($);
|
|
2263
|
+
} catch ($) {
|
|
2264
|
+
x.textContent = $.message, y(!1), s(c), f == null || f($);
|
|
2218
2265
|
}
|
|
2219
2266
|
}
|
|
2220
|
-
for (const n of
|
|
2221
|
-
const
|
|
2222
|
-
n.addEventListener("mouseenter", () =>
|
|
2267
|
+
for (const n of k) {
|
|
2268
|
+
const i = Number(n.dataset.score);
|
|
2269
|
+
n.addEventListener("mouseenter", () => s(i)), n.addEventListener("focus", () => s(i)), n.addEventListener("blur", () => s(c)), n.addEventListener("click", () => T(i));
|
|
2223
2270
|
}
|
|
2224
|
-
e.querySelector(".stars").addEventListener("mouseleave", () =>
|
|
2225
|
-
var
|
|
2271
|
+
e.querySelector(".stars").addEventListener("mouseleave", () => s(c)), (a = e.querySelector('[data-act="rating-note"]')) == null || a.addEventListener("click", () => {
|
|
2272
|
+
var i;
|
|
2226
2273
|
const n = e.querySelector(".fr-note textarea").value.trim();
|
|
2227
2274
|
if (!n) {
|
|
2228
|
-
(
|
|
2275
|
+
(i = e.querySelector(".fr-note")) == null || i.remove();
|
|
2229
2276
|
return;
|
|
2230
2277
|
}
|
|
2231
2278
|
T(d.score, n);
|
|
2232
2279
|
});
|
|
2233
2280
|
}
|
|
2234
|
-
const
|
|
2235
|
-
function
|
|
2236
|
-
return e.rating ? ` · <span class="rated" aria-label="You rated this ${Number(e.rating)} out of 5">${
|
|
2281
|
+
const le = /* @__PURE__ */ new WeakMap();
|
|
2282
|
+
function Et(e) {
|
|
2283
|
+
return e.rating ? ` · <span class="rated" aria-label="You rated this ${Number(e.rating)} out of 5">${ye}${Number(e.rating)}</span>` : e.ratingAsked ? ' · <span class="rate-ask">Rate it</span>' : "";
|
|
2237
2284
|
}
|
|
2238
|
-
function
|
|
2285
|
+
function Mt(e) {
|
|
2239
2286
|
var T;
|
|
2240
2287
|
const {
|
|
2241
2288
|
client: t,
|
|
2242
|
-
scrim:
|
|
2289
|
+
scrim: o,
|
|
2243
2290
|
close: d
|
|
2244
2291
|
} = e;
|
|
2245
|
-
let
|
|
2246
|
-
function S(
|
|
2247
|
-
if (
|
|
2248
|
-
|
|
2249
|
-
|
|
2292
|
+
let l = null;
|
|
2293
|
+
function S(a, { callFailed: n = null } = {}) {
|
|
2294
|
+
if (a != null && a.id && !n) {
|
|
2295
|
+
c(a.id, { fresh: !0 }).then((i) => {
|
|
2296
|
+
i || m(a, { callFailed: n });
|
|
2250
2297
|
});
|
|
2251
2298
|
return;
|
|
2252
2299
|
}
|
|
2253
|
-
|
|
2300
|
+
m(a, { callFailed: n });
|
|
2254
2301
|
}
|
|
2255
|
-
function
|
|
2256
|
-
var
|
|
2257
|
-
const
|
|
2258
|
-
|
|
2302
|
+
function m(a, { callFailed: n = null } = {}) {
|
|
2303
|
+
var q;
|
|
2304
|
+
const i = a != null && a.id ? String(a.id).slice(0, 8) : null, r = (q = a == null ? void 0 : a.estimate) != null && q.label ? String(a.estimate.label) : null, $ = n ? `<p class="eta">${v(n)} Your report is filed, and the team will reply in the chat.</p>` : "";
|
|
2305
|
+
o.querySelector(".panel").innerHTML = `
|
|
2259
2306
|
<div class="done">
|
|
2260
|
-
<div class="tick">${
|
|
2307
|
+
<div class="tick">${F}</div>
|
|
2261
2308
|
<h3>Thanks — that's on its way.</h3>
|
|
2262
|
-
<p>${
|
|
2263
|
-
${
|
|
2264
|
-
${
|
|
2265
|
-
</div>`, setTimeout(d,
|
|
2266
|
-
}
|
|
2267
|
-
async function
|
|
2268
|
-
const
|
|
2269
|
-
clearTimeout(
|
|
2270
|
-
${
|
|
2271
|
-
<div class="history" aria-busy="true">${
|
|
2309
|
+
<p>${i ? `Filed as <code>${v(i)}</code>.` : "The team has what they need to reproduce it."}</p>
|
|
2310
|
+
${$}
|
|
2311
|
+
${r ? `<p class="eta">Reports like this usually take <strong>${v(r)}</strong>. We'll let you know when it moves.</p>` : ""}
|
|
2312
|
+
</div>`, setTimeout(d, $ ? 6e3 : r ? 4e3 : 2e3);
|
|
2313
|
+
}
|
|
2314
|
+
async function f() {
|
|
2315
|
+
const a = o.querySelector(".panel");
|
|
2316
|
+
clearTimeout(h), l = null, a.classList.remove("is-chat"), a.innerHTML = `
|
|
2317
|
+
${de({ title: "Your reports", sub: "Where each one has got to.", theme: e.themeLabel() })}
|
|
2318
|
+
<div class="history" aria-busy="true">${st(3)}</div>`, a.querySelector('[data-act="close"]').addEventListener("click", d);
|
|
2272
2319
|
let n = [];
|
|
2273
2320
|
try {
|
|
2274
2321
|
({ reports: n } = await t.myReports());
|
|
2275
2322
|
} catch {
|
|
2276
|
-
const
|
|
2277
|
-
|
|
2323
|
+
const r = a.querySelector(".history");
|
|
2324
|
+
r && (r.innerHTML = ie("Couldn't load your reports just now.", P));
|
|
2278
2325
|
return;
|
|
2279
2326
|
}
|
|
2280
|
-
const
|
|
2281
|
-
if (
|
|
2282
|
-
|
|
2283
|
-
<button class="row" type="button" data-report="${v(
|
|
2284
|
-
<span class="row-ico" aria-hidden="true">${
|
|
2327
|
+
const i = a.querySelector(".history");
|
|
2328
|
+
if (i) {
|
|
2329
|
+
i.removeAttribute("aria-busy"), i.innerHTML = n.length ? n.map((r, $) => `
|
|
2330
|
+
<button class="row" type="button" data-report="${v(r.id)}" style="animation-delay:${Math.min($, 8) * 30}ms">
|
|
2331
|
+
<span class="row-ico" aria-hidden="true">${Fe}</span>
|
|
2285
2332
|
<span class="who">
|
|
2286
|
-
<span class="ttl">${v(
|
|
2287
|
-
<span class="sub">${v(
|
|
2333
|
+
<span class="ttl">${v(r.title)}</span>
|
|
2334
|
+
<span class="sub">${v(r.reference)} · ${v(X(r.createdAt))}${Et(r)}</span>
|
|
2288
2335
|
</span>
|
|
2289
|
-
<span class="pill ${v(String(
|
|
2290
|
-
<span class="chev" aria-hidden="true">${
|
|
2291
|
-
</button>`).join("") :
|
|
2292
|
-
for (const
|
|
2293
|
-
|
|
2336
|
+
<span class="pill ${v(String(r.status).toLowerCase())}">${v(se(r.status))}</span>
|
|
2337
|
+
<span class="chev" aria-hidden="true">${Xe}</span>
|
|
2338
|
+
</button>`).join("") : ie("You haven't reported anything yet.", Je);
|
|
2339
|
+
for (const r of i.querySelectorAll("[data-report]"))
|
|
2340
|
+
r.addEventListener("click", () => c(r.dataset.report));
|
|
2294
2341
|
}
|
|
2295
2342
|
}
|
|
2296
|
-
async function
|
|
2297
|
-
var
|
|
2298
|
-
const
|
|
2299
|
-
clearTimeout(
|
|
2300
|
-
${
|
|
2343
|
+
async function c(a, { fresh: n = !1 } = {}) {
|
|
2344
|
+
var p;
|
|
2345
|
+
const i = o.querySelector(".panel");
|
|
2346
|
+
clearTimeout(h), i.classList.add("is-chat"), i.innerHTML = `
|
|
2347
|
+
${de({
|
|
2301
2348
|
back: !0,
|
|
2302
2349
|
title: n ? "Looking into it" : "Your report",
|
|
2303
2350
|
sub: n ? "It may ask you a question here." : "Updates, and a way to reply.",
|
|
2304
2351
|
theme: e.themeLabel()
|
|
2305
2352
|
})}
|
|
2306
|
-
<div class="history chatting" aria-busy="true"><div class="thread">${
|
|
2307
|
-
let
|
|
2353
|
+
<div class="history chatting" aria-busy="true"><div class="thread">${lt()}</div></div>`, i.querySelector('[data-act="close"]').addEventListener("click", d), i.querySelector('[data-act="back"]').addEventListener("click", f);
|
|
2354
|
+
let r = null;
|
|
2308
2355
|
try {
|
|
2309
|
-
|
|
2356
|
+
r = await t.myReport(a);
|
|
2310
2357
|
} catch {
|
|
2311
|
-
|
|
2358
|
+
r = null;
|
|
2312
2359
|
}
|
|
2313
|
-
const
|
|
2314
|
-
if (
|
|
2315
|
-
if (!
|
|
2316
|
-
return n ? (
|
|
2317
|
-
|
|
2318
|
-
const
|
|
2319
|
-
|
|
2360
|
+
const $ = i.querySelector(".history");
|
|
2361
|
+
if (!$ || !i.querySelector('[data-act="back"]')) return !1;
|
|
2362
|
+
if (!r)
|
|
2363
|
+
return n ? (i.classList.remove("is-chat"), !1) : ($.removeAttribute("aria-busy"), $.innerHTML = ie("Couldn't load that report just now.", P), !1);
|
|
2364
|
+
l = a, t.markReportRead(a);
|
|
2365
|
+
const q = fe(r.timeline);
|
|
2366
|
+
$.classList.add("chatting"), $.removeAttribute("aria-busy"), $.innerHTML = `
|
|
2320
2367
|
<div class="report-head">
|
|
2321
|
-
<span class="ttl">${v(
|
|
2322
|
-
<span class="sub">${v(
|
|
2323
|
-
<span class="pill ${v(String(
|
|
2324
|
-
${(
|
|
2368
|
+
<span class="ttl">${v(r.title)}</span>
|
|
2369
|
+
<span class="sub">${v(r.reference)} · ${v(r.project || "")}</span>
|
|
2370
|
+
<span class="pill ${v(String(r.status).toLowerCase())}">${v(se(r.status))}</span>
|
|
2371
|
+
${(p = r.estimate) != null && p.label ? `<span class="eta-line">Usually takes ${v(String(r.estimate.label))}</span>` : ""}
|
|
2325
2372
|
</div>
|
|
2326
|
-
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${
|
|
2327
|
-
const
|
|
2328
|
-
return
|
|
2329
|
-
}
|
|
2330
|
-
let
|
|
2331
|
-
function
|
|
2332
|
-
var
|
|
2333
|
-
clearTimeout(
|
|
2334
|
-
const
|
|
2335
|
-
let
|
|
2336
|
-
if (!
|
|
2337
|
-
|
|
2373
|
+
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${q}</div>`;
|
|
2374
|
+
const w = $.querySelector(".thread");
|
|
2375
|
+
return le.set(w, q), G(w), k($, r), s($, r), r.canReply && qt(e, $, w, a), b($, r, a), G(w), !0;
|
|
2376
|
+
}
|
|
2377
|
+
let h = null;
|
|
2378
|
+
function b(a, n, i) {
|
|
2379
|
+
var O, Q, I;
|
|
2380
|
+
clearTimeout(h);
|
|
2381
|
+
const r = n.assistant, $ = a.querySelector(".thread");
|
|
2382
|
+
let q = a.querySelector(".assistant");
|
|
2383
|
+
if (!r) {
|
|
2384
|
+
q == null || q.remove(), (O = $ == null ? void 0 : $.querySelector(".typing-row")) == null || O.remove();
|
|
2338
2385
|
return;
|
|
2339
2386
|
}
|
|
2340
|
-
const
|
|
2341
|
-
|
|
2342
|
-
const
|
|
2343
|
-
<div class="as-body${
|
|
2387
|
+
const w = (q == null ? void 0 : q.dataset.phase) || null;
|
|
2388
|
+
q || (q = document.createElement("div"), q.setAttribute("role", "status"), q.setAttribute("aria-live", "polite"), (Q = a.querySelector(".report-head")) == null || Q.after(q)), q.className = `assistant ${v(r.phase)}`, q.dataset.phase = r.phase;
|
|
2389
|
+
const p = r.steps || [], L = p.filter((H) => H.state === "done").length, g = p.some((H) => H.state === "active") ? 0.5 : 0, z = p.length ? Math.round((L + g) / p.length * 100) : 0, M = `
|
|
2390
|
+
<div class="as-body${w && w !== r.phase ? " entering" : ""}">
|
|
2344
2391
|
<div class="as-top">
|
|
2345
|
-
<span class="as-orb${
|
|
2392
|
+
<span class="as-orb${r.phase === "calling" || r.phase === "resolved" ? "" : " orb"}" aria-hidden="true">${r.phase === "calling" ? oe : r.phase === "resolved" ? F : ""}</span>
|
|
2346
2393
|
<div class="as-text">
|
|
2347
|
-
<div class="as-title">${v(
|
|
2348
|
-
<div class="as-detail">${v(
|
|
2394
|
+
<div class="as-title">${v(r.title)}</div>
|
|
2395
|
+
<div class="as-detail">${v(r.detail)}</div>
|
|
2349
2396
|
</div>
|
|
2350
2397
|
</div>
|
|
2351
2398
|
</div>
|
|
2352
|
-
${
|
|
2353
|
-
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${
|
|
2354
|
-
<ol class="as-steps">${
|
|
2355
|
-
if (
|
|
2356
|
-
const
|
|
2357
|
-
|
|
2358
|
-
const
|
|
2359
|
-
|
|
2360
|
-
|
|
2399
|
+
${p.length ? `
|
|
2400
|
+
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${z}"><i style="width:${z}%"></i></div>
|
|
2401
|
+
<ol class="as-steps">${p.map((H) => `<li class="${v(H.state)}"${H.state === "active" ? ' aria-current="step"' : ""}><span class="dot"></span><span class="lbl">${v(H.label)}</span></li>`).join("")}</ol>` : ""}`, A = JSON.stringify([r.phase, r.title, r.detail, p]);
|
|
2402
|
+
if (q.dataset.key !== A) {
|
|
2403
|
+
const H = q.querySelector(".as-progress i"), V = H == null ? void 0 : H.style.width;
|
|
2404
|
+
q.innerHTML = M, q.dataset.key = A;
|
|
2405
|
+
const B = q.querySelector(".as-progress i");
|
|
2406
|
+
B && V && (B.style.width = V, requestAnimationFrame(() => {
|
|
2407
|
+
B.style.width = `${z}%`;
|
|
2361
2408
|
}));
|
|
2362
2409
|
}
|
|
2363
|
-
if (
|
|
2364
|
-
const
|
|
2365
|
-
|
|
2410
|
+
if ($) {
|
|
2411
|
+
const H = be($), V = $.querySelector(".typing-row");
|
|
2412
|
+
r.phase !== "analyzing" ? V == null || V.remove() : (!V || V !== $.lastElementChild) && (V == null || V.remove(), $.insertAdjacentHTML("beforeend", Qt()), H && G($));
|
|
2366
2413
|
}
|
|
2367
|
-
|
|
2368
|
-
}
|
|
2369
|
-
function
|
|
2370
|
-
var
|
|
2371
|
-
if ((
|
|
2372
|
-
const
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2414
|
+
r.phase === "analyzing" ? h = setTimeout(() => y(i), 3e3) : r.phase === "calling" ? h = setTimeout(() => y(i), 1e4) : r.phase === "needs_info" && w !== "needs_info" && ((I = a.querySelector(".composer textarea")) == null || I.focus());
|
|
2415
|
+
}
|
|
2416
|
+
function k(a, n) {
|
|
2417
|
+
var r, $;
|
|
2418
|
+
if ((r = a.querySelector(".fix-verification")) == null || r.remove(), !n.resolvedAt || !["RESOLVED", "CLOSED"].includes(n.status)) return;
|
|
2419
|
+
const i = document.createElement("div");
|
|
2420
|
+
i.className = "fix-verification", n.verification ? i.textContent = n.verification === "CONFIRMED" ? "You confirmed that this fix works." : "Your feedback was recorded." : (i.innerHTML = '<p>Does the fix work for you?</p><textarea maxlength="4000" aria-label="Fix feedback" placeholder="What happens when you try again? (optional)"></textarea><button type="button" data-result="CONFIRMED">It works now</button> <button type="button" data-result="STILL_HAPPENING">Still happening</button><p class="feedback-status" role="status"></p>', i.querySelectorAll("[data-result]").forEach((q) => {
|
|
2421
|
+
q.onclick = async () => {
|
|
2422
|
+
i.querySelectorAll("button").forEach((w) => {
|
|
2423
|
+
w.disabled = !0;
|
|
2377
2424
|
});
|
|
2378
2425
|
try {
|
|
2379
|
-
await t.verifyFix(n.id, { result:
|
|
2380
|
-
} catch (
|
|
2381
|
-
|
|
2382
|
-
|
|
2426
|
+
await t.verifyFix(n.id, { result: q.dataset.result, resolvedAt: n.resolvedAt, note: i.querySelector("textarea").value }), await c(n.id);
|
|
2427
|
+
} catch (w) {
|
|
2428
|
+
i.querySelector(".feedback-status").textContent = w.message, i.querySelectorAll("button").forEach((p) => {
|
|
2429
|
+
p.disabled = !1;
|
|
2383
2430
|
});
|
|
2384
2431
|
}
|
|
2385
2432
|
};
|
|
2386
|
-
})), (
|
|
2433
|
+
})), ($ = a.querySelector(".report-head")) == null || $.after(i);
|
|
2387
2434
|
}
|
|
2388
|
-
function
|
|
2389
|
-
var
|
|
2390
|
-
let
|
|
2435
|
+
function s(a, n) {
|
|
2436
|
+
var $;
|
|
2437
|
+
let i = a.querySelector(".fix-rating");
|
|
2391
2438
|
if (!["RESOLVED", "CLOSED"].includes(n.status) || !n.ratingAsked) {
|
|
2392
|
-
|
|
2439
|
+
i == null || i.remove();
|
|
2393
2440
|
return;
|
|
2394
2441
|
}
|
|
2395
|
-
|
|
2442
|
+
i && i.dataset.key === Se(n.rating) || (i || (i = document.createElement("div"), i.className = "fix-rating", ($ = a.querySelector(".fix-verification") || a.querySelector(".report-head")) == null || $.after(i)), ue(i, { client: t, report: n, rating: n.rating || null }));
|
|
2396
2443
|
}
|
|
2397
|
-
async function
|
|
2398
|
-
const n =
|
|
2399
|
-
if (!
|
|
2400
|
-
let
|
|
2444
|
+
async function y(a) {
|
|
2445
|
+
const n = o.querySelector(".history.chatting"), i = n == null ? void 0 : n.querySelector(".thread");
|
|
2446
|
+
if (!i || l !== a) return;
|
|
2447
|
+
let r = null;
|
|
2401
2448
|
try {
|
|
2402
|
-
|
|
2449
|
+
r = await t.myReport(a);
|
|
2403
2450
|
} catch {
|
|
2404
2451
|
}
|
|
2405
|
-
if (e.closed || !
|
|
2406
|
-
|
|
2407
|
-
const
|
|
2408
|
-
|
|
2409
|
-
const
|
|
2410
|
-
|
|
2411
|
-
}
|
|
2412
|
-
const x = t.on("update", (
|
|
2413
|
-
!
|
|
2452
|
+
if (e.closed || !r || l !== a) return;
|
|
2453
|
+
k(n, r), s(n, r);
|
|
2454
|
+
const $ = be(i), q = fe(r.timeline);
|
|
2455
|
+
le.get(i) !== q && (i.innerHTML = q, le.set(i, q)), b(n, r, a), $ && G(i);
|
|
2456
|
+
const w = n.querySelector(".report-head .pill");
|
|
2457
|
+
w && (w.className = `pill ${String(r.status).toLowerCase()}`, w.textContent = se(r.status));
|
|
2458
|
+
}
|
|
2459
|
+
const x = t.on("update", (a) => {
|
|
2460
|
+
!l || (a == null ? void 0 : a.bugId) !== l || (t.markReportRead(l), y(l));
|
|
2414
2461
|
});
|
|
2415
2462
|
e.onDestroy(() => {
|
|
2416
|
-
x(), clearTimeout(
|
|
2417
|
-
}), (T =
|
|
2463
|
+
x(), clearTimeout(h);
|
|
2464
|
+
}), (T = o.querySelector('[data-act="history"]')) == null || T.addEventListener("click", f), e.succeed = S, e.refreshThread = y, e.openReportId = () => l;
|
|
2418
2465
|
}
|
|
2419
|
-
const
|
|
2420
|
-
function
|
|
2466
|
+
const Le = "bugcatch.rateLater", zt = 50;
|
|
2467
|
+
function Qe() {
|
|
2421
2468
|
try {
|
|
2422
|
-
const e = JSON.parse(window.localStorage.getItem(
|
|
2469
|
+
const e = JSON.parse(window.localStorage.getItem(Le) || "[]");
|
|
2423
2470
|
return Array.isArray(e) ? e : [];
|
|
2424
2471
|
} catch {
|
|
2425
2472
|
return [];
|
|
2426
2473
|
}
|
|
2427
2474
|
}
|
|
2428
|
-
function
|
|
2475
|
+
function Ct(e) {
|
|
2429
2476
|
try {
|
|
2430
|
-
const t =
|
|
2431
|
-
t.push(e), window.localStorage.setItem(
|
|
2477
|
+
const t = Qe().filter((o) => o !== e);
|
|
2478
|
+
t.push(e), window.localStorage.setItem(Le, JSON.stringify(t.slice(-zt)));
|
|
2432
2479
|
} catch {
|
|
2433
2480
|
}
|
|
2434
2481
|
}
|
|
2435
|
-
function
|
|
2436
|
-
const
|
|
2482
|
+
function At(e, t = Qe()) {
|
|
2483
|
+
const o = new Set(t), d = (e || []).filter((S) => S.ratingDue === "require" || S.ratingDue === "ask" && !o.has(S.id));
|
|
2437
2484
|
if (!d.length) return null;
|
|
2438
|
-
const
|
|
2439
|
-
return d.reduce((S,
|
|
2485
|
+
const l = (S) => new Date(S.resolvedAt || S.updatedAt || 0).getTime() || 0;
|
|
2486
|
+
return d.reduce((S, m) => l(m) > l(S) ? m : S);
|
|
2440
2487
|
}
|
|
2441
|
-
function
|
|
2488
|
+
function Ht(e) {
|
|
2442
2489
|
const {
|
|
2443
2490
|
client: t,
|
|
2444
|
-
rateDue:
|
|
2491
|
+
rateDue: o,
|
|
2445
2492
|
compose: d,
|
|
2446
|
-
picks:
|
|
2493
|
+
picks: l,
|
|
2447
2494
|
known: S,
|
|
2448
|
-
callBtn:
|
|
2449
|
-
titleInput:
|
|
2450
|
-
scrim:
|
|
2495
|
+
callBtn: m,
|
|
2496
|
+
titleInput: f,
|
|
2497
|
+
scrim: c
|
|
2451
2498
|
} = e;
|
|
2452
|
-
let
|
|
2453
|
-
e.mustRate = () =>
|
|
2454
|
-
function
|
|
2455
|
-
|
|
2456
|
-
for (const T of [d,
|
|
2499
|
+
let h = !1;
|
|
2500
|
+
e.mustRate = () => h;
|
|
2501
|
+
function b(x) {
|
|
2502
|
+
h = x;
|
|
2503
|
+
for (const T of [d, l, S])
|
|
2457
2504
|
T.classList.toggle("held", x), T.inert = x;
|
|
2458
|
-
x ?
|
|
2505
|
+
x ? m.hidden = !0 : e.callOffered() && !e.mustSignIn() && (m.hidden = !1), e.refreshSendState();
|
|
2459
2506
|
}
|
|
2460
|
-
function
|
|
2461
|
-
|
|
2507
|
+
function k() {
|
|
2508
|
+
h && b(!1);
|
|
2462
2509
|
}
|
|
2463
|
-
function
|
|
2464
|
-
|
|
2510
|
+
function s() {
|
|
2511
|
+
o.hidden = !0, o.replaceChildren(), k(), f.focus();
|
|
2465
2512
|
}
|
|
2466
|
-
function
|
|
2467
|
-
var
|
|
2468
|
-
const T = x.ratingDue === "require",
|
|
2469
|
-
if (
|
|
2513
|
+
function y(x) {
|
|
2514
|
+
var i;
|
|
2515
|
+
const T = x.ratingDue === "require", a = x.resolvedAt ? X(x.resolvedAt) : "", n = x.status === "CLOSED" ? "closed" : "fixed";
|
|
2516
|
+
if (o.hidden = !1, o.classList.toggle("is-required", T), o.innerHTML = `
|
|
2470
2517
|
<div class="rd-head">
|
|
2471
2518
|
<span class="rd-eyebrow">${T ? "Before you report something new" : `Your report was ${n}`}</span>
|
|
2472
2519
|
${T ? "" : '<button type="button" class="link rd-later" data-act="rate-later">Not now</button>'}
|
|
2473
2520
|
</div>
|
|
2474
2521
|
<p class="rd-report">
|
|
2475
|
-
<span class="rd-ico" aria-hidden="true">${
|
|
2522
|
+
<span class="rd-ico" aria-hidden="true">${F}</span>
|
|
2476
2523
|
<span class="rd-ttl">${v(x.title)}</span>
|
|
2477
|
-
<span class="rd-sub">${v(x.reference)}${
|
|
2524
|
+
<span class="rd-sub">${v(x.reference)}${a ? ` · ${n} ${v(a)}` : ""}</span>
|
|
2478
2525
|
</p>
|
|
2479
|
-
<div class="rd-stars"></div>`, (
|
|
2480
|
-
|
|
2481
|
-
}),
|
|
2526
|
+
<div class="rd-stars"></div>`, (i = o.querySelector('[data-act="rate-later"]')) == null || i.addEventListener("click", () => {
|
|
2527
|
+
Ct(x.id), s();
|
|
2528
|
+
}), ue(o.querySelector(".rd-stars"), {
|
|
2482
2529
|
client: t,
|
|
2483
2530
|
report: x,
|
|
2484
2531
|
rating: null,
|
|
2485
2532
|
question: T ? "How did we handle it? Rate it to send a new one." : "How did we do?",
|
|
2486
2533
|
onRated: () => {
|
|
2487
|
-
var
|
|
2488
|
-
|
|
2534
|
+
var r;
|
|
2535
|
+
o.querySelector(".rd-eyebrow").textContent = `Your report was ${n}`, (r = o.querySelector('[data-act="skip"]')) == null || r.remove(), o.classList.remove("is-required"), k();
|
|
2489
2536
|
},
|
|
2490
2537
|
// The rating could not be sent. A held form must not turn into a locked
|
|
2491
2538
|
// door because of our outage: offer the way past.
|
|
2492
2539
|
onError: () => {
|
|
2493
|
-
if (!
|
|
2494
|
-
const
|
|
2495
|
-
|
|
2540
|
+
if (!h || o.querySelector('[data-act="skip"]')) return;
|
|
2541
|
+
const r = document.createElement("button");
|
|
2542
|
+
r.type = "button", r.className = "link rd-later", r.dataset.act = "skip", r.textContent = "Skip for now", r.addEventListener("click", s), o.querySelector(".rd-head").append(r);
|
|
2496
2543
|
}
|
|
2497
2544
|
}), T) {
|
|
2498
|
-
|
|
2499
|
-
const
|
|
2500
|
-
(!
|
|
2545
|
+
b(!0);
|
|
2546
|
+
const r = c.getRootNode().activeElement;
|
|
2547
|
+
(!r || !o.contains(r)) && o.focus();
|
|
2501
2548
|
}
|
|
2502
2549
|
}
|
|
2503
2550
|
t.hasReports() && t.myReports().then(({ reports: x }) => {
|
|
2504
2551
|
if (e.closed) return;
|
|
2505
|
-
const T =
|
|
2506
|
-
T &&
|
|
2552
|
+
const T = At(x);
|
|
2553
|
+
T && y(T);
|
|
2507
2554
|
}).catch(() => {
|
|
2508
2555
|
});
|
|
2509
2556
|
}
|
|
2510
|
-
|
|
2557
|
+
const ge = {
|
|
2558
|
+
idea: { label: "Idea", icon: at },
|
|
2559
|
+
praise: { label: "Praise", icon: rt },
|
|
2560
|
+
confusing: { label: "Confusing", icon: ot },
|
|
2561
|
+
other: { label: "Other", icon: nt }
|
|
2562
|
+
}, Te = [
|
|
2563
|
+
{ score: 1, word: "Terrible", mouth: "M7.8 17.2c1.1-2 2.5-2.9 4.2-2.9s3.1.9 4.2 2.9M8 8l2.4 1.2M16 8l-2.4 1.2" },
|
|
2564
|
+
{ score: 2, word: "Not great", mouth: "M8.6 16c1-.8 2.1-1.2 3.4-1.2s2.4.4 3.4 1.2" },
|
|
2565
|
+
{ score: 3, word: "Okay", mouth: "M8.8 15.2h6.4" },
|
|
2566
|
+
{ score: 4, word: "Good", mouth: "M8.6 14.4c1 .9 2.1 1.4 3.4 1.4s2.4-.5 3.4-1.4" },
|
|
2567
|
+
{ score: 5, word: "Great", mouth: "M7.8 13.2h8.4a4.2 4.2 0 0 1-8.4 0z" }
|
|
2568
|
+
];
|
|
2569
|
+
function It(e) {
|
|
2570
|
+
return `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9.2"/><path d="M9 9.9h.01M15 9.9h.01" stroke-width="2.6"/><path d="${e}"/></svg>`;
|
|
2571
|
+
}
|
|
2572
|
+
function Rt() {
|
|
2573
|
+
return `
|
|
2574
|
+
<div class="feedback fb-only">
|
|
2575
|
+
<div class="field">
|
|
2576
|
+
<label for="bc-fb-msg">What's on your mind?</label>
|
|
2577
|
+
<textarea id="bc-fb-msg" maxlength="${We}" aria-describedby="bc-fb-err"
|
|
2578
|
+
placeholder="An idea, something you like, or something that confused you."></textarea>
|
|
2579
|
+
<p class="field-err" id="bc-fb-err" hidden></p>
|
|
2580
|
+
</div>
|
|
2581
|
+
<div class="field">
|
|
2582
|
+
<label id="bc-fb-kind-l">What kind is it? <span class="opt">(optional)</span></label>
|
|
2583
|
+
<div class="kinds" role="group" aria-labelledby="bc-fb-kind-l">
|
|
2584
|
+
${Ye.map((e) => `
|
|
2585
|
+
<button class="tool" type="button" data-kind="${e}" aria-pressed="false">${ge[e].icon}${ge[e].label}</button>
|
|
2586
|
+
`).join("")}
|
|
2587
|
+
</div>
|
|
2588
|
+
</div>
|
|
2589
|
+
<div class="field">
|
|
2590
|
+
<div class="field-head">
|
|
2591
|
+
<label id="bc-fb-score-l">How's your experience so far? <span class="opt">(optional)</span></label>
|
|
2592
|
+
<span class="count face-word" aria-hidden="true"></span>
|
|
2593
|
+
</div>
|
|
2594
|
+
<div class="faces" role="group" aria-labelledby="bc-fb-score-l">
|
|
2595
|
+
${Te.map((e) => `
|
|
2596
|
+
<button class="face" type="button" data-score="${e.score}" aria-pressed="false"
|
|
2597
|
+
aria-label="${e.word}" title="${e.word}">${It(e.mouth)}</button>
|
|
2598
|
+
`).join("")}
|
|
2599
|
+
</div>
|
|
2600
|
+
</div>
|
|
2601
|
+
<!-- Who it is from: an address to write back to when the page knows
|
|
2602
|
+
none, and a line saying which one when it does. -->
|
|
2603
|
+
<div class="field fb-who"></div>
|
|
2604
|
+
</div>`;
|
|
2605
|
+
}
|
|
2606
|
+
function Dt(e) {
|
|
2607
|
+
var g, z;
|
|
2608
|
+
const { client: t, cfg: o, scrim: d, $: l, say: S, close: m } = e, f = l(".feedback"), c = l("#bc-fb-msg"), h = l("#bc-fb-err"), b = l('[data-act="send-feedback"]'), k = l(".face-word");
|
|
2609
|
+
let s = null, y = null, x = !1, T = !1;
|
|
2610
|
+
const a = l(".fb-who"), n = ((g = t.signedInAs()) == null ? void 0 : g.email) || ((z = o.user) == null ? void 0 : z.email) || null;
|
|
2611
|
+
n ? a.innerHTML = `<p class="fb-as">Sent as <strong>${v(n)}</strong></p>` : a.innerHTML = `
|
|
2612
|
+
<label for="bc-fb-email">Your email <span class="opt">(optional — only if you'd like a reply)</span></label>
|
|
2613
|
+
<input id="bc-fb-email" type="email" autocomplete="email" placeholder="you@example.com" />`;
|
|
2614
|
+
const i = l("#bc-fb-email"), r = `bugcatch.feedbackDraft:${o.projectId || ""}`, $ = o.drafts !== !1;
|
|
2615
|
+
if ($)
|
|
2616
|
+
try {
|
|
2617
|
+
c.value = localStorage.getItem(r) || "";
|
|
2618
|
+
} catch {
|
|
2619
|
+
}
|
|
2620
|
+
let q;
|
|
2621
|
+
function w() {
|
|
2622
|
+
if (clearTimeout(q), !!$)
|
|
2623
|
+
try {
|
|
2624
|
+
c.value.trim() ? localStorage.setItem(r, c.value) : localStorage.removeItem(r);
|
|
2625
|
+
} catch {
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
c.addEventListener("input", () => {
|
|
2629
|
+
c.value.trim() && p(""), clearTimeout(q), q = setTimeout(w, 250);
|
|
2630
|
+
}), e.onDestroy(() => {
|
|
2631
|
+
T || w();
|
|
2632
|
+
}), f.querySelectorAll("[data-kind]").forEach((M) => {
|
|
2633
|
+
M.addEventListener("click", () => {
|
|
2634
|
+
s = s === M.dataset.kind ? null : M.dataset.kind, f.querySelectorAll("[data-kind]").forEach((A) => A.setAttribute("aria-pressed", String(A.dataset.kind === s)));
|
|
2635
|
+
});
|
|
2636
|
+
}), f.querySelectorAll("[data-score]").forEach((M) => {
|
|
2637
|
+
M.addEventListener("click", () => {
|
|
2638
|
+
const A = Number(M.dataset.score);
|
|
2639
|
+
y = y === A ? null : A, f.querySelectorAll("[data-score]").forEach((O) => O.setAttribute("aria-pressed", String(Number(O.dataset.score) === y))), k.textContent = y ? Te[y - 1].word : "";
|
|
2640
|
+
});
|
|
2641
|
+
});
|
|
2642
|
+
function p(M) {
|
|
2643
|
+
h.hidden = !M, h.innerHTML = M ? `${P}<span>${v(M)}</span>` : "", c.classList.toggle("invalid", !!M), c.setAttribute("aria-invalid", String(!!M));
|
|
2644
|
+
}
|
|
2645
|
+
b.addEventListener("click", async () => {
|
|
2646
|
+
if (x) return;
|
|
2647
|
+
if (!c.value.trim()) {
|
|
2648
|
+
p("Write a few words — a sentence is plenty."), c.focus();
|
|
2649
|
+
return;
|
|
2650
|
+
}
|
|
2651
|
+
x = !0, e.sending = !0, S("");
|
|
2652
|
+
const M = b.innerHTML;
|
|
2653
|
+
b.disabled = !0, b.innerHTML = '<span class="spinner" aria-hidden="true"></span>Sending…';
|
|
2654
|
+
try {
|
|
2655
|
+
const A = await t.feedback({
|
|
2656
|
+
message: c.value,
|
|
2657
|
+
kind: s,
|
|
2658
|
+
score: y,
|
|
2659
|
+
...i && i.value.trim() ? { email: i.value.trim() } : {}
|
|
2660
|
+
});
|
|
2661
|
+
if (A != null && A.cancelled) throw Object.assign(new Error(""), { quiet: !0 });
|
|
2662
|
+
if (T = !0, clearTimeout(q), $)
|
|
2663
|
+
try {
|
|
2664
|
+
localStorage.removeItem(r);
|
|
2665
|
+
} catch {
|
|
2666
|
+
}
|
|
2667
|
+
L();
|
|
2668
|
+
} catch (A) {
|
|
2669
|
+
x = !1, e.sending = !1, b.disabled = !1, b.innerHTML = M, A.quiet || S(String(A.message || "That did not send. Please try again.").replace("[BugCatch] ", ""));
|
|
2670
|
+
}
|
|
2671
|
+
});
|
|
2672
|
+
function L() {
|
|
2673
|
+
e.sending = !1, d.querySelector(".panel").innerHTML = `
|
|
2674
|
+
<div class="done">
|
|
2675
|
+
<div class="tick">${F}</div>
|
|
2676
|
+
<h3>Thanks — that's with the team.</h3>
|
|
2677
|
+
<p>Everything sent here is read by the people who build this.</p>
|
|
2678
|
+
</div>`, setTimeout(m, 2600);
|
|
2679
|
+
}
|
|
2680
|
+
e.focusFeedback = () => c.focus();
|
|
2681
|
+
}
|
|
2682
|
+
const te = {
|
|
2683
|
+
report: { title: "Report a bug", sub: "We attach the page details for you." },
|
|
2684
|
+
feedback: { title: "Give feedback", sub: "The team reads every note." }
|
|
2685
|
+
};
|
|
2686
|
+
function Ot({
|
|
2511
2687
|
root: e,
|
|
2512
2688
|
host: t,
|
|
2513
|
-
dock:
|
|
2689
|
+
dock: o,
|
|
2514
2690
|
client: d,
|
|
2515
|
-
onClose:
|
|
2691
|
+
onClose: l,
|
|
2516
2692
|
preloadCall: S = () => {
|
|
2517
2693
|
},
|
|
2518
|
-
themeControls:
|
|
2694
|
+
themeControls: m = null,
|
|
2695
|
+
mode: f = "report"
|
|
2519
2696
|
}) {
|
|
2520
|
-
|
|
2521
|
-
const
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2697
|
+
jt(e);
|
|
2698
|
+
const c = d.config, h = () => (m == null ? void 0 : m.label()) || "", b = c.feedback !== !1;
|
|
2699
|
+
let k = b && f === "feedback" ? "feedback" : "report";
|
|
2700
|
+
const s = document.createElement("div");
|
|
2701
|
+
s.className = `scrim ${o.classList.contains("at-left") ? "at-left" : "at-right"} ${o.classList.contains("at-top") ? "at-top" : "at-bottom"}`, s.style.setProperty("--bc-dock-h", `${Math.round(o.getBoundingClientRect().height)}px`), s.innerHTML = `
|
|
2702
|
+
<div class="panel" role="dialog" aria-modal="true" aria-labelledby="bc-h" data-mode="${k}">
|
|
2703
|
+
${de({
|
|
2525
2704
|
id: "bc-h",
|
|
2526
2705
|
// Not "Tell us what went wrong": that is the first field's own label,
|
|
2527
2706
|
// a few pixels below. The header names the errand the launcher named.
|
|
2528
|
-
title:
|
|
2529
|
-
sub:
|
|
2530
|
-
theme:
|
|
2707
|
+
title: te[k].title,
|
|
2708
|
+
sub: te[k].sub,
|
|
2709
|
+
theme: h()
|
|
2531
2710
|
})}
|
|
2711
|
+
${b ? `
|
|
2712
|
+
<div class="modes" role="group" aria-label="What would you like to do?">
|
|
2713
|
+
<button type="button" data-mode="report" aria-pressed="${k === "report"}">${Ze}Report a bug</button>
|
|
2714
|
+
<button type="button" data-mode="feedback" aria-pressed="${k === "feedback"}">${tt}Give feedback</button>
|
|
2715
|
+
</div>` : ""}
|
|
2532
2716
|
<div class="body">
|
|
2533
2717
|
<div class="slot" role="alert"></div>
|
|
2534
2718
|
<!-- A settled report still waiting for its rating. Drawn only when the
|
|
2535
2719
|
project asks for one here; see rate-due.js. -->
|
|
2536
|
-
<div class="rate-due fix-rating" tabindex="-1" hidden></div>
|
|
2720
|
+
<div class="rate-due fix-rating bug-only" tabindex="-1" hidden></div>
|
|
2537
2721
|
<!-- What the project's team is telling visitors. Drawn only when it
|
|
2538
2722
|
has published something. -->
|
|
2539
2723
|
<div class="notices" hidden></div>
|
|
2540
|
-
<div class="whoami" hidden></div>
|
|
2724
|
+
<div class="whoami bug-only" hidden></div>
|
|
2541
2725
|
<!-- The questions the assistant can answer from their account and
|
|
2542
2726
|
close by itself. Drawn only when the project offers any. -->
|
|
2543
|
-
<div class="picks" hidden></div>
|
|
2544
|
-
<div class="known" hidden></div>
|
|
2545
|
-
${
|
|
2727
|
+
<div class="picks bug-only" hidden></div>
|
|
2728
|
+
<div class="known bug-only" hidden></div>
|
|
2729
|
+
${ft(c)}
|
|
2730
|
+
${b ? Rt() : ""}
|
|
2546
2731
|
</div>
|
|
2547
2732
|
<div class="foot">
|
|
2548
|
-
<span class="note" aria-live="polite"></span>
|
|
2733
|
+
<span class="note bug-only" aria-live="polite"></span>
|
|
2549
2734
|
${d.hasReports() ? '<button class="quiet" type="button" data-act="history">Your reports</button>' : ""}
|
|
2550
2735
|
<span class="spacer"></span>
|
|
2551
2736
|
<!-- Hidden until the API confirms this project can take a call, which
|
|
2552
2737
|
most cannot. Drawn here rather than as a second launcher because it
|
|
2553
2738
|
is the same errand as Send report — the difference is only whether
|
|
2554
2739
|
the reporter would rather say it than type it. -->
|
|
2555
|
-
<button class="ghost" type="button" data-act="call" hidden>${
|
|
2556
|
-
<button class="primary" type="button" data-act="send">Send report ${
|
|
2740
|
+
<button class="ghost bug-only" type="button" data-act="call" hidden>${oe}Talk to the team</button>
|
|
2741
|
+
<button class="primary bug-only" type="button" data-act="send">Send report ${ce}</button>
|
|
2742
|
+
${b ? `<button class="primary fb-only" type="button" data-act="send-feedback">Send feedback ${ce}</button>` : ""}
|
|
2557
2743
|
</div>
|
|
2558
2744
|
<div class="powered">Powered by
|
|
2559
|
-
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${
|
|
2745
|
+
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${et}</a>
|
|
2560
2746
|
</div>
|
|
2561
2747
|
</div>`;
|
|
2562
|
-
const
|
|
2748
|
+
const y = (g) => s.querySelector(g), x = y(".slot"), T = [], a = {
|
|
2563
2749
|
client: d,
|
|
2564
|
-
cfg:
|
|
2750
|
+
cfg: c,
|
|
2565
2751
|
root: e,
|
|
2566
2752
|
host: t,
|
|
2567
|
-
dock:
|
|
2753
|
+
dock: o,
|
|
2568
2754
|
scrim: s,
|
|
2569
|
-
$:
|
|
2570
|
-
titleInput:
|
|
2571
|
-
descInput:
|
|
2572
|
-
compose:
|
|
2573
|
-
sendBtn:
|
|
2574
|
-
callBtn:
|
|
2575
|
-
historyBtn:
|
|
2576
|
-
note:
|
|
2577
|
-
whoami:
|
|
2578
|
-
refsBox:
|
|
2579
|
-
notices:
|
|
2580
|
-
known:
|
|
2581
|
-
picks:
|
|
2582
|
-
rateDue:
|
|
2755
|
+
$: y,
|
|
2756
|
+
titleInput: y("#bc-title"),
|
|
2757
|
+
descInput: y("#bc-desc"),
|
|
2758
|
+
compose: y(".compose"),
|
|
2759
|
+
sendBtn: y('[data-act="send"]'),
|
|
2760
|
+
callBtn: y('[data-act="call"]'),
|
|
2761
|
+
historyBtn: y('[data-act="history"]'),
|
|
2762
|
+
note: y(".foot .note"),
|
|
2763
|
+
whoami: y(".whoami"),
|
|
2764
|
+
refsBox: y(".refs"),
|
|
2765
|
+
notices: y(".notices"),
|
|
2766
|
+
known: y(".known"),
|
|
2767
|
+
picks: y(".picks"),
|
|
2768
|
+
rateDue: y(".rate-due"),
|
|
2583
2769
|
// A report or a call is on its way. Escape and a click outside wait for it.
|
|
2584
2770
|
sending: !1,
|
|
2585
2771
|
closed: !1,
|
|
2586
|
-
say:
|
|
2587
|
-
close:
|
|
2772
|
+
say: L,
|
|
2773
|
+
close: w,
|
|
2588
2774
|
preloadCall: S,
|
|
2589
|
-
themeLabel:
|
|
2590
|
-
onDestroy: (
|
|
2591
|
-
|
|
2775
|
+
themeLabel: h,
|
|
2776
|
+
onDestroy: (g) => {
|
|
2777
|
+
T.push(g);
|
|
2592
2778
|
},
|
|
2593
2779
|
// compose.js
|
|
2594
2780
|
refreshSendState: null,
|
|
@@ -2608,65 +2794,81 @@ function Qt({
|
|
|
2608
2794
|
recheckSignIn: null,
|
|
2609
2795
|
// rate-due.js
|
|
2610
2796
|
mustRate: () => !1,
|
|
2797
|
+
// feedback.js
|
|
2798
|
+
focusFeedback: () => {
|
|
2799
|
+
},
|
|
2611
2800
|
// thread.js
|
|
2612
2801
|
succeed: null,
|
|
2613
2802
|
refreshThread: null,
|
|
2614
2803
|
openReportId: null
|
|
2615
2804
|
};
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2805
|
+
gt(a), mt(a), yt(a), xt(a), wt(a), kt(a), $t(a), Mt(a), Ht(a), b && Dt(a);
|
|
2806
|
+
function n(g, { focus: z = !0 } = {}) {
|
|
2807
|
+
const M = g === "feedback" && y(".modes") ? "feedback" : "report", A = s.querySelector(".panel");
|
|
2808
|
+
a.closed || a.sending || !A || !s.querySelector(".modes") || M === "feedback" && a.isRecording() || (k = M, A.dataset.mode = M, A.querySelector("#bc-h").textContent = te[M].title, A.querySelector(".head .titles p").textContent = te[M].sub, s.querySelectorAll(".modes [data-mode]").forEach((O) => {
|
|
2809
|
+
O.setAttribute("aria-pressed", String(O.dataset.mode === M));
|
|
2810
|
+
}), L(""), z && (M === "feedback" ? a.focusFeedback() : a.titleInput.focus()));
|
|
2811
|
+
}
|
|
2812
|
+
s.querySelectorAll(".modes [data-mode]").forEach((g) => {
|
|
2813
|
+
g.addEventListener("click", () => n(g.dataset.mode));
|
|
2814
|
+
}), b && d.feedbackEnabled().then((g) => {
|
|
2815
|
+
var M, A, O;
|
|
2816
|
+
if (g || a.closed || a.sending) return;
|
|
2817
|
+
n("report", { focus: k === "feedback" }), (M = s.querySelector(".modes")) == null || M.remove(), (A = s.querySelector(".feedback")) == null || A.remove(), (O = s.querySelector('[data-act="send-feedback"]')) == null || O.remove();
|
|
2818
|
+
});
|
|
2819
|
+
const i = document.activeElement, r = document.documentElement.style, $ = r.overflow;
|
|
2820
|
+
r.overflow = "hidden";
|
|
2821
|
+
function q() {
|
|
2822
|
+
a.closed || (T.forEach((g) => g()), a.closed = !0, r.overflow = $, document.removeEventListener("keydown", p, !0), s.remove(), o.hidden = !1, t.style.opacity = "", l == null || l());
|
|
2823
|
+
}
|
|
2824
|
+
function w() {
|
|
2825
|
+
var g;
|
|
2826
|
+
if (!a.closed) {
|
|
2827
|
+
s.classList.add("closing"), setTimeout(q, 160);
|
|
2626
2828
|
try {
|
|
2627
|
-
(
|
|
2829
|
+
(g = i == null ? void 0 : i.focus) == null || g.call(i);
|
|
2628
2830
|
} catch {
|
|
2629
2831
|
}
|
|
2630
2832
|
}
|
|
2631
2833
|
}
|
|
2632
|
-
function
|
|
2633
|
-
if (
|
|
2634
|
-
if (
|
|
2635
|
-
|
|
2834
|
+
function p(g) {
|
|
2835
|
+
if (g.key === "Escape") {
|
|
2836
|
+
if (g.stopPropagation(), a.isRecording()) {
|
|
2837
|
+
a.stopRecording({ keep: !1 });
|
|
2636
2838
|
return;
|
|
2637
2839
|
}
|
|
2638
|
-
|
|
2840
|
+
a.sending || w();
|
|
2639
2841
|
return;
|
|
2640
2842
|
}
|
|
2641
|
-
if (
|
|
2642
|
-
const
|
|
2843
|
+
if (g.key !== "Tab" || a.isRecording()) return;
|
|
2844
|
+
const z = [...s.querySelectorAll(
|
|
2643
2845
|
"button:not(:disabled), input:not([hidden]), textarea, select, [href]"
|
|
2644
|
-
)].filter((
|
|
2645
|
-
if (!
|
|
2646
|
-
const
|
|
2647
|
-
|
|
2648
|
-
}
|
|
2649
|
-
document.addEventListener("keydown",
|
|
2650
|
-
|
|
2651
|
-
}),
|
|
2652
|
-
const
|
|
2653
|
-
if (!
|
|
2654
|
-
const
|
|
2655
|
-
|
|
2846
|
+
)].filter((Q) => Q.offsetParent !== null || Q === document.activeElement);
|
|
2847
|
+
if (!z.length) return;
|
|
2848
|
+
const M = z[0], A = z[z.length - 1], O = s.getRootNode().activeElement;
|
|
2849
|
+
g.shiftKey && O === M ? (g.preventDefault(), A.focus()) : !g.shiftKey && O === A && (g.preventDefault(), M.focus());
|
|
2850
|
+
}
|
|
2851
|
+
document.addEventListener("keydown", p, !0), s.addEventListener("click", (g) => {
|
|
2852
|
+
g.target === s && !a.sending && w();
|
|
2853
|
+
}), y('[data-act="close"]').addEventListener("click", w), s.addEventListener("click", (g) => {
|
|
2854
|
+
const z = g.target.closest('[data-act="theme"]');
|
|
2855
|
+
if (!z || !m) return;
|
|
2856
|
+
const M = m.cycle();
|
|
2857
|
+
z.title = `Theme: ${M.label}`, z.setAttribute("aria-label", `Theme: ${M.label}. Change theme`);
|
|
2656
2858
|
});
|
|
2657
|
-
function
|
|
2658
|
-
|
|
2859
|
+
function L(g, z = "err") {
|
|
2860
|
+
x.innerHTML = g ? `<div class="msg ${z}">${z === "err" ? P : ""}<span>${v(g)}</span></div>` : "";
|
|
2659
2861
|
}
|
|
2660
|
-
return e.appendChild(s),
|
|
2862
|
+
return e.appendChild(s), a.refreshSendState(), k === "feedback" ? a.focusFeedback() : a.titleInput.focus(), { destroy: q, close: w, setMode: n };
|
|
2661
2863
|
}
|
|
2662
|
-
function
|
|
2864
|
+
function jt(e) {
|
|
2663
2865
|
if (e.querySelector("style[data-panel]")) return;
|
|
2664
2866
|
const t = document.createElement("style");
|
|
2665
|
-
t.setAttribute("data-panel", ""), t.textContent =
|
|
2666
|
-
const
|
|
2667
|
-
|
|
2867
|
+
t.setAttribute("data-panel", ""), t.textContent = it;
|
|
2868
|
+
const o = e.querySelector("style");
|
|
2869
|
+
o ? o.after(t) : e.prepend(t);
|
|
2668
2870
|
}
|
|
2669
2871
|
export {
|
|
2670
|
-
|
|
2872
|
+
Ot as openPanel
|
|
2671
2873
|
};
|
|
2672
2874
|
//# sourceMappingURL=bugcatch-panel.es.js.map
|