makethisbetter 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/LICENSE +62 -0
  2. package/README.md +113 -0
  3. package/dist/annotate/draw.d.ts +21 -0
  4. package/dist/annotate/draw.d.ts.map +1 -0
  5. package/dist/annotate/draw.test.d.ts +2 -0
  6. package/dist/annotate/draw.test.d.ts.map +1 -0
  7. package/dist/annotate/highlighter.d.ts +11 -0
  8. package/dist/annotate/highlighter.d.ts.map +1 -0
  9. package/dist/annotate/highlighter.test.d.ts +2 -0
  10. package/dist/annotate/highlighter.test.d.ts.map +1 -0
  11. package/dist/annotate/overlay.d.ts +17 -0
  12. package/dist/annotate/overlay.d.ts.map +1 -0
  13. package/dist/annotate/overlay.test.d.ts +2 -0
  14. package/dist/annotate/overlay.test.d.ts.map +1 -0
  15. package/dist/annotate/pin.d.ts +10 -0
  16. package/dist/annotate/pin.d.ts.map +1 -0
  17. package/dist/annotate/pin.test.d.ts +2 -0
  18. package/dist/annotate/pin.test.d.ts.map +1 -0
  19. package/dist/annotate/session.d.ts +20 -0
  20. package/dist/annotate/session.d.ts.map +1 -0
  21. package/dist/annotate/session.test.d.ts +2 -0
  22. package/dist/annotate/session.test.d.ts.map +1 -0
  23. package/dist/annotate/toolbar.d.ts +17 -0
  24. package/dist/annotate/toolbar.d.ts.map +1 -0
  25. package/dist/annotate/toolbar.test.d.ts +2 -0
  26. package/dist/annotate/toolbar.test.d.ts.map +1 -0
  27. package/dist/api/client.d.ts +10 -0
  28. package/dist/api/client.d.ts.map +1 -0
  29. package/dist/api/client.test.d.ts +2 -0
  30. package/dist/api/client.test.d.ts.map +1 -0
  31. package/dist/context/collector.d.ts +10 -0
  32. package/dist/context/collector.d.ts.map +1 -0
  33. package/dist/context/collector.test.d.ts +2 -0
  34. package/dist/context/collector.test.d.ts.map +1 -0
  35. package/dist/context/console.d.ts +10 -0
  36. package/dist/context/console.d.ts.map +1 -0
  37. package/dist/context/console.test.d.ts +2 -0
  38. package/dist/context/console.test.d.ts.map +1 -0
  39. package/dist/context/error-source.d.ts +21 -0
  40. package/dist/context/error-source.d.ts.map +1 -0
  41. package/dist/context/error-source.test.d.ts +2 -0
  42. package/dist/context/error-source.test.d.ts.map +1 -0
  43. package/dist/context/frustration.d.ts +27 -0
  44. package/dist/context/frustration.d.ts.map +1 -0
  45. package/dist/context/frustration.test.d.ts +2 -0
  46. package/dist/context/frustration.test.d.ts.map +1 -0
  47. package/dist/global.d.ts +3 -0
  48. package/dist/global.d.ts.map +1 -0
  49. package/dist/i18n/en.d.ts +47 -0
  50. package/dist/i18n/en.d.ts.map +1 -0
  51. package/dist/i18n/index.d.ts +4 -0
  52. package/dist/i18n/index.d.ts.map +1 -0
  53. package/dist/i18n/index.test.d.ts +2 -0
  54. package/dist/i18n/index.test.d.ts.map +1 -0
  55. package/dist/i18n/zh-CN.d.ts +47 -0
  56. package/dist/i18n/zh-CN.d.ts.map +1 -0
  57. package/dist/index.d.mts +8 -0
  58. package/dist/index.d.ts +8 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/makethisbetter.cjs.js +84 -0
  61. package/dist/makethisbetter.cjs.js.map +1 -0
  62. package/dist/makethisbetter.esm.js +1433 -0
  63. package/dist/makethisbetter.esm.js.map +1 -0
  64. package/dist/makethisbetter.js +84 -0
  65. package/dist/makethisbetter.js.map +1 -0
  66. package/dist/popup/comment.d.ts +31 -0
  67. package/dist/popup/comment.d.ts.map +1 -0
  68. package/dist/popup/comment.test.d.ts +2 -0
  69. package/dist/popup/comment.test.d.ts.map +1 -0
  70. package/dist/popup/success.d.ts +8 -0
  71. package/dist/popup/success.d.ts.map +1 -0
  72. package/dist/popup/success.test.d.ts +2 -0
  73. package/dist/popup/success.test.d.ts.map +1 -0
  74. package/dist/record/control-bar.d.ts +12 -0
  75. package/dist/record/control-bar.d.ts.map +1 -0
  76. package/dist/record/control-bar.test.d.ts +2 -0
  77. package/dist/record/control-bar.test.d.ts.map +1 -0
  78. package/dist/record/session.d.ts +26 -0
  79. package/dist/record/session.d.ts.map +1 -0
  80. package/dist/record/session.test.d.ts +2 -0
  81. package/dist/record/session.test.d.ts.map +1 -0
  82. package/dist/screenshot/capture.d.ts +3 -0
  83. package/dist/screenshot/capture.d.ts.map +1 -0
  84. package/dist/screenshot/capture.test.d.ts +2 -0
  85. package/dist/screenshot/capture.test.d.ts.map +1 -0
  86. package/dist/styles.d.ts +9 -0
  87. package/dist/styles.d.ts.map +1 -0
  88. package/dist/types.d.ts +45 -0
  89. package/dist/types.d.ts.map +1 -0
  90. package/dist/widget/controller.d.ts +37 -0
  91. package/dist/widget/controller.d.ts.map +1 -0
  92. package/dist/widget/controller.test.d.ts +2 -0
  93. package/dist/widget/controller.test.d.ts.map +1 -0
  94. package/dist/widget/frustration-prompt.d.ts +11 -0
  95. package/dist/widget/frustration-prompt.d.ts.map +1 -0
  96. package/dist/widget/frustration-prompt.test.d.ts +2 -0
  97. package/dist/widget/frustration-prompt.test.d.ts.map +1 -0
  98. package/dist/widget/payload.d.ts +5 -0
  99. package/dist/widget/payload.d.ts.map +1 -0
  100. package/dist/widget/payload.test.d.ts +2 -0
  101. package/dist/widget/payload.test.d.ts.map +1 -0
  102. package/dist/widget/pet.d.ts +12 -0
  103. package/dist/widget/pet.d.ts.map +1 -0
  104. package/dist/widget/pet.test.d.ts +2 -0
  105. package/dist/widget/pet.test.d.ts.map +1 -0
  106. package/dist/widget/shadow.d.ts +11 -0
  107. package/dist/widget/shadow.d.ts.map +1 -0
  108. package/dist/widget/shadow.test.d.ts +2 -0
  109. package/dist/widget/shadow.test.d.ts.map +1 -0
  110. package/dist/widget/tab.d.ts +10 -0
  111. package/dist/widget/tab.d.ts.map +1 -0
  112. package/dist/widget/tab.test.d.ts +2 -0
  113. package/dist/widget/tab.test.d.ts.map +1 -0
  114. package/package.json +64 -0
  115. package/src/annotate/draw.test.ts +168 -0
  116. package/src/annotate/draw.ts +108 -0
  117. package/src/annotate/highlighter.test.ts +47 -0
  118. package/src/annotate/highlighter.ts +84 -0
  119. package/src/annotate/overlay.test.ts +91 -0
  120. package/src/annotate/overlay.ts +44 -0
  121. package/src/annotate/pin.test.ts +87 -0
  122. package/src/annotate/pin.ts +28 -0
  123. package/src/annotate/session.test.ts +219 -0
  124. package/src/annotate/session.ts +104 -0
  125. package/src/annotate/toolbar.test.ts +132 -0
  126. package/src/annotate/toolbar.ts +81 -0
  127. package/src/api/client.test.ts +75 -0
  128. package/src/api/client.ts +77 -0
  129. package/src/context/collector.test.ts +14 -0
  130. package/src/context/collector.ts +41 -0
  131. package/src/context/console.test.ts +44 -0
  132. package/src/context/console.ts +34 -0
  133. package/src/context/error-source.test.ts +115 -0
  134. package/src/context/error-source.ts +62 -0
  135. package/src/context/frustration.test.ts +134 -0
  136. package/src/context/frustration.ts +145 -0
  137. package/src/global.ts +3 -0
  138. package/src/i18n/en.ts +47 -0
  139. package/src/i18n/index.test.ts +24 -0
  140. package/src/i18n/index.ts +16 -0
  141. package/src/i18n/zh-CN.ts +47 -0
  142. package/src/index.ts +32 -0
  143. package/src/popup/comment.test.ts +73 -0
  144. package/src/popup/comment.ts +177 -0
  145. package/src/popup/success.test.ts +75 -0
  146. package/src/popup/success.ts +33 -0
  147. package/src/record/control-bar.test.ts +110 -0
  148. package/src/record/control-bar.ts +46 -0
  149. package/src/record/session.test.ts +153 -0
  150. package/src/record/session.ts +139 -0
  151. package/src/screenshot/capture.test.ts +68 -0
  152. package/src/screenshot/capture.ts +96 -0
  153. package/src/styles/widget.css +847 -0
  154. package/src/styles.ts +9 -0
  155. package/src/types.ts +46 -0
  156. package/src/vite-env.d.ts +6 -0
  157. package/src/widget/controller.test.ts +62 -0
  158. package/src/widget/controller.ts +249 -0
  159. package/src/widget/frustration-prompt.test.ts +86 -0
  160. package/src/widget/frustration-prompt.ts +34 -0
  161. package/src/widget/payload.test.ts +167 -0
  162. package/src/widget/payload.ts +31 -0
  163. package/src/widget/pet.test.ts +63 -0
  164. package/src/widget/pet.ts +67 -0
  165. package/src/widget/shadow.test.ts +25 -0
  166. package/src/widget/shadow.ts +41 -0
  167. package/src/widget/tab.test.ts +92 -0
  168. package/src/widget/tab.ts +31 -0
