@qaiddev/thumbs-embed 1.7.0 → 1.8.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 +32 -21
- package/dist/chunks/{annotate-CMq95aXG.js → annotate-D-o8xCV9.js} +23 -17
- package/dist/chunks/annotate-D-o8xCV9.js.map +1 -0
- package/dist/chunks/dom-DvdtcUS8.js +17 -0
- package/dist/chunks/dom-DvdtcUS8.js.map +1 -0
- package/dist/chunks/{loader-CYM1rxDH.js → loader-DHtXHt1z.js} +172 -156
- package/dist/chunks/loader-DHtXHt1z.js.map +1 -0
- package/dist/chunks/modal-CTbqN-h9.js +213 -0
- package/dist/chunks/modal-CTbqN-h9.js.map +1 -0
- package/dist/chunks/{recording-BVFd_ryf.js → recording-Dx8AX-BC.js} +103 -98
- package/dist/chunks/recording-Dx8AX-BC.js.map +1 -0
- package/dist/chunks/{screenshot-BkOCLuS2.js → screenshot-DYOKg2bS.js} +2 -2
- package/dist/chunks/{screenshot-BkOCLuS2.js.map → screenshot-DYOKg2bS.js.map} +1 -1
- package/dist/chunks/{targeting-1pK6nJI9.js → targeting-Dz6z1BYl.js} +2 -2
- package/dist/chunks/{targeting-1pK6nJI9.js.map → targeting-Dz6z1BYl.js.map} +1 -1
- package/dist/chunks/{video-BOYqf2Im.js → video-Bd_29-rK.js} +76 -71
- package/dist/chunks/video-Bd_29-rK.js.map +1 -0
- package/dist/embed.d.ts +11 -0
- package/dist/icons.d.ts +2 -0
- package/dist/index.js +523 -418
- package/dist/index.js.map +1 -1
- package/dist/loader.js +1 -1
- package/dist/modal.d.ts +14 -4
- package/dist/qaid.umd.cjs +12 -36
- package/dist/qaid.umd.cjs.map +1 -1
- package/dist/recording.d.ts +6 -0
- package/dist/screenshot.d.ts +1 -1
- package/dist/types.d.ts +14 -2
- package/dist/video-capture.d.ts +6 -0
- package/package.json +1 -1
- package/dist/chunks/annotate-CMq95aXG.js.map +0 -1
- package/dist/chunks/loader-CYM1rxDH.js.map +0 -1
- package/dist/chunks/modal-Br5x7m6f.js +0 -150
- package/dist/chunks/modal-Br5x7m6f.js.map +0 -1
- package/dist/chunks/recording-BVFd_ryf.js.map +0 -1
- package/dist/chunks/video-BOYqf2Im.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -2,40 +2,42 @@ const V = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none"
|
|
|
2
2
|
<path stroke-linecap="round" stroke-linejoin="round" d="M14 10h4.764a2 2 0 011.789 2.894l-3.5 7A2 2 0 0115.263 21h-4.017c-.163 0-.326-.02-.485-.06L7 20m7-10V5a2 2 0 00-2-2h-.095c-.5 0-.905.405-.905.905 0 .714-.211 1.412-.608 2.006L7 11v9m7-10h-2M7 20H5a2 2 0 01-2-2v-6a2 2 0 012-2h2.5"/>
|
|
3
3
|
</svg>`, N = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
4
4
|
<path stroke-linecap="round" stroke-linejoin="round" d="M10 14H5.236a2 2 0 01-1.789-2.894l3.5-7A2 2 0 018.737 3h4.018a2 2 0 01.485.06l3.76.94m-7 10v5a2 2 0 002 2h.095c.5 0 .905-.405.905-.905 0-.714.211-1.412.608-2.006L17 13V4m-7 10h2m5-10h2a2 2 0 012 2v6a2 2 0 01-2 2h-2.5"/>
|
|
5
|
-
</svg>`,
|
|
5
|
+
</svg>`, Jt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
6
6
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 10.5l4.72-4.72a.75.75 0 011.28.53v11.38a.75.75 0 01-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25h-9A2.25 2.25 0 002.25 7.5v9a2.25 2.25 0 002.25 2.25z"/>
|
|
7
|
-
</svg>`,
|
|
7
|
+
</svg>`, wt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
8
8
|
<path stroke-linecap="round" stroke-linejoin="round" d="M8 10h8M8 14h5m-9 6l3.5-3.5H18a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v14z"/>
|
|
9
|
-
</svg>`,
|
|
9
|
+
</svg>`, Zt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
10
10
|
<rect x="4" y="6" width="16" height="12" rx="1" stroke-linejoin="round"/>
|
|
11
|
-
</svg>`,
|
|
11
|
+
</svg>`, te = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
12
12
|
<path stroke-linecap="round" stroke-linejoin="round" d="M5 19L19 5m0 0h-8m8 0v8"/>
|
|
13
|
-
</svg>`,
|
|
13
|
+
</svg>`, ee = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
14
14
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 20h9M16.5 3.5a2.121 2.121 0 013 3L7 19l-4 1 1-4L16.5 3.5z"/>
|
|
15
|
-
</svg>`,
|
|
15
|
+
</svg>`, ie = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
16
16
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3s6 6.4 6 10a6 6 0 01-12 0c0-3.6 6-10 6-10z"/>
|
|
17
|
-
</svg>`,
|
|
17
|
+
</svg>`, oe = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
18
18
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 14L4 9l5-5M4 9h11a5 5 0 010 10h-4"/>
|
|
19
|
-
</svg>`,
|
|
19
|
+
</svg>`, kt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
20
20
|
<path stroke-linecap="round" stroke-linejoin="round" d="M20 6L9 17l-5-5"/>
|
|
21
|
-
</svg>`,
|
|
21
|
+
</svg>`, ne = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
22
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v8m0 4h.01"/>
|
|
23
|
+
</svg>`, se = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
22
24
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 6l12 12M18 6L6 18"/>
|
|
23
|
-
</svg>`, ee = "button{cursor:pointer}.qaid-buttons{display:flex;gap:.5rem}.qaid-buttons.qaid-vertical{flex-direction:column}.qaid-buttons.qaid-auto-container{position:fixed;z-index:50}.qaid-buttons.qaid-auto-container.qaid-bottom-right{bottom:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-bottom-left{bottom:1rem;left:1rem}.qaid-buttons.qaid-auto-container.qaid-top-right{top:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-top-left{top:1rem;left:1rem}.qaid-buttons.qaid-incognito{opacity:0;transition:opacity .2s ease-in-out}.qaid-buttons.qaid-incognito:hover{opacity:1}.qaid-buttons.qaid-dismissed{display:none!important}.qaid-dismiss-btn{width:20px;height:20px;padding:0;border:none;border-radius:50%;background:#0006;color:#fff;display:flex;align-items:center;justify-content:center;align-self:center;opacity:0;transition:opacity .15s,background .15s;cursor:pointer;pointer-events:auto;-webkit-appearance:none;appearance:none}.qaid-dismiss-btn:hover{background:#0009}.qaid-buttons:hover .qaid-dismiss-btn{opacity:1}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:1rem;font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;inset:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;inset:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.3) 70%,rgba(0,0,0,.6) 100%);z-index:41}.qaid-crosshair-h,.qaid-crosshair-v{position:fixed;pointer-events:none;z-index:42}.qaid-crosshair-h{left:0;right:0;height:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-crosshair-v{top:0;bottom:0;width:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-type-up .qaid-crosshair-h,.qaid-type-up .qaid-crosshair-v{background:color-mix(in srgb,var(--qaid-positive) 60%,transparent)}.qaid-highlight-box{position:fixed;top:0;left:0;pointer-events:none;z-index:41;display:none;border:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:2px;background:color-mix(in srgb,var(--qaid-negative) 8%,transparent);will-change:transform,width,height}.qaid-type-up .qaid-highlight-box{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent);background:color-mix(in srgb,var(--qaid-positive) 8%,transparent)}.qaid-scope{position:fixed;width:80px;height:80px;pointer-events:none;z-index:43;transform:translate(-50%,-50%)}.qaid-scope-ring{position:absolute;inset:10px;border:2px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)}.qaid-scope-ring-inner{position:absolute;inset:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6366f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;inset:0;z-index:45;background:#0000004d}.qaid-modal-container{position:fixed;z-index:50;display:flex;flex-direction:column;align-items:flex-start;max-height:calc(100vh - 32px);font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-modal-container.qaid-above{flex-direction:column-reverse}.qaid-modal-arrow{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;position:relative;align-self:flex-start}.qaid-modal-container.qaid-below .qaid-modal-arrow{border-bottom:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-container.qaid-above .qaid-modal-arrow{border-top:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5));width:var(--qaid-modal-width, 400px);max-width:calc(100vw - 32px);max-height:calc(100vh - 60px);overflow-y:auto}.qaid-modal-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}button.qaid-type-toggle{border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;flex-shrink:0;-webkit-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-type-static{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--qaid-marker, #6366f1);color:var(--qaid-marker-text, white)}.qaid-type-static svg{width:1.25rem;height:1.25rem}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:1.125rem;font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:.875rem}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:1rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:.875rem;font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:.75rem;font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0 0 auto;height:100vh;height:100dvh;display:flex;align-items:center;justify-content:center;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#0009;z-index:99998;animation:qaid-fadeIn .2s ease-out}@keyframes qaid-fadeIn{0%{opacity:0}to{opacity:1}}.qaid-video-preview-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px #00000080;width:560px;max-width:100%;max-height:100%;overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:1.125rem;font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;max-height:50vh;max-height:50dvh;object-fit:contain;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:.875rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:light-dark(#6b7280,#9ca3af)}.qaid-annotate{position:fixed;inset:0;z-index:2147483000;display:flex;flex-direction:column;gap:.75rem;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#000000d9;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px);animation:qaid-fadeIn .2s ease-out}.qaid-annotate-title{margin:0;font-size:1rem;font-weight:700;text-align:center;color:#f9fafb}.qaid-annotate-desc{margin:0;font-size:.8125rem;line-height:1.4;text-align:center;color:#f9fafbbf}.qaid-annotate-stage{flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;overflow:auto}.qaid-annotate-canvas{max-width:100%;max-height:100%;object-fit:contain;background:light-dark(#ffffff,#111827);border-radius:.5rem;box-shadow:0 10px 30px #00000080;touch-action:none;cursor:crosshair}.qaid-annotate-toolbar{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;justify-content:center;padding:.5rem .75rem;background:light-dark(#ffffff,#1f2937);border-radius:.75rem;box-shadow:0 10px 30px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5))}.qaid-annotate-tools,.qaid-annotate-actions{display:flex;gap:.375rem;align-items:center}button.qaid-annotate-tool,button.qaid-annotate-action{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;min-width:44px;min-height:44px;padding:0 .75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;background:light-dark(#f9fafb,#111827);color:light-dark(#1f2937,#f9fafb);font-family:inherit;font-size:.8125rem;font-weight:600;cursor:pointer;-webkit-appearance:none;appearance:none;transition:background-color .15s,color .15s,border-color .15s,filter .15s}button.qaid-annotate-tool svg,button.qaid-annotate-action svg{width:20px;height:20px}.qaid-annotate-colors{display:flex;gap:.25rem;align-items:center}button.qaid-annotate-swatch{width:28px;height:28px;min-width:28px;padding:0;border-radius:9999px;border:2px solid light-dark(#d1d5db,#4b5563);background:var(--qaid-swatch, #000);cursor:pointer;-webkit-appearance:none;appearance:none;transition:transform .1s,box-shadow .15s,border-color .15s}button.qaid-annotate-swatch:hover{transform:scale(1.12)}button.qaid-annotate-swatch[aria-pressed=true]{border-color:light-dark(#111827,#f9fafb);box-shadow:0 0 0 2px var(--qaid-swatch)}@media(forced-colors:active){button.qaid-annotate-swatch[aria-pressed=true]{outline:2px solid Highlight;outline-offset:1px}}button.qaid-annotate-tool:hover,button.qaid-annotate-action:hover{background:light-dark(#eef2ff,#312e81)}button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{background:var(--qaid-marker, #6366f1);color:var(--qaid-marker-text, #fff);border-color:var(--qaid-marker, #6366f1)}button.qaid-annotate-done:hover{filter:brightness(.9);background:var(--qaid-marker, #6366f1)}button.qaid-annotate-action:disabled{opacity:.45;cursor:not-allowed}@media(forced-colors:active){button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{border:2px solid Highlight}.qaid-annotate-canvas{border:1px solid CanvasText}}button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible{outline:2px solid var(--qaid-marker, #6366f1);outline-offset:2px}.qaid-textarea:focus-visible,button.qaid-btn-submit:focus-visible,.qaid-video-preview-box textarea:focus-visible{outline:2px solid var(--qaid-marker, #6366f1);outline-offset:2px}.qaid-buttons.qaid-incognito:focus-within{opacity:1}.qaid-buttons:focus-within .qaid-dismiss-btn,.qaid-dismiss-btn:focus-visible{opacity:1}.qaid-dismiss-btn{min-width:24px;min-height:24px}button.qaid-recording-stop{min-height:24px}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}@media(forced-colors:active){button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible,.qaid-textarea:focus,button.qaid-btn-submit:focus,.qaid-video-preview-box textarea:focus{outline:2px solid CanvasText;outline-offset:2px}.qaid-selected-marker,.qaid-highlight-box{border-color:Highlight}}.qaid-confirm{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;padding:.5rem 0}.qaid-confirm-icon{display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:9999px;color:#fff;background:var(--qaid-success, #22c55e);margin-bottom:.25rem;animation:qaid-confirm-pop .28s cubic-bezier(.34,1.56,.64,1)}.qaid-confirm-icon .qaid-icon{width:24px;height:24px}.qaid-confirm-title{margin:0;font-size:1rem;font-weight:600;color:var(--qaid-text, #111827)}.qaid-confirm-title:focus-visible{outline:2px solid var(--qaid-primary, #6366f1);outline-offset:3px;border-radius:4px}.qaid-confirm-message{margin:0;font-size:.875rem;color:var(--qaid-text-muted, #6b7280)}.qaid-confirm .qaid-confirm-close{margin-top:.5rem;min-width:96px}@keyframes qaid-confirm-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.qaid-confirm-icon{animation:none}}", ie = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
|
|
24
|
-
let
|
|
25
|
-
const
|
|
25
|
+
</svg>`, ae = "button{cursor:pointer}.qaid-buttons{display:flex;gap:.5rem}.qaid-buttons.qaid-vertical{flex-direction:column}.qaid-buttons.qaid-auto-container{position:fixed;z-index:50}.qaid-buttons.qaid-auto-container.qaid-bottom-right{bottom:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-bottom-left{bottom:1rem;left:1rem}.qaid-buttons.qaid-auto-container.qaid-top-right{top:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-top-left{top:1rem;left:1rem}.qaid-buttons.qaid-incognito{opacity:0;transition:opacity .2s ease-in-out}.qaid-buttons.qaid-incognito:hover{opacity:1}.qaid-buttons.qaid-dismissed{display:none!important}.qaid-dismiss-btn{width:20px;height:20px;padding:0;border:none;border-radius:50%;background:#0006;color:#fff;display:flex;align-items:center;justify-content:center;align-self:center;opacity:0;transition:opacity .15s,background .15s;cursor:pointer;pointer-events:auto;-webkit-appearance:none;appearance:none}.qaid-dismiss-btn:hover{background:#0009}.qaid-buttons:hover .qaid-dismiss-btn{opacity:1}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}:where(button.qaid-btn-structural)>svg:where(:not(.qaid-icon):not([width])){width:var(--qaid-icon-size, 24px);height:var(--qaid-icon-size, 24px)}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:var(--qaid-font-size, 16px);font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;inset:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;inset:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.3) 70%,rgba(0,0,0,.6) 100%);z-index:41}.qaid-crosshair-h,.qaid-crosshair-v{position:fixed;pointer-events:none;z-index:42}.qaid-crosshair-h{left:0;right:0;height:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-crosshair-v{top:0;bottom:0;width:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-type-up .qaid-crosshair-h,.qaid-type-up .qaid-crosshair-v{background:color-mix(in srgb,var(--qaid-positive) 60%,transparent)}.qaid-highlight-box{position:fixed;top:0;left:0;pointer-events:none;z-index:41;display:none;border:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:2px;background:color-mix(in srgb,var(--qaid-negative) 8%,transparent);will-change:transform,width,height}.qaid-type-up .qaid-highlight-box{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent);background:color-mix(in srgb,var(--qaid-positive) 8%,transparent)}.qaid-scope{position:fixed;width:80px;height:80px;pointer-events:none;z-index:43;transform:translate(-50%,-50%)}.qaid-scope-ring{position:absolute;inset:10px;border:2px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)}.qaid-scope-ring-inner{position:absolute;inset:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6365f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;inset:0;z-index:45;background:#0000004d}.qaid-modal-container{position:fixed;z-index:50;display:flex;flex-direction:column;align-items:flex-start;max-height:calc(100vh - 32px);font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-modal-container.qaid-above{flex-direction:column-reverse}.qaid-modal-arrow{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;position:relative;align-self:flex-start}.qaid-modal-container.qaid-below .qaid-modal-arrow{border-bottom:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-container.qaid-above .qaid-modal-arrow{border-top:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5));width:var(--qaid-modal-width, 400px);max-width:calc(100vw - 32px);max-height:calc(100vh - 60px);overflow-y:auto}.qaid-modal-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}button.qaid-type-toggle{border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;flex-shrink:0;-webkit-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-type-static{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--qaid-marker, #6365f1);color:var(--qaid-marker-text, white)}.qaid-type-static svg{width:1.25rem;height:1.25rem}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:calc(var(--qaid-font-size, 16px) * 1.125);font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:calc(var(--qaid-font-size, 16px) * .875)}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:var(--qaid-font-size, 16px);resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:calc(var(--qaid-font-size, 16px) * .75);font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0 0 auto;height:100vh;height:100dvh;display:flex;align-items:center;justify-content:center;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#0009;z-index:99998;animation:qaid-fadeIn .2s ease-out}@keyframes qaid-fadeIn{0%{opacity:0}to{opacity:1}}.qaid-video-preview-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px #00000080;width:560px;max-width:100%;max-height:100%;overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:calc(var(--qaid-font-size, 16px) * 1.125);font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;max-height:50vh;max-height:50dvh;object-fit:contain;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:calc(var(--qaid-font-size, 16px) * .875);resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-error{margin:0 0 .75rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;color:light-dark(#b91c1c,#fca5a5)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);color:light-dark(#6b7280,#9ca3af)}.qaid-annotate{position:fixed;inset:0;z-index:2147483000;display:flex;flex-direction:column;gap:.75rem;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#000000d9;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px);animation:qaid-fadeIn .2s ease-out}.qaid-annotate-title{margin:0;font-size:var(--qaid-font-size, 16px);font-weight:700;text-align:center;color:#f9fafb}.qaid-annotate-desc{margin:0;font-size:calc(var(--qaid-font-size, 16px) * .8125);line-height:1.4;text-align:center;color:#f9fafbbf}.qaid-annotate-stage{flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;overflow:auto}.qaid-annotate-canvas{max-width:100%;max-height:100%;object-fit:contain;background:light-dark(#ffffff,#111827);border-radius:.5rem;box-shadow:0 10px 30px #00000080;touch-action:none;cursor:crosshair}.qaid-annotate-toolbar{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;justify-content:center;padding:.5rem .75rem;background:light-dark(#ffffff,#1f2937);border-radius:.75rem;box-shadow:0 10px 30px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5))}.qaid-annotate-tools,.qaid-annotate-actions{display:flex;gap:.375rem;align-items:center}button.qaid-annotate-tool,button.qaid-annotate-action{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;min-width:44px;min-height:44px;padding:0 .75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;background:light-dark(#f9fafb,#111827);color:light-dark(#1f2937,#f9fafb);font-family:inherit;font-size:calc(var(--qaid-font-size, 16px) * .8125);font-weight:600;cursor:pointer;-webkit-appearance:none;appearance:none;transition:background-color .15s,color .15s,border-color .15s,filter .15s}button.qaid-annotate-tool svg,button.qaid-annotate-action svg{width:20px;height:20px}.qaid-annotate-colors{display:flex;gap:.25rem;align-items:center}button.qaid-annotate-swatch{width:28px;height:28px;min-width:28px;padding:0;border-radius:9999px;border:2px solid light-dark(#d1d5db,#4b5563);background:var(--qaid-swatch, #000);cursor:pointer;-webkit-appearance:none;appearance:none;transition:transform .1s,box-shadow .15s,border-color .15s}button.qaid-annotate-swatch:hover{transform:scale(1.12)}button.qaid-annotate-swatch[aria-pressed=true]{border-color:light-dark(#111827,#f9fafb);box-shadow:0 0 0 2px var(--qaid-swatch)}@media(forced-colors:active){button.qaid-annotate-swatch[aria-pressed=true]{outline:2px solid Highlight;outline-offset:1px}}button.qaid-annotate-tool:hover,button.qaid-annotate-action:hover{background:light-dark(#eef2ff,#312e81)}button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{background:var(--qaid-marker, #6365f1);color:var(--qaid-marker-text, #fff);border-color:var(--qaid-marker, #6365f1)}button.qaid-annotate-done:hover{filter:brightness(.9);background:var(--qaid-marker, #6365f1)}button.qaid-annotate-action:disabled{opacity:.45;cursor:not-allowed}@media(forced-colors:active){button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{border:2px solid Highlight}.qaid-annotate-canvas{border:1px solid CanvasText}}button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible{outline:2px solid var(--qaid-marker, #6365f1);outline-offset:2px}.qaid-textarea:focus-visible,button.qaid-btn-submit:focus-visible,.qaid-video-preview-box textarea:focus-visible{outline:2px solid var(--qaid-marker, #6365f1);outline-offset:2px}.qaid-buttons.qaid-incognito:focus-within{opacity:1}.qaid-buttons:focus-within .qaid-dismiss-btn,.qaid-dismiss-btn:focus-visible{opacity:1}.qaid-dismiss-btn{min-width:24px;min-height:24px}button.qaid-recording-stop{min-height:24px}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}@media(forced-colors:active){button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible,.qaid-textarea:focus,button.qaid-btn-submit:focus,.qaid-video-preview-box textarea:focus{outline:2px solid CanvasText;outline-offset:2px}.qaid-selected-marker,.qaid-highlight-box{border-color:Highlight}}.qaid-confirm{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;padding:.5rem 0}.qaid-confirm-icon{display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:9999px;color:#fff;background:var(--qaid-success, #22c55e);margin-bottom:.25rem;animation:qaid-confirm-pop .28s cubic-bezier(.34,1.56,.64,1)}.qaid-confirm-icon .qaid-icon{width:24px;height:24px}.qaid-confirm-error .qaid-confirm-icon{background:var(--qaid-error, #dc2626)}.qaid-confirm-title{margin:0;font-size:var(--qaid-font-size, 16px);font-weight:600;color:var(--qaid-text, light-dark(#111827, #f9fafb))}.qaid-confirm-title:focus-visible{outline:2px solid var(--qaid-primary, #6365f1);outline-offset:3px;border-radius:4px}.qaid-confirm-message{margin:0;font-size:calc(var(--qaid-font-size, 16px) * .875);color:var(--qaid-text-muted, light-dark(#6b7280, #9ca3af))}.qaid-confirm .qaid-confirm-close{margin-top:.5rem;min-width:96px}@keyframes qaid-confirm-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.qaid-confirm-icon{animation:none}}", re = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
|
|
26
|
+
let D = 0;
|
|
27
|
+
const de = "button.qaid-btn{width:var(--qaid-btn-size);height:var(--qaid-btn-size);border-radius:50%;border:none;background:#f3f4f6;color:#374151;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);transition:background-color .2s,color .2s,transform .2s;-webkit-appearance:none;appearance:none;--qaid-hover-up-bg:var(--qaid-positive);--qaid-hover-up-color:#fff;--qaid-hover-down-bg:var(--qaid-negative);--qaid-hover-down-color:#fff}button.qaid-btn:hover{transform:scale(1.05)}button.qaid-btn-up:hover{background:var(--qaid-hover-up-bg);color:var(--qaid-hover-up-color)}button.qaid-btn-down:hover{background:var(--qaid-hover-down-bg);color:var(--qaid-hover-down-color)}button.qaid-btn-feedback:hover{background:var(--qaid-marker,#6365f1);color:var(--qaid-marker-text,#fff)}button.qaid-btn svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", ce = {
|
|
26
28
|
small: 36,
|
|
27
29
|
medium: 48,
|
|
28
30
|
large: 64
|
|
29
|
-
},
|
|
31
|
+
}, le = {
|
|
30
32
|
small: 18,
|
|
31
33
|
medium: 24,
|
|
32
34
|
large: 32
|
|
33
35
|
};
|
|
34
|
-
function
|
|
36
|
+
function he(i, t, e) {
|
|
35
37
|
const [o, n, s] = [i, t, e].map((a) => (a = a / 255, a <= 0.03928 ? a / 12.92 : Math.pow((a + 0.055) / 1.055, 2.4)));
|
|
36
38
|
return 0.2126 * o + 0.7152 * n + 0.0722 * s;
|
|
37
39
|
}
|
|
38
|
-
function
|
|
40
|
+
function ue(i) {
|
|
39
41
|
if (i.startsWith("#")) {
|
|
40
42
|
const e = i.slice(1), o = e.length === 3 ? e.split("").map((s) => s + s).join("") : e, n = parseInt(o, 16);
|
|
41
43
|
return {
|
|
@@ -51,21 +53,21 @@ function re(i) {
|
|
|
51
53
|
b: parseInt(t[3])
|
|
52
54
|
} : null;
|
|
53
55
|
}
|
|
54
|
-
function
|
|
55
|
-
const t =
|
|
56
|
-
return t &&
|
|
56
|
+
function pe(i) {
|
|
57
|
+
const t = ue(i);
|
|
58
|
+
return t && he(t.r, t.g, t.b) > 0.4 ? "black" : "white";
|
|
57
59
|
}
|
|
58
|
-
function
|
|
60
|
+
function fe(i = {}) {
|
|
59
61
|
const {
|
|
60
62
|
positiveColor: t = "rgb(0, 200, 83)",
|
|
61
63
|
negativeColor: e = "rgb(255, 0, 0)",
|
|
62
|
-
markerColor: o = "#
|
|
64
|
+
markerColor: o = "#6365f1",
|
|
63
65
|
buttonSize: n = "medium",
|
|
64
66
|
modalWidth: s = 400,
|
|
65
67
|
backdropOpacity: a = 0.3,
|
|
66
68
|
fontFamily: c = "system-ui, -apple-system, sans-serif",
|
|
67
69
|
fontSize: l = 16
|
|
68
|
-
} = i, d =
|
|
70
|
+
} = i, d = ce[n], r = le[n], h = pe(o);
|
|
69
71
|
return {
|
|
70
72
|
"--qaid-positive": t,
|
|
71
73
|
"--qaid-negative": e,
|
|
@@ -79,22 +81,22 @@ function ce(i = {}) {
|
|
|
79
81
|
"--qaid-font-size": `${l}px`
|
|
80
82
|
};
|
|
81
83
|
}
|
|
82
|
-
function
|
|
84
|
+
function me(i, t) {
|
|
83
85
|
for (const [e, o] of Object.entries(t))
|
|
84
86
|
i.style.setProperty(e, o);
|
|
85
87
|
}
|
|
86
|
-
function
|
|
87
|
-
return
|
|
88
|
+
function et() {
|
|
89
|
+
return ae + de;
|
|
88
90
|
}
|
|
89
|
-
function
|
|
90
|
-
if (
|
|
91
|
+
function be() {
|
|
92
|
+
if (D++, D > 1) return;
|
|
91
93
|
const i = document.createElement("style");
|
|
92
|
-
i.id = "qaid-styles", i.textContent =
|
|
94
|
+
i.id = "qaid-styles", i.textContent = re, document.head.appendChild(i);
|
|
93
95
|
}
|
|
94
|
-
function
|
|
95
|
-
|
|
96
|
+
function ge() {
|
|
97
|
+
D <= 0 || (D--, D === 0 && document.getElementById("qaid-styles")?.remove());
|
|
96
98
|
}
|
|
97
|
-
const
|
|
99
|
+
const it = "data-qaid-a11y-live", ve = "position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;", ye = [
|
|
98
100
|
"a[href]",
|
|
99
101
|
"button",
|
|
100
102
|
"input",
|
|
@@ -102,25 +104,25 @@ const tt = "data-qaid-a11y-live", pe = "position:absolute;width:1px;height:1px;m
|
|
|
102
104
|
"select",
|
|
103
105
|
"[tabindex]"
|
|
104
106
|
].join(",");
|
|
105
|
-
function
|
|
107
|
+
function we(i) {
|
|
106
108
|
return i.ownerDocument || document;
|
|
107
109
|
}
|
|
108
|
-
function
|
|
110
|
+
function ke(i, t) {
|
|
109
111
|
const e = t ? "assertive" : "polite", o = i.querySelector(
|
|
110
|
-
`[${
|
|
112
|
+
`[${it}="${e}"]`
|
|
111
113
|
);
|
|
112
114
|
if (o) return o;
|
|
113
|
-
const s =
|
|
114
|
-
return s.setAttribute(
|
|
115
|
+
const s = we(i).createElement("div");
|
|
116
|
+
return s.setAttribute(it, e), s.setAttribute("role", t ? "alert" : "status"), s.setAttribute("aria-live", t ? "assertive" : "polite"), s.setAttribute("aria-atomic", "true"), s.style.cssText = ve, i.appendChild(s), s;
|
|
115
117
|
}
|
|
116
|
-
function
|
|
117
|
-
const o =
|
|
118
|
+
function xe(i, t, e = {}) {
|
|
119
|
+
const o = ke(i, !!e.assertive);
|
|
118
120
|
o.textContent = "", o.textContent = t;
|
|
119
121
|
}
|
|
120
|
-
function
|
|
122
|
+
function qe(i) {
|
|
121
123
|
return i.hasAttribute("disabled") ? !0 : i.disabled === !0;
|
|
122
124
|
}
|
|
123
|
-
function
|
|
125
|
+
function Ce(i) {
|
|
124
126
|
let t = i;
|
|
125
127
|
for (; t; ) {
|
|
126
128
|
if (t.hasAttribute("hidden")) return !0;
|
|
@@ -131,52 +133,52 @@ function ye(i) {
|
|
|
131
133
|
}
|
|
132
134
|
return !1;
|
|
133
135
|
}
|
|
134
|
-
function
|
|
136
|
+
function ot(i) {
|
|
135
137
|
return Array.from(
|
|
136
|
-
i.querySelectorAll(
|
|
137
|
-
).filter((e) => !(e.getAttribute("tabindex") === "-1" || e instanceof HTMLInputElement && e.type === "hidden" || e instanceof HTMLAnchorElement && !e.getAttribute("href") ||
|
|
138
|
+
i.querySelectorAll(ye)
|
|
139
|
+
).filter((e) => !(e.getAttribute("tabindex") === "-1" || e instanceof HTMLInputElement && e.type === "hidden" || e instanceof HTMLAnchorElement && !e.getAttribute("href") || qe(e) || Ce(e)));
|
|
138
140
|
}
|
|
139
|
-
function
|
|
141
|
+
function xt(i) {
|
|
140
142
|
let t = i.activeElement;
|
|
141
143
|
for (; t && t.shadowRoot && t.shadowRoot.activeElement; )
|
|
142
144
|
t = t.shadowRoot.activeElement;
|
|
143
145
|
return t instanceof HTMLElement ? t : null;
|
|
144
146
|
}
|
|
145
|
-
function
|
|
147
|
+
function Se(i) {
|
|
146
148
|
const t = i.ownerDocument || document;
|
|
147
149
|
let e = !1;
|
|
148
150
|
const o = (s) => {
|
|
149
151
|
if (s.key !== "Tab") return;
|
|
150
|
-
const a =
|
|
152
|
+
const a = ot(i);
|
|
151
153
|
if (a.length === 0) {
|
|
152
154
|
s.preventDefault(), i.focus();
|
|
153
155
|
return;
|
|
154
156
|
}
|
|
155
|
-
const c = a[0], l = a[a.length - 1], d =
|
|
157
|
+
const c = a[0], l = a[a.length - 1], d = xt(t), r = d ? a.indexOf(d) !== -1 : !1;
|
|
156
158
|
s.shiftKey ? (!r || d === c) && (s.preventDefault(), l.focus()) : (!r || d === l) && (s.preventDefault(), c.focus());
|
|
157
159
|
};
|
|
158
160
|
i.addEventListener("keydown", o);
|
|
159
|
-
const n =
|
|
161
|
+
const n = ot(i);
|
|
160
162
|
return n.length > 0 ? n[0].focus() : (i.hasAttribute("tabindex") || (i.setAttribute("tabindex", "-1"), e = !0), i.focus()), {
|
|
161
163
|
release() {
|
|
162
164
|
i.removeEventListener("keydown", o), e && (i.removeAttribute("tabindex"), e = !1);
|
|
163
165
|
}
|
|
164
166
|
};
|
|
165
167
|
}
|
|
166
|
-
function
|
|
167
|
-
return
|
|
168
|
+
function Ee() {
|
|
169
|
+
return xt(document);
|
|
168
170
|
}
|
|
169
|
-
function
|
|
171
|
+
function Te(i) {
|
|
170
172
|
if (!(!i || typeof i.focus != "function"))
|
|
171
173
|
try {
|
|
172
174
|
i.focus();
|
|
173
175
|
} catch {
|
|
174
176
|
}
|
|
175
177
|
}
|
|
176
|
-
function
|
|
178
|
+
function Ae(i, t = {}) {
|
|
177
179
|
i.setAttribute("role", "dialog"), i.setAttribute("aria-modal", "true"), t.labelledbyId && i.setAttribute("aria-labelledby", t.labelledbyId), t.describedbyId && i.setAttribute("aria-describedby", t.describedbyId), t.label && i.setAttribute("aria-label", t.label);
|
|
178
180
|
}
|
|
179
|
-
function
|
|
181
|
+
function Ie(i, t) {
|
|
180
182
|
let e = i;
|
|
181
183
|
for (; e && e !== t; ) {
|
|
182
184
|
const o = e.parentNode;
|
|
@@ -190,11 +192,11 @@ function Ce(i, t) {
|
|
|
190
192
|
}
|
|
191
193
|
return null;
|
|
192
194
|
}
|
|
193
|
-
function
|
|
195
|
+
function Le(i) {
|
|
194
196
|
const e = (i.ownerDocument || document).body;
|
|
195
197
|
if (!e) return () => {
|
|
196
198
|
};
|
|
197
|
-
const o =
|
|
199
|
+
const o = Ie(i, e), n = [];
|
|
198
200
|
return Array.from(e.children).forEach((s) => {
|
|
199
201
|
if (!(s instanceof HTMLElement) || o && s === o) return;
|
|
200
202
|
const a = s.inert === !0, c = s.getAttribute("aria-hidden");
|
|
@@ -206,14 +208,14 @@ function Se(i) {
|
|
|
206
208
|
}
|
|
207
209
|
};
|
|
208
210
|
}
|
|
209
|
-
const
|
|
211
|
+
const qt = {
|
|
210
212
|
width: 400,
|
|
211
213
|
height: 280,
|
|
212
214
|
arrowHeight: 12,
|
|
213
215
|
gap: 8,
|
|
214
216
|
viewportPadding: 16
|
|
215
217
|
};
|
|
216
|
-
function
|
|
218
|
+
function De(i, t, e, o, n) {
|
|
217
219
|
const s = i.y, a = t - (i.y + i.height);
|
|
218
220
|
if (a >= e + o)
|
|
219
221
|
return {
|
|
@@ -232,22 +234,22 @@ function Ee(i, t, e, o, n) {
|
|
|
232
234
|
t - e - n
|
|
233
235
|
) : l = Math.max(n, i.y - e - o), { top: l, position: c };
|
|
234
236
|
}
|
|
235
|
-
function
|
|
237
|
+
function Me(i, t, e, o) {
|
|
236
238
|
let s = i.x + i.width / 2 - e / 2;
|
|
237
239
|
return s = Math.max(o, Math.min(s, t - e - o)), s;
|
|
238
240
|
}
|
|
239
|
-
function
|
|
241
|
+
function Re(i, t, e, o = 24, n = 24) {
|
|
240
242
|
const a = i.clickX - t - n / 2;
|
|
241
243
|
return Math.max(o, Math.min(a, e - o - n / 2));
|
|
242
244
|
}
|
|
243
|
-
function
|
|
244
|
-
const n = o.height + o.arrowHeight, s =
|
|
245
|
+
function Pe(i, t, e, o = qt) {
|
|
246
|
+
const n = o.height + o.arrowHeight, s = De(
|
|
245
247
|
i,
|
|
246
248
|
e,
|
|
247
249
|
n,
|
|
248
250
|
o.gap,
|
|
249
251
|
o.viewportPadding
|
|
250
|
-
), a =
|
|
252
|
+
), a = Me(
|
|
251
253
|
i,
|
|
252
254
|
t,
|
|
253
255
|
o.width,
|
|
@@ -259,15 +261,15 @@ function Le(i, t, e, o = wt) {
|
|
|
259
261
|
position: s.position
|
|
260
262
|
};
|
|
261
263
|
}
|
|
262
|
-
function
|
|
264
|
+
function Be(i, t, e, o = {}) {
|
|
263
265
|
const n = o.gap ?? 8;
|
|
264
266
|
let s = i.bottom + n;
|
|
265
267
|
s + t.height > e.height - n && (s = i.top - t.height - n);
|
|
266
268
|
let a = i.left;
|
|
267
269
|
return a < n ? a = n : a + t.width > e.width - n && (a = e.width - t.width - n), s < n ? s = n : s + t.height > e.height - n && (s = e.height - t.height - n), { top: s, left: a };
|
|
268
270
|
}
|
|
269
|
-
function
|
|
270
|
-
const n =
|
|
271
|
+
function He(i, t, e, o = qt) {
|
|
272
|
+
const n = Pe(i, t, e, o), s = Re(
|
|
271
273
|
i,
|
|
272
274
|
n.left,
|
|
273
275
|
o.width
|
|
@@ -277,15 +279,15 @@ function De(i, t, e, o = wt) {
|
|
|
277
279
|
arrow: { left: s }
|
|
278
280
|
};
|
|
279
281
|
}
|
|
280
|
-
const
|
|
281
|
-
function
|
|
282
|
+
const Oe = 20;
|
|
283
|
+
function ze(i) {
|
|
282
284
|
const t = [], e = console.error, o = console.warn, n = console.log, s = (a, c) => {
|
|
283
285
|
const l = {
|
|
284
286
|
message: c.map((d) => String(d)).join(" "),
|
|
285
287
|
timestamp: Date.now(),
|
|
286
288
|
level: a
|
|
287
289
|
};
|
|
288
|
-
t.length >=
|
|
290
|
+
t.length >= Oe && t.shift(), t.push(l), i && i(l);
|
|
289
291
|
};
|
|
290
292
|
return console.error = function(...a) {
|
|
291
293
|
s("error", a), e.apply(console, a);
|
|
@@ -307,10 +309,10 @@ function q(i, t, e) {
|
|
|
307
309
|
n === "className" ? o.className = s : o.setAttribute(n, s);
|
|
308
310
|
return o;
|
|
309
311
|
}
|
|
310
|
-
function
|
|
312
|
+
function $e(i = 640) {
|
|
311
313
|
return typeof window < "u" && window.innerWidth < i;
|
|
312
314
|
}
|
|
313
|
-
function
|
|
315
|
+
function nt(i, t, e) {
|
|
314
316
|
const o = e.map((s) => s.style.visibility);
|
|
315
317
|
e.forEach((s) => s.style.visibility = "hidden");
|
|
316
318
|
const n = document.elementFromPoint(i, t);
|
|
@@ -319,7 +321,7 @@ function it(i, t, e) {
|
|
|
319
321
|
function M(i) {
|
|
320
322
|
return i ? i.hasAttribute("data-qaid-embed") || i.hasAttribute("data-qaid-embed-overlay") ? !0 : !!i.closest("[data-qaid-embed], [data-qaid-embed-overlay]") : !1;
|
|
321
323
|
}
|
|
322
|
-
function
|
|
324
|
+
function st(i, t = 0) {
|
|
323
325
|
const e = i.getBoundingClientRect();
|
|
324
326
|
return {
|
|
325
327
|
x: e.left - t,
|
|
@@ -328,7 +330,7 @@ function ot(i, t = 0) {
|
|
|
328
330
|
height: e.height + t * 2
|
|
329
331
|
};
|
|
330
332
|
}
|
|
331
|
-
const
|
|
333
|
+
const _e = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", Fe = (i) => (
|
|
332
334
|
// The URL is a runtime value, not a static specifier — keep Vite from
|
|
333
335
|
// trying to analyze/bundle it.
|
|
334
336
|
import(
|
|
@@ -336,19 +338,19 @@ const Be = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", He =
|
|
|
336
338
|
i
|
|
337
339
|
)
|
|
338
340
|
);
|
|
339
|
-
let
|
|
340
|
-
function
|
|
341
|
-
return
|
|
341
|
+
let Ve = Fe, I = null, _ = null;
|
|
342
|
+
function Ne(i) {
|
|
343
|
+
return I && _ === i || (_ = i, I = Promise.resolve(Ve(i)).then((t) => {
|
|
342
344
|
const e = t;
|
|
343
345
|
if (!e || typeof e.QaidQuests != "function")
|
|
344
346
|
throw new Error("quests module has no QaidQuests export");
|
|
345
347
|
return e;
|
|
346
348
|
}).catch((t) => {
|
|
347
|
-
throw
|
|
348
|
-
})),
|
|
349
|
+
throw I = null, _ = null, t;
|
|
350
|
+
})), I;
|
|
349
351
|
}
|
|
350
|
-
async function
|
|
351
|
-
const t = await
|
|
352
|
+
async function Ue(i) {
|
|
353
|
+
const t = await Ne(i.moduleUrl), e = i.base.replace(/\/+$/, ""), o = i.feedbackId != null ? { feedbackId: i.feedbackId } : void 0;
|
|
352
354
|
return new t.QaidQuests({
|
|
353
355
|
endpoint: `${e}/responses`,
|
|
354
356
|
configUrl: `${e}/${encodeURIComponent(i.questId)}/definition`,
|
|
@@ -357,7 +359,7 @@ async function ze(i) {
|
|
|
357
359
|
onClose: i.onClose
|
|
358
360
|
});
|
|
359
361
|
}
|
|
360
|
-
const
|
|
362
|
+
const at = "qaid_visitor_id", rt = "qaid_hide_feedback", je = [
|
|
361
363
|
"#ef4444",
|
|
362
364
|
"#f59e0b",
|
|
363
365
|
"#22c55e",
|
|
@@ -365,34 +367,46 @@ const nt = "qaid_visitor_id", st = "qaid_hide_feedback", _e = [
|
|
|
365
367
|
"#111827",
|
|
366
368
|
"#ffffff"
|
|
367
369
|
];
|
|
368
|
-
function
|
|
370
|
+
function Ke() {
|
|
369
371
|
return typeof window.matchMedia == "function" && window.matchMedia("(pointer: coarse)").matches;
|
|
370
372
|
}
|
|
371
373
|
function U(i) {
|
|
372
|
-
return i ? `${
|
|
374
|
+
return i ? `${rt}_${i}` : rt;
|
|
373
375
|
}
|
|
374
|
-
function
|
|
376
|
+
function We(i) {
|
|
375
377
|
try {
|
|
376
378
|
return localStorage.getItem(U(i)) === "1";
|
|
377
379
|
} catch {
|
|
378
380
|
return !1;
|
|
379
381
|
}
|
|
380
382
|
}
|
|
381
|
-
function
|
|
383
|
+
function dt(i, t = !0) {
|
|
382
384
|
try {
|
|
383
385
|
t ? localStorage.setItem(U(i), "1") : localStorage.removeItem(U(i));
|
|
384
386
|
} catch {
|
|
385
387
|
}
|
|
386
388
|
}
|
|
387
|
-
function
|
|
389
|
+
function ct() {
|
|
390
|
+
const i = typeof crypto < "u" ? crypto : void 0;
|
|
391
|
+
if (i && typeof i.randomUUID == "function") return i.randomUUID();
|
|
392
|
+
const t = new Uint8Array(16);
|
|
393
|
+
if (i && typeof i.getRandomValues == "function")
|
|
394
|
+
i.getRandomValues(t);
|
|
395
|
+
else
|
|
396
|
+
for (let o = 0; o < t.length; o++) t[o] = Math.floor(Math.random() * 256);
|
|
397
|
+
t[6] = t[6] & 15 | 64, t[8] = t[8] & 63 | 128;
|
|
398
|
+
const e = Array.from(t, (o) => o.toString(16).padStart(2, "0")).join("");
|
|
399
|
+
return `${e.slice(0, 8)}-${e.slice(8, 12)}-${e.slice(12, 16)}-${e.slice(16, 20)}-${e.slice(20)}`;
|
|
400
|
+
}
|
|
401
|
+
function Xe() {
|
|
388
402
|
try {
|
|
389
|
-
let i = localStorage.getItem(
|
|
390
|
-
return i || (i =
|
|
403
|
+
let i = localStorage.getItem(at);
|
|
404
|
+
return i || (i = ct(), localStorage.setItem(at, i)), i;
|
|
391
405
|
} catch {
|
|
392
|
-
return
|
|
406
|
+
return ct();
|
|
393
407
|
}
|
|
394
408
|
}
|
|
395
|
-
class
|
|
409
|
+
class Ye {
|
|
396
410
|
config;
|
|
397
411
|
state = "IDLE";
|
|
398
412
|
feedbackData = {
|
|
@@ -481,7 +495,7 @@ class Ue {
|
|
|
481
495
|
colors: {
|
|
482
496
|
positive: t.colors?.positive ?? "rgb(0, 200, 83)",
|
|
483
497
|
negative: t.colors?.negative ?? "rgb(255, 0, 0)",
|
|
484
|
-
marker: t.colors?.marker ?? "#
|
|
498
|
+
marker: t.colors?.marker ?? "#6365f1"
|
|
485
499
|
},
|
|
486
500
|
buttonSize: t.buttonSize ?? "medium",
|
|
487
501
|
text: {
|
|
@@ -498,7 +512,9 @@ class Ue {
|
|
|
498
512
|
feedbackLabel: t.text?.feedbackLabel ?? "Send feedback",
|
|
499
513
|
confirmationTitle: t.text?.confirmationTitle ?? "Thank you!",
|
|
500
514
|
confirmationMessage: t.text?.confirmationMessage ?? "Your feedback has been received.",
|
|
501
|
-
confirmationClose: t.text?.confirmationClose ?? "Close"
|
|
515
|
+
confirmationClose: t.text?.confirmationClose ?? "Close",
|
|
516
|
+
errorTitle: t.text?.errorTitle ?? "Message not sent",
|
|
517
|
+
errorMessage: t.text?.errorMessage ?? "Something went wrong, so we did not get your message. Please try again later."
|
|
502
518
|
},
|
|
503
519
|
hideConfirmation: t.hideConfirmation ?? !1,
|
|
504
520
|
modalWidth: t.modalWidth ?? 400,
|
|
@@ -507,8 +523,8 @@ class Ue {
|
|
|
507
523
|
fontSize: t.fontSize ?? 16,
|
|
508
524
|
captureScreenshot: t.captureScreenshot ?? !1,
|
|
509
525
|
annotate: t.annotate ?? !0,
|
|
510
|
-
annotationColor: t.annotationColor ?? t.colors?.marker ?? "#
|
|
511
|
-
annotationPalette: t.annotationPalette ??
|
|
526
|
+
annotationColor: t.annotationColor ?? t.colors?.marker ?? "#6365f1",
|
|
527
|
+
annotationPalette: t.annotationPalette ?? je,
|
|
512
528
|
screenshotMethod: t.screenshotMethod ?? "permission",
|
|
513
529
|
screenshotOptions: {
|
|
514
530
|
quality: t.screenshotOptions?.quality ?? 0.8,
|
|
@@ -535,12 +551,12 @@ class Ue {
|
|
|
535
551
|
video: t.quests?.video ?? "",
|
|
536
552
|
// Quest service reuses the feedback API key unless overridden.
|
|
537
553
|
apiKey: t.quests?.apiKey ?? t.apiKey ?? "",
|
|
538
|
-
moduleUrl: t.quests?.moduleUrl ??
|
|
554
|
+
moduleUrl: t.quests?.moduleUrl ?? _e
|
|
539
555
|
}
|
|
540
|
-
}, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId =
|
|
556
|
+
}, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = Xe(), this.init();
|
|
541
557
|
}
|
|
542
558
|
applyVars(t) {
|
|
543
|
-
|
|
559
|
+
me(t, this.cssVars);
|
|
544
560
|
}
|
|
545
561
|
/**
|
|
546
562
|
* Announce a message via the shared visually-hidden live regions.
|
|
@@ -550,7 +566,7 @@ class Ue {
|
|
|
550
566
|
*/
|
|
551
567
|
announceMsg(t, e = !1) {
|
|
552
568
|
const o = this.overlayShadowRoot ?? this.shadowRoot;
|
|
553
|
-
o &&
|
|
569
|
+
o && xe(o, t, { assertive: e });
|
|
554
570
|
}
|
|
555
571
|
/**
|
|
556
572
|
* Turn a transient surface into an accessible modal dialog: save the
|
|
@@ -558,16 +574,16 @@ class Ue {
|
|
|
558
574
|
* background. Paired with closeDialogA11y() on every close path.
|
|
559
575
|
*/
|
|
560
576
|
openDialogA11y(t, e) {
|
|
561
|
-
this.dialogTrigger =
|
|
577
|
+
this.dialogTrigger = Ee(), Ae(t, e), this.dialogTrap = Se(t), this.dialogRestoreInert = Le(t);
|
|
562
578
|
}
|
|
563
579
|
closeDialogA11y() {
|
|
564
|
-
this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null),
|
|
580
|
+
this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null), Te(this.dialogTrigger), this.dialogTrigger = null;
|
|
565
581
|
}
|
|
566
582
|
clearActiveThumb() {
|
|
567
583
|
this.activeThumbBtn && (this.activeThumbBtn.setAttribute("aria-pressed", "false"), this.activeThumbBtn = null);
|
|
568
584
|
}
|
|
569
585
|
init() {
|
|
570
|
-
|
|
586
|
+
be(), this.cssVars = fe({
|
|
571
587
|
positiveColor: this.config.colors.positive,
|
|
572
588
|
negativeColor: this.config.colors.negative,
|
|
573
589
|
markerColor: this.config.colors.marker,
|
|
@@ -576,7 +592,7 @@ class Ue {
|
|
|
576
592
|
backdropOpacity: this.config.backdropOpacity,
|
|
577
593
|
fontFamily: this.config.fontFamily,
|
|
578
594
|
fontSize: this.config.fontSize
|
|
579
|
-
}), !this.config.hideDismiss &&
|
|
595
|
+
}), !this.config.hideDismiss && We(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = ze((t) => {
|
|
580
596
|
this.feedbackData.consoleErrors = this.consoleCapture?.errors ?? [];
|
|
581
597
|
}), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom(), (this.config.captureVideo && this.videoSupported() || this.config.captureScreenshot) && this.schedulePrewarm(() => {
|
|
582
598
|
this.config.captureVideo && this.videoSupported() && this.prewarmVideo(), this.config.captureScreenshot && this.prewarmScreenshot();
|
|
@@ -589,13 +605,13 @@ class Ue {
|
|
|
589
605
|
* swallowed — a failed preload just falls back to an on-demand load.
|
|
590
606
|
*/
|
|
591
607
|
prewarmVideo() {
|
|
592
|
-
this.videoPrewarmed || (this.videoPrewarmed = !0, Promise.resolve().then(() =>
|
|
593
|
-
}), Promise.resolve().then(() =>
|
|
608
|
+
this.videoPrewarmed || (this.videoPrewarmed = !0, Promise.resolve().then(() => bt).catch(() => {
|
|
609
|
+
}), Promise.resolve().then(() => It).catch(() => {
|
|
594
610
|
}));
|
|
595
611
|
}
|
|
596
612
|
prewarmScreenshot() {
|
|
597
|
-
this.screenshotPrewarmed || (this.screenshotPrewarmed = !0, (this.shouldCaptureViaDom() ? Promise.resolve().then(() =>
|
|
598
|
-
}), this.config.annotate && Promise.resolve().then(() =>
|
|
613
|
+
this.screenshotPrewarmed || (this.screenshotPrewarmed = !0, (this.shouldCaptureViaDom() ? Promise.resolve().then(() => pt) : Promise.resolve().then(() => gt)).catch(() => {
|
|
614
|
+
}), this.config.annotate && Promise.resolve().then(() => mt).catch(() => {
|
|
599
615
|
}));
|
|
600
616
|
}
|
|
601
617
|
/** Run fn when the main thread is idle; cancelled by destroy(). */
|
|
@@ -624,7 +640,7 @@ class Ue {
|
|
|
624
640
|
}), this.domObserver.observe(document.body, { childList: !0 });
|
|
625
641
|
}
|
|
626
642
|
checkMobile() {
|
|
627
|
-
this.isMobile =
|
|
643
|
+
this.isMobile = $e();
|
|
628
644
|
}
|
|
629
645
|
handleResize() {
|
|
630
646
|
this.checkMobile();
|
|
@@ -634,7 +650,7 @@ class Ue {
|
|
|
634
650
|
let t = null;
|
|
635
651
|
this.config.container && (t = document.querySelector(this.config.container)), t ? (t.appendChild(this.shadowHost), this.isUserProvidedContainer = !0, this.config.hideDismiss = !0) : (this.shadowHost.style.position = "fixed", this.shadowHost.style.display = "block", this.shadowHost.style.inset = "0", this.shadowHost.style.pointerEvents = "none", this.shadowHost.style.zIndex = String(this.config.zIndex), document.body.appendChild(this.shadowHost)), this.shadowRoot = this.shadowHost.attachShadow({ mode: "open" });
|
|
636
652
|
const e = document.createElement("style");
|
|
637
|
-
if (e.textContent =
|
|
653
|
+
if (e.textContent = et(), this.shadowRoot.appendChild(e), this.config.css) {
|
|
638
654
|
const d = document.createElement("style");
|
|
639
655
|
d.textContent = this.config.css, this.shadowRoot.appendChild(d);
|
|
640
656
|
}
|
|
@@ -658,7 +674,7 @@ class Ue {
|
|
|
658
674
|
const d = document.createElement("div");
|
|
659
675
|
d.className = "qaid-tooltip-wrapper";
|
|
660
676
|
const r = document.createElement("button");
|
|
661
|
-
r.type = "button", r.className = n ? `${s} qaid-btn-feedback` : "qaid-btn qaid-btn-feedback", r.setAttribute("aria-label", this.config.text.feedbackLabel), r.innerHTML = this.config.feedbackIcon ||
|
|
677
|
+
r.type = "button", r.className = n ? `${s} qaid-btn-feedback` : "qaid-btn qaid-btn-feedback", r.setAttribute("aria-label", this.config.text.feedbackLabel), r.innerHTML = this.config.feedbackIcon || wt, r.addEventListener("click", (h) => this.handleThumbClick("neutral", h.currentTarget, h)), r.addEventListener("mouseenter", () => {
|
|
662
678
|
this.prewarmTargeting(), this.showTooltip(r);
|
|
663
679
|
}), r.addEventListener("mouseleave", () => this.hideTooltip()), d.appendChild(r), this.buttonsContainer.appendChild(d);
|
|
664
680
|
} else if (!this.config.hideThumbs) {
|
|
@@ -670,18 +686,18 @@ class Ue {
|
|
|
670
686
|
}), r.addEventListener("mouseleave", () => this.hideTooltip()), d.appendChild(r);
|
|
671
687
|
const h = document.createElement("div");
|
|
672
688
|
h.className = "qaid-tooltip-wrapper";
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
this.prewarmTargeting(), this.showTooltip(
|
|
676
|
-
}),
|
|
689
|
+
const f = document.createElement("button");
|
|
690
|
+
f.type = "button", f.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", f.setAttribute("aria-label", this.config.text.negativeLabel), f.innerHTML = this.config.negativeIcon || N, f.addEventListener("click", (b) => this.handleThumbClick("down", b.currentTarget, b)), f.addEventListener("mouseenter", () => {
|
|
691
|
+
this.prewarmTargeting(), this.showTooltip(f);
|
|
692
|
+
}), f.addEventListener("mouseleave", () => this.hideTooltip()), h.appendChild(f), this.buttonsContainer.appendChild(d), this.buttonsContainer.appendChild(h);
|
|
677
693
|
}
|
|
678
694
|
if (this.config.captureVideo && this.videoSupported()) {
|
|
679
695
|
const d = document.createElement("div");
|
|
680
696
|
d.className = "qaid-tooltip-wrapper";
|
|
681
697
|
const r = document.createElement("button");
|
|
682
|
-
r.type = "button", r.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", r.setAttribute("aria-label", this.config.text.recordLabel), r.innerHTML = this.config.recordIcon ||
|
|
698
|
+
r.type = "button", r.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", r.setAttribute("aria-label", this.config.text.recordLabel), r.innerHTML = this.config.recordIcon || Jt, r.addEventListener("click", () => {
|
|
683
699
|
this.ensureRecording().then(
|
|
684
|
-
(
|
|
700
|
+
(f) => this.config.videoOptions.redaction ? f.startPicking() : f.startRecording()
|
|
685
701
|
);
|
|
686
702
|
});
|
|
687
703
|
const h = () => this.prewarmVideo();
|
|
@@ -703,7 +719,7 @@ class Ue {
|
|
|
703
719
|
if (this.overlayShadowRoot) return this.overlayShadowRoot;
|
|
704
720
|
this.overlayShadowHost = document.createElement("div"), this.overlayShadowHost.setAttribute("data-qaid-embed-overlay", ""), this.overlayShadowHost.style.position = "fixed", this.overlayShadowHost.style.inset = "0", this.overlayShadowHost.style.pointerEvents = "none", this.overlayShadowHost.style.zIndex = String(this.config.zIndex), document.body.appendChild(this.overlayShadowHost), this.overlayShadowRoot = this.overlayShadowHost.attachShadow({ mode: "open" });
|
|
705
721
|
const t = document.createElement("style");
|
|
706
|
-
if (t.textContent =
|
|
722
|
+
if (t.textContent = et(), this.overlayShadowRoot.appendChild(t), this.config.css) {
|
|
707
723
|
const e = document.createElement("style");
|
|
708
724
|
e.textContent = this.config.css, this.overlayShadowRoot.appendChild(e);
|
|
709
725
|
}
|
|
@@ -713,7 +729,7 @@ class Ue {
|
|
|
713
729
|
showTooltip(t) {
|
|
714
730
|
const e = this.tooltipElement;
|
|
715
731
|
e.style.visibility = "hidden", e.classList.add("qaid-tooltip-visible");
|
|
716
|
-
const o = t.getBoundingClientRect(), n = e.getBoundingClientRect(), { top: s, left: a } =
|
|
732
|
+
const o = t.getBoundingClientRect(), n = e.getBoundingClientRect(), { top: s, left: a } = Be(
|
|
717
733
|
o,
|
|
718
734
|
n,
|
|
719
735
|
{ width: window.innerWidth, height: window.innerHeight }
|
|
@@ -724,10 +740,10 @@ class Ue {
|
|
|
724
740
|
this.tooltipElement.classList.remove("qaid-tooltip-visible");
|
|
725
741
|
}
|
|
726
742
|
handleDismiss() {
|
|
727
|
-
this.buttonsContainer.classList.add("qaid-dismissed"),
|
|
743
|
+
this.buttonsContainer.classList.add("qaid-dismissed"), dt(this.config.apiKey, !0);
|
|
728
744
|
}
|
|
729
745
|
handleThumbClick(t, e, o) {
|
|
730
|
-
if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"),
|
|
746
|
+
if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"), dt(this.config.apiKey, !1)), this.prewarmModal(), this.config.skipTargeting || this.config.feedbackMode === "annotate")
|
|
731
747
|
this.submitDirectFeedback(t, e);
|
|
732
748
|
else {
|
|
733
749
|
this.activeThumbBtn = e, e.setAttribute("aria-pressed", "true");
|
|
@@ -760,7 +776,7 @@ class Ue {
|
|
|
760
776
|
* instead of the permission-based Screen Capture API. Explicit "dom" wins;
|
|
761
777
|
* otherwise DOM is used on touch devices to avoid the getDisplayMedia prompt. */
|
|
762
778
|
shouldCaptureViaDom() {
|
|
763
|
-
return this.config.screenshotMethod === "dom" ||
|
|
779
|
+
return this.config.screenshotMethod === "dom" || Ke();
|
|
764
780
|
}
|
|
765
781
|
/**
|
|
766
782
|
* Open the full-screen annotation editor over the captured screenshot,
|
|
@@ -773,7 +789,7 @@ class Ue {
|
|
|
773
789
|
const e = this.ensureOverlayHost(), o = this.overlayShadowHost, n = o.style.pointerEvents;
|
|
774
790
|
o.style.pointerEvents = "auto";
|
|
775
791
|
try {
|
|
776
|
-
const { openAnnotationEditor: s } = await Promise.resolve().then(() =>
|
|
792
|
+
const { openAnnotationEditor: s } = await Promise.resolve().then(() => mt);
|
|
777
793
|
return await s({
|
|
778
794
|
dataUrl: t,
|
|
779
795
|
root: e,
|
|
@@ -796,10 +812,10 @@ class Ue {
|
|
|
796
812
|
if (this.config.captureScreenshot || this.config.feedbackMode === "annotate")
|
|
797
813
|
try {
|
|
798
814
|
if (this.shouldCaptureViaDom()) {
|
|
799
|
-
const { captureDomScreenshot: a } = await Promise.resolve().then(() =>
|
|
815
|
+
const { captureDomScreenshot: a } = await Promise.resolve().then(() => pt);
|
|
800
816
|
t = await a(this.config.screenshotOptions);
|
|
801
817
|
} else {
|
|
802
|
-
const { captureScreenshot: a } = await Promise.resolve().then(() =>
|
|
818
|
+
const { captureScreenshot: a } = await Promise.resolve().then(() => gt);
|
|
803
819
|
t = await a(this.config.screenshotOptions);
|
|
804
820
|
}
|
|
805
821
|
t && this.announceMsg("Screenshot captured");
|
|
@@ -877,7 +893,7 @@ class Ue {
|
|
|
877
893
|
const o = this.questIdFor(t);
|
|
878
894
|
if (!o) return !1;
|
|
879
895
|
try {
|
|
880
|
-
return this.activeQuest?.destroy(), this.activeQuest = await
|
|
896
|
+
return this.activeQuest?.destroy(), this.activeQuest = await Ue({
|
|
881
897
|
questId: o,
|
|
882
898
|
base: this.config.quests.base,
|
|
883
899
|
apiKey: this.config.quests.apiKey || void 0,
|
|
@@ -906,7 +922,7 @@ class Ue {
|
|
|
906
922
|
*/
|
|
907
923
|
async ensureModal() {
|
|
908
924
|
if (!this.modal) {
|
|
909
|
-
const { ModalController: t } = await Promise.resolve().then(() =>
|
|
925
|
+
const { ModalController: t } = await Promise.resolve().then(() => vt);
|
|
910
926
|
this.modal = new t(this.makeModalHost());
|
|
911
927
|
}
|
|
912
928
|
return this.modal;
|
|
@@ -952,7 +968,7 @@ class Ue {
|
|
|
952
968
|
}
|
|
953
969
|
/** Warm the modal chunk while the user is targeting, so it opens instantly. */
|
|
954
970
|
prewarmModal() {
|
|
955
|
-
this.modalPrewarmed || (this.modalPrewarmed = !0, Promise.resolve().then(() =>
|
|
971
|
+
this.modalPrewarmed || (this.modalPrewarmed = !0, Promise.resolve().then(() => vt).catch(() => {
|
|
956
972
|
}));
|
|
957
973
|
}
|
|
958
974
|
/**
|
|
@@ -962,7 +978,7 @@ class Ue {
|
|
|
962
978
|
*/
|
|
963
979
|
async ensureTargeting() {
|
|
964
980
|
if (!this.targeting) {
|
|
965
|
-
const { TargetingController: t } = await Promise.resolve().then(() =>
|
|
981
|
+
const { TargetingController: t } = await Promise.resolve().then(() => yt);
|
|
966
982
|
this.targeting = new t(this.makeTargetingHost());
|
|
967
983
|
}
|
|
968
984
|
return this.targeting;
|
|
@@ -1007,7 +1023,7 @@ class Ue {
|
|
|
1007
1023
|
}
|
|
1008
1024
|
/** Warm the targeting chunk on thumb-button hover, before the click. */
|
|
1009
1025
|
prewarmTargeting() {
|
|
1010
|
-
this.targetingPrewarmed || this.config.skipTargeting || (this.targetingPrewarmed = !0, Promise.resolve().then(() =>
|
|
1026
|
+
this.targetingPrewarmed || this.config.skipTargeting || (this.targetingPrewarmed = !0, Promise.resolve().then(() => yt).catch(() => {
|
|
1011
1027
|
}));
|
|
1012
1028
|
}
|
|
1013
1029
|
// ==================== Video Recording ====================
|
|
@@ -1026,7 +1042,7 @@ class Ue {
|
|
|
1026
1042
|
*/
|
|
1027
1043
|
async ensureRecording() {
|
|
1028
1044
|
if (!this.recording) {
|
|
1029
|
-
const { RecordingController: t } = await Promise.resolve().then(() =>
|
|
1045
|
+
const { RecordingController: t } = await Promise.resolve().then(() => bt);
|
|
1030
1046
|
this.recording = new t(this.makeRecordingHost());
|
|
1031
1047
|
}
|
|
1032
1048
|
return this.recording;
|
|
@@ -1082,13 +1098,13 @@ class Ue {
|
|
|
1082
1098
|
const t = window;
|
|
1083
1099
|
this.prewarmIsTimeout ? clearTimeout(this.prewarmHandle) : t.cancelIdleCallback?.(this.prewarmHandle), this.prewarmHandle = null;
|
|
1084
1100
|
}
|
|
1085
|
-
this.recording?.destroy(), this.recording = null, this.modal?.destroy(), this.modal = null, this.activeQuest?.destroy(), this.activeQuest = null, this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.overlayShadowHost && (this.overlayShadowHost.remove(), this.overlayShadowHost = null, this.overlayShadowRoot = null), this.buttonsContainer = null, this.dismissBtn = null, this.tooltipElement = null,
|
|
1101
|
+
this.recording?.destroy(), this.recording = null, this.modal?.destroy(), this.modal = null, this.activeQuest?.destroy(), this.activeQuest = null, this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.overlayShadowHost && (this.overlayShadowHost.remove(), this.overlayShadowHost = null, this.overlayShadowRoot = null), this.buttonsContainer = null, this.dismissBtn = null, this.tooltipElement = null, ge();
|
|
1086
1102
|
}
|
|
1087
1103
|
}
|
|
1088
|
-
function
|
|
1104
|
+
function Ct(i) {
|
|
1089
1105
|
return document.querySelector(i)?.textContent?.trim() ?? "";
|
|
1090
1106
|
}
|
|
1091
|
-
function
|
|
1107
|
+
function Qe() {
|
|
1092
1108
|
const i = document.querySelector(
|
|
1093
1109
|
'script[type="application/json"][data-feedback-config]'
|
|
1094
1110
|
);
|
|
@@ -1097,37 +1113,37 @@ function je() {
|
|
|
1097
1113
|
if (!t) return null;
|
|
1098
1114
|
try {
|
|
1099
1115
|
const e = JSON.parse(t);
|
|
1100
|
-
return e.cssSelector && !e.css && (e.css =
|
|
1116
|
+
return e.cssSelector && !e.css && (e.css = Ct(e.cssSelector), delete e.cssSelector), e;
|
|
1101
1117
|
} catch {
|
|
1102
1118
|
return null;
|
|
1103
1119
|
}
|
|
1104
1120
|
}
|
|
1105
|
-
function
|
|
1121
|
+
function Ge(i) {
|
|
1106
1122
|
const t = i.getAttribute("data-endpoint");
|
|
1107
1123
|
if (!t) return null;
|
|
1108
|
-
const e = i.getAttribute("data-position"), o = i.getAttribute("data-zindex"), n = i.getAttribute("data-positive-color"), s = i.getAttribute("data-negative-color"), a = i.getAttribute("data-marker-color"), c = i.getAttribute("data-container"), l = i.getAttribute("data-button-class"), d = i.getAttribute("data-skip-targeting"), r = i.getAttribute("data-hide-confirmation"), h = i.getAttribute("data-single-button"),
|
|
1124
|
+
const e = i.getAttribute("data-position"), o = i.getAttribute("data-zindex"), n = i.getAttribute("data-positive-color"), s = i.getAttribute("data-negative-color"), a = i.getAttribute("data-marker-color"), c = i.getAttribute("data-container"), l = i.getAttribute("data-button-class"), d = i.getAttribute("data-skip-targeting"), r = i.getAttribute("data-hide-confirmation"), h = i.getAttribute("data-single-button"), f = i.getAttribute("data-feedback-mode"), b = i.getAttribute("data-incognito"), y = i.getAttribute("data-button-size"), g = i.getAttribute("data-offset-x"), w = i.getAttribute("data-offset-y"), x = i.getAttribute("data-modal-width"), u = i.getAttribute("data-backdrop-opacity"), k = i.getAttribute("data-font-family"), v = i.getAttribute("data-font-size"), C = i.getAttribute("data-tooltip"), A = i.getAttribute("data-modal-title"), S = i.getAttribute("data-confirmation-title"), m = i.getAttribute("data-confirmation-message"), E = i.getAttribute("data-confirmation-close"), j = i.getAttribute("data-error-title"), K = i.getAttribute("data-error-message"), W = i.getAttribute("data-modal-subtitle"), X = i.getAttribute("data-placeholder"), Y = i.getAttribute("data-submit-button"), Q = i.getAttribute("data-skip-button"), Bt = i.getAttribute("data-positive-icon"), Ht = i.getAttribute("data-negative-icon"), Ot = i.getAttribute("data-feedback-icon"), G = i.getAttribute("data-feedback-label"), zt = i.getAttribute("data-api-key"), $t = i.getAttribute("data-capture-screenshot"), _t = i.getAttribute("data-annotate"), Ft = i.getAttribute("data-annotation-color"), H = i.getAttribute("data-screenshot-quality"), O = i.getAttribute("data-screenshot-max-width"), z = i.getAttribute("data-screenshot-max-height"), Vt = i.getAttribute("data-capture-video"), J = i.getAttribute("data-video-redaction"), Nt = i.getAttribute("data-hide-thumbs"), Ut = i.getAttribute("data-hide-dismiss"), $ = i.getAttribute("data-video-max-duration"), jt = i.getAttribute("data-screenshot-method"), Kt = i.getAttribute("data-direction"), Z = i.getAttribute("data-css-selector"), tt = i.getAttribute("data-quest-base"), Wt = i.getAttribute("data-quest-up"), Xt = i.getAttribute("data-quest-down"), Yt = i.getAttribute("data-quest-video"), Qt = i.getAttribute("data-quest-api-key"), Gt = i.getAttribute("data-quest-module-url");
|
|
1109
1125
|
return {
|
|
1110
1126
|
endpoint: t,
|
|
1111
|
-
css:
|
|
1112
|
-
apiKey:
|
|
1113
|
-
captureScreenshot:
|
|
1127
|
+
css: Z ? Ct(Z) : void 0,
|
|
1128
|
+
apiKey: zt ?? void 0,
|
|
1129
|
+
captureScreenshot: $t === "true" ? !0 : void 0,
|
|
1114
1130
|
// Annotation is on by default; only an explicit "false" disables it.
|
|
1115
|
-
annotate:
|
|
1116
|
-
annotationColor:
|
|
1117
|
-
screenshotOptions: H || O ||
|
|
1131
|
+
annotate: _t === "false" ? !1 : void 0,
|
|
1132
|
+
annotationColor: Ft ?? void 0,
|
|
1133
|
+
screenshotOptions: H || O || z ? {
|
|
1118
1134
|
quality: H ? parseFloat(H) : void 0,
|
|
1119
1135
|
maxWidth: O ? parseInt(O, 10) : void 0,
|
|
1120
|
-
maxHeight:
|
|
1136
|
+
maxHeight: z ? parseInt(z, 10) : void 0
|
|
1121
1137
|
} : void 0,
|
|
1122
1138
|
container: c ?? void 0,
|
|
1123
1139
|
buttonClass: l ?? void 0,
|
|
1124
|
-
direction:
|
|
1140
|
+
direction: Kt ?? void 0,
|
|
1125
1141
|
position: e ?? void 0,
|
|
1126
1142
|
zIndex: o ? parseInt(o, 10) : void 0,
|
|
1127
1143
|
skipTargeting: d === "true" ? !0 : void 0,
|
|
1128
1144
|
hideConfirmation: r === "true" ? !0 : void 0,
|
|
1129
1145
|
singleButton: h === "true" ? !0 : void 0,
|
|
1130
|
-
feedbackMode:
|
|
1146
|
+
feedbackMode: f ?? void 0,
|
|
1131
1147
|
incognito: b === "true" ? !0 : void 0,
|
|
1132
1148
|
buttonSize: y ?? void 0,
|
|
1133
1149
|
offset: g || w ? {
|
|
@@ -1143,56 +1159,58 @@ function Ke(i) {
|
|
|
1143
1159
|
negative: s ?? void 0,
|
|
1144
1160
|
marker: a ?? void 0
|
|
1145
1161
|
},
|
|
1146
|
-
text: C ||
|
|
1162
|
+
text: C || A || W || X || Y || Q || G || S || m || E || j || K ? {
|
|
1147
1163
|
tooltip: C ?? void 0,
|
|
1148
|
-
modalTitle:
|
|
1149
|
-
modalSubtitle:
|
|
1150
|
-
placeholder:
|
|
1151
|
-
submitButton:
|
|
1152
|
-
skipButton:
|
|
1153
|
-
feedbackLabel:
|
|
1164
|
+
modalTitle: A ?? void 0,
|
|
1165
|
+
modalSubtitle: W ?? void 0,
|
|
1166
|
+
placeholder: X ?? void 0,
|
|
1167
|
+
submitButton: Y ?? void 0,
|
|
1168
|
+
skipButton: Q ?? void 0,
|
|
1169
|
+
feedbackLabel: G ?? void 0,
|
|
1154
1170
|
confirmationTitle: S ?? void 0,
|
|
1155
|
-
confirmationMessage:
|
|
1156
|
-
confirmationClose:
|
|
1171
|
+
confirmationMessage: m ?? void 0,
|
|
1172
|
+
confirmationClose: E ?? void 0,
|
|
1173
|
+
errorTitle: j ?? void 0,
|
|
1174
|
+
errorMessage: K ?? void 0
|
|
1157
1175
|
} : void 0,
|
|
1158
|
-
positiveIcon:
|
|
1159
|
-
negativeIcon:
|
|
1160
|
-
feedbackIcon:
|
|
1161
|
-
screenshotMethod:
|
|
1162
|
-
captureVideo:
|
|
1163
|
-
hideThumbs:
|
|
1164
|
-
hideDismiss:
|
|
1165
|
-
videoOptions:
|
|
1166
|
-
maxDuration:
|
|
1167
|
-
redaction:
|
|
1176
|
+
positiveIcon: Bt ?? void 0,
|
|
1177
|
+
negativeIcon: Ht ?? void 0,
|
|
1178
|
+
feedbackIcon: Ot ?? void 0,
|
|
1179
|
+
screenshotMethod: jt ?? void 0,
|
|
1180
|
+
captureVideo: Vt === "true" ? !0 : void 0,
|
|
1181
|
+
hideThumbs: Nt === "true" ? !0 : void 0,
|
|
1182
|
+
hideDismiss: Ut === "true" ? !0 : void 0,
|
|
1183
|
+
videoOptions: $ || J ? {
|
|
1184
|
+
maxDuration: $ ? parseInt($, 10) : void 0,
|
|
1185
|
+
redaction: J === "true" ? !0 : void 0
|
|
1168
1186
|
} : void 0,
|
|
1169
|
-
quests:
|
|
1170
|
-
base:
|
|
1171
|
-
up:
|
|
1172
|
-
down:
|
|
1173
|
-
video:
|
|
1174
|
-
apiKey:
|
|
1175
|
-
moduleUrl:
|
|
1187
|
+
quests: tt ? {
|
|
1188
|
+
base: tt,
|
|
1189
|
+
up: Wt ?? void 0,
|
|
1190
|
+
down: Xt ?? void 0,
|
|
1191
|
+
video: Yt ?? void 0,
|
|
1192
|
+
apiKey: Qt ?? void 0,
|
|
1193
|
+
moduleUrl: Gt ?? void 0
|
|
1176
1194
|
} : void 0
|
|
1177
1195
|
};
|
|
1178
1196
|
}
|
|
1179
|
-
function
|
|
1197
|
+
function Je() {
|
|
1180
1198
|
if (typeof document > "u") return;
|
|
1181
1199
|
const i = () => {
|
|
1182
|
-
const t = document.currentScript ?? document.querySelector("script[data-endpoint]"), e =
|
|
1183
|
-
n?.endpoint && new
|
|
1200
|
+
const t = document.currentScript ?? document.querySelector("script[data-endpoint]"), e = Qe(), o = t ? Ge(t) : null, n = e ?? o;
|
|
1201
|
+
n?.endpoint && new Ye(n);
|
|
1184
1202
|
};
|
|
1185
1203
|
document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", i) : i();
|
|
1186
1204
|
}
|
|
1187
|
-
const
|
|
1205
|
+
const Ze = 20, lt = 4096;
|
|
1188
1206
|
function R(i) {
|
|
1189
1207
|
const t = typeof i == "string" ? i : JSON.stringify(i);
|
|
1190
|
-
return t.length >
|
|
1208
|
+
return t.length > lt ? t.slice(0, lt) + "…[truncated]" : t;
|
|
1191
1209
|
}
|
|
1192
|
-
function
|
|
1193
|
-
i.length >=
|
|
1210
|
+
function ht(i, t) {
|
|
1211
|
+
i.length >= Ze && i.shift(), i.push(t);
|
|
1194
1212
|
}
|
|
1195
|
-
async function
|
|
1213
|
+
async function ti(i) {
|
|
1196
1214
|
try {
|
|
1197
1215
|
const t = await i.clone().text();
|
|
1198
1216
|
return R(t);
|
|
@@ -1200,7 +1218,7 @@ async function Ye(i) {
|
|
|
1200
1218
|
return;
|
|
1201
1219
|
}
|
|
1202
1220
|
}
|
|
1203
|
-
function
|
|
1221
|
+
function ei() {
|
|
1204
1222
|
const i = [], t = window.fetch;
|
|
1205
1223
|
window.fetch = async function(n, s) {
|
|
1206
1224
|
const a = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url, c = s?.method ?? (typeof n == "object" && "method" in n ? n.method : "GET");
|
|
@@ -1208,8 +1226,8 @@ function Qe() {
|
|
|
1208
1226
|
s?.body && (l = R(s.body));
|
|
1209
1227
|
const d = await t.apply(window, [n, s]);
|
|
1210
1228
|
if (d.status >= 400) {
|
|
1211
|
-
const r = await
|
|
1212
|
-
|
|
1229
|
+
const r = await ti(d);
|
|
1230
|
+
ht(i, {
|
|
1213
1231
|
url: a,
|
|
1214
1232
|
method: c.toUpperCase(),
|
|
1215
1233
|
status: d.status,
|
|
@@ -1227,7 +1245,7 @@ function Qe() {
|
|
|
1227
1245
|
}, XMLHttpRequest.prototype.send = function(n) {
|
|
1228
1246
|
const s = this, a = n ? R(n) : void 0;
|
|
1229
1247
|
return s.addEventListener("load", function() {
|
|
1230
|
-
s.status >= 400 &&
|
|
1248
|
+
s.status >= 400 && ht(i, {
|
|
1231
1249
|
url: s._qaid_url,
|
|
1232
1250
|
method: s._qaid_method.toUpperCase(),
|
|
1233
1251
|
status: s.status,
|
|
@@ -1244,27 +1262,27 @@ function Qe() {
|
|
|
1244
1262
|
}
|
|
1245
1263
|
};
|
|
1246
1264
|
}
|
|
1247
|
-
function
|
|
1265
|
+
function ii() {
|
|
1248
1266
|
const i = navigator.userAgent || "";
|
|
1249
1267
|
return /iP(hone|ad|od)/.test(i) || // iPadOS 13+ masquerades as "MacIntel" but is a multi-touch device.
|
|
1250
1268
|
navigator.platform === "MacIntel" && (navigator.maxTouchPoints || 0) > 1;
|
|
1251
1269
|
}
|
|
1252
|
-
function
|
|
1270
|
+
function oi(i, t, e, o, n) {
|
|
1253
1271
|
const s = i >= t, a = e >= o;
|
|
1254
1272
|
return s === a ? { width: i, height: t, rotate: 0 } : { width: t, height: i, rotate: n === 270 ? -90 : 90 };
|
|
1255
1273
|
}
|
|
1256
|
-
function
|
|
1274
|
+
function ni(i, t, e) {
|
|
1257
1275
|
if (e.rotate === 0) {
|
|
1258
1276
|
i.drawImage(t, 0, 0, e.width, e.height);
|
|
1259
1277
|
return;
|
|
1260
1278
|
}
|
|
1261
1279
|
i.save(), e.rotate === 90 ? (i.translate(e.width, 0), i.rotate(Math.PI / 2)) : (i.translate(0, e.height), i.rotate(-Math.PI / 2)), i.drawImage(t, 0, 0, e.height, e.width), i.restore();
|
|
1262
1280
|
}
|
|
1263
|
-
function
|
|
1281
|
+
function si() {
|
|
1264
1282
|
const i = typeof screen < "u" ? screen.orientation : void 0;
|
|
1265
1283
|
return i && typeof i.angle == "number" ? i.angle : 0;
|
|
1266
1284
|
}
|
|
1267
|
-
function
|
|
1285
|
+
function St(i) {
|
|
1268
1286
|
return new Promise((t) => {
|
|
1269
1287
|
if (i.videoWidth > 0) {
|
|
1270
1288
|
t();
|
|
@@ -1273,30 +1291,30 @@ function xt(i) {
|
|
|
1273
1291
|
i.addEventListener("loadedmetadata", () => t(), { once: !0 });
|
|
1274
1292
|
});
|
|
1275
1293
|
}
|
|
1276
|
-
async function
|
|
1294
|
+
async function Et(i) {
|
|
1277
1295
|
try {
|
|
1278
1296
|
await i.play();
|
|
1279
1297
|
} catch {
|
|
1280
1298
|
}
|
|
1281
1299
|
}
|
|
1282
|
-
async function
|
|
1300
|
+
async function ai(i, t = 15) {
|
|
1283
1301
|
const e = document.createElement("canvas");
|
|
1284
1302
|
if (typeof e.captureStream != "function") return null;
|
|
1285
1303
|
const o = e.getContext("2d");
|
|
1286
1304
|
if (!o) return null;
|
|
1287
1305
|
const n = document.createElement("video");
|
|
1288
|
-
n.muted = !0, n.playsInline = !0, n.srcObject = i, await
|
|
1289
|
-
const s =
|
|
1306
|
+
n.muted = !0, n.playsInline = !0, n.srcObject = i, await St(n);
|
|
1307
|
+
const s = oi(
|
|
1290
1308
|
n.videoWidth,
|
|
1291
1309
|
n.videoHeight,
|
|
1292
1310
|
window.innerWidth,
|
|
1293
1311
|
window.innerHeight,
|
|
1294
|
-
|
|
1312
|
+
si()
|
|
1295
1313
|
);
|
|
1296
|
-
e.width = s.width, e.height = s.height, await
|
|
1314
|
+
e.width = s.width, e.height = s.height, await Et(n);
|
|
1297
1315
|
let a = 0;
|
|
1298
1316
|
const c = () => {
|
|
1299
|
-
|
|
1317
|
+
ni(o, n, s), a = requestAnimationFrame(c);
|
|
1300
1318
|
};
|
|
1301
1319
|
c();
|
|
1302
1320
|
const l = e.captureStream(t);
|
|
@@ -1307,15 +1325,15 @@ async function ei(i, t = 15) {
|
|
|
1307
1325
|
}
|
|
1308
1326
|
};
|
|
1309
1327
|
}
|
|
1310
|
-
function
|
|
1328
|
+
function ri(i, t, e, o, n) {
|
|
1311
1329
|
const s = Math.max(0, Math.min(o, i.left * t)), a = Math.max(0, Math.min(n, i.top * e)), c = Math.max(0, Math.min(o, (i.left + i.width) * t)), l = Math.max(0, Math.min(n, (i.top + i.height) * e)), d = c - s, r = l - a;
|
|
1312
1330
|
return d <= 0 || r <= 0 ? null : { x: s, y: a, w: d, h: r };
|
|
1313
1331
|
}
|
|
1314
|
-
function
|
|
1332
|
+
function di(i, t, e, o, n, s, a) {
|
|
1315
1333
|
i.drawImage(t, 0, 0, o, n);
|
|
1316
1334
|
const c = o / Math.max(1, window.innerWidth), l = n / Math.max(1, window.innerHeight);
|
|
1317
1335
|
for (const d of e) {
|
|
1318
|
-
const r =
|
|
1336
|
+
const r = ri(
|
|
1319
1337
|
d.getBoundingClientRect(),
|
|
1320
1338
|
c,
|
|
1321
1339
|
l,
|
|
@@ -1325,16 +1343,16 @@ function oi(i, t, e, o, n, s, a) {
|
|
|
1325
1343
|
r && (i.save(), a ? (i.filter = `blur(${s}px)`, i.drawImage(t, r.x, r.y, r.w, r.h, r.x, r.y, r.w, r.h)) : (i.fillStyle = "#0b0b0b", i.fillRect(r.x, r.y, r.w, r.h)), i.restore());
|
|
1326
1344
|
}
|
|
1327
1345
|
}
|
|
1328
|
-
async function
|
|
1346
|
+
async function ci(i, t, e = {}) {
|
|
1329
1347
|
const o = e.frameRate ?? 15, n = e.blurRadius ?? 12, s = document.createElement("canvas");
|
|
1330
1348
|
if (typeof s.captureStream != "function") return null;
|
|
1331
1349
|
const a = s.getContext("2d");
|
|
1332
1350
|
if (!a) return null;
|
|
1333
1351
|
const c = "filter" in a, l = document.createElement("video");
|
|
1334
|
-
l.muted = !0, l.playsInline = !0, l.srcObject = i, await
|
|
1352
|
+
l.muted = !0, l.playsInline = !0, l.srcObject = i, await St(l), s.width = l.videoWidth, s.height = l.videoHeight, await Et(l);
|
|
1335
1353
|
let d = 0;
|
|
1336
1354
|
const r = () => {
|
|
1337
|
-
|
|
1355
|
+
di(
|
|
1338
1356
|
a,
|
|
1339
1357
|
l,
|
|
1340
1358
|
t,
|
|
@@ -1349,14 +1367,15 @@ async function ni(i, t, e = {}) {
|
|
|
1349
1367
|
return {
|
|
1350
1368
|
stream: h,
|
|
1351
1369
|
stop: () => {
|
|
1352
|
-
d && cancelAnimationFrame(d), d = 0, h.getTracks().forEach((
|
|
1370
|
+
d && cancelAnimationFrame(d), d = 0, h.getTracks().forEach((f) => f.stop()), l.pause(), l.srcObject = null;
|
|
1353
1371
|
}
|
|
1354
1372
|
};
|
|
1355
1373
|
}
|
|
1356
|
-
|
|
1374
|
+
const Tt = "This browser cannot blur the areas you picked, so the recording was not started.";
|
|
1375
|
+
function li() {
|
|
1357
1376
|
return typeof navigator < "u" && !!navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia == "function" && typeof MediaRecorder < "u";
|
|
1358
1377
|
}
|
|
1359
|
-
function
|
|
1378
|
+
function At() {
|
|
1360
1379
|
if (typeof MediaRecorder > "u") return "";
|
|
1361
1380
|
const i = [
|
|
1362
1381
|
"video/webm;codecs=vp9",
|
|
@@ -1369,11 +1388,11 @@ function Ct() {
|
|
|
1369
1388
|
return t;
|
|
1370
1389
|
return "";
|
|
1371
1390
|
}
|
|
1372
|
-
function
|
|
1391
|
+
function hi(i = {}) {
|
|
1373
1392
|
const t = i.maxDuration ?? 15, e = i.videoBitsPerSecond ?? 8e5, o = i.redactionElements ?? [], n = i.redactionBlurRadius;
|
|
1374
|
-
let s = null, a = null, c = null, l = null, d = [], r = null, h = null,
|
|
1393
|
+
let s = null, a = null, c = null, l = null, d = [], r = null, h = null, f = null, b = 0, y = null, g = null, w = !1, x = null;
|
|
1375
1394
|
function u() {
|
|
1376
|
-
|
|
1395
|
+
f !== null && (clearInterval(f), f = null), x !== null && (clearTimeout(x), x = null), a && (a.stop(), a = null), c && (c.stop(), c = null), s && (s.getTracks().forEach((v) => v.stop()), s = null), l = null, d = [], r = null, h = null, y = null, g = null;
|
|
1377
1396
|
}
|
|
1378
1397
|
function k() {
|
|
1379
1398
|
w || (w = !0, l && l.state !== "inactive" && l.stop());
|
|
@@ -1381,7 +1400,7 @@ function ai(i = {}) {
|
|
|
1381
1400
|
return {
|
|
1382
1401
|
async start() {
|
|
1383
1402
|
w = !1, d = [];
|
|
1384
|
-
const v =
|
|
1403
|
+
const v = At();
|
|
1385
1404
|
if (!v)
|
|
1386
1405
|
throw new Error("No supported video MIME type found");
|
|
1387
1406
|
s = await navigator.mediaDevices.getDisplayMedia({
|
|
@@ -1396,37 +1415,40 @@ function ai(i = {}) {
|
|
|
1396
1415
|
monitorTypeSurfaces: "exclude",
|
|
1397
1416
|
surfaceSwitching: "exclude"
|
|
1398
1417
|
});
|
|
1399
|
-
const C = s.getVideoTracks()[0],
|
|
1400
|
-
if (
|
|
1401
|
-
throw s.getTracks().forEach((
|
|
1418
|
+
const C = s.getVideoTracks()[0], A = C?.getSettings?.()?.displaySurface;
|
|
1419
|
+
if (A === "monitor" || A === "window")
|
|
1420
|
+
throw s.getTracks().forEach((m) => m.stop()), s = null, new Error(
|
|
1402
1421
|
"qaid records only the current tab — please share this tab, not a window or your whole screen."
|
|
1403
1422
|
);
|
|
1404
1423
|
C && C.addEventListener("ended", () => {
|
|
1405
1424
|
k();
|
|
1406
1425
|
});
|
|
1407
1426
|
let S = s;
|
|
1408
|
-
if (
|
|
1409
|
-
const
|
|
1410
|
-
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1427
|
+
if (ii()) {
|
|
1428
|
+
const m = await ai(s);
|
|
1429
|
+
m && (a = m, S = m.stream);
|
|
1430
|
+
}
|
|
1431
|
+
if (o.length > 0) {
|
|
1432
|
+
const m = await ci(S, o, {
|
|
1413
1433
|
blurRadius: n
|
|
1414
1434
|
});
|
|
1415
|
-
|
|
1435
|
+
if (!m)
|
|
1436
|
+
throw a && (a.stop(), a = null), s.getTracks().forEach((E) => E.stop()), s = null, new Error(Tt);
|
|
1437
|
+
c = m, S = m.stream;
|
|
1416
1438
|
}
|
|
1417
1439
|
l = new MediaRecorder(S, {
|
|
1418
1440
|
mimeType: v,
|
|
1419
1441
|
videoBitsPerSecond: e
|
|
1420
|
-
}), l.ondataavailable = (
|
|
1421
|
-
|
|
1442
|
+
}), l.ondataavailable = (m) => {
|
|
1443
|
+
m.data.size > 0 && d.push(m.data);
|
|
1422
1444
|
}, l.onstop = () => {
|
|
1423
|
-
const
|
|
1424
|
-
y && y(
|
|
1445
|
+
const m = new Blob(d, { type: v });
|
|
1446
|
+
y && y(m), h && h(m), a && (a.stop(), a = null), c && (c.stop(), c = null), s && s.getTracks().forEach((E) => E.stop());
|
|
1425
1447
|
}, l.onerror = () => {
|
|
1426
1448
|
g && g(new Error("MediaRecorder error"));
|
|
1427
|
-
}, l.start(1e3), b = Date.now(),
|
|
1428
|
-
const
|
|
1429
|
-
r && r(
|
|
1449
|
+
}, l.start(1e3), b = Date.now(), f = setInterval(() => {
|
|
1450
|
+
const m = Math.floor((Date.now() - b) / 1e3);
|
|
1451
|
+
r && r(m);
|
|
1430
1452
|
}, 1e3), x = setTimeout(() => {
|
|
1431
1453
|
k();
|
|
1432
1454
|
}, t * 1e3);
|
|
@@ -1447,45 +1469,46 @@ function ai(i = {}) {
|
|
|
1447
1469
|
}
|
|
1448
1470
|
};
|
|
1449
1471
|
}
|
|
1450
|
-
const
|
|
1472
|
+
const It = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1451
1473
|
__proto__: null,
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1474
|
+
REDACTION_UNAVAILABLE: Tt,
|
|
1475
|
+
createVideoRecorder: hi,
|
|
1476
|
+
getSupportedMimeType: At,
|
|
1477
|
+
isVideoRecordingSupported: li
|
|
1478
|
+
}, Symbol.toStringTag, { value: "Module" })), ut = "https://qaid.dev/lib/html2canvas.min.js", ui = 1e4, pi = 50;
|
|
1456
1479
|
let L = null;
|
|
1457
|
-
function
|
|
1480
|
+
function fi() {
|
|
1458
1481
|
if (typeof document > "u" || typeof window > "u")
|
|
1459
1482
|
return !1;
|
|
1460
1483
|
const i = document.createElement("canvas");
|
|
1461
1484
|
return typeof i.getContext == "function" && !!i.getContext("2d");
|
|
1462
1485
|
}
|
|
1463
|
-
function
|
|
1486
|
+
function mi() {
|
|
1464
1487
|
return window.html2canvas ? Promise.resolve(!0) : L || (L = new Promise((i) => {
|
|
1465
1488
|
if (!document.querySelector(
|
|
1466
|
-
`script[src="${
|
|
1489
|
+
`script[src="${ut}"]`
|
|
1467
1490
|
)) {
|
|
1468
1491
|
const n = document.createElement("script");
|
|
1469
|
-
n.src =
|
|
1492
|
+
n.src = ut, n.async = !0, document.head.appendChild(n);
|
|
1470
1493
|
}
|
|
1471
1494
|
const e = Date.now(), o = () => {
|
|
1472
1495
|
if (window.html2canvas) {
|
|
1473
1496
|
i(!0);
|
|
1474
1497
|
return;
|
|
1475
1498
|
}
|
|
1476
|
-
if (Date.now() - e >
|
|
1499
|
+
if (Date.now() - e > ui) {
|
|
1477
1500
|
L = null, i(!1);
|
|
1478
1501
|
return;
|
|
1479
1502
|
}
|
|
1480
|
-
setTimeout(o,
|
|
1503
|
+
setTimeout(o, pi);
|
|
1481
1504
|
};
|
|
1482
1505
|
o();
|
|
1483
1506
|
}), L);
|
|
1484
1507
|
}
|
|
1485
|
-
async function
|
|
1508
|
+
async function bi(i = {}) {
|
|
1486
1509
|
const { quality: t = 0.8, maxWidth: e = 1280, maxHeight: o = 800 } = i;
|
|
1487
1510
|
try {
|
|
1488
|
-
if (!await
|
|
1511
|
+
if (!await mi() || !window.html2canvas)
|
|
1489
1512
|
return console.warn("html2canvas failed to load"), null;
|
|
1490
1513
|
const s = await window.html2canvas(document.body, {
|
|
1491
1514
|
useCORS: !0,
|
|
@@ -1502,31 +1525,34 @@ async function hi(i = {}) {
|
|
|
1502
1525
|
if (l < 1) {
|
|
1503
1526
|
const d = Math.round(a * l), r = Math.round(c * l), h = document.createElement("canvas");
|
|
1504
1527
|
h.width = d, h.height = r;
|
|
1505
|
-
const
|
|
1506
|
-
return
|
|
1528
|
+
const f = h.getContext("2d");
|
|
1529
|
+
return f ? (f.drawImage(s, 0, 0, d, r), h.toDataURL("image/webp", t)) : null;
|
|
1507
1530
|
}
|
|
1508
1531
|
return s.toDataURL("image/webp", t);
|
|
1509
1532
|
} catch (n) {
|
|
1510
1533
|
return console.warn("DOM screenshot capture failed:", n), null;
|
|
1511
1534
|
}
|
|
1512
1535
|
}
|
|
1513
|
-
const
|
|
1536
|
+
const pt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1514
1537
|
__proto__: null,
|
|
1515
|
-
captureDomScreenshot:
|
|
1516
|
-
isDomScreenshotSupported:
|
|
1517
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
1538
|
+
captureDomScreenshot: bi,
|
|
1539
|
+
isDomScreenshotSupported: fi
|
|
1540
|
+
}, Symbol.toStringTag, { value: "Module" })), T = 12, gi = "#ef4444", vi = ["#ef4444", "#f59e0b", "#22c55e", "#3b82f6", "#111827", "#ffffff"], yi = {
|
|
1518
1541
|
"#ef4444": "red",
|
|
1519
1542
|
"#f59e0b": "amber",
|
|
1520
1543
|
"#22c55e": "green",
|
|
1521
1544
|
"#3b82f6": "blue",
|
|
1522
1545
|
"#111827": "black",
|
|
1523
1546
|
"#ffffff": "white",
|
|
1547
|
+
// The default marker (nudged from #6366f1 so white text on it clears 4.5:1);
|
|
1548
|
+
// the old value keeps its name for sites that pass it explicitly.
|
|
1549
|
+
"#6365f1": "indigo",
|
|
1524
1550
|
"#6366f1": "indigo"
|
|
1525
1551
|
};
|
|
1526
|
-
function
|
|
1527
|
-
return
|
|
1552
|
+
function ft(i) {
|
|
1553
|
+
return yi[i.toLowerCase()] ?? i;
|
|
1528
1554
|
}
|
|
1529
|
-
const
|
|
1555
|
+
const wi = 4, ki = 0.8, xi = {
|
|
1530
1556
|
title: "Annotate screenshot",
|
|
1531
1557
|
instructions: "Draw on the screenshot to highlight or hide details, then choose Done to attach it or Skip to send the original.",
|
|
1532
1558
|
rectangle: "Rectangle",
|
|
@@ -1546,12 +1572,12 @@ function P(i, t) {
|
|
|
1546
1572
|
h: Math.abs(i.y - t.y)
|
|
1547
1573
|
};
|
|
1548
1574
|
}
|
|
1549
|
-
function
|
|
1575
|
+
function qi(i) {
|
|
1550
1576
|
if (i.type === "pen") return i.points.length < 2;
|
|
1551
1577
|
const t = P(i.points[0], i.points[1]);
|
|
1552
1578
|
return t.w < 3 && t.h < 3;
|
|
1553
1579
|
}
|
|
1554
|
-
function
|
|
1580
|
+
function Ci(i, t, e, o) {
|
|
1555
1581
|
i.beginPath(), i.moveTo(t.x, t.y), i.lineTo(e.x, e.y), i.stroke();
|
|
1556
1582
|
const n = Math.atan2(e.y - t.y, e.x - t.x), s = Math.max(10, o * 3);
|
|
1557
1583
|
i.beginPath(), i.moveTo(e.x, e.y), i.lineTo(
|
|
@@ -1562,7 +1588,7 @@ function yi(i, t, e, o) {
|
|
|
1562
1588
|
e.y - s * Math.sin(n + Math.PI / 6)
|
|
1563
1589
|
), i.stroke();
|
|
1564
1590
|
}
|
|
1565
|
-
function
|
|
1591
|
+
function Si(i, t) {
|
|
1566
1592
|
if (t.length !== 0) {
|
|
1567
1593
|
i.beginPath(), i.moveTo(t[0].x, t[0].y);
|
|
1568
1594
|
for (let e = 1; e < t.length; e++)
|
|
@@ -1570,15 +1596,15 @@ function wi(i, t) {
|
|
|
1570
1596
|
i.stroke();
|
|
1571
1597
|
}
|
|
1572
1598
|
}
|
|
1573
|
-
function
|
|
1599
|
+
function Ei(i, t, e, o, n) {
|
|
1574
1600
|
i.fillStyle = "rgb(15, 23, 42)", i.fillRect(t, e, o, n), i.fillStyle = "rgb(37, 47, 63)";
|
|
1575
|
-
for (let s = e; s < e + n; s +=
|
|
1576
|
-
for (let a = t; a < t + o; a +=
|
|
1577
|
-
(Math.floor((a - t) /
|
|
1601
|
+
for (let s = e; s < e + n; s += T)
|
|
1602
|
+
for (let a = t; a < t + o; a += T)
|
|
1603
|
+
(Math.floor((a - t) / T) + Math.floor((s - e) / T)) % 2 === 0 && i.fillRect(
|
|
1578
1604
|
a,
|
|
1579
1605
|
s,
|
|
1580
|
-
Math.min(
|
|
1581
|
-
Math.min(
|
|
1606
|
+
Math.min(T, t + o - a),
|
|
1607
|
+
Math.min(T, e + n - s)
|
|
1582
1608
|
);
|
|
1583
1609
|
}
|
|
1584
1610
|
function B(i, t) {
|
|
@@ -1589,30 +1615,30 @@ function B(i, t) {
|
|
|
1589
1615
|
break;
|
|
1590
1616
|
}
|
|
1591
1617
|
case "arrow":
|
|
1592
|
-
|
|
1618
|
+
Ci(i, t.points[0], t.points[1], t.strokeWidth);
|
|
1593
1619
|
break;
|
|
1594
1620
|
case "pen":
|
|
1595
|
-
|
|
1621
|
+
Si(i, t.points);
|
|
1596
1622
|
break;
|
|
1597
1623
|
case "blur": {
|
|
1598
1624
|
const e = P(t.points[0], t.points[1]);
|
|
1599
|
-
|
|
1625
|
+
Ei(i, e.x, e.y, e.w, e.h);
|
|
1600
1626
|
break;
|
|
1601
1627
|
}
|
|
1602
1628
|
}
|
|
1603
1629
|
i.restore();
|
|
1604
1630
|
}
|
|
1605
|
-
function
|
|
1631
|
+
function Lt(i) {
|
|
1606
1632
|
return new Promise((t, e) => {
|
|
1607
1633
|
const o = new Image();
|
|
1608
1634
|
o.onload = () => t(o), o.onerror = () => e(new Error("Failed to load screenshot")), o.src = i;
|
|
1609
1635
|
});
|
|
1610
1636
|
}
|
|
1611
|
-
async function
|
|
1612
|
-
const o = e.quality ??
|
|
1637
|
+
async function Dt(i, t, e = {}) {
|
|
1638
|
+
const o = e.quality ?? ki;
|
|
1613
1639
|
let n;
|
|
1614
1640
|
try {
|
|
1615
|
-
n = await
|
|
1641
|
+
n = await Lt(i);
|
|
1616
1642
|
} catch {
|
|
1617
1643
|
return i;
|
|
1618
1644
|
}
|
|
@@ -1625,8 +1651,8 @@ async function Tt(i, t, e = {}) {
|
|
|
1625
1651
|
B(a, c);
|
|
1626
1652
|
return s.toDataURL("image/webp", o);
|
|
1627
1653
|
}
|
|
1628
|
-
let
|
|
1629
|
-
class
|
|
1654
|
+
let Ti = 0;
|
|
1655
|
+
class Mt {
|
|
1630
1656
|
shapes = [];
|
|
1631
1657
|
tool = "rect";
|
|
1632
1658
|
opts;
|
|
@@ -1634,7 +1660,7 @@ class At {
|
|
|
1634
1660
|
color;
|
|
1635
1661
|
palette;
|
|
1636
1662
|
strokeWidth;
|
|
1637
|
-
uid = `qaid-annotate-${++
|
|
1663
|
+
uid = `qaid-annotate-${++Ti}`;
|
|
1638
1664
|
container;
|
|
1639
1665
|
canvas;
|
|
1640
1666
|
ctx = null;
|
|
@@ -1648,7 +1674,7 @@ class At {
|
|
|
1648
1674
|
// after the editor is mounted).
|
|
1649
1675
|
resolveResult;
|
|
1650
1676
|
constructor(t) {
|
|
1651
|
-
this.opts = t, this.labels = { ...
|
|
1677
|
+
this.opts = t, this.labels = { ...xi, ...t.labels ?? {} }, this.color = t.color ?? gi, this.palette = (t.palette && t.palette.length ? t.palette : vi).slice(), this.palette.some((e) => e.toLowerCase() === this.color.toLowerCase()) || this.palette.unshift(this.color), this.strokeWidth = t.strokeWidth ?? wi;
|
|
1652
1678
|
}
|
|
1653
1679
|
/** Mount the editor and resolve when the user commits (Done) or skips. */
|
|
1654
1680
|
open() {
|
|
@@ -1670,7 +1696,7 @@ class At {
|
|
|
1670
1696
|
}
|
|
1671
1697
|
/** A round colour swatch button for the toolbar's colour group. */
|
|
1672
1698
|
swatchButton(t) {
|
|
1673
|
-
const e =
|
|
1699
|
+
const e = ft(t), o = q("button", {
|
|
1674
1700
|
type: "button",
|
|
1675
1701
|
class: "qaid-annotate-swatch",
|
|
1676
1702
|
"data-qaid-color": t,
|
|
@@ -1710,19 +1736,19 @@ class At {
|
|
|
1710
1736
|
"aria-label": this.labels.title
|
|
1711
1737
|
});
|
|
1712
1738
|
const a = q("div", { class: "qaid-annotate-tools" });
|
|
1713
|
-
a.appendChild(this.toolButton("rect",
|
|
1739
|
+
a.appendChild(this.toolButton("rect", Zt, this.labels.rectangle)), a.appendChild(this.toolButton("arrow", te, this.labels.arrow)), a.appendChild(this.toolButton("pen", ee, this.labels.pen)), a.appendChild(this.toolButton("blur", ie, this.labels.blur));
|
|
1714
1740
|
const c = q("div", {
|
|
1715
1741
|
class: "qaid-annotate-colors",
|
|
1716
1742
|
role: "group",
|
|
1717
1743
|
"aria-label": this.labels.colors
|
|
1718
1744
|
});
|
|
1719
1745
|
for (const h of this.palette) c.appendChild(this.swatchButton(h));
|
|
1720
|
-
this.undoBtn = this.actionButton("undo",
|
|
1721
|
-
const l = this.actionButton("skip",
|
|
1746
|
+
this.undoBtn = this.actionButton("undo", oe, this.labels.undo, "qaid-annotate-undo"), this.undoBtn.disabled = !0;
|
|
1747
|
+
const l = this.actionButton("skip", se, this.labels.skip, "qaid-annotate-skip"), d = this.actionButton("done", kt, this.labels.done, "qaid-annotate-done"), r = q("div", { class: "qaid-annotate-actions" });
|
|
1722
1748
|
r.appendChild(this.undoBtn), r.appendChild(l), r.appendChild(d), this.toolbar.appendChild(a), this.toolbar.appendChild(c), this.toolbar.appendChild(r), this.container.appendChild(o), this.container.appendChild(n), this.container.appendChild(s), this.container.appendChild(this.toolbar), this.opts.root.appendChild(this.container), this.toolbar.addEventListener("click", this.onToolbarClick), this.canvas.addEventListener("pointerdown", this.onPointerDown), this.container.addEventListener("pointermove", this.onPointerMove), this.container.addEventListener("pointerup", this.onPointerUp), this.container.addEventListener("keydown", this.onKeyDown), this.opts.openDialog?.(this.container, {
|
|
1723
1749
|
labelledbyId: t,
|
|
1724
1750
|
describedbyId: e
|
|
1725
|
-
}), this.opts.announce?.(this.labels.instructions),
|
|
1751
|
+
}), this.opts.announce?.(this.labels.instructions), Lt(this.opts.dataUrl).then((h) => {
|
|
1726
1752
|
this.img = h, this.canvas.width = h.naturalWidth || h.width || 1, this.canvas.height = h.naturalHeight || h.height || 1, this.redraw();
|
|
1727
1753
|
}).catch(() => {
|
|
1728
1754
|
this.img = null, this.redraw();
|
|
@@ -1754,7 +1780,7 @@ class At {
|
|
|
1754
1780
|
n.getAttribute("data-qaid-tool") === t ? "true" : "false"
|
|
1755
1781
|
);
|
|
1756
1782
|
});
|
|
1757
|
-
const o = this.labels[
|
|
1783
|
+
const o = this.labels[Ai[t]];
|
|
1758
1784
|
this.opts.announce?.(`${o} tool selected`);
|
|
1759
1785
|
}
|
|
1760
1786
|
/** Set the active drawing colour; subsequent shapes use it. */
|
|
@@ -1764,7 +1790,7 @@ class At {
|
|
|
1764
1790
|
"aria-pressed",
|
|
1765
1791
|
(o.getAttribute("data-qaid-color") ?? "").toLowerCase() === t.toLowerCase() ? "true" : "false"
|
|
1766
1792
|
);
|
|
1767
|
-
}), this.opts.announce?.(`${
|
|
1793
|
+
}), this.opts.announce?.(`${ft(t)} colour selected`);
|
|
1768
1794
|
}
|
|
1769
1795
|
onToolbarClick = (t) => {
|
|
1770
1796
|
const o = t.target?.closest(
|
|
@@ -1803,7 +1829,7 @@ class At {
|
|
|
1803
1829
|
if (!this.drawing || !this.current) return;
|
|
1804
1830
|
this.drawing = !1;
|
|
1805
1831
|
const t = this.current;
|
|
1806
|
-
if (this.current = null,
|
|
1832
|
+
if (this.current = null, qi(t)) {
|
|
1807
1833
|
this.redraw();
|
|
1808
1834
|
return;
|
|
1809
1835
|
}
|
|
@@ -1832,7 +1858,7 @@ class At {
|
|
|
1832
1858
|
/** Composite the annotations and resolve with the new WebP data URL. */
|
|
1833
1859
|
async done() {
|
|
1834
1860
|
if (this.settled) return;
|
|
1835
|
-
const t = await
|
|
1861
|
+
const t = await Dt(this.opts.dataUrl, this.shapes, {
|
|
1836
1862
|
quality: this.opts.quality
|
|
1837
1863
|
});
|
|
1838
1864
|
this.opts.announce?.("Annotated screenshot attached"), this.settle(t);
|
|
@@ -1848,27 +1874,27 @@ class At {
|
|
|
1848
1874
|
this.toolbar.removeEventListener("click", this.onToolbarClick), this.canvas.removeEventListener("pointerdown", this.onPointerDown), this.container.removeEventListener("pointermove", this.onPointerMove), this.container.removeEventListener("pointerup", this.onPointerUp), this.container.removeEventListener("keydown", this.onKeyDown), this.opts.closeDialog?.(), this.container.remove();
|
|
1849
1875
|
}
|
|
1850
1876
|
}
|
|
1851
|
-
const
|
|
1877
|
+
const Ai = {
|
|
1852
1878
|
rect: "rectangle",
|
|
1853
1879
|
arrow: "arrow",
|
|
1854
1880
|
pen: "pen",
|
|
1855
1881
|
blur: "blur"
|
|
1856
1882
|
};
|
|
1857
|
-
function
|
|
1858
|
-
return new
|
|
1883
|
+
function Ii(i) {
|
|
1884
|
+
return new Mt(i).open();
|
|
1859
1885
|
}
|
|
1860
|
-
const
|
|
1886
|
+
const mt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1861
1887
|
__proto__: null,
|
|
1862
|
-
AnnotationEditor:
|
|
1863
|
-
compositeAnnotations:
|
|
1888
|
+
AnnotationEditor: Mt,
|
|
1889
|
+
compositeAnnotations: Dt,
|
|
1864
1890
|
drawShape: B,
|
|
1865
|
-
openAnnotationEditor:
|
|
1891
|
+
openAnnotationEditor: Ii,
|
|
1866
1892
|
rectFromPoints: P
|
|
1867
1893
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1868
|
-
|
|
1869
|
-
const
|
|
1870
|
-
function
|
|
1871
|
-
const o =
|
|
1894
|
+
Je();
|
|
1895
|
+
const Li = document;
|
|
1896
|
+
function p(i, t, ...e) {
|
|
1897
|
+
const o = Li.createElement(i);
|
|
1872
1898
|
if (t) {
|
|
1873
1899
|
if (t.class && (o.className = t.class), t.style && (o.style.cssText = t.style), t.html != null && (o.innerHTML = t.html), t.text != null && (o.textContent = t.text), t.attrs)
|
|
1874
1900
|
for (const n in t.attrs) o.setAttribute(n, t.attrs[n]);
|
|
@@ -1879,7 +1905,7 @@ function m(i, t, ...e) {
|
|
|
1879
1905
|
n != null && n !== !1 && o.append(n);
|
|
1880
1906
|
return o;
|
|
1881
1907
|
}
|
|
1882
|
-
class
|
|
1908
|
+
class Di {
|
|
1883
1909
|
constructor(t) {
|
|
1884
1910
|
this.host = t;
|
|
1885
1911
|
}
|
|
@@ -1906,8 +1932,8 @@ class Ei {
|
|
|
1906
1932
|
async startRecording(t = []) {
|
|
1907
1933
|
if (!(this.isRecording || this.host.state !== "IDLE"))
|
|
1908
1934
|
try {
|
|
1909
|
-
this.networkCapture =
|
|
1910
|
-
const { createVideoRecorder: e } = await Promise.resolve().then(() =>
|
|
1935
|
+
this.networkCapture = ei();
|
|
1936
|
+
const { createVideoRecorder: e } = await Promise.resolve().then(() => It);
|
|
1911
1937
|
this.videoRecorder = e({
|
|
1912
1938
|
maxDuration: this.host.config.videoOptions.maxDuration,
|
|
1913
1939
|
redactionElements: t
|
|
@@ -1917,7 +1943,7 @@ class Ei {
|
|
|
1917
1943
|
this.isRecording && (this.recordedBlob = o, this.isRecording = !1, this.host.announceMsg("Recording stopped"), this.removeRecordingIndicator(), document.removeEventListener("keydown", this.host.boundKeyDown), this.host.setButtonsDisabled(!1), o && o.size > 0 ? this.showRecordingPreview() : this.cleanupRecording());
|
|
1918
1944
|
}), await this.videoRecorder.start(), this.isRecording = !0, this.host.announceMsg("Recording started"), this.host.setButtonsDisabled(!0), this.showRecordingIndicator(), document.addEventListener("keydown", this.host.boundKeyDown);
|
|
1919
1945
|
} catch (e) {
|
|
1920
|
-
e instanceof Error && /current tab/i.test(e.message) && this.host.announceMsg(e.message), this.cleanupRecording();
|
|
1946
|
+
e instanceof Error && /current tab|cannot blur/i.test(e.message) && this.host.announceMsg(e.message), this.cleanupRecording();
|
|
1921
1947
|
}
|
|
1922
1948
|
}
|
|
1923
1949
|
async stopRecording() {
|
|
@@ -1937,27 +1963,27 @@ class Ei {
|
|
|
1937
1963
|
startPicking() {
|
|
1938
1964
|
if (this.isRecording || this.host.state !== "IDLE") return;
|
|
1939
1965
|
this.host.setState("REDACT_PICKING"), this.redactPicks = [];
|
|
1940
|
-
const t = this.host.ensureOverlayHost(), e =
|
|
1966
|
+
const t = this.host.ensureOverlayHost(), e = p("div", { style: "position:absolute;inset:0;" }), o = p(
|
|
1941
1967
|
"div",
|
|
1942
1968
|
{ class: "qaid-redact-picker", style: "position:fixed;inset:0;pointer-events:none;" },
|
|
1943
1969
|
e,
|
|
1944
1970
|
// Control bar — the only pointer-interactive part of the overlay.
|
|
1945
|
-
|
|
1971
|
+
p(
|
|
1946
1972
|
"div",
|
|
1947
1973
|
{
|
|
1948
1974
|
style: "position:fixed;left:50%;bottom:24px;transform:translateX(-50%);display:flex;gap:12px;align-items:center;pointer-events:auto;background:#0b1220;color:#fff;border:1px solid #ff6b6b;border-radius:9999px;padding:10px 16px;font:600 13px system-ui,sans-serif;box-shadow:0 8px 30px rgba(0,0,0,.5);"
|
|
1949
1975
|
},
|
|
1950
|
-
|
|
1976
|
+
p("span", {
|
|
1951
1977
|
text: "Click sensitive areas to blur",
|
|
1952
1978
|
attrs: { "data-qaid-redact-label": "" }
|
|
1953
1979
|
}),
|
|
1954
|
-
|
|
1980
|
+
p("button", {
|
|
1955
1981
|
text: "Start recording",
|
|
1956
1982
|
attrs: { type: "button" },
|
|
1957
1983
|
style: "cursor:pointer;border:0;border-radius:9999px;padding:8px 14px;background:#ff6b6b;color:#0b1220;font:inherit;",
|
|
1958
1984
|
on: { click: () => this.finishRedactionPicking(!0) }
|
|
1959
1985
|
}),
|
|
1960
|
-
|
|
1986
|
+
p("button", {
|
|
1961
1987
|
text: "Cancel",
|
|
1962
1988
|
attrs: { type: "button" },
|
|
1963
1989
|
style: "cursor:pointer;border:0;background:transparent;color:#9fb3c8;font:inherit;",
|
|
@@ -1988,7 +2014,7 @@ class Ei {
|
|
|
1988
2014
|
for (const e of this.redactPicks) {
|
|
1989
2015
|
const o = e.getBoundingClientRect();
|
|
1990
2016
|
o.width <= 0 || o.height <= 0 || t.appendChild(
|
|
1991
|
-
|
|
2017
|
+
p("div", {
|
|
1992
2018
|
style: `position:fixed;left:${o.left}px;top:${o.top}px;width:${o.width}px;height:${o.height}px;border:2px solid #ff6b6b;border-radius:4px;background:rgba(255,107,107,.18);pointer-events:none;`
|
|
1993
2019
|
})
|
|
1994
2020
|
);
|
|
@@ -2001,15 +2027,15 @@ class Ei {
|
|
|
2001
2027
|
}
|
|
2002
2028
|
showRecordingIndicator() {
|
|
2003
2029
|
const t = this.host.ensureOverlayHost();
|
|
2004
|
-
this.recordingIndicator =
|
|
2030
|
+
this.recordingIndicator = p(
|
|
2005
2031
|
"div",
|
|
2006
2032
|
{ class: "qaid-recording-indicator", style: `z-index:${this.host.config.zIndex + 100}` },
|
|
2007
|
-
|
|
2008
|
-
|
|
2033
|
+
p("div", { class: "qaid-recording-dot" }),
|
|
2034
|
+
p("span", {
|
|
2009
2035
|
class: "qaid-recording-time",
|
|
2010
2036
|
text: this.formatTime(this.host.config.videoOptions.maxDuration)
|
|
2011
2037
|
}),
|
|
2012
|
-
|
|
2038
|
+
p("button", {
|
|
2013
2039
|
class: "qaid-recording-stop",
|
|
2014
2040
|
text: "Stop",
|
|
2015
2041
|
attrs: { type: "button" },
|
|
@@ -2033,34 +2059,34 @@ class Ei {
|
|
|
2033
2059
|
this.recordingIndicator && (this.recordingIndicator.remove(), this.recordingIndicator = null);
|
|
2034
2060
|
}
|
|
2035
2061
|
showRecordingPreview() {
|
|
2036
|
-
const t = this.host.ensureOverlayHost(), e = URL.createObjectURL(this.recordedBlob), o = `qaid-video-title-${this.host.uid}`, n =
|
|
2062
|
+
const t = this.host.ensureOverlayHost(), e = URL.createObjectURL(this.recordedBlob), o = `qaid-video-title-${this.host.uid}`, n = p("h3", { text: "Review your recording", attrs: { id: o } }), s = p("video");
|
|
2037
2063
|
s.src = e, s.controls = !0, s.autoplay = !0, s.muted = !0;
|
|
2038
|
-
const a =
|
|
2064
|
+
const a = p("textarea", {
|
|
2039
2065
|
attrs: {
|
|
2040
2066
|
placeholder: "Optional: Describe the issue you recorded...",
|
|
2041
2067
|
"aria-label": "Describe the issue you recorded"
|
|
2042
2068
|
}
|
|
2043
|
-
}), c =
|
|
2069
|
+
}), c = p("button", {
|
|
2044
2070
|
class: "qaid-video-btn qaid-video-btn-send",
|
|
2045
2071
|
text: "Send",
|
|
2046
2072
|
attrs: { type: "button" },
|
|
2047
2073
|
on: { click: () => this.submitVideoFeedback(a.value.trim() || null, c) }
|
|
2048
|
-
}), l =
|
|
2074
|
+
}), l = p(
|
|
2049
2075
|
"div",
|
|
2050
2076
|
{ class: "qaid-video-preview-box" },
|
|
2051
2077
|
n,
|
|
2052
2078
|
s,
|
|
2053
2079
|
a,
|
|
2054
|
-
|
|
2080
|
+
p(
|
|
2055
2081
|
"div",
|
|
2056
2082
|
{ class: "qaid-video-preview-actions" },
|
|
2057
|
-
|
|
2083
|
+
p("button", {
|
|
2058
2084
|
class: "qaid-video-btn qaid-video-btn-cancel",
|
|
2059
2085
|
text: "Cancel",
|
|
2060
2086
|
attrs: { type: "button" },
|
|
2061
2087
|
on: { click: () => this.cancelRecordingPreview() }
|
|
2062
2088
|
}),
|
|
2063
|
-
|
|
2089
|
+
p("button", {
|
|
2064
2090
|
class: "qaid-video-btn qaid-video-btn-rerecord",
|
|
2065
2091
|
text: "Re-record",
|
|
2066
2092
|
attrs: { type: "button" },
|
|
@@ -2073,7 +2099,7 @@ class Ei {
|
|
|
2073
2099
|
c
|
|
2074
2100
|
)
|
|
2075
2101
|
);
|
|
2076
|
-
this.videoPreview =
|
|
2102
|
+
this.videoPreview = p(
|
|
2077
2103
|
"div",
|
|
2078
2104
|
{ class: "qaid-video-preview", style: `z-index:${this.host.config.zIndex + 100}` },
|
|
2079
2105
|
l
|
|
@@ -2094,35 +2120,52 @@ class Ei {
|
|
|
2094
2120
|
this.isSendingVideo = !0, e.disabled = !0, e.textContent = "Sending...";
|
|
2095
2121
|
const o = new FormData();
|
|
2096
2122
|
o.append("video", this.recordedBlob, `recording.${this.recordedBlob.type.includes("mp4") ? "mp4" : "webm"}`), o.append("pageUrl", window.location.href), o.append("visitorId", this.host.visitorId), this.host.config.apiKey && o.append("apiKey", this.host.config.apiKey), t && o.append("message", t), this.host.consoleCapture && o.append("consoleErrors", JSON.stringify(this.host.consoleCapture.errors)), this.networkCapture && o.append("networkErrors", JSON.stringify(this.networkCapture.errors));
|
|
2097
|
-
let n = null;
|
|
2123
|
+
let n = null, s = null;
|
|
2098
2124
|
try {
|
|
2099
|
-
const
|
|
2125
|
+
const a = await fetch(`${this.host.config.endpoint}/video`, {
|
|
2100
2126
|
method: "POST",
|
|
2101
2127
|
body: o
|
|
2102
2128
|
});
|
|
2103
|
-
if (
|
|
2129
|
+
if (a.ok) {
|
|
2104
2130
|
this.host.announceMsg("Recording sent");
|
|
2105
2131
|
try {
|
|
2106
|
-
n = (await
|
|
2132
|
+
n = (await a.json())?.id ?? null;
|
|
2107
2133
|
} catch {
|
|
2108
2134
|
}
|
|
2109
2135
|
} else
|
|
2110
|
-
console.error("Failed to submit video feedback:", await
|
|
2111
|
-
} catch (
|
|
2112
|
-
console.error("Failed to submit video feedback:",
|
|
2136
|
+
console.error("Failed to submit video feedback:", await a.text()), s = a.status === 413 ? "This recording is too large to send. Try a shorter one." : "Your recording could not be sent.";
|
|
2137
|
+
} catch (a) {
|
|
2138
|
+
console.error("Failed to submit video feedback:", a), s = "Your recording could not be sent. Check your connection and try again.";
|
|
2139
|
+
}
|
|
2140
|
+
if (this.isSendingVideo = !1, s) {
|
|
2141
|
+
this.showSendError(s, e);
|
|
2142
|
+
return;
|
|
2143
|
+
}
|
|
2144
|
+
this.removeVideoPreview(), this.cleanupRecording(), await this.host.tryLaunchQuest("video", n);
|
|
2145
|
+
}
|
|
2146
|
+
/**
|
|
2147
|
+
* Keep the preview open and say the upload failed. Closing it, as a success
|
|
2148
|
+
* does, told the visitor their recording had arrived when it had not. Send
|
|
2149
|
+
* is re-enabled for another try; Cancel and Re-record still work.
|
|
2150
|
+
*/
|
|
2151
|
+
showSendError(t, e) {
|
|
2152
|
+
this.host.announceMsg(`Failed to send recording. ${t}`, !0), e.disabled = !1, e.textContent = "Send";
|
|
2153
|
+
const o = this.videoPreview?.querySelector(".qaid-video-preview-actions");
|
|
2154
|
+
if (o) {
|
|
2155
|
+
let n = this.videoPreview.querySelector(".qaid-video-error");
|
|
2156
|
+
n || (n = p("p", { class: "qaid-video-error" }), o.before(n)), n.textContent = t;
|
|
2113
2157
|
}
|
|
2114
|
-
this.isSendingVideo = !1, this.removeVideoPreview(), this.cleanupRecording(), await this.host.tryLaunchQuest("video", n);
|
|
2115
2158
|
}
|
|
2116
2159
|
cleanupRecording() {
|
|
2117
2160
|
this.isRecording = !1, this.removeRecordingIndicator(), this.videoRecorder && (this.videoRecorder.destroy(), this.videoRecorder = null), this.networkCapture && (this.networkCapture.restore(), this.networkCapture = null), this.recordedBlob && (this.recordedBlob = null), this.host.setButtonsDisabled(!1), this.host.overlayShadowHost && this.host.state === "IDLE" && (this.host.overlayShadowHost.style.pointerEvents = "none");
|
|
2118
2161
|
}
|
|
2119
2162
|
}
|
|
2120
|
-
const
|
|
2163
|
+
const bt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2121
2164
|
__proto__: null,
|
|
2122
|
-
RecordingController:
|
|
2165
|
+
RecordingController: Di
|
|
2123
2166
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2124
|
-
async function
|
|
2125
|
-
const { quality: t =
|
|
2167
|
+
async function Mi(i = {}) {
|
|
2168
|
+
const { quality: t = 0.8, maxWidth: e = 1280, maxHeight: o = 800 } = i;
|
|
2126
2169
|
try {
|
|
2127
2170
|
if (!navigator.mediaDevices?.getDisplayMedia)
|
|
2128
2171
|
return console.warn("Screen Capture API not available"), null;
|
|
@@ -2142,19 +2185,19 @@ async function Ti(i = {}) {
|
|
|
2142
2185
|
};
|
|
2143
2186
|
w();
|
|
2144
2187
|
}), await new Promise((g) => setTimeout(g, 100));
|
|
2145
|
-
const l = a.width || c.videoWidth, d = a.height || c.videoHeight, r = Math.min(e / l, o / d, 1), h = Math.round(l * r),
|
|
2146
|
-
b.width = h, b.height =
|
|
2188
|
+
const l = a.width || c.videoWidth, d = a.height || c.videoHeight, r = Math.min(e / l, o / d, 1), h = Math.round(l * r), f = Math.round(d * r), b = document.createElement("canvas");
|
|
2189
|
+
b.width = h, b.height = f;
|
|
2147
2190
|
const y = b.getContext("2d");
|
|
2148
|
-
return y ? (y.drawImage(c, 0, 0, h,
|
|
2191
|
+
return y ? (y.drawImage(c, 0, 0, h, f), s.stop(), b.toDataURL("image/webp", t)) : (s.stop(), null);
|
|
2149
2192
|
} catch (n) {
|
|
2150
2193
|
return console.warn("Screenshot capture failed:", n), null;
|
|
2151
2194
|
}
|
|
2152
2195
|
}
|
|
2153
|
-
const
|
|
2196
|
+
const gt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2154
2197
|
__proto__: null,
|
|
2155
|
-
captureScreenshot:
|
|
2198
|
+
captureScreenshot: Mi
|
|
2156
2199
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2157
|
-
class
|
|
2200
|
+
class Ri {
|
|
2158
2201
|
constructor(t) {
|
|
2159
2202
|
this.host = t;
|
|
2160
2203
|
}
|
|
@@ -2182,15 +2225,17 @@ class Ai {
|
|
|
2182
2225
|
}
|
|
2183
2226
|
showBottomSheet() {
|
|
2184
2227
|
const t = this.host.ensureOverlayHost(), e = document.createElement("div");
|
|
2185
|
-
e.className = "qaid-bottom-sheet", e.style.zIndex = String(this.host.config.zIndex + 3), e.
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2228
|
+
e.className = "qaid-bottom-sheet", e.style.zIndex = String(this.host.config.zIndex + 3), e.appendChild(
|
|
2229
|
+
p(
|
|
2230
|
+
"div",
|
|
2231
|
+
{ class: "qaid-bottom-sheet-content" },
|
|
2232
|
+
p("div", { class: "qaid-bottom-sheet-handle" }),
|
|
2233
|
+
this.buildModalContent()
|
|
2234
|
+
)
|
|
2235
|
+
), this.host.applyVars(e), t.appendChild(e), this.modalContainer = e, this.setupModalInteractions();
|
|
2191
2236
|
}
|
|
2192
2237
|
showPositionedModal() {
|
|
2193
|
-
const t = this.host.ensureOverlayHost(), { modal: e, arrow: o } =
|
|
2238
|
+
const t = this.host.ensureOverlayHost(), { modal: e, arrow: o } = He(
|
|
2194
2239
|
this.host.selectedBounds,
|
|
2195
2240
|
window.innerWidth,
|
|
2196
2241
|
window.innerHeight,
|
|
@@ -2206,25 +2251,65 @@ class Ai {
|
|
|
2206
2251
|
const n = document.createElement("div");
|
|
2207
2252
|
n.className = "qaid-modal-arrow", n.style.left = `${o.left}px`;
|
|
2208
2253
|
const s = document.createElement("div");
|
|
2209
|
-
s.className = "qaid-modal-box", s.
|
|
2210
|
-
}
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2254
|
+
s.className = "qaid-modal-box", s.appendChild(this.buildModalContent()), this.modalContainer.appendChild(n), this.modalContainer.appendChild(s), this.host.applyVars(this.modalContainer), t.appendChild(this.modalContainer), this.setupModalInteractions();
|
|
2255
|
+
}
|
|
2256
|
+
/**
|
|
2257
|
+
* The modal's contents, built as nodes rather than an HTML string.
|
|
2258
|
+
*
|
|
2259
|
+
* Every piece of copy (title, subtitle, placeholder, button) goes in as
|
|
2260
|
+
* text, so a `<`, `&` or `"` in a translation shows as written instead of
|
|
2261
|
+
* being parsed as markup or cutting an attribute short. Only the icons are
|
|
2262
|
+
* markup, because they are documented as SVG/HTML strings.
|
|
2263
|
+
*/
|
|
2264
|
+
buildModalContent() {
|
|
2265
|
+
const { config: t, uid: e } = this.host, o = t.text, n = this.host.feedbackData.feedbackType, s = n === "up", a = t.positiveIcon || V, c = t.negativeIcon || N, l = t.buttonClass ? `qaid-type-toggle qaid-type-toggle-custom ${t.buttonClass} ${s ? "qaid-btn-up" : "qaid-btn-down"}` : `qaid-type-toggle ${s ? "qaid-type-up" : "qaid-type-down"}`, d = s ? "Feedback type: positive" : "Feedback type: negative", r = n === "neutral" ? p("span", {
|
|
2266
|
+
class: "qaid-type-static",
|
|
2267
|
+
html: t.feedbackIcon || wt,
|
|
2268
|
+
attrs: { "aria-hidden": "true" }
|
|
2269
|
+
}) : p("button", {
|
|
2270
|
+
class: l,
|
|
2271
|
+
html: s ? a : c,
|
|
2272
|
+
attrs: {
|
|
2273
|
+
type: "button",
|
|
2274
|
+
title: "Click to switch",
|
|
2275
|
+
"aria-pressed": String(s),
|
|
2276
|
+
"aria-label": d
|
|
2277
|
+
}
|
|
2278
|
+
}), h = document.createDocumentFragment();
|
|
2279
|
+
return h.append(
|
|
2280
|
+
p(
|
|
2281
|
+
"div",
|
|
2282
|
+
{ class: "qaid-modal-header" },
|
|
2283
|
+
r,
|
|
2284
|
+
p(
|
|
2285
|
+
"div",
|
|
2286
|
+
{ class: "qaid-modal-header-text" },
|
|
2287
|
+
p("h3", {
|
|
2288
|
+
class: "qaid-modal-title",
|
|
2289
|
+
text: o.modalTitle,
|
|
2290
|
+
attrs: { id: `qaid-modal-title-${e}` }
|
|
2291
|
+
}),
|
|
2292
|
+
p("p", {
|
|
2293
|
+
class: "qaid-modal-subtitle",
|
|
2294
|
+
text: o.modalSubtitle,
|
|
2295
|
+
attrs: { id: `qaid-modal-subtitle-${e}` }
|
|
2296
|
+
})
|
|
2297
|
+
)
|
|
2298
|
+
),
|
|
2299
|
+
p("textarea", {
|
|
2300
|
+
class: "qaid-textarea",
|
|
2301
|
+
attrs: { "aria-label": o.modalSubtitle, placeholder: o.placeholder }
|
|
2302
|
+
}),
|
|
2303
|
+
p(
|
|
2304
|
+
"div",
|
|
2305
|
+
{ class: "qaid-btn-row" },
|
|
2306
|
+
p("button", {
|
|
2307
|
+
class: "qaid-btn-submit",
|
|
2308
|
+
text: o.skipButton,
|
|
2309
|
+
attrs: { type: "button" }
|
|
2310
|
+
})
|
|
2311
|
+
)
|
|
2312
|
+
), h;
|
|
2228
2313
|
}
|
|
2229
2314
|
setupModalInteractions() {
|
|
2230
2315
|
this.host.openDialogA11y(this.modalContainer, {
|
|
@@ -2253,59 +2338,79 @@ class Ai {
|
|
|
2253
2338
|
});
|
|
2254
2339
|
}
|
|
2255
2340
|
async submitMessage(t) {
|
|
2256
|
-
let e =
|
|
2341
|
+
let e = null;
|
|
2257
2342
|
if (this.host.feedbackId) {
|
|
2258
2343
|
try {
|
|
2259
|
-
await fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
|
|
2344
|
+
const o = await fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
|
|
2260
2345
|
method: "PATCH",
|
|
2261
2346
|
headers: { "Content-Type": "application/json" },
|
|
2262
2347
|
body: JSON.stringify({ message: t })
|
|
2263
|
-
})
|
|
2348
|
+
});
|
|
2349
|
+
e = o.ok, o.ok || console.error("Failed to submit feedback message: HTTP", o.status);
|
|
2264
2350
|
} catch (o) {
|
|
2265
|
-
console.error("Failed to submit feedback message:", o);
|
|
2351
|
+
console.error("Failed to submit feedback message:", o), e = !1;
|
|
2266
2352
|
}
|
|
2267
2353
|
this.host.setFeedbackId(null);
|
|
2268
2354
|
}
|
|
2355
|
+
if (e === !1) {
|
|
2356
|
+
this.showResult(!1);
|
|
2357
|
+
return;
|
|
2358
|
+
}
|
|
2269
2359
|
if (e && !this.host.config.hideConfirmation) {
|
|
2270
|
-
this.
|
|
2360
|
+
this.showResult(!0);
|
|
2271
2361
|
return;
|
|
2272
2362
|
}
|
|
2273
2363
|
this.close();
|
|
2274
2364
|
}
|
|
2275
2365
|
/**
|
|
2276
|
-
* Replace the modal's contents with a checkmark and a short
|
|
2366
|
+
* Replace the modal's contents with the outcome: a checkmark and a short
|
|
2367
|
+
* acknowledgement, or an error mark and a "not sent" notice.
|
|
2277
2368
|
*
|
|
2278
2369
|
* The submit button that had focus is gone by this point, so focus moves to
|
|
2279
2370
|
* the heading (WCAG 2.4.3) and the message is announced. Mirrors the quests
|
|
2280
|
-
* embed's thank-you screen so the two products confirm the same way.
|
|
2371
|
+
* embed's thank-you screen so the two products confirm the same way. Copy
|
|
2372
|
+
* goes in as text, never markup.
|
|
2281
2373
|
*/
|
|
2282
|
-
|
|
2283
|
-
const
|
|
2284
|
-
if (!
|
|
2374
|
+
showResult(t) {
|
|
2375
|
+
const e = this.modalContainer?.querySelector(".qaid-modal-box") ?? this.modalContainer?.querySelector(".qaid-bottom-sheet-content") ?? this.modalContainer;
|
|
2376
|
+
if (!e) {
|
|
2285
2377
|
this.close();
|
|
2286
2378
|
return;
|
|
2287
2379
|
}
|
|
2288
|
-
const
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2380
|
+
const o = this.host.config.text, n = t ? o.confirmationTitle : o.errorTitle, s = t ? o.confirmationMessage : o.errorMessage, a = p("h3", {
|
|
2381
|
+
class: "qaid-confirm-title",
|
|
2382
|
+
text: n,
|
|
2383
|
+
attrs: { id: `qaid-confirm-title-${this.host.uid}`, tabindex: "-1" }
|
|
2384
|
+
});
|
|
2385
|
+
e.textContent = "", e.appendChild(
|
|
2386
|
+
p(
|
|
2387
|
+
"div",
|
|
2388
|
+
{ class: t ? "qaid-confirm" : "qaid-confirm qaid-confirm-error" },
|
|
2389
|
+
p("span", {
|
|
2390
|
+
class: "qaid-confirm-icon",
|
|
2391
|
+
html: t ? kt : ne,
|
|
2392
|
+
attrs: { "aria-hidden": "true" }
|
|
2393
|
+
}),
|
|
2394
|
+
a,
|
|
2395
|
+
p("p", { class: "qaid-confirm-message", text: s }),
|
|
2396
|
+
p("button", {
|
|
2397
|
+
class: "qaid-btn-submit qaid-confirm-close",
|
|
2398
|
+
text: o.confirmationClose,
|
|
2399
|
+
attrs: { type: "button" },
|
|
2400
|
+
on: { click: () => this.close() }
|
|
2401
|
+
})
|
|
2402
|
+
)
|
|
2403
|
+
), requestAnimationFrame(() => a.focus()), this.host.announceMsg(`${n} ${s}`, !0);
|
|
2299
2404
|
}
|
|
2300
2405
|
}
|
|
2301
|
-
const
|
|
2406
|
+
const vt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2302
2407
|
__proto__: null,
|
|
2303
|
-
ModalController:
|
|
2304
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
2305
|
-
function
|
|
2408
|
+
ModalController: Ri
|
|
2409
|
+
}, Symbol.toStringTag, { value: "Module" })), Rt = ["data-comp", "data-qa", "data-testid", "data-id"];
|
|
2410
|
+
function Pt(i, t = document.body) {
|
|
2306
2411
|
let e = i;
|
|
2307
2412
|
for (; e && e !== t; ) {
|
|
2308
|
-
for (const o of
|
|
2413
|
+
for (const o of Rt) {
|
|
2309
2414
|
const n = e.getAttribute(o);
|
|
2310
2415
|
if (n)
|
|
2311
2416
|
return `${o}="${n}"`;
|
|
@@ -2314,37 +2419,37 @@ function It(i, t = document.body) {
|
|
|
2314
2419
|
}
|
|
2315
2420
|
return null;
|
|
2316
2421
|
}
|
|
2317
|
-
function
|
|
2422
|
+
function Pi(i, t = 100) {
|
|
2318
2423
|
const e = i.textContent?.trim().slice(0, t) || "";
|
|
2319
2424
|
return e.length === t ? e + "..." : e;
|
|
2320
2425
|
}
|
|
2321
|
-
function
|
|
2426
|
+
function Bi(i) {
|
|
2322
2427
|
let t = 1, e = i.previousElementSibling;
|
|
2323
2428
|
for (; e; )
|
|
2324
2429
|
t++, e = e.previousElementSibling;
|
|
2325
2430
|
return t;
|
|
2326
2431
|
}
|
|
2327
|
-
function
|
|
2432
|
+
function Hi(i) {
|
|
2328
2433
|
const t = [];
|
|
2329
2434
|
let e = i;
|
|
2330
2435
|
for (; e && e !== document.body && e !== document.documentElement; ) {
|
|
2331
|
-
const o = e.tagName.toLowerCase(), n =
|
|
2436
|
+
const o = e.tagName.toLowerCase(), n = Bi(e);
|
|
2332
2437
|
t.unshift(`${o}:nth-child(${n})`), e = e.parentElement;
|
|
2333
2438
|
}
|
|
2334
2439
|
return t.length > 0 ? `body > ${t.join(" > ")}` : "body";
|
|
2335
2440
|
}
|
|
2336
|
-
function
|
|
2441
|
+
function Oi(i) {
|
|
2337
2442
|
return i.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1");
|
|
2338
2443
|
}
|
|
2339
|
-
function
|
|
2340
|
-
const t =
|
|
2341
|
-
return t ? `[${t}]` : i.id ? `#${
|
|
2444
|
+
function zi(i) {
|
|
2445
|
+
const t = Pt(i);
|
|
2446
|
+
return t ? `[${t}]` : i.id ? `#${Oi(i.id)}` : Hi(i);
|
|
2342
2447
|
}
|
|
2343
2448
|
function F(i) {
|
|
2344
|
-
const t =
|
|
2345
|
-
return { selector:
|
|
2449
|
+
const t = Pi(i), e = Pt(i);
|
|
2450
|
+
return { selector: zi(i), text: t, dataAttr: e };
|
|
2346
2451
|
}
|
|
2347
|
-
const
|
|
2452
|
+
const $i = [
|
|
2348
2453
|
"a[href]",
|
|
2349
2454
|
"button",
|
|
2350
2455
|
"input:not([type=hidden])",
|
|
@@ -2363,9 +2468,9 @@ const Pi = [
|
|
|
2363
2468
|
"p",
|
|
2364
2469
|
"li",
|
|
2365
2470
|
"label",
|
|
2366
|
-
...
|
|
2367
|
-
].join(","),
|
|
2368
|
-
function
|
|
2471
|
+
...Rt.map((i) => `[${i}]`)
|
|
2472
|
+
].join(","), _i = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
|
|
2473
|
+
function Fi(i) {
|
|
2369
2474
|
if (i.hasAttribute("hidden") || i.getAttribute("aria-hidden") === "true") return !1;
|
|
2370
2475
|
const t = i.ownerDocument?.defaultView;
|
|
2371
2476
|
if (t && typeof t.getComputedStyle == "function") {
|
|
@@ -2374,14 +2479,14 @@ function Hi(i) {
|
|
|
2374
2479
|
}
|
|
2375
2480
|
return !0;
|
|
2376
2481
|
}
|
|
2377
|
-
function
|
|
2378
|
-
const t = i.root ?? document.body, e = i.selector ??
|
|
2482
|
+
function Vi(i = {}) {
|
|
2483
|
+
const t = i.root ?? document.body, e = i.selector ?? $i, o = i.isExcluded ?? (() => !1), n = i.isVisible ?? Fi;
|
|
2379
2484
|
return Array.from(t.querySelectorAll(e)).filter(
|
|
2380
2485
|
(s) => !o(s) && n(s)
|
|
2381
2486
|
);
|
|
2382
2487
|
}
|
|
2383
|
-
function
|
|
2384
|
-
const t = i.candidates ??
|
|
2488
|
+
function Ni(i) {
|
|
2489
|
+
const t = i.candidates ?? Vi({
|
|
2385
2490
|
root: i.root,
|
|
2386
2491
|
selector: i.selector,
|
|
2387
2492
|
isExcluded: i.isExcluded,
|
|
@@ -2398,7 +2503,7 @@ function $i(i) {
|
|
|
2398
2503
|
if (!e) return;
|
|
2399
2504
|
const k = u;
|
|
2400
2505
|
if (typeof k.focus == "function") {
|
|
2401
|
-
u.getAttribute("tabindex") === null && !
|
|
2506
|
+
u.getAttribute("tabindex") === null && !_i.test(u.tagName) && (u.setAttribute("tabindex", "-1"), n.add(u));
|
|
2402
2507
|
try {
|
|
2403
2508
|
k.focus();
|
|
2404
2509
|
} catch {
|
|
@@ -2417,7 +2522,7 @@ function $i(i) {
|
|
|
2417
2522
|
function h() {
|
|
2418
2523
|
r(s + 1);
|
|
2419
2524
|
}
|
|
2420
|
-
function
|
|
2525
|
+
function f() {
|
|
2421
2526
|
r(s - 1);
|
|
2422
2527
|
}
|
|
2423
2528
|
function b() {
|
|
@@ -2438,7 +2543,7 @@ function $i(i) {
|
|
|
2438
2543
|
if (!a)
|
|
2439
2544
|
switch (u.key) {
|
|
2440
2545
|
case "Tab":
|
|
2441
|
-
u.preventDefault(), u.stopPropagation(), u.shiftKey ?
|
|
2546
|
+
u.preventDefault(), u.stopPropagation(), u.shiftKey ? f() : h();
|
|
2442
2547
|
break;
|
|
2443
2548
|
case "ArrowDown":
|
|
2444
2549
|
case "ArrowRight":
|
|
@@ -2446,7 +2551,7 @@ function $i(i) {
|
|
|
2446
2551
|
break;
|
|
2447
2552
|
case "ArrowUp":
|
|
2448
2553
|
case "ArrowLeft":
|
|
2449
|
-
u.preventDefault(), u.stopPropagation(),
|
|
2554
|
+
u.preventDefault(), u.stopPropagation(), f();
|
|
2450
2555
|
break;
|
|
2451
2556
|
case "Enter":
|
|
2452
2557
|
case " ":
|
|
@@ -2464,7 +2569,7 @@ function $i(i) {
|
|
|
2464
2569
|
getIndex: () => s,
|
|
2465
2570
|
getCurrent: b,
|
|
2466
2571
|
next: h,
|
|
2467
|
-
prev:
|
|
2572
|
+
prev: f,
|
|
2468
2573
|
moveTo: r,
|
|
2469
2574
|
select: g,
|
|
2470
2575
|
cancel: w,
|
|
@@ -2472,8 +2577,8 @@ function $i(i) {
|
|
|
2472
2577
|
stop: y
|
|
2473
2578
|
};
|
|
2474
2579
|
}
|
|
2475
|
-
const
|
|
2476
|
-
class
|
|
2580
|
+
const Ui = 12;
|
|
2581
|
+
class ji {
|
|
2477
2582
|
constructor(t) {
|
|
2478
2583
|
this.host = t;
|
|
2479
2584
|
}
|
|
@@ -2502,7 +2607,7 @@ class _i {
|
|
|
2502
2607
|
* KeyboardTargetingController owns Tab/Arrow/Enter/Space/Escape.
|
|
2503
2608
|
*/
|
|
2504
2609
|
startKeyboard(t) {
|
|
2505
|
-
this.host.setState("TARGETING"), this.host.feedbackData.feedbackType = t, this.host.feedbackData.elementSelector = null, this.host.feedbackData.elementText = null, this.host.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.host.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.host.cssVars["--qaid-negative"]), this.createTargetingOverlay(), this.crosshairH && (this.crosshairH.style.display = "none"), this.crosshairV && (this.crosshairV.style.display = "none"), this.scope && (this.scope.style.display = "none"), this.keyboardController =
|
|
2610
|
+
this.host.setState("TARGETING"), this.host.feedbackData.feedbackType = t, this.host.feedbackData.elementSelector = null, this.host.feedbackData.elementText = null, this.host.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.host.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.host.cssVars["--qaid-negative"]), this.createTargetingOverlay(), this.crosshairH && (this.crosshairH.style.display = "none"), this.crosshairV && (this.crosshairV.style.display = "none"), this.scope && (this.scope.style.display = "none"), this.keyboardController = Ni({
|
|
2506
2611
|
isExcluded: (e) => M(e),
|
|
2507
2612
|
onHighlight: (e) => {
|
|
2508
2613
|
const o = e.getBoundingClientRect(), n = this.highlightBox;
|
|
@@ -2515,7 +2620,7 @@ class _i {
|
|
|
2515
2620
|
});
|
|
2516
2621
|
}
|
|
2517
2622
|
selectKeyboardTarget(t) {
|
|
2518
|
-
const e =
|
|
2623
|
+
const e = st(t, 8);
|
|
2519
2624
|
Object.assign(this.host.selectedBounds, e, {
|
|
2520
2625
|
clickX: e.x + e.width / 2,
|
|
2521
2626
|
clickY: e.y + e.height / 2,
|
|
@@ -2540,7 +2645,7 @@ class _i {
|
|
|
2540
2645
|
/** Move the crosshair/scope reticle and highlight the element under (x, y). */
|
|
2541
2646
|
updateReticleAt(t, e) {
|
|
2542
2647
|
if (this.mousePos.x = t, this.mousePos.y = e, this.crosshairH && (this.crosshairH.style.top = `${e}px`), this.crosshairV && (this.crosshairV.style.left = `${t}px`), this.scope && (this.scope.style.left = `${t}px`, this.scope.style.top = `${e}px`), this.captureLayer && this.host.shadowHost) {
|
|
2543
|
-
const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n =
|
|
2648
|
+
const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = nt(t, e, o);
|
|
2544
2649
|
if (n && !M(n)) {
|
|
2545
2650
|
if (this.highlightBox) {
|
|
2546
2651
|
const s = n.getBoundingClientRect();
|
|
@@ -2559,14 +2664,14 @@ class _i {
|
|
|
2559
2664
|
}
|
|
2560
2665
|
handleTouchEnd(t) {
|
|
2561
2666
|
const e = t.changedTouches[0], o = this.touchStartPos;
|
|
2562
|
-
this.touchStartPos = null, !(!e || !o || Math.hypot(e.clientX - o.x, e.clientY - o.y) >
|
|
2667
|
+
this.touchStartPos = null, !(!e || !o || Math.hypot(e.clientX - o.x, e.clientY - o.y) > Ui) && (t.preventDefault(), this.selectAt(e.clientX, e.clientY));
|
|
2563
2668
|
}
|
|
2564
2669
|
/** Select the element under (x, y) and tear down targeting. */
|
|
2565
2670
|
selectAt(t, e) {
|
|
2566
|
-
const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n =
|
|
2671
|
+
const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = nt(t, e, o);
|
|
2567
2672
|
if (!n || M(n))
|
|
2568
2673
|
return;
|
|
2569
|
-
const s =
|
|
2674
|
+
const s = st(n, 8);
|
|
2570
2675
|
Object.assign(this.host.selectedBounds, s, { clickX: t, clickY: e, visible: !0 });
|
|
2571
2676
|
const { selector: a, text: c } = F(n);
|
|
2572
2677
|
this.host.feedbackData.elementSelector = a, this.host.feedbackData.elementText = c, this.stopTargetingListeners(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.host.setState("SELECTED"), this.host.clearActiveThumb(), this.showSelectedMarker(), this.host.submitFeedback();
|
|
@@ -2592,22 +2697,22 @@ class _i {
|
|
|
2592
2697
|
this.keyboardController?.stop(), this.keyboardController = null, this.stopTargetingListeners(), this.hideMarker();
|
|
2593
2698
|
}
|
|
2594
2699
|
}
|
|
2595
|
-
const
|
|
2700
|
+
const yt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2596
2701
|
__proto__: null,
|
|
2597
|
-
TargetingController:
|
|
2702
|
+
TargetingController: ji
|
|
2598
2703
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2599
2704
|
export {
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2705
|
+
Mt as AnnotationEditor,
|
|
2706
|
+
Ye as QaidFeedback,
|
|
2707
|
+
bi as captureDomScreenshot,
|
|
2708
|
+
ei as captureNetworkErrors,
|
|
2709
|
+
Dt as compositeAnnotations,
|
|
2710
|
+
hi as createVideoRecorder,
|
|
2606
2711
|
B as drawShape,
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2712
|
+
At as getSupportedMimeType,
|
|
2713
|
+
fi as isDomScreenshotSupported,
|
|
2714
|
+
li as isVideoRecordingSupported,
|
|
2715
|
+
Ii as openAnnotationEditor,
|
|
2611
2716
|
P as rectFromPoints
|
|
2612
2717
|
};
|
|
2613
2718
|
//# sourceMappingURL=index.js.map
|