@@ -0,0 +1,1433 @@
1
+ const et = '*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:host{all:initial;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;color:#191a1c;-webkit-font-smoothing:antialiased}:host([data-mtb-theme="dark"]) .mtb-popup,:host([data-mtb-theme="dark"]) .mtb-success{background:#151719;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-popup-header{border-bottom-color:#ffffff1a}:host([data-mtb-theme="dark"]) .mtb-popup-title,:host([data-mtb-theme="dark"]) .mtb-success-title{color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-quick-option,:host([data-mtb-theme="dark"]) .mtb-textarea{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-popup-close,:host([data-mtb-theme="dark"]) .mtb-success-msg,:host([data-mtb-theme="dark"]) .mtb-close-link{color:#ffffffad}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-popup,:host([data-mtb-theme="auto"]) .mtb-success{background:#151719;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-popup-header{border-bottom-color:#ffffff1a}:host([data-mtb-theme="auto"]) .mtb-popup-title,:host([data-mtb-theme="auto"]) .mtb-success-title{color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-quick-option,:host([data-mtb-theme="auto"]) .mtb-textarea{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-popup-close,:host([data-mtb-theme="auto"]) .mtb-success-msg,:host([data-mtb-theme="auto"]) .mtb-close-link{color:#ffffffad}}.mtb-tab{position:fixed;top:50%;right:0;transform:translateY(-50%);z-index:2147483646;display:flex;align-items:center;justify-content:center;width:32px;padding:14px 0;background:#059669;color:#fff;border-radius:8px 0 0 8px;cursor:pointer;box-shadow:-2px 0 14px #05966959;transition:background .15s,box-shadow .15s,width .15s;writing-mode:vertical-lr;text-orientation:mixed;font-size:12px;font-weight:600;letter-spacing:.04em;user-select:none;border:none;outline:none}.mtb-tab.left{right:auto;left:0;border-radius:0 8px 8px 0;box-shadow:2px 0 14px #05966959}.mtb-tab:hover{background:#047857;box-shadow:-3px 0 20px #05966980}.mtb-tab.active{background:#065f46}.mtb-toolbar{position:fixed;top:18px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:11px;height:46px;padding:0 7px;border-radius:13px;background:linear-gradient(120deg,#10b981,#059669);box-shadow:0 10px 26px #0f172a38;animation:mtbBarIn .2s ease;white-space:nowrap}@keyframes mtbBarIn{0%{transform:translate(-50%,12px);opacity:0}to{transform:translate(-50%);opacity:1}}.mtb-toolbar-modes{display:flex;align-items:center;gap:3px;background:#ffffff29;border-radius:9px;padding:3px}.mtb-toolbar-mode-btn{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 12px;border-radius:7px;border:none;cursor:pointer;font-family:inherit;font-size:12px;font-weight:550;white-space:nowrap;background:transparent;color:#fffffff2;transition:all .12s}.mtb-toolbar-mode-btn.active{background:#fff;color:#047857}.mtb-toolbar-hint{font-size:12px;color:#fffffff2;white-space:nowrap}.mtb-toolbar-sep{width:1px;height:20px;background:#ffffff38}.mtb-exit-btn{display:inline-flex;align-items:center;gap:5px;height:30px;padding:0 12px;border-radius:8px;font-size:11.5px;font-weight:500;color:#fff;cursor:pointer;background:#ffffff29;border:none;font-family:inherit;transition:background .12s}.mtb-exit-btn:hover{background:#ffffff47}.mtb-overlay{position:fixed;inset:0;z-index:2147483640;cursor:crosshair}.mtb-dim{position:fixed;inset:0;z-index:2147483639;background:#00000014}.mtb-highlight{position:fixed;z-index:2147483641;pointer-events:none;border:2px solid #10b981;border-radius:6px;background:#10b9810f;transition:all .08s ease}.mtb-highlight-tooltip{position:fixed;z-index:2147483642;pointer-events:none;transform:translate(-50%);background:#064e3b;color:#fff;padding:4px 10px;border-radius:6px;font-size:11px;font-weight:500;white-space:nowrap;box-shadow:0 4px 12px #0000002e}.mtb-highlight-tooltip:after{content:"";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-color:#064e3b}.mtb-draw-svg{position:fixed;inset:0;z-index:2147483643;pointer-events:none;width:100%;height:100%;overflow:visible}.mtb-pin{position:fixed;z-index:2147483644;pointer-events:none;width:22px;height:22px;border-radius:50% 50% 50% 2px;background:#059669;border:2px solid #fff;display:flex;align-items:center;justify-content:center;font-size:10px;color:#fff;font-weight:700;box-shadow:0 2px 8px #05966973;animation:mtbPinPop .25s cubic-bezier(.34,1.56,.64,1);transform:translate(-50%,-50%)}@keyframes mtbPinPop{0%{transform:translate(-50%,-50%) scale(.4)}to{transform:translate(-50%,-50%) scale(1)}}.mtb-popup{position:fixed;z-index:2147483645;width:320px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:14px;box-shadow:0 12px 40px #00000029;overflow:hidden;animation:mtbSlideUp .28s cubic-bezier(.34,1.56,.64,1);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}@keyframes mtbSlideUp{0%{transform:translateY(14px) scale(.97);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}.mtb-popup-header{padding:11px 13px 11px 14px;border-bottom:1px solid rgba(0,0,0,.06);display:flex;align-items:center;gap:8px}.mtb-popup-icon{width:20px;height:20px;border-radius:5px;background:#10b9811a;display:flex;align-items:center;justify-content:center;flex-shrink:0}.mtb-popup-title{flex:1;font-size:12.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#191a1c}.mtb-popup-close{background:none;border:none;cursor:pointer;padding:3px;color:#00000061;display:flex;align-items:center;border-radius:4px;transition:color .12s}.mtb-popup-close:hover{color:#000000b3}.mtb-popup-body{padding:13px}.mtb-quick-options{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}.mtb-quick-option{display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;border:1px solid rgba(0,0,0,.09);border-radius:10px;background:#fafafa;cursor:pointer;font-family:inherit;font-size:13px;color:#191a1c;text-align:left;transition:all .12s}.mtb-quick-option:hover{background:#10b9810f;border-color:#10b9814d}.mtb-quick-option-emoji{font-size:15px;flex-shrink:0;line-height:1}.mtb-textarea-wrap{position:relative}.mtb-textarea{width:100%;height:64px;padding:9px 11px;border:1px solid rgba(0,0,0,.12);border-radius:9px;font-family:inherit;font-size:12.5px;line-height:1.5;color:#191a1c;outline:none;background:#fff;resize:none;transition:border-color .12s,box-shadow .12s}.mtb-textarea:focus{border-color:#10b981;box-shadow:0 0 0 3px #10b9811f}.mtb-textarea::placeholder{color:#00000057}.mtb-popup-error{margin-top:8px;color:#b91c1c;font-size:11.5px}.mtb-popup-error:empty,.mtb-popup-error[hidden]{display:none}.mtb-popup-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:12px}.mtb-cancel-btn,.mtb-submit-btn{min-width:72px;height:30px;border:none;border-radius:7px;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0 12px;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-cancel-btn{background:#f3f4f6;color:#000000ad}.mtb-cancel-btn:hover{background:#e5e7eb}.mtb-submit-btn{background:#d1d5db;color:#fff}.mtb-submit-btn.ready{background:#059669}.mtb-submit-btn.ready:hover{background:#047857}.mtb-submit-btn.loading{background:#059669;opacity:.7;cursor:wait}.mtb-submit-btn:disabled{cursor:not-allowed}.mtb-success{position:fixed;z-index:2147483645;width:300px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:16px;box-shadow:0 20px 60px #0000001f;padding:26px 22px;text-align:center;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.mtb-success-icon{width:44px;height:44px;border-radius:50%;background:#05966914;display:flex;align-items:center;justify-content:center;margin:0 auto 12px}.mtb-success-title{font-size:16px;font-weight:700;margin-bottom:6px;color:#191a1c}.mtb-success-msg{font-size:13px;color:#0000008c;margin-bottom:16px;line-height:1.6}.mtb-close-link{background:none;border:none;cursor:pointer;font-size:12px;color:#00000073;font-family:inherit;transition:color .12s}.mtb-close-link:hover{color:#000000b3}.mtb-pet{position:fixed;bottom:20px;right:20px;z-index:2147483646;cursor:pointer;width:52px;height:52px;display:flex;align-items:center;justify-content:center;border-radius:50%;background:transparent;animation:mtbPetBounce 3s ease-in-out infinite;transition:transform .2s;user-select:none;outline:none;filter:drop-shadow(0 4px 12px rgba(5,150,105,.35))}.mtb-pet:hover{transform:scale(1.12);animation-play-state:paused}.mtb-pet:hover .mtb-pet-bubble{opacity:1;transform:translate(-50%) translateY(0);pointer-events:auto}.mtb-pet.active{animation:none;opacity:.6}.mtb-pet-svg{display:block}@keyframes mtbPetBounce{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}.mtb-pet-bubble{position:absolute;bottom:100%;left:50%;transform:translate(-50%) translateY(4px);margin-bottom:8px;background:#064e3b;color:#fff;padding:6px 12px;border-radius:8px;font-size:12px;font-weight:500;white-space:nowrap;box-shadow:0 4px 14px #0000002e;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s}.mtb-pet-bubble.visible{opacity:1;transform:translate(-50%) translateY(0);pointer-events:auto}.mtb-pet-bubble.hidden{opacity:0;pointer-events:none}.mtb-pet-bubble:after{content:"";position:absolute;top:100%;left:50%;transform:translate(-50%);border:5px solid transparent;border-top-color:#064e3b}.mtb-frustration-prompt{position:fixed;bottom:20px;right:20px;z-index:2147483645;display:flex;align-items:center;gap:10px;padding:12px 16px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:12px;box-shadow:0 8px 30px #0000001f;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}:host([data-mtb-theme="dark"]) .mtb-frustration-prompt{background:#151719;border-color:#ffffff1f;color:#f9fafb}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-frustration-prompt{background:#151719;border-color:#ffffff1f;color:#f9fafb}}.mtb-frustration-icon{width:32px;height:32px;border-radius:50%;background:#eab3081a;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:16px;line-height:1}.mtb-frustration-text{font-size:13px;font-weight:500;color:inherit;line-height:1.4}.mtb-frustration-actions{display:flex;gap:6px;flex-shrink:0}.mtb-frustration-tell{height:28px;padding:0 12px;border:none;border-radius:7px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-frustration-tell:hover{background:#047857}.mtb-frustration-dismiss{height:28px;padding:0 8px;border:none;border-radius:7px;background:transparent;color:#0006;cursor:pointer;font-family:inherit;font-size:12px;transition:color .12s}.mtb-frustration-dismiss:hover{color:#000000b3}:host([data-mtb-theme="dark"]) .mtb-frustration-dismiss{color:#fff6}:host([data-mtb-theme="dark"]) .mtb-frustration-dismiss:hover{color:#ffffffb3}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-frustration-dismiss{color:#fff6}:host([data-mtb-theme="auto"]) .mtb-frustration-dismiss:hover{color:#ffffffb3}}.mtb-record-bar{position:fixed;bottom:24px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:12px;height:42px;padding:0 8px 0 14px;border-radius:12px;background:#0f172aeb;box-shadow:0 8px 24px #00000040;animation:mtbBarIn .2s ease}.mtb-record-dot{width:8px;height:8px;border-radius:50%;background:#ef4444;animation:mtbRecordPulse 1.2s ease-in-out infinite;flex-shrink:0}@keyframes mtbRecordPulse{0%,to{opacity:1}50%{opacity:.3}}.mtb-record-timer{font-family:JetBrains Mono,SF Mono,Fira Code,Cascadia Code,monospace;font-size:13px;font-weight:500;color:#fff;font-variant-numeric:tabular-nums;letter-spacing:.02em;min-width:38px}.mtb-record-stop{height:28px;padding:0 14px;border:none;border-radius:7px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-record-stop:hover{background:#047857}.mtb-click-ripple{position:fixed;z-index:2147483644;width:24px;height:24px;border-radius:50%;border:2px solid #10b981;background:#10b98133;pointer-events:none;transform:translate(-50%,-50%) scale(.5);animation:mtbClickRipple .3s ease-out forwards}@keyframes mtbClickRipple{0%{transform:translate(-50%,-50%) scale(.5);opacity:1}to{transform:translate(-50%,-50%) scale(2);opacity:0}}.mtb-dot{display:inline-block;width:4px;height:4px;border-radius:50%;background:#fff;animation:mtbDot 1.2s infinite}.mtb-dot:nth-child(2){animation-delay:.2s}.mtb-dot:nth-child(3){animation-delay:.4s}@keyframes mtbDot{0%,80%,to{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}';
2
+ class it {
3
+ constructor(t = "auto") {
4
+ this.host = document.createElement("div"), this.host.id = "mtb-widget-host", this.host.style.cssText = "position:fixed;top:0;left:0;width:0;height:0;overflow:visible;z-index:2147483646;", this.host.setAttribute("data-mtb-theme", t), document.body.appendChild(this.host), this.root = this.host.attachShadow({ mode: "open" });
5
+ const i = document.createElement("style");
6
+ i.textContent = et, this.root.appendChild(i);
7
+ }
8
+ el(t, i) {
9
+ const r = document.createElement(t);
10
+ return i && (r.className = i), r;
11
+ }
12
+ append(...t) {
13
+ for (const i of t) this.root.appendChild(i);
14
+ }
15
+ remove(...t) {
16
+ for (const i of t)
17
+ i.parentNode === this.root && this.root.removeChild(i);
18
+ }
19
+ destroy() {
20
+ document.body.removeChild(this.host);
21
+ }
22
+ }
23
+ class rt {
24
+ constructor(t, i, r, s) {
25
+ this.onClick = s, this.el = t.el("button", "mtb-tab"), r === "left" && this.el.classList.add("left"), this.el.textContent = i.tab, this.el.setAttribute("aria-label", i.tab), this.el.addEventListener("click", s), t.append(this.el);
26
+ }
27
+ setActive(t) {
28
+ this.el.classList.toggle("active", t);
29
+ }
30
+ destroy() {
31
+ this.el.removeEventListener("click", this.onClick), this.el.remove();
32
+ }
33
+ }
34
+ const y = "#059669", x = {
35
+ color: y,
36
+ width: "3.5",
37
+ linecap: "round",
38
+ linejoin: "round",
39
+ filter: "drop-shadow(0 1px 2px rgba(5,150,105,0.35))"
40
+ };
41
+ class st {
42
+ constructor(t, i, r) {
43
+ this.onClick = r, this.el = t.el("div", "mtb-pet"), this.el.innerHTML = this.buildSVG(), this.el.setAttribute("role", "button"), this.el.setAttribute("aria-label", i.tab), this.el.tabIndex = 0, this.bubble = t.el("div", "mtb-pet-bubble"), this.bubble.textContent = i.pet.bubble, this.el.appendChild(this.bubble), this.el.addEventListener("click", this.onClick), this.el.addEventListener("keydown", (s) => {
44
+ (s.key === "Enter" || s.key === " ") && (s.preventDefault(), this.onClick());
45
+ }), t.append(this.el);
46
+ }
47
+ buildSVG() {
48
+ return `<svg class="mtb-pet-svg" width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
49
+ <circle cx="24" cy="28" r="16" fill="${y}"/>
50
+ <circle cx="24" cy="28" r="14" fill="#10b981"/>
51
+ <circle cx="19" cy="25" r="3" fill="#fff"/>
52
+ <circle cx="29" cy="25" r="3" fill="#fff"/>
53
+ <circle cx="20" cy="24.5" r="1.5" fill="#064e3b"/>
54
+ <circle cx="30" cy="24.5" r="1.5" fill="#064e3b"/>
55
+ <ellipse cx="19.5" cy="23.5" rx="0.8" ry="0.6" fill="#fff" opacity="0.7"/>
56
+ <ellipse cx="29.5" cy="23.5" rx="0.8" ry="0.6" fill="#fff" opacity="0.7"/>
57
+ <path d="M20 31 Q24 34 28 31" stroke="#064e3b" stroke-width="1.5" stroke-linecap="round" fill="none"/>
58
+ <circle cx="15" cy="30" r="2.5" fill="${y}" opacity="0.4"/>
59
+ <circle cx="33" cy="30" r="2.5" fill="${y}" opacity="0.4"/>
60
+ <path d="M14 17 Q16 12 20 15" stroke="#10b981" stroke-width="2" stroke-linecap="round" fill="none"/>
61
+ <path d="M34 17 Q32 12 28 15" stroke="#10b981" stroke-width="2" stroke-linecap="round" fill="none"/>
62
+ </svg>`;
63
+ }
64
+ setActive(t) {
65
+ this.el.classList.toggle("active", t), t && this.bubble.classList.add("hidden");
66
+ }
67
+ destroy() {
68
+ this.el.removeEventListener("click", this.onClick), this.el.remove();
69
+ }
70
+ }
71
+ const nt = 8e3;
72
+ class ot {
73
+ constructor(t, i, r) {
74
+ this.el = t.el("div", "mtb-frustration-prompt"), this.el.innerHTML = `
75
+ <div class="mtb-frustration-icon">&#9888;&#65039;</div>
76
+ <span class="mtb-frustration-text">${i.frustration.prompt}</span>
77
+ <div class="mtb-frustration-actions">
78
+ <button class="mtb-frustration-tell">${i.frustration.action}</button>
79
+ <button class="mtb-frustration-dismiss">${i.frustration.dismiss}</button>
80
+ </div>
81
+ `, this.el.querySelector(".mtb-frustration-tell").addEventListener("click", r.onTell), this.el.querySelector(".mtb-frustration-dismiss").addEventListener("click", r.onDismiss), t.append(this.el), setTimeout(r.onDismiss, nt);
82
+ }
83
+ destroy() {
84
+ this.el.remove();
85
+ }
86
+ }
87
+ class at {
88
+ constructor(t, i, r, s) {
89
+ this.currentMode = "markup", this.messages = i, this.el = t.el("div", "mtb-toolbar"), this.el.innerHTML = this.buildHTML(i), t.append(this.el), this.hintEl = this.el.querySelector(".mtb-toolbar-hint"), this.markupBtn = this.el.querySelector(".mtb-toolbar-mode-markup"), this.recordBtn = this.el.querySelector(".mtb-toolbar-mode-record"), this.markupBtn.addEventListener("click", () => {
90
+ this.setMode("markup"), s?.("markup");
91
+ }), this.recordBtn.addEventListener("click", () => {
92
+ this.setMode("record"), s?.("record");
93
+ }), this.el.querySelector(".mtb-exit-btn").addEventListener("click", r);
94
+ }
95
+ buildHTML(t) {
96
+ return `
97
+ <div class="mtb-toolbar-modes">
98
+ <button class="mtb-toolbar-mode-btn mtb-toolbar-mode-markup active">
99
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><line x1="12" y1="3" x2="12" y2="7"/><line x1="12" y1="17" x2="12" y2="21"/><line x1="3" y1="12" x2="7" y2="12"/><line x1="17" y1="12" x2="21" y2="12"/></svg>${t.toolbar.markup}
100
+ </button>
101
+ <button class="mtb-toolbar-mode-btn mtb-toolbar-mode-record">
102
+ <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="4" fill="currentColor" stroke="none"/></svg>${t.toolbar.record}
103
+ </button>
104
+ </div>
105
+ <span class="mtb-toolbar-hint">${t.toolbar.hint}</span>
106
+ <span class="mtb-toolbar-sep"></span>
107
+ <button class="mtb-exit-btn">
108
+ <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round">
109
+ <path d="M18 6L6 18M6 6l12 12"/>
110
+ </svg>${t.toolbar.exit}
111
+ </button>
112
+ `;
113
+ }
114
+ setMode(t) {
115
+ this.currentMode = t, t === "markup" ? (this.markupBtn.classList.add("active"), this.recordBtn.classList.remove("active"), this.hintEl.textContent = this.messages.toolbar.hint) : (this.markupBtn.classList.remove("active"), this.recordBtn.classList.add("active"), this.hintEl.textContent = this.messages.toolbar.hintRecord);
116
+ }
117
+ getMode() {
118
+ return this.currentMode;
119
+ }
120
+ destroy() {
121
+ this.el.remove();
122
+ }
123
+ }
124
+ class lt {
125
+ constructor(t, i) {
126
+ this.onMouseDown = i.onMouseDown, this.onMouseMove = i.onMouseMove, this.onMouseUp = i.onMouseUp, this.onMouseLeave = i.onMouseLeave, this.overlayEl = t.el("div", "mtb-overlay"), this.overlayEl.addEventListener("mousedown", this.onMouseDown), this.overlayEl.addEventListener("mousemove", this.onMouseMove), this.overlayEl.addEventListener("mouseup", this.onMouseUp), this.overlayEl.addEventListener("mouseleave", this.onMouseLeave), t.append(this.overlayEl), this.dimEl = t.el("div", "mtb-dim"), t.append(this.dimEl);
127
+ }
128
+ destroy() {
129
+ this.overlayEl.removeEventListener("mousedown", this.onMouseDown), this.overlayEl.removeEventListener("mousemove", this.onMouseMove), this.overlayEl.removeEventListener("mouseup", this.onMouseUp), this.overlayEl.removeEventListener("mouseleave", this.onMouseLeave), this.overlayEl.remove(), this.dimEl.remove();
130
+ }
131
+ }
132
+ class ct {
133
+ constructor(t) {
134
+ this.highlightEl = t.el("div", "mtb-highlight"), this.hide(), t.append(this.highlightEl);
135
+ }
136
+ highlight(t) {
137
+ const i = t.getBoundingClientRect();
138
+ this.highlightEl.style.top = `${i.top - 2}px`, this.highlightEl.style.left = `${i.left - 2}px`, this.highlightEl.style.width = `${i.width + 4}px`, this.highlightEl.style.height = `${i.height + 4}px`, this.highlightEl.style.display = "block";
139
+ }
140
+ hide() {
141
+ this.highlightEl.style.display = "none";
142
+ }
143
+ destroy() {
144
+ this.highlightEl.remove();
145
+ }
146
+ }
147
+ function ht(e) {
148
+ if (e instanceof HTMLElement) {
149
+ const t = e.getAttribute("aria-label");
150
+ if (t) return t;
151
+ const i = e.getAttribute("title");
152
+ if (i) return i;
153
+ const r = e.textContent?.trim().slice(0, 40);
154
+ if (r) return r;
155
+ const s = e.placeholder;
156
+ if (s) return s;
157
+ const n = e.alt;
158
+ if (n) return n;
159
+ const o = e.getAttribute("data-mark");
160
+ if (o) return o;
161
+ }
162
+ return e.tagName.toLowerCase();
163
+ }
164
+ function dt(e) {
165
+ const t = [];
166
+ let i = e;
167
+ for (; i && i !== document.body && t.length < 5; ) {
168
+ let r = i.tagName.toLowerCase();
169
+ if (i.id) {
170
+ r = `#${i.id}`, t.unshift(r);
171
+ break;
172
+ }
173
+ const s = Array.from(i.classList).filter((o) => !o.startsWith("mtb-")).slice(0, 2).join(".");
174
+ s && (r += `.${s}`);
175
+ const n = i.parentElement;
176
+ if (n) {
177
+ const o = Array.from(n.children).filter(
178
+ (a) => a.tagName === i.tagName
179
+ );
180
+ if (o.length > 1) {
181
+ const a = o.indexOf(i) + 1;
182
+ r += `:nth-child(${a})`;
183
+ }
184
+ }
185
+ t.unshift(r), i = i.parentElement;
186
+ }
187
+ return t.join(" > ");
188
+ }
189
+ class ut {
190
+ constructor(t) {
191
+ this.pins = [], this.shadow = t;
192
+ }
193
+ addPin(t, i, r) {
194
+ const s = this.shadow.el("div", "mtb-pin");
195
+ s.textContent = String(r), s.style.top = `${i}px`, s.style.left = `${t}px`, this.shadow.append(s), this.pins.push(s);
196
+ }
197
+ clearAll() {
198
+ for (const t of this.pins) t.remove();
199
+ this.pins = [];
200
+ }
201
+ destroy() {
202
+ this.clearAll();
203
+ }
204
+ }
205
+ class pt {
206
+ constructor(t, i) {
207
+ this.path = null, this.points = [], this.isDrawing = !1, this.onDrawComplete = i, this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), this.svg.setAttribute("class", "mtb-draw-svg"), t.append(this.svg);
208
+ }
209
+ startDraw(t, i) {
210
+ this.isDrawing = !0, this.points = [[t, i]], this.path = document.createElementNS("http://www.w3.org/2000/svg", "path"), this.path.setAttribute("fill", "none"), this.path.setAttribute("stroke", x.color), this.path.setAttribute("stroke-width", x.width), this.path.setAttribute("stroke-linecap", x.linecap), this.path.setAttribute("stroke-linejoin", x.linejoin), this.path.setAttribute("style", `filter:${x.filter}`), this.svg.appendChild(this.path);
211
+ }
212
+ continueDraw(t, i) {
213
+ !this.isDrawing || !this.path || (this.points.push([t, i]), this.path.setAttribute("d", this.buildPathD()));
214
+ }
215
+ endDraw() {
216
+ if (!this.isDrawing || this.points.length < 2) {
217
+ this.isDrawing = !1, this.path && (this.path.remove(), this.path = null);
218
+ return;
219
+ }
220
+ this.isDrawing = !1;
221
+ const t = this.getCenter(), i = this.buildPathD(), r = {
222
+ type: "draw",
223
+ x: t[0],
224
+ y: t[1],
225
+ drawPath: i
226
+ };
227
+ this.onDrawComplete(r);
228
+ }
229
+ buildPathD() {
230
+ if (this.points.length === 0) return "";
231
+ const [t, i] = this.points[0];
232
+ let r = `M ${t} ${i}`;
233
+ for (let s = 1; s < this.points.length; s++) {
234
+ const [n, o] = this.points[s];
235
+ r += ` L ${n} ${o}`;
236
+ }
237
+ return r;
238
+ }
239
+ getCenter() {
240
+ const t = this.points.map((n) => n[0]), i = this.points.map((n) => n[1]), r = (Math.min(...t) + Math.max(...t)) / 2, s = (Math.min(...i) + Math.max(...i)) / 2;
241
+ return [r, s];
242
+ }
243
+ clearAll() {
244
+ for (; this.svg.firstChild; ) this.svg.removeChild(this.svg.firstChild);
245
+ this.path = null, this.isDrawing = !1, this.points = [];
246
+ }
247
+ cancelCurrentDraw() {
248
+ this.path?.remove(), this.path = null, this.isDrawing = !1, this.points = [];
249
+ }
250
+ isCurrentlyDrawing() {
251
+ return this.isDrawing;
252
+ }
253
+ getPointCount() {
254
+ return this.points.length;
255
+ }
256
+ destroy() {
257
+ this.svg.remove();
258
+ }
259
+ }
260
+ const ft = 5;
261
+ class P {
262
+ constructor(t, i, r) {
263
+ this.messages = i, this.onReady = r, this.pinCount = 0, this.interactionActive = !0, this.highlighter = new ct(t), this.pinMarker = new ut(t), this.drawLayer = new pt(t, (s) => {
264
+ this.onReady(s, this.messages.annotation.drawing);
265
+ }), this.overlay = new lt(t, {
266
+ onMouseDown: (s) => this.handleMouseDown(s),
267
+ onMouseMove: (s) => this.handleMouseMove(s),
268
+ onMouseUp: (s) => this.handleMouseUp(s),
269
+ onMouseLeave: () => {
270
+ this.drawLayer.isCurrentlyDrawing() && this.drawLayer.endDraw(), this.highlighter.hide();
271
+ }
272
+ });
273
+ }
274
+ handleMouseDown(t) {
275
+ t.preventDefault(), this.drawLayer.startDraw(t.clientX, t.clientY);
276
+ }
277
+ handleMouseMove(t) {
278
+ if (this.drawLayer.isCurrentlyDrawing()) {
279
+ this.drawLayer.continueDraw(t.clientX, t.clientY), this.highlighter.hide();
280
+ return;
281
+ }
282
+ const i = D(t.clientX, t.clientY);
283
+ i ? this.highlighter.highlight(i) : this.highlighter.hide();
284
+ }
285
+ handleMouseUp(t) {
286
+ if (!this.drawLayer.isCurrentlyDrawing()) return;
287
+ if (this.drawLayer.getPointCount() >= ft) {
288
+ this.drawLayer.endDraw();
289
+ return;
290
+ }
291
+ this.drawLayer.cancelCurrentDraw();
292
+ const i = D(t.clientX, t.clientY), r = i ? ht(i) : this.messages.annotation.element, s = {
293
+ type: "pin",
294
+ x: t.clientX,
295
+ y: t.clientY,
296
+ targetSelector: i ? dt(i) : void 0,
297
+ targetText: i?.textContent?.trim().slice(0, 200) ?? "",
298
+ targetName: r
299
+ };
300
+ this.pinMarker.addPin(t.clientX, t.clientY, ++this.pinCount), this.drawLayer.clearAll(), this.highlighter.hide(), this.onReady(s, r);
301
+ }
302
+ dismissInteraction() {
303
+ this.interactionActive && (this.interactionActive = !1, this.overlay.destroy(), this.highlighter.destroy());
304
+ }
305
+ destroy() {
306
+ this.dismissInteraction(), this.pinMarker.destroy(), this.drawLayer.destroy();
307
+ }
308
+ }
309
+ function D(e, t) {
310
+ const i = document.getElementById("mtb-widget-host");
311
+ i && (i.style.display = "none");
312
+ const r = document.elementFromPoint(e, t);
313
+ return i && (i.style.display = ""), r;
314
+ }
315
+ class mt {
316
+ constructor(t, i) {
317
+ this.loading = !1, this.onSubmit = i.onSubmit, this.onClose = i.onClose, this.submitLabel = i.messages.popup.submit, this.el = t.el("div", "mtb-popup"), this.el.innerHTML = this.buildHTML(i), t.append(this.el), this.textarea = this.el.querySelector(".mtb-textarea"), this.submitBtn = this.el.querySelector(".mtb-submit-btn"), this.positionPopup(i.x, i.y), this.bindEvents(i.messages), this.textarea.focus();
318
+ }
319
+ buildHTML(t) {
320
+ const i = t.messages, r = i.popup.quickOptions.map(
321
+ (s) => `
322
+ <button class="mtb-quick-option" data-quick="${m(s.label)}">
323
+ <span class="mtb-quick-option-emoji">${s.emoji}</span>
324
+ <span>${m(s.label)}</span>
325
+ </button>`
326
+ ).join("");
327
+ return `
328
+ <div class="mtb-popup-header">
329
+ <div class="mtb-popup-icon">
330
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#059669" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
331
+ <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/>
332
+ </svg>
333
+ </div>
334
+ <span class="mtb-popup-title">${i.popup.about} "${m(t.targetName)}"</span>
335
+ <button class="mtb-popup-close" aria-label="Close">
336
+ <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
337
+ <path d="M18 6L6 18M6 6l12 12"/>
338
+ </svg>
339
+ </button>
340
+ </div>
341
+ <div class="mtb-popup-body">
342
+ <div class="mtb-quick-options">
343
+ ${r}
344
+ </div>
345
+ <div class="mtb-textarea-wrap">
346
+ <textarea class="mtb-textarea" placeholder="${m(i.popup.placeholder)}"></textarea>
347
+ </div>
348
+ <div class="mtb-popup-error" role="alert"></div>
349
+ <div class="mtb-popup-actions">
350
+ <button class="mtb-cancel-btn" type="button">${m(i.popup.cancel)}</button>
351
+ <button class="mtb-submit-btn" type="button" disabled>${m(i.popup.submit)}</button>
352
+ </div>
353
+ </div>
354
+ `;
355
+ }
356
+ positionPopup(t, i) {
357
+ const n = window.innerWidth, o = window.innerHeight, a = 12;
358
+ let l = t + 12, c = i + 12;
359
+ l + 320 > n - a && (l = t - 320 - 12), l < a && (l = a), c + 260 > o - a && (c = o - 260 - a), c < a && (c = a), this.el.style.left = `${l}px`, this.el.style.top = `${c}px`;
360
+ }
361
+ bindEvents(t) {
362
+ this.el.querySelector(".mtb-popup-close").addEventListener("click", () => this.onClose()), this.el.querySelector(".mtb-cancel-btn").addEventListener("click", () => this.onClose()), this.errorEl = this.el.querySelector(".mtb-popup-error"), this.el.querySelectorAll(".mtb-quick-option").forEach((i) => {
363
+ i.addEventListener("click", () => {
364
+ const r = i.dataset.quick ?? "";
365
+ this.textarea.value = r, this.updateSubmitState(), this.textarea.focus();
366
+ });
367
+ }), this.textarea.addEventListener("input", () => this.updateSubmitState()), this.textarea.addEventListener("keydown", (i) => {
368
+ i.key === "Enter" && (i.metaKey || i.ctrlKey) && (i.preventDefault(), this.submit());
369
+ }), this.submitBtn.addEventListener("click", () => this.submit());
370
+ }
371
+ updateSubmitState() {
372
+ const t = this.textarea.value.trim().length > 0;
373
+ this.submitBtn.classList.toggle("ready", t && !this.loading), this.submitBtn.disabled = !t || this.loading, this.errorEl.hidden = !0, this.errorEl.textContent = "";
374
+ }
375
+ submit() {
376
+ const t = this.textarea.value.trim();
377
+ !t || this.loading || this.onSubmit(t);
378
+ }
379
+ setLoading(t) {
380
+ this.loading = t, t ? (this.submitBtn.classList.add("loading"), this.submitBtn.innerHTML = '<span class="mtb-dot"></span><span class="mtb-dot"></span><span class="mtb-dot"></span>', this.textarea.disabled = !0) : (this.submitBtn.classList.remove("loading"), this.submitBtn.textContent = this.submitLabel, this.textarea.disabled = !1), this.updateSubmitState();
381
+ }
382
+ setError(t) {
383
+ this.errorEl.textContent = t, this.errorEl.hidden = !1;
384
+ }
385
+ destroy() {
386
+ this.el.remove();
387
+ }
388
+ }
389
+ function m(e) {
390
+ return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
391
+ }
392
+ const bt = 5e3;
393
+ class gt {
394
+ constructor(t, i, r) {
395
+ this.el = t.el("div", "mtb-success"), this.el.style.right = "20px", this.el.style.bottom = "20px", this.el.innerHTML = `
396
+ <div class="mtb-success-icon">
397
+ <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="${y}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
398
+ <polyline points="20 6 9 17 4 12"/>
399
+ </svg>
400
+ </div>
401
+ <div class="mtb-success-title">${i.success.title}</div>
402
+ <div class="mtb-success-msg">${i.success.message}</div>
403
+ <button class="mtb-close-link">${i.success.close}</button>
404
+ `, t.append(this.el), this.el.querySelector(".mtb-close-link").addEventListener("click", r), setTimeout(() => r(), bt);
405
+ }
406
+ destroy() {
407
+ this.el.remove();
408
+ }
409
+ }
410
+ function xt(e, t) {
411
+ if (e.match(/^[a-z]+:\/\//i))
412
+ return e;
413
+ if (e.match(/^\/\//))
414
+ return window.location.protocol + e;
415
+ if (e.match(/^[a-z]+:/i))
416
+ return e;
417
+ const i = document.implementation.createHTMLDocument(), r = i.createElement("base"), s = i.createElement("a");
418
+ return i.head.appendChild(r), i.body.appendChild(s), t && (r.href = t), s.href = e, s.href;
419
+ }
420
+ const wt = /* @__PURE__ */ (() => {
421
+ let e = 0;
422
+ const t = () => (
423
+ // eslint-disable-next-line no-bitwise
424
+ `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4)
425
+ );
426
+ return () => (e += 1, `u${t()}${e}`);
427
+ })();
428
+ function p(e) {
429
+ const t = [];
430
+ for (let i = 0, r = e.length; i < r; i++)
431
+ t.push(e[i]);
432
+ return t;
433
+ }
434
+ let b = null;
435
+ function W(e = {}) {
436
+ return b || (e.includeStyleProperties ? (b = e.includeStyleProperties, b) : (b = p(window.getComputedStyle(document.documentElement)), b));
437
+ }
438
+ function S(e, t) {
439
+ const r = (e.ownerDocument.defaultView || window).getComputedStyle(e).getPropertyValue(t);
440
+ return r ? parseFloat(r.replace("px", "")) : 0;
441
+ }
442
+ function yt(e) {
443
+ const t = S(e, "border-left-width"), i = S(e, "border-right-width");
444
+ return e.clientWidth + t + i;
445
+ }
446
+ function kt(e) {
447
+ const t = S(e, "border-top-width"), i = S(e, "border-bottom-width");
448
+ return e.clientHeight + t + i;
449
+ }
450
+ function V(e, t = {}) {
451
+ const i = t.width || yt(e), r = t.height || kt(e);
452
+ return { width: i, height: r };
453
+ }
454
+ function vt() {
455
+ let e, t;
456
+ try {
457
+ t = process;
458
+ } catch {
459
+ }
460
+ const i = t && t.env ? t.env.devicePixelRatio : null;
461
+ return i && (e = parseInt(i, 10), Number.isNaN(e) && (e = 1)), e || window.devicePixelRatio || 1;
462
+ }
463
+ const d = 16384;
464
+ function St(e) {
465
+ (e.width > d || e.height > d) && (e.width > d && e.height > d ? e.width > e.height ? (e.height *= d / e.width, e.width = d) : (e.width *= d / e.height, e.height = d) : e.width > d ? (e.height *= d / e.width, e.width = d) : (e.width *= d / e.height, e.height = d));
466
+ }
467
+ function E(e) {
468
+ return new Promise((t, i) => {
469
+ const r = new Image();
470
+ r.onload = () => {
471
+ r.decode().then(() => {
472
+ requestAnimationFrame(() => t(r));
473
+ });
474
+ }, r.onerror = i, r.crossOrigin = "anonymous", r.decoding = "async", r.src = e;
475
+ });
476
+ }
477
+ async function Et(e) {
478
+ return Promise.resolve().then(() => new XMLSerializer().serializeToString(e)).then(encodeURIComponent).then((t) => `data:image/svg+xml;charset=utf-8,${t}`);
479
+ }
480
+ async function Ct(e, t, i) {
481
+ const r = "http://www.w3.org/2000/svg", s = document.createElementNS(r, "svg"), n = document.createElementNS(r, "foreignObject");
482
+ return s.setAttribute("width", `${t}`), s.setAttribute("height", `${i}`), s.setAttribute("viewBox", `0 0 ${t} ${i}`), n.setAttribute("width", "100%"), n.setAttribute("height", "100%"), n.setAttribute("x", "0"), n.setAttribute("y", "0"), n.setAttribute("externalResourcesRequired", "true"), s.appendChild(n), n.appendChild(e), Et(s);
483
+ }
484
+ const h = (e, t) => {
485
+ if (e instanceof t)
486
+ return !0;
487
+ const i = Object.getPrototypeOf(e);
488
+ return i === null ? !1 : i.constructor.name === t.name || h(i, t);
489
+ };
490
+ function Lt(e) {
491
+ const t = e.getPropertyValue("content");
492
+ return `${e.cssText} content: '${t.replace(/'|"/g, "")}';`;
493
+ }
494
+ function Mt(e, t) {
495
+ return W(t).map((i) => {
496
+ const r = e.getPropertyValue(i), s = e.getPropertyPriority(i);
497
+ return `${i}: ${r}${s ? " !important" : ""};`;
498
+ }).join(" ");
499
+ }
500
+ function Rt(e, t, i, r) {
501
+ const s = `.${e}:${t}`, n = i.cssText ? Lt(i) : Mt(i, r);
502
+ return document.createTextNode(`${s}{${n}}`);
503
+ }
504
+ function _(e, t, i, r) {
505
+ const s = window.getComputedStyle(e, i), n = s.getPropertyValue("content");
506
+ if (n === "" || n === "none")
507
+ return;
508
+ const o = wt();
509
+ try {
510
+ t.className = `${t.className} ${o}`;
511
+ } catch {
512
+ return;
513
+ }
514
+ const a = document.createElement("style");
515
+ a.appendChild(Rt(o, i, s, r)), t.appendChild(a);
516
+ }
517
+ function At(e, t, i) {
518
+ _(e, t, ":before", i), _(e, t, ":after", i);
519
+ }
520
+ const I = "application/font-woff", H = "image/jpeg", Tt = {
521
+ woff: I,
522
+ woff2: I,
523
+ ttf: "application/font-truetype",
524
+ eot: "application/vnd.ms-fontobject",
525
+ png: "image/png",
526
+ jpg: H,
527
+ jpeg: H,
528
+ gif: "image/gif",
529
+ tiff: "image/tiff",
530
+ svg: "image/svg+xml",
531
+ webp: "image/webp"
532
+ };
533
+ function $t(e) {
534
+ const t = /\.([^./]*?)$/g.exec(e);
535
+ return t ? t[1] : "";
536
+ }
537
+ function T(e) {
538
+ const t = $t(e).toLowerCase();
539
+ return Tt[t] || "";
540
+ }
541
+ function Pt(e) {
542
+ return e.split(/,/)[1];
543
+ }
544
+ function R(e) {
545
+ return e.search(/^(data:)/) !== -1;
546
+ }
547
+ function Dt(e, t) {
548
+ return `data:${t};base64,${e}`;
549
+ }
550
+ async function N(e, t, i) {
551
+ const r = await fetch(e, t);
552
+ if (r.status === 404)
553
+ throw new Error(`Resource "${r.url}" not found`);
554
+ const s = await r.blob();
555
+ return new Promise((n, o) => {
556
+ const a = new FileReader();
557
+ a.onerror = o, a.onloadend = () => {
558
+ try {
559
+ n(i({ res: r, result: a.result }));
560
+ } catch (l) {
561
+ o(l);
562
+ }
563
+ }, a.readAsDataURL(s);
564
+ });
565
+ }
566
+ const M = {};
567
+ function _t(e, t, i) {
568
+ let r = e.replace(/\?.*/, "");
569
+ return i && (r = e), /ttf|otf|eot|woff2?/i.test(r) && (r = r.replace(/.*\//, "")), t ? `[${t}]${r}` : r;
570
+ }
571
+ async function $(e, t, i) {
572
+ const r = _t(e, t, i.includeQueryParams);
573
+ if (M[r] != null)
574
+ return M[r];
575
+ i.cacheBust && (e += (/\?/.test(e) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime());
576
+ let s;
577
+ try {
578
+ const n = await N(e, i.fetchRequestInit, ({ res: o, result: a }) => (t || (t = o.headers.get("Content-Type") || ""), Pt(a)));
579
+ s = Dt(n, t);
580
+ } catch (n) {
581
+ s = i.imagePlaceholder || "";
582
+ let o = `Failed to fetch resource: ${e}`;
583
+ n && (o = typeof n == "string" ? n : n.message), o && console.warn(o);
584
+ }
585
+ return M[r] = s, s;
586
+ }
587
+ async function It(e) {
588
+ const t = e.toDataURL();
589
+ return t === "data:," ? e.cloneNode(!1) : E(t);
590
+ }
591
+ async function Ht(e, t) {
592
+ if (e.currentSrc) {
593
+ const n = document.createElement("canvas"), o = n.getContext("2d");
594
+ n.width = e.clientWidth, n.height = e.clientHeight, o?.drawImage(e, 0, 0, n.width, n.height);
595
+ const a = n.toDataURL();
596
+ return E(a);
597
+ }
598
+ const i = e.poster, r = T(i), s = await $(i, r, t);
599
+ return E(s);
600
+ }
601
+ async function Ft(e, t) {
602
+ var i;
603
+ try {
604
+ if (!((i = e?.contentDocument) === null || i === void 0) && i.body)
605
+ return await C(e.contentDocument.body, t, !0);
606
+ } catch {
607
+ }
608
+ return e.cloneNode(!1);
609
+ }
610
+ async function Ot(e, t) {
611
+ return h(e, HTMLCanvasElement) ? It(e) : h(e, HTMLVideoElement) ? Ht(e, t) : h(e, HTMLIFrameElement) ? Ft(e, t) : e.cloneNode(Y(e));
612
+ }
613
+ const Ut = (e) => e.tagName != null && e.tagName.toUpperCase() === "SLOT", Y = (e) => e.tagName != null && e.tagName.toUpperCase() === "SVG";
614
+ async function Bt(e, t, i) {
615
+ var r, s;
616
+ if (Y(t))
617
+ return t;
618
+ let n = [];
619
+ return Ut(e) && e.assignedNodes ? n = p(e.assignedNodes()) : h(e, HTMLIFrameElement) && (!((r = e.contentDocument) === null || r === void 0) && r.body) ? n = p(e.contentDocument.body.childNodes) : n = p(((s = e.shadowRoot) !== null && s !== void 0 ? s : e).childNodes), n.length === 0 || h(e, HTMLVideoElement) || await n.reduce((o, a) => o.then(() => C(a, i)).then((l) => {
620
+ l && t.appendChild(l);
621
+ }), Promise.resolve()), t;
622
+ }
623
+ function jt(e, t, i) {
624
+ const r = t.style;
625
+ if (!r)
626
+ return;
627
+ const s = window.getComputedStyle(e);
628
+ s.cssText ? (r.cssText = s.cssText, r.transformOrigin = s.transformOrigin) : W(i).forEach((n) => {
629
+ let o = s.getPropertyValue(n);
630
+ n === "font-size" && o.endsWith("px") && (o = `${Math.floor(parseFloat(o.substring(0, o.length - 2))) - 0.1}px`), h(e, HTMLIFrameElement) && n === "display" && o === "inline" && (o = "block"), n === "d" && t.getAttribute("d") && (o = `path(${t.getAttribute("d")})`), r.setProperty(n, o, s.getPropertyPriority(n));
631
+ });
632
+ }
633
+ function zt(e, t) {
634
+ h(e, HTMLTextAreaElement) && (t.innerHTML = e.value), h(e, HTMLInputElement) && t.setAttribute("value", e.value);
635
+ }
636
+ function qt(e, t) {
637
+ if (h(e, HTMLSelectElement)) {
638
+ const i = t, r = Array.from(i.children).find((s) => e.value === s.getAttribute("value"));
639
+ r && r.setAttribute("selected", "");
640
+ }
641
+ }
642
+ function Wt(e, t, i) {
643
+ return h(t, Element) && (jt(e, t, i), At(e, t, i), zt(e, t), qt(e, t)), t;
644
+ }
645
+ async function Vt(e, t) {
646
+ const i = e.querySelectorAll ? e.querySelectorAll("use") : [];
647
+ if (i.length === 0)
648
+ return e;
649
+ const r = {};
650
+ for (let n = 0; n < i.length; n++) {
651
+ const a = i[n].getAttribute("xlink:href");
652
+ if (a) {
653
+ const l = e.querySelector(a), c = document.querySelector(a);
654
+ !l && c && !r[a] && (r[a] = await C(c, t, !0));
655
+ }
656
+ }
657
+ const s = Object.values(r);
658
+ if (s.length) {
659
+ const n = "http://www.w3.org/1999/xhtml", o = document.createElementNS(n, "svg");
660
+ o.setAttribute("xmlns", n), o.style.position = "absolute", o.style.width = "0", o.style.height = "0", o.style.overflow = "hidden", o.style.display = "none";
661
+ const a = document.createElementNS(n, "defs");
662
+ o.appendChild(a);
663
+ for (let l = 0; l < s.length; l++)
664
+ a.appendChild(s[l]);
665
+ e.appendChild(o);
666
+ }
667
+ return e;
668
+ }
669
+ async function C(e, t, i) {
670
+ return !i && t.filter && !t.filter(e) ? null : Promise.resolve(e).then((r) => Ot(r, t)).then((r) => Bt(e, r, t)).then((r) => Wt(e, r, t)).then((r) => Vt(r, t));
671
+ }
672
+ const X = /url\((['"]?)([^'"]+?)\1\)/g, Nt = /url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g, Yt = /src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;
673
+ function Xt(e) {
674
+ const t = e.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
675
+ return new RegExp(`(url\\(['"]?)(${t})(['"]?\\))`, "g");
676
+ }
677
+ function Gt(e) {
678
+ const t = [];
679
+ return e.replace(X, (i, r, s) => (t.push(s), i)), t.filter((i) => !R(i));
680
+ }
681
+ async function Kt(e, t, i, r, s) {
682
+ try {
683
+ const n = i ? xt(t, i) : t, o = T(t);
684
+ let a;
685
+ return s || (a = await $(n, o, r)), e.replace(Xt(t), `$1${a}$3`);
686
+ } catch {
687
+ }
688
+ return e;
689
+ }
690
+ function Jt(e, { preferredFontFormat: t }) {
691
+ return t ? e.replace(Yt, (i) => {
692
+ for (; ; ) {
693
+ const [r, , s] = Nt.exec(i) || [];
694
+ if (!s)
695
+ return "";
696
+ if (s === t)
697
+ return `src: ${r};`;
698
+ }
699
+ }) : e;
700
+ }
701
+ function G(e) {
702
+ return e.search(X) !== -1;
703
+ }
704
+ async function K(e, t, i) {
705
+ if (!G(e))
706
+ return e;
707
+ const r = Jt(e, i);
708
+ return Gt(r).reduce((n, o) => n.then((a) => Kt(a, o, t, i)), Promise.resolve(r));
709
+ }
710
+ async function g(e, t, i) {
711
+ var r;
712
+ const s = (r = t.style) === null || r === void 0 ? void 0 : r.getPropertyValue(e);
713
+ if (s) {
714
+ const n = await K(s, null, i);
715
+ return t.style.setProperty(e, n, t.style.getPropertyPriority(e)), !0;
716
+ }
717
+ return !1;
718
+ }
719
+ async function Qt(e, t) {
720
+ await g("background", e, t) || await g("background-image", e, t), await g("mask", e, t) || await g("-webkit-mask", e, t) || await g("mask-image", e, t) || await g("-webkit-mask-image", e, t);
721
+ }
722
+ async function Zt(e, t) {
723
+ const i = h(e, HTMLImageElement);
724
+ if (!(i && !R(e.src)) && !(h(e, SVGImageElement) && !R(e.href.baseVal)))
725
+ return;
726
+ const r = i ? e.src : e.href.baseVal, s = await $(r, T(r), t);
727
+ await new Promise((n, o) => {
728
+ e.onload = n, e.onerror = t.onImageErrorHandler ? (...l) => {
729
+ try {
730
+ n(t.onImageErrorHandler(...l));
731
+ } catch (c) {
732
+ o(c);
733
+ }
734
+ } : o;
735
+ const a = e;
736
+ a.decode && (a.decode = n), a.loading === "lazy" && (a.loading = "eager"), i ? (e.srcset = "", e.src = s) : e.href.baseVal = s;
737
+ });
738
+ }
739
+ async function te(e, t) {
740
+ const r = p(e.childNodes).map((s) => J(s, t));
741
+ await Promise.all(r).then(() => e);
742
+ }
743
+ async function J(e, t) {
744
+ h(e, Element) && (await Qt(e, t), await Zt(e, t), await te(e, t));
745
+ }
746
+ function ee(e, t) {
747
+ const { style: i } = e;
748
+ t.backgroundColor && (i.backgroundColor = t.backgroundColor), t.width && (i.width = `${t.width}px`), t.height && (i.height = `${t.height}px`);
749
+ const r = t.style;
750
+ return r != null && Object.keys(r).forEach((s) => {
751
+ i[s] = r[s];
752
+ }), e;
753
+ }
754
+ const F = {};
755
+ async function O(e) {
756
+ let t = F[e];
757
+ if (t != null)
758
+ return t;
759
+ const r = await (await fetch(e)).text();
760
+ return t = { url: e, cssText: r }, F[e] = t, t;
761
+ }
762
+ async function U(e, t) {
763
+ let i = e.cssText;
764
+ const r = /url\(["']?([^"')]+)["']?\)/g, n = (i.match(/url\([^)]+\)/g) || []).map(async (o) => {
765
+ let a = o.replace(r, "$1");
766
+ return a.startsWith("https://") || (a = new URL(a, e.url).href), N(a, t.fetchRequestInit, ({ result: l }) => (i = i.replace(o, `url(${l})`), [o, l]));
767
+ });
768
+ return Promise.all(n).then(() => i);
769
+ }
770
+ function B(e) {
771
+ if (e == null)
772
+ return [];
773
+ const t = [], i = /(\/\*[\s\S]*?\*\/)/gi;
774
+ let r = e.replace(i, "");
775
+ const s = new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})", "gi");
776
+ for (; ; ) {
777
+ const l = s.exec(r);
778
+ if (l === null)
779
+ break;
780
+ t.push(l[0]);
781
+ }
782
+ r = r.replace(s, "");
783
+ const n = /@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi, o = "((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})", a = new RegExp(o, "gi");
784
+ for (; ; ) {
785
+ let l = n.exec(r);
786
+ if (l === null) {
787
+ if (l = a.exec(r), l === null)
788
+ break;
789
+ n.lastIndex = a.lastIndex;
790
+ } else
791
+ a.lastIndex = n.lastIndex;
792
+ t.push(l[0]);
793
+ }
794
+ return t;
795
+ }
796
+ async function ie(e, t) {
797
+ const i = [], r = [];
798
+ return e.forEach((s) => {
799
+ if ("cssRules" in s)
800
+ try {
801
+ p(s.cssRules || []).forEach((n, o) => {
802
+ if (n.type === CSSRule.IMPORT_RULE) {
803
+ let a = o + 1;
804
+ const l = n.href, c = O(l).then((u) => U(u, t)).then((u) => B(u).forEach((L) => {
805
+ try {
806
+ s.insertRule(L, L.startsWith("@import") ? a += 1 : s.cssRules.length);
807
+ } catch (tt) {
808
+ console.error("Error inserting rule from remote css", {
809
+ rule: L,
810
+ error: tt
811
+ });
812
+ }
813
+ })).catch((u) => {
814
+ console.error("Error loading remote css", u.toString());
815
+ });
816
+ r.push(c);
817
+ }
818
+ });
819
+ } catch (n) {
820
+ const o = e.find((a) => a.href == null) || document.styleSheets[0];
821
+ s.href != null && r.push(O(s.href).then((a) => U(a, t)).then((a) => B(a).forEach((l) => {
822
+ o.insertRule(l, o.cssRules.length);
823
+ })).catch((a) => {
824
+ console.error("Error loading remote stylesheet", a);
825
+ })), console.error("Error inlining remote css file", n);
826
+ }
827
+ }), Promise.all(r).then(() => (e.forEach((s) => {
828
+ if ("cssRules" in s)
829
+ try {
830
+ p(s.cssRules || []).forEach((n) => {
831
+ i.push(n);
832
+ });
833
+ } catch (n) {
834
+ console.error(`Error while reading CSS rules from ${s.href}`, n);
835
+ }
836
+ }), i));
837
+ }
838
+ function re(e) {
839
+ return e.filter((t) => t.type === CSSRule.FONT_FACE_RULE).filter((t) => G(t.style.getPropertyValue("src")));
840
+ }
841
+ async function se(e, t) {
842
+ if (e.ownerDocument == null)
843
+ throw new Error("Provided element is not within a Document");
844
+ const i = p(e.ownerDocument.styleSheets), r = await ie(i, t);
845
+ return re(r);
846
+ }
847
+ function Q(e) {
848
+ return e.trim().replace(/["']/g, "");
849
+ }
850
+ function ne(e) {
851
+ const t = /* @__PURE__ */ new Set();
852
+ function i(r) {
853
+ (r.style.fontFamily || getComputedStyle(r).fontFamily).split(",").forEach((n) => {
854
+ t.add(Q(n));
855
+ }), Array.from(r.children).forEach((n) => {
856
+ n instanceof HTMLElement && i(n);
857
+ });
858
+ }
859
+ return i(e), t;
860
+ }
861
+ async function oe(e, t) {
862
+ const i = await se(e, t), r = ne(e);
863
+ return (await Promise.all(i.filter((n) => r.has(Q(n.style.fontFamily))).map((n) => {
864
+ const o = n.parentStyleSheet ? n.parentStyleSheet.href : null;
865
+ return K(n.cssText, o, t);
866
+ }))).join(`
867
+ `);
868
+ }
869
+ async function ae(e, t) {
870
+ const i = t.fontEmbedCSS != null ? t.fontEmbedCSS : t.skipFonts ? null : await oe(e, t);
871
+ if (i) {
872
+ const r = document.createElement("style"), s = document.createTextNode(i);
873
+ r.appendChild(s), e.firstChild ? e.insertBefore(r, e.firstChild) : e.appendChild(r);
874
+ }
875
+ }
876
+ async function le(e, t = {}) {
877
+ const { width: i, height: r } = V(e, t), s = await C(e, t, !0);
878
+ return await ae(s, t), await J(s, t), ee(s, t), await Ct(s, i, r);
879
+ }
880
+ async function ce(e, t = {}) {
881
+ const { width: i, height: r } = V(e, t), s = await le(e, t), n = await E(s), o = document.createElement("canvas"), a = o.getContext("2d"), l = t.pixelRatio || vt(), c = t.canvasWidth || i, u = t.canvasHeight || r;
882
+ return o.width = c * l, o.height = u * l, t.skipAutoScale || St(o), o.style.width = `${c}`, o.style.height = `${u}`, t.backgroundColor && (a.fillStyle = t.backgroundColor, a.fillRect(0, 0, o.width, o.height)), a.drawImage(n, 0, 0, o.width, o.height), o;
883
+ }
884
+ async function he(e, t = {}) {
885
+ return (await ce(e, t)).toDataURL();
886
+ }
887
+ async function de(e = []) {
888
+ const t = ue(e);
889
+ try {
890
+ const i = await he(document.body, {
891
+ cacheBust: !0,
892
+ skipAutoScale: !1,
893
+ filter: (r) => !(r instanceof HTMLElement && r.id === "mtb-widget-host")
894
+ });
895
+ return me(i);
896
+ } catch {
897
+ return null;
898
+ } finally {
899
+ t?.remove();
900
+ }
901
+ }
902
+ function ue(e) {
903
+ if (e.length === 0) return null;
904
+ const t = document.createElement("div");
905
+ t.setAttribute("data-mtb-capture-annotations", "true"), t.setAttribute("aria-hidden", "true"), t.style.cssText = "position:fixed;inset:0;pointer-events:none;z-index:2147483645;";
906
+ for (const [i, r] of e.entries())
907
+ r.type === "pin" ? t.appendChild(pe(r, i + 1)) : r.type === "draw" && r.drawPath && t.appendChild(fe(r.drawPath));
908
+ return document.body.appendChild(t), t;
909
+ }
910
+ function pe(e, t) {
911
+ const i = document.createElement("div");
912
+ return i.textContent = String(t), i.style.cssText = [
913
+ "position:fixed",
914
+ `left:${e.x}px`,
915
+ `top:${e.y}px`,
916
+ "width:22px",
917
+ "height:22px",
918
+ "border-radius:50% 50% 50% 2px",
919
+ "background:#059669",
920
+ "border:2px solid #fff",
921
+ "display:flex",
922
+ "align-items:center",
923
+ "justify-content:center",
924
+ 'font:700 10px -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif',
925
+ "color:#fff",
926
+ "box-shadow:0 2px 8px rgba(5,150,105,0.45)",
927
+ "transform:translate(-50%,-50%)"
928
+ ].join(";"), i;
929
+ }
930
+ function fe(e) {
931
+ const t = document.createElementNS("http://www.w3.org/2000/svg", "svg");
932
+ t.setAttribute("width", "100%"), t.setAttribute("height", "100%"), t.setAttribute("viewBox", `0 0 ${window.innerWidth} ${window.innerHeight}`), t.style.cssText = "position:fixed;inset:0;width:100%;height:100%;overflow:visible;";
933
+ const i = document.createElementNS("http://www.w3.org/2000/svg", "path");
934
+ return i.setAttribute("d", e), i.setAttribute("fill", "none"), i.setAttribute("stroke", "#059669"), i.setAttribute("stroke-width", "3.5"), i.setAttribute("stroke-linecap", "round"), i.setAttribute("stroke-linejoin", "round"), i.setAttribute("filter", "drop-shadow(0 1px 2px rgba(5,150,105,0.35))"), t.appendChild(i), t;
935
+ }
936
+ function me(e) {
937
+ const [t, i] = e.split(","), r = t.match(/:(.*?);/)?.[1] ?? "image/png", s = atob(i), n = new Uint8Array(s.length);
938
+ for (let o = 0; o < s.length; o++)
939
+ n[o] = s.charCodeAt(o);
940
+ return new Blob([n], { type: r });
941
+ }
942
+ class be {
943
+ constructor() {
944
+ this.listeners = /* @__PURE__ */ new Set(), this.originalOnError = null, this.rejectionHandler = null, this.hooked = !1;
945
+ }
946
+ subscribe(t) {
947
+ return this.listeners.add(t), this.hook(), () => {
948
+ this.listeners.delete(t), this.listeners.size === 0 && this.unhook();
949
+ };
950
+ }
951
+ hook() {
952
+ this.hooked || (this.hooked = !0, this.originalOnError = window.onerror, window.onerror = (t, i, r, s, n) => (this.emit({ message: String(t), source: i, line: r, col: s, error: n }), this.originalOnError ? this.originalOnError.call(window, t, i, r, s, n) : !1), this.rejectionHandler = (t) => {
953
+ const i = t.reason instanceof Error ? t.reason.message : String(t.reason);
954
+ this.emit({ message: `Unhandled rejection: ${i}` });
955
+ }, window.addEventListener("unhandledrejection", this.rejectionHandler));
956
+ }
957
+ unhook() {
958
+ this.hooked && (this.hooked = !1, window.onerror = this.originalOnError, this.originalOnError = null, this.rejectionHandler && (window.removeEventListener("unhandledrejection", this.rejectionHandler), this.rejectionHandler = null));
959
+ }
960
+ emit(t) {
961
+ for (const i of this.listeners) i(t);
962
+ }
963
+ }
964
+ const Z = new be(), ge = 20;
965
+ class xe {
966
+ constructor() {
967
+ this.errors = [], this.unsubscribe = null;
968
+ }
969
+ start() {
970
+ this.unsubscribe || (this.unsubscribe = Z.subscribe((t) => this.record(t)));
971
+ }
972
+ record(t) {
973
+ const i = t.line != null ? ` (${t.line}:${t.col ?? 0})` : "";
974
+ this.addError(`${t.message}${i}`);
975
+ }
976
+ addError(t) {
977
+ this.errors.length >= ge || this.errors.includes(t) || this.errors.push(t);
978
+ }
979
+ getErrors() {
980
+ return [...this.errors];
981
+ }
982
+ stop() {
983
+ this.unsubscribe?.(), this.unsubscribe = null;
984
+ }
985
+ }
986
+ const we = 3, ye = 1e3, ke = /* @__PURE__ */ new Set([
987
+ "A",
988
+ "BUTTON",
989
+ "INPUT",
990
+ "SELECT",
991
+ "TEXTAREA",
992
+ "LABEL",
993
+ "SUMMARY",
994
+ "DETAILS"
995
+ ]), ve = /* @__PURE__ */ new Set([
996
+ "button",
997
+ "link",
998
+ "checkbox",
999
+ "radio",
1000
+ "tab",
1001
+ "menuitem",
1002
+ "option",
1003
+ "switch",
1004
+ "textbox",
1005
+ "combobox",
1006
+ "listbox",
1007
+ "slider",
1008
+ "spinbutton"
1009
+ ]), k = class k {
1010
+ constructor(t) {
1011
+ this.clickHistory = [], this.unsubscribeErrors = null, this.active = !1, this.errorCount = 0, this.deadClickCount = 0, this.cooldownUntil = 0, this.onFrustration = t, this.boundClickHandler = (i) => this.handleClick(i);
1012
+ }
1013
+ start() {
1014
+ this.active || (this.active = !0, document.addEventListener("click", this.boundClickHandler, !0), this.unsubscribeErrors = Z.subscribe((t) => {
1015
+ this.errorCount++;
1016
+ }));
1017
+ }
1018
+ stop() {
1019
+ this.active && (this.active = !1, document.removeEventListener("click", this.boundClickHandler, !0), this.unsubscribeErrors?.(), this.unsubscribeErrors = null, this.clickHistory = []);
1020
+ }
1021
+ handleClick(t) {
1022
+ const i = t.target;
1023
+ if (!i || this.isWidgetElement(i)) return;
1024
+ const r = Date.now();
1025
+ this.clickHistory.push({ target: i, time: r });
1026
+ const s = r - ye;
1027
+ if (this.clickHistory = this.clickHistory.filter((o) => o.time > s), this.clickHistory.filter((o) => o.target === i).length >= we) {
1028
+ this.clickHistory = [], this.emitHighPriority({
1029
+ signal: "rage_click",
1030
+ target: j(i),
1031
+ timestamp: r
1032
+ });
1033
+ return;
1034
+ }
1035
+ this.isInteractive(i) || (this.deadClickCount++, this.deadClickCount >= 3 && this.errorCount > 0 && (this.deadClickCount = 0, this.errorCount = 0, this.emitIfReady({
1036
+ signal: "dead_click",
1037
+ target: j(i),
1038
+ timestamp: r
1039
+ })));
1040
+ }
1041
+ isInteractive(t) {
1042
+ if (ke.has(t.tagName)) return !0;
1043
+ const i = t.getAttribute("role");
1044
+ return !!(i && ve.has(i) || t.hasAttribute("onclick") || t.hasAttribute("tabindex") || t.contentEditable === "true" || window.getComputedStyle(t).cursor === "pointer" || t.closest('a, button, [role="button"], [role="link"], label'));
1045
+ }
1046
+ isWidgetElement(t) {
1047
+ const i = document.getElementById("mtb-widget-host");
1048
+ return i ? i === t || i.contains(t) : !1;
1049
+ }
1050
+ emitIfReady(t) {
1051
+ const i = Date.now();
1052
+ i < this.cooldownUntil || (this.cooldownUntil = i + k.COOLDOWN_MS, this.onFrustration(t));
1053
+ }
1054
+ emitHighPriority(t) {
1055
+ this.cooldownUntil = Date.now() + k.COOLDOWN_MS, this.onFrustration(t);
1056
+ }
1057
+ };
1058
+ k.COOLDOWN_MS = 6e4;
1059
+ let A = k;
1060
+ function j(e) {
1061
+ const t = e.tagName.toLowerCase(), i = e.id ? `#${e.id}` : "", r = e.className && typeof e.className == "string" ? "." + e.className.trim().split(/\s+/).slice(0, 2).join(".") : "", s = e.textContent?.trim().slice(0, 30) ?? "";
1062
+ return `<${t}${i}${r}>${s ? ` "${s}"` : ""}`;
1063
+ }
1064
+ function Se() {
1065
+ return {
1066
+ page_url: window.location.href,
1067
+ user_agent: navigator.userAgent,
1068
+ browser: Ee(),
1069
+ os: Ce(),
1070
+ screen_width: window.screen.width,
1071
+ screen_height: window.screen.height
1072
+ };
1073
+ }
1074
+ function Ee() {
1075
+ const e = navigator.userAgent;
1076
+ return /Edg\//.test(e) ? `Edge ${e.match(/Edg\/(\S+)/)?.[1] ?? ""}` : /OPR\//.test(e) ? `Opera ${e.match(/OPR\/(\S+)/)?.[1] ?? ""}` : /Chrome\//.test(e) ? `Chrome ${e.match(/Chrome\/(\S+)/)?.[1] ?? ""}` : /Safari\//.test(e) && /Version\//.test(e) ? `Safari ${e.match(/Version\/(\S+)/)?.[1] ?? ""}` : /Firefox\//.test(e) ? `Firefox ${e.match(/Firefox\/(\S+)/)?.[1] ?? ""}` : "Unknown";
1077
+ }
1078
+ function Ce() {
1079
+ const e = navigator.userAgent;
1080
+ return /Windows NT 10/.test(e) ? "Windows 10/11" : /Windows NT/.test(e) ? "Windows" : /Mac OS X 10_15|macOS 1[56789]/.test(e) || /Mac OS X/.test(e) ? "macOS" : /Android/.test(e) ? `Android ${e.match(/Android (\d+)/)?.[1] ?? ""}` : /iPhone|iPad|iPod/.test(e) ? "iOS" : /Linux/.test(e) ? "Linux" : "Unknown";
1081
+ }
1082
+ const Le = "https://makethisbetter.dev/api/v1";
1083
+ class Me {
1084
+ constructor(t, i, r = 1e3) {
1085
+ this.projectKey = t, this.apiUrl = (i ?? Le).replace(/\/$/, ""), this.retryDelayMs = r;
1086
+ }
1087
+ async submitFeedback(t, i) {
1088
+ const r = new FormData();
1089
+ if (r.append("feedback[description]", t.description), r.append("feedback[page_url]", t.page_url), r.append("feedback[user_agent]", t.user_agent), r.append("feedback[browser]", t.browser), r.append("feedback[os]", t.os), r.append("feedback[screen_width]", String(t.screen_width)), r.append("feedback[screen_height]", String(t.screen_height)), r.append("feedback[console_errors]", JSON.stringify(t.console_errors)), r.append("feedback[annotations]", JSON.stringify(t.annotations)), t.target_element && r.append("feedback[target_element]", JSON.stringify(t.target_element)), t.user_id && r.append("feedback[user_id]", t.user_id), t.user_email && r.append("feedback[user_email]", t.user_email), t.user_name && r.append("feedback[user_name]", t.user_name), t.recording_events && t.recording_events.length > 0) {
1090
+ const s = JSON.stringify(t.recording_events), n = new Blob([s], { type: "application/json" });
1091
+ r.append("feedback[recording]", n, "recording.json"), r.append("feedback[recording_duration]", String(t.recording_duration ?? 0));
1092
+ }
1093
+ i && r.append("feedback[screenshot]", i, "screenshot.png"), await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks`, {
1094
+ method: "POST",
1095
+ headers: { "X-Project-Key": this.projectKey },
1096
+ body: r
1097
+ });
1098
+ }
1099
+ async fetchWithRetry(t, i, r = 1) {
1100
+ let s;
1101
+ try {
1102
+ s = await fetch(t, i);
1103
+ } catch (n) {
1104
+ if (r > 0)
1105
+ return await z(this.retryDelayMs), this.fetchWithRetry(t, i, r - 1);
1106
+ throw n;
1107
+ }
1108
+ if (s.ok) return s;
1109
+ if (s.status >= 500 && r > 0)
1110
+ return await z(this.retryDelayMs), this.fetchWithRetry(t, i, r - 1);
1111
+ throw new Error(`HTTP ${s.status}`);
1112
+ }
1113
+ }
1114
+ function z(e) {
1115
+ return e <= 0 ? Promise.resolve() : new Promise((t) => setTimeout(t, e));
1116
+ }
1117
+ function Re(e, t, i, r, s, n) {
1118
+ return {
1119
+ description: e,
1120
+ ...t,
1121
+ console_errors: i,
1122
+ annotations: r ? [r] : [],
1123
+ target_element: r?.targetSelector ? {
1124
+ selector: r.targetSelector,
1125
+ text: r.targetText ?? "",
1126
+ name: r.targetName ?? ""
1127
+ } : void 0,
1128
+ user_id: s?.id,
1129
+ user_email: s?.email,
1130
+ user_name: s?.name,
1131
+ recording_events: n?.events,
1132
+ recording_duration: n?.duration
1133
+ };
1134
+ }
1135
+ const Ae = {
1136
+ tab: "Feedback",
1137
+ toolbar: {
1138
+ markup: "Mark up",
1139
+ record: "Record",
1140
+ hint: "Click any element to annotate · drag to draw",
1141
+ hintRecord: "Recording your screen",
1142
+ exit: "Exit"
1143
+ },
1144
+ popup: {
1145
+ about: "About",
1146
+ placeholder: "Describe the issue or suggestion...",
1147
+ submit: "Submit",
1148
+ cancel: "Cancel",
1149
+ quickOptions: [
1150
+ { emoji: "🐛", label: "Something is broken" },
1151
+ { emoji: "💡", label: "I wish this worked differently" },
1152
+ { emoji: "🤔", label: "I don't understand this" },
1153
+ { emoji: "✨", label: "I have an idea" }
1154
+ ]
1155
+ },
1156
+ success: {
1157
+ title: "Thanks!",
1158
+ message: "Your feedback has been received.",
1159
+ close: "Close"
1160
+ },
1161
+ error: {
1162
+ submit: "Failed to submit. Please try again."
1163
+ },
1164
+ pet: {
1165
+ bubble: "Need help?"
1166
+ },
1167
+ frustration: {
1168
+ prompt: "Something not working? Tell us.",
1169
+ action: "Annotate",
1170
+ dismiss: "Dismiss"
1171
+ },
1172
+ annotation: {
1173
+ drawing: "Drawing",
1174
+ element: "element"
1175
+ },
1176
+ record: {
1177
+ stop: "Stop",
1178
+ timer_label: "Recording",
1179
+ max_reached: "Maximum recording time reached"
1180
+ }
1181
+ }, Te = {
1182
+ tab: "反馈",
1183
+ toolbar: {
1184
+ markup: "标注",
1185
+ record: "录屏",
1186
+ hint: "点击任意元素进行标注 · 拖拽可自由绘制",
1187
+ hintRecord: "正在录制屏幕",
1188
+ exit: "退出"
1189
+ },
1190
+ popup: {
1191
+ about: "关于",
1192
+ placeholder: "描述问题或建议...",
1193
+ submit: "提交",
1194
+ cancel: "取消",
1195
+ quickOptions: [
1196
+ { emoji: "🐛", label: "这里有问题" },
1197
+ { emoji: "💡", label: "我希望它能更好用" },
1198
+ { emoji: "🤔", label: "我看不懂这里" },
1199
+ { emoji: "✨", label: "我有个想法" }
1200
+ ]
1201
+ },
1202
+ success: {
1203
+ title: "感谢!",
1204
+ message: "您的反馈已收到。",
1205
+ close: "关闭"
1206
+ },
1207
+ error: {
1208
+ submit: "提交失败,请重试。"
1209
+ },
1210
+ pet: {
1211
+ bubble: "需要帮助吗?"
1212
+ },
1213
+ frustration: {
1214
+ prompt: "遇到问题了?告诉我们。",
1215
+ action: "标注",
1216
+ dismiss: "关闭"
1217
+ },
1218
+ annotation: {
1219
+ drawing: "绘制",
1220
+ element: "元素"
1221
+ },
1222
+ record: {
1223
+ stop: "停止",
1224
+ timer_label: "录制中",
1225
+ max_reached: "已达到最大录制时长"
1226
+ }
1227
+ }, w = {
1228
+ en: Ae,
1229
+ "zh-CN": Te
1230
+ };
1231
+ function $e(e) {
1232
+ if (w[e]) return w[e];
1233
+ const t = e.split("-")[0];
1234
+ return w[t] ? w[t] : w.en;
1235
+ }
1236
+ const Pe = 60, De = "https://cdn.jsdelivr.net/npm/rrweb@2/dist/rrweb.min.js";
1237
+ let v = null;
1238
+ function _e() {
1239
+ return v || (v = Ie().catch(() => He()), v);
1240
+ }
1241
+ async function Ie() {
1242
+ return (await import("rrweb")).record;
1243
+ }
1244
+ function He() {
1245
+ return new Promise((e, t) => {
1246
+ const i = globalThis;
1247
+ if (i.rrweb?.record) {
1248
+ e(i.rrweb.record);
1249
+ return;
1250
+ }
1251
+ const r = document.createElement("script");
1252
+ r.src = De, r.onload = () => {
1253
+ const s = globalThis;
1254
+ s.rrweb?.record ? e(s.rrweb.record) : t(new Error("rrweb global not found after script load"));
1255
+ }, r.onerror = () => t(new Error("Failed to load rrweb from CDN")), document.head.appendChild(r);
1256
+ });
1257
+ }
1258
+ class Fe {
1259
+ constructor(t, i) {
1260
+ this.events = [], this.stopFn = null, this.startedAt = 0, this.timer = null, this.clickHandler = null, this.stopped = !1, this.shadow = t, this.onMaxReached = i;
1261
+ }
1262
+ async start() {
1263
+ const t = await _e();
1264
+ this.startedAt = Date.now(), this.stopped = !1, this.stopFn = t({
1265
+ emit: (i) => {
1266
+ this.stopped || this.events.push(i);
1267
+ }
1268
+ }), this.clickHandler = (i) => {
1269
+ this.showClickRipple(i.clientX, i.clientY), t.addCustomEvent?.("mtb-click", {
1270
+ x: i.clientX,
1271
+ y: i.clientY,
1272
+ target: i.target instanceof HTMLElement ? i.target.tagName : ""
1273
+ });
1274
+ }, document.addEventListener("click", this.clickHandler, !0), this.timer = setTimeout(() => {
1275
+ this.onMaxReached?.();
1276
+ }, Pe * 1e3);
1277
+ }
1278
+ stop() {
1279
+ return this.stopped = !0, this.stopFn?.(), this.stopFn = null, this.cleanupTimer(), this.cleanupClickHandler(), {
1280
+ events: this.events,
1281
+ duration: this.getDuration()
1282
+ };
1283
+ }
1284
+ getDuration() {
1285
+ return this.startedAt === 0 ? 0 : Math.round((Date.now() - this.startedAt) / 1e3);
1286
+ }
1287
+ destroy() {
1288
+ this.stopped = !0, this.stopFn?.(), this.stopFn = null, this.cleanupTimer(), this.cleanupClickHandler(), this.events = [], this.startedAt = 0;
1289
+ }
1290
+ cleanupTimer() {
1291
+ this.timer && (clearTimeout(this.timer), this.timer = null);
1292
+ }
1293
+ cleanupClickHandler() {
1294
+ this.clickHandler && (document.removeEventListener("click", this.clickHandler, !0), this.clickHandler = null);
1295
+ }
1296
+ showClickRipple(t, i) {
1297
+ const r = this.shadow.el("div", "mtb-click-ripple");
1298
+ r.style.left = `${t}px`, r.style.top = `${i}px`, this.shadow.append(r), r.addEventListener("animationend", () => r.remove());
1299
+ }
1300
+ }
1301
+ class Oe {
1302
+ constructor(t, i, r, s) {
1303
+ this.intervalId = null, this.getDuration = r, this.el = t.el("div", "mtb-record-bar"), this.el.innerHTML = `
1304
+ <span class="mtb-record-dot"></span>
1305
+ <span class="mtb-record-timer">00:00</span>
1306
+ <button class="mtb-record-stop" type="button">${i.record.stop}</button>
1307
+ `, t.append(this.el), this.timerEl = this.el.querySelector(".mtb-record-timer"), this.el.querySelector(".mtb-record-stop").addEventListener("click", s), this.intervalId = setInterval(() => this.updateTimer(), 1e3);
1308
+ }
1309
+ updateTimer() {
1310
+ const t = this.getDuration(), i = String(Math.floor(t / 60)).padStart(2, "0"), r = String(t % 60).padStart(2, "0");
1311
+ this.timerEl.textContent = `${i}:${r}`;
1312
+ }
1313
+ destroy() {
1314
+ this.intervalId && (clearInterval(this.intervalId), this.intervalId = null), this.el.remove();
1315
+ }
1316
+ }
1317
+ class q {
1318
+ constructor(t) {
1319
+ this.tab = null, this.pet = null, this.toolbar = null, this.session = null, this.popup = null, this.success = null, this.frustrationPrompt = null, this.frustrationDetector = null, this.mode = "idle", this.currentAnnotation = null, this.recordSession = null, this.recordBar = null, this.currentRecording = null, this.config = t, this.messages = $e(t.locale ?? "en"), this.apiClient = new Me(t.projectKey, t.apiUrl), this.consoleCollector = new xe(), this.consoleCollector.start(), this.buildUI(), t.frustrationDetection !== !1 && (this.frustrationDetector = new A(() => this.handleFrustration()), this.frustrationDetector.start());
1320
+ }
1321
+ buildUI() {
1322
+ this.shadow = new it(this.config.theme ?? "auto"), (this.config.entryMode ?? "button") === "pet" ? this.pet = new st(this.shadow, this.messages, () => this.handleTabClick()) : this.tab = new rt(
1323
+ this.shadow,
1324
+ this.messages,
1325
+ this.config.position ?? "right",
1326
+ () => this.handleTabClick()
1327
+ );
1328
+ }
1329
+ handleTabClick() {
1330
+ this.mode === "idle" ? (this.dismissFrustrationPrompt(), this.enterAnnotationMode()) : this.exitAll();
1331
+ }
1332
+ handleFrustration() {
1333
+ this.mode !== "idle" || this.frustrationPrompt || (this.frustrationPrompt = new ot(this.shadow, this.messages, {
1334
+ onTell: () => {
1335
+ this.dismissFrustrationPrompt(), this.enterAnnotationMode();
1336
+ },
1337
+ onDismiss: () => this.dismissFrustrationPrompt()
1338
+ }));
1339
+ }
1340
+ dismissFrustrationPrompt() {
1341
+ this.frustrationPrompt?.destroy(), this.frustrationPrompt = null;
1342
+ }
1343
+ enterAnnotationMode() {
1344
+ this.mode = "annotating", this.tab?.setActive(!0), this.pet?.setActive(!0), this.toolbar = new at(
1345
+ this.shadow,
1346
+ this.messages,
1347
+ () => this.exitAll(),
1348
+ (t) => this.handleToolbarModeChange(t)
1349
+ ), this.session = new P(this.shadow, this.messages, (t, i) => {
1350
+ this.currentAnnotation = t, this.showPopup(t.x, t.y, i);
1351
+ });
1352
+ }
1353
+ handleToolbarModeChange(t) {
1354
+ t === "record" ? this.enterRecordingMode() : (this.exitRecordingMode(), this.session || (this.session = new P(this.shadow, this.messages, (i, r) => {
1355
+ this.currentAnnotation = i, this.showPopup(i.x, i.y, r);
1356
+ })), this.mode = "annotating");
1357
+ }
1358
+ async enterRecordingMode() {
1359
+ this.mode = "recording", this.session?.destroy(), this.session = null, this.recordSession = new Fe(this.shadow, () => this.stopRecording()), this.recordBar = new Oe(
1360
+ this.shadow,
1361
+ this.messages,
1362
+ () => this.recordSession?.getDuration() ?? 0,
1363
+ () => this.stopRecording()
1364
+ ), await this.recordSession.start();
1365
+ }
1366
+ stopRecording() {
1367
+ this.recordSession && (this.currentRecording = this.recordSession.stop(), this.exitRecordingMode(), this.showPopup(
1368
+ window.innerWidth / 2,
1369
+ window.innerHeight / 2,
1370
+ this.messages.record.timer_label
1371
+ ));
1372
+ }
1373
+ exitRecordingMode() {
1374
+ this.recordSession?.destroy(), this.recordSession = null, this.recordBar?.destroy(), this.recordBar = null;
1375
+ }
1376
+ showPopup(t, i, r) {
1377
+ this.mode = "popup", this.session?.dismissInteraction(), this.popup = new mt(this.shadow, {
1378
+ targetName: r,
1379
+ x: t,
1380
+ y: i,
1381
+ messages: this.messages,
1382
+ onSubmit: (s) => this.handleSubmit(s),
1383
+ onClose: () => this.exitAll()
1384
+ });
1385
+ }
1386
+ async handleSubmit(t) {
1387
+ if (!this.popup) return;
1388
+ this.popup.setLoading(!0);
1389
+ const i = this.currentAnnotation, r = this.currentRecording ?? void 0, [s, n] = await Promise.all([
1390
+ de(i ? [i] : []),
1391
+ Promise.resolve(Se())
1392
+ ]), o = Re(
1393
+ t,
1394
+ n,
1395
+ this.consoleCollector.getErrors(),
1396
+ i,
1397
+ this.config.user,
1398
+ r
1399
+ );
1400
+ try {
1401
+ await this.apiClient.submitFeedback(o, s), this.popup?.destroy(), this.popup = null, this.session?.destroy(), this.session = null, this.currentRecording = null, this.showSuccess();
1402
+ } catch {
1403
+ this.popup?.setLoading(!1), this.popup?.setError(this.messages.error.submit);
1404
+ }
1405
+ }
1406
+ showSuccess() {
1407
+ this.mode = "idle", this.tab?.setActive(!1), this.pet?.setActive(!1), this.success = new gt(this.shadow, this.messages, () => {
1408
+ this.success?.destroy(), this.success = null;
1409
+ });
1410
+ }
1411
+ exitAll() {
1412
+ this.mode = "idle", this.tab?.setActive(!1), this.pet?.setActive(!1), this.toolbar?.destroy(), this.toolbar = null, this.session?.destroy(), this.session = null, this.popup?.destroy(), this.popup = null, this.currentAnnotation = null, this.currentRecording = null, this.exitRecordingMode();
1413
+ }
1414
+ destroy() {
1415
+ this.exitAll(), this.consoleCollector.stop(), this.frustrationDetector?.stop(), this.dismissFrustrationPrompt(), this.success?.destroy(), this.tab?.destroy(), this.pet?.destroy(), this.exitRecordingMode(), this.shadow.destroy();
1416
+ }
1417
+ }
1418
+ let f = null;
1419
+ const Ue = {
1420
+ init(e) {
1421
+ f && (f.destroy(), f = null), document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", () => {
1422
+ f = new q(e);
1423
+ }) : f = new q(e);
1424
+ },
1425
+ destroy() {
1426
+ f?.destroy(), f = null;
1427
+ }
1428
+ };
1429
+ typeof window < "u" && (window.MakeThisBetter = Ue);
1430
+ export {
1431
+ Ue as MakeThisBetter
1432
+ };
1433
+ //# sourceMappingURL=makethisbetter.esm.js.map