@qaiddev/thumbs-embed 1.6.2 → 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/bootstrap.d.ts +6 -0
- package/dist/chunks/{annotate-NeITyYNe.js → annotate-D-o8xCV9.js} +24 -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-DnJ3MHkt.js → loader-DHtXHt1z.js} +187 -163
- 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-DhRZ6-tW.js → recording-Dx8AX-BC.js} +104 -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-BEQU2Ogo.js → targeting-Dz6z1BYl.js} +3 -2
- package/dist/chunks/{targeting-BEQU2Ogo.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 +597 -451
- package/dist/index.js.map +1 -1
- package/dist/loader.js +1 -1
- package/dist/modal.d.ts +19 -1
- package/dist/qaid.umd.cjs +14 -31
- 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 +33 -2
- package/dist/video-capture.d.ts +6 -0
- package/package.json +1 -1
- package/dist/chunks/annotate-NeITyYNe.js.map +0 -1
- package/dist/chunks/loader-DnJ3MHkt.js.map +0 -1
- package/dist/chunks/modal-C8Ca7E5j.js +0 -119
- package/dist/chunks/modal-C8Ca7E5j.js.map +0 -1
- package/dist/chunks/recording-DhRZ6-tW.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>`, Gt = "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}}", Jt = "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 oe(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 se(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 Q = "data-qaid-a11y-live", ce = "position:absolute;width:1px;height:1px;ma
|
|
|
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 be(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 we(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 ke(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 xe(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 Se(i, t, e, o = bt) {
|
|
|
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 Te(i, t, e, o = bt) {
|
|
|
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 J(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 Z(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 De = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", Me =
|
|
|
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 Be(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 tt = "qaid_visitor_id", et = "qaid_hide_feedback", He = [
|
|
|
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 _e {
|
|
|
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: {
|
|
@@ -495,16 +509,22 @@ class _e {
|
|
|
495
509
|
negativeLabel: t.text?.negativeLabel ?? "Send negative feedback",
|
|
496
510
|
recordLabel: t.text?.recordLabel ?? "Record a screen recording",
|
|
497
511
|
dismissLabel: t.text?.dismissLabel ?? "Hide Feedback",
|
|
498
|
-
feedbackLabel: t.text?.feedbackLabel ?? "Send feedback"
|
|
512
|
+
feedbackLabel: t.text?.feedbackLabel ?? "Send feedback",
|
|
513
|
+
confirmationTitle: t.text?.confirmationTitle ?? "Thank you!",
|
|
514
|
+
confirmationMessage: t.text?.confirmationMessage ?? "Your feedback has been received.",
|
|
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."
|
|
499
518
|
},
|
|
519
|
+
hideConfirmation: t.hideConfirmation ?? !1,
|
|
500
520
|
modalWidth: t.modalWidth ?? 400,
|
|
501
521
|
backdropOpacity: t.backdropOpacity ?? 0.3,
|
|
502
522
|
fontFamily: t.fontFamily ?? "system-ui, -apple-system, sans-serif",
|
|
503
523
|
fontSize: t.fontSize ?? 16,
|
|
504
524
|
captureScreenshot: t.captureScreenshot ?? !1,
|
|
505
525
|
annotate: t.annotate ?? !0,
|
|
506
|
-
annotationColor: t.annotationColor ?? t.colors?.marker ?? "#
|
|
507
|
-
annotationPalette: t.annotationPalette ??
|
|
526
|
+
annotationColor: t.annotationColor ?? t.colors?.marker ?? "#6365f1",
|
|
527
|
+
annotationPalette: t.annotationPalette ?? je,
|
|
508
528
|
screenshotMethod: t.screenshotMethod ?? "permission",
|
|
509
529
|
screenshotOptions: {
|
|
510
530
|
quality: t.screenshotOptions?.quality ?? 0.8,
|
|
@@ -531,12 +551,12 @@ class _e {
|
|
|
531
551
|
video: t.quests?.video ?? "",
|
|
532
552
|
// Quest service reuses the feedback API key unless overridden.
|
|
533
553
|
apiKey: t.quests?.apiKey ?? t.apiKey ?? "",
|
|
534
|
-
moduleUrl: t.quests?.moduleUrl ??
|
|
554
|
+
moduleUrl: t.quests?.moduleUrl ?? _e
|
|
535
555
|
}
|
|
536
|
-
}, 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();
|
|
537
557
|
}
|
|
538
558
|
applyVars(t) {
|
|
539
|
-
|
|
559
|
+
me(t, this.cssVars);
|
|
540
560
|
}
|
|
541
561
|
/**
|
|
542
562
|
* Announce a message via the shared visually-hidden live regions.
|
|
@@ -546,7 +566,7 @@ class _e {
|
|
|
546
566
|
*/
|
|
547
567
|
announceMsg(t, e = !1) {
|
|
548
568
|
const o = this.overlayShadowRoot ?? this.shadowRoot;
|
|
549
|
-
o &&
|
|
569
|
+
o && xe(o, t, { assertive: e });
|
|
550
570
|
}
|
|
551
571
|
/**
|
|
552
572
|
* Turn a transient surface into an accessible modal dialog: save the
|
|
@@ -554,16 +574,16 @@ class _e {
|
|
|
554
574
|
* background. Paired with closeDialogA11y() on every close path.
|
|
555
575
|
*/
|
|
556
576
|
openDialogA11y(t, e) {
|
|
557
|
-
this.dialogTrigger =
|
|
577
|
+
this.dialogTrigger = Ee(), Ae(t, e), this.dialogTrap = Se(t), this.dialogRestoreInert = Le(t);
|
|
558
578
|
}
|
|
559
579
|
closeDialogA11y() {
|
|
560
|
-
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;
|
|
561
581
|
}
|
|
562
582
|
clearActiveThumb() {
|
|
563
583
|
this.activeThumbBtn && (this.activeThumbBtn.setAttribute("aria-pressed", "false"), this.activeThumbBtn = null);
|
|
564
584
|
}
|
|
565
585
|
init() {
|
|
566
|
-
|
|
586
|
+
be(), this.cssVars = fe({
|
|
567
587
|
positiveColor: this.config.colors.positive,
|
|
568
588
|
negativeColor: this.config.colors.negative,
|
|
569
589
|
markerColor: this.config.colors.marker,
|
|
@@ -572,7 +592,7 @@ class _e {
|
|
|
572
592
|
backdropOpacity: this.config.backdropOpacity,
|
|
573
593
|
fontFamily: this.config.fontFamily,
|
|
574
594
|
fontSize: this.config.fontSize
|
|
575
|
-
}), !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) => {
|
|
576
596
|
this.feedbackData.consoleErrors = this.consoleCapture?.errors ?? [];
|
|
577
597
|
}), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom(), (this.config.captureVideo && this.videoSupported() || this.config.captureScreenshot) && this.schedulePrewarm(() => {
|
|
578
598
|
this.config.captureVideo && this.videoSupported() && this.prewarmVideo(), this.config.captureScreenshot && this.prewarmScreenshot();
|
|
@@ -585,13 +605,13 @@ class _e {
|
|
|
585
605
|
* swallowed — a failed preload just falls back to an on-demand load.
|
|
586
606
|
*/
|
|
587
607
|
prewarmVideo() {
|
|
588
|
-
this.videoPrewarmed || (this.videoPrewarmed = !0, Promise.resolve().then(() =>
|
|
589
|
-
}), Promise.resolve().then(() =>
|
|
608
|
+
this.videoPrewarmed || (this.videoPrewarmed = !0, Promise.resolve().then(() => bt).catch(() => {
|
|
609
|
+
}), Promise.resolve().then(() => It).catch(() => {
|
|
590
610
|
}));
|
|
591
611
|
}
|
|
592
612
|
prewarmScreenshot() {
|
|
593
|
-
this.screenshotPrewarmed || (this.screenshotPrewarmed = !0, (this.shouldCaptureViaDom() ? Promise.resolve().then(() =>
|
|
594
|
-
}), 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(() => {
|
|
595
615
|
}));
|
|
596
616
|
}
|
|
597
617
|
/** Run fn when the main thread is idle; cancelled by destroy(). */
|
|
@@ -620,7 +640,7 @@ class _e {
|
|
|
620
640
|
}), this.domObserver.observe(document.body, { childList: !0 });
|
|
621
641
|
}
|
|
622
642
|
checkMobile() {
|
|
623
|
-
this.isMobile =
|
|
643
|
+
this.isMobile = $e();
|
|
624
644
|
}
|
|
625
645
|
handleResize() {
|
|
626
646
|
this.checkMobile();
|
|
@@ -630,7 +650,7 @@ class _e {
|
|
|
630
650
|
let t = null;
|
|
631
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" });
|
|
632
652
|
const e = document.createElement("style");
|
|
633
|
-
if (e.textContent =
|
|
653
|
+
if (e.textContent = et(), this.shadowRoot.appendChild(e), this.config.css) {
|
|
634
654
|
const d = document.createElement("style");
|
|
635
655
|
d.textContent = this.config.css, this.shadowRoot.appendChild(d);
|
|
636
656
|
}
|
|
@@ -654,30 +674,30 @@ class _e {
|
|
|
654
674
|
const d = document.createElement("div");
|
|
655
675
|
d.className = "qaid-tooltip-wrapper";
|
|
656
676
|
const r = document.createElement("button");
|
|
657
|
-
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", () => {
|
|
658
678
|
this.prewarmTargeting(), this.showTooltip(r);
|
|
659
679
|
}), r.addEventListener("mouseleave", () => this.hideTooltip()), d.appendChild(r), this.buttonsContainer.appendChild(d);
|
|
660
680
|
} else if (!this.config.hideThumbs) {
|
|
661
681
|
const d = document.createElement("div");
|
|
662
682
|
d.className = "qaid-tooltip-wrapper";
|
|
663
683
|
const r = document.createElement("button");
|
|
664
|
-
r.type = "button", r.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", r.setAttribute("aria-label", this.config.text.positiveLabel), r.innerHTML = this.config.positiveIcon || V, r.addEventListener("click", (
|
|
684
|
+
r.type = "button", r.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", r.setAttribute("aria-label", this.config.text.positiveLabel), r.innerHTML = this.config.positiveIcon || V, r.addEventListener("click", (b) => this.handleThumbClick("up", b.currentTarget, b)), r.addEventListener("mouseenter", () => {
|
|
665
685
|
this.prewarmTargeting(), this.showTooltip(r);
|
|
666
686
|
}), r.addEventListener("mouseleave", () => this.hideTooltip()), d.appendChild(r);
|
|
667
687
|
const h = document.createElement("div");
|
|
668
688
|
h.className = "qaid-tooltip-wrapper";
|
|
669
|
-
const
|
|
670
|
-
|
|
671
|
-
this.prewarmTargeting(), this.showTooltip(
|
|
672
|
-
}),
|
|
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);
|
|
673
693
|
}
|
|
674
694
|
if (this.config.captureVideo && this.videoSupported()) {
|
|
675
695
|
const d = document.createElement("div");
|
|
676
696
|
d.className = "qaid-tooltip-wrapper";
|
|
677
697
|
const r = document.createElement("button");
|
|
678
|
-
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", () => {
|
|
679
699
|
this.ensureRecording().then(
|
|
680
|
-
(
|
|
700
|
+
(f) => this.config.videoOptions.redaction ? f.startPicking() : f.startRecording()
|
|
681
701
|
);
|
|
682
702
|
});
|
|
683
703
|
const h = () => this.prewarmVideo();
|
|
@@ -699,7 +719,7 @@ class _e {
|
|
|
699
719
|
if (this.overlayShadowRoot) return this.overlayShadowRoot;
|
|
700
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" });
|
|
701
721
|
const t = document.createElement("style");
|
|
702
|
-
if (t.textContent =
|
|
722
|
+
if (t.textContent = et(), this.overlayShadowRoot.appendChild(t), this.config.css) {
|
|
703
723
|
const e = document.createElement("style");
|
|
704
724
|
e.textContent = this.config.css, this.overlayShadowRoot.appendChild(e);
|
|
705
725
|
}
|
|
@@ -709,7 +729,7 @@ class _e {
|
|
|
709
729
|
showTooltip(t) {
|
|
710
730
|
const e = this.tooltipElement;
|
|
711
731
|
e.style.visibility = "hidden", e.classList.add("qaid-tooltip-visible");
|
|
712
|
-
const o = t.getBoundingClientRect(), n = e.getBoundingClientRect(), { top: s, left: a } =
|
|
732
|
+
const o = t.getBoundingClientRect(), n = e.getBoundingClientRect(), { top: s, left: a } = Be(
|
|
713
733
|
o,
|
|
714
734
|
n,
|
|
715
735
|
{ width: window.innerWidth, height: window.innerHeight }
|
|
@@ -720,10 +740,10 @@ class _e {
|
|
|
720
740
|
this.tooltipElement.classList.remove("qaid-tooltip-visible");
|
|
721
741
|
}
|
|
722
742
|
handleDismiss() {
|
|
723
|
-
this.buttonsContainer.classList.add("qaid-dismissed"),
|
|
743
|
+
this.buttonsContainer.classList.add("qaid-dismissed"), dt(this.config.apiKey, !0);
|
|
724
744
|
}
|
|
725
745
|
handleThumbClick(t, e, o) {
|
|
726
|
-
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")
|
|
727
747
|
this.submitDirectFeedback(t, e);
|
|
728
748
|
else {
|
|
729
749
|
this.activeThumbBtn = e, e.setAttribute("aria-pressed", "true");
|
|
@@ -756,7 +776,7 @@ class _e {
|
|
|
756
776
|
* instead of the permission-based Screen Capture API. Explicit "dom" wins;
|
|
757
777
|
* otherwise DOM is used on touch devices to avoid the getDisplayMedia prompt. */
|
|
758
778
|
shouldCaptureViaDom() {
|
|
759
|
-
return this.config.screenshotMethod === "dom" ||
|
|
779
|
+
return this.config.screenshotMethod === "dom" || Ke();
|
|
760
780
|
}
|
|
761
781
|
/**
|
|
762
782
|
* Open the full-screen annotation editor over the captured screenshot,
|
|
@@ -769,7 +789,7 @@ class _e {
|
|
|
769
789
|
const e = this.ensureOverlayHost(), o = this.overlayShadowHost, n = o.style.pointerEvents;
|
|
770
790
|
o.style.pointerEvents = "auto";
|
|
771
791
|
try {
|
|
772
|
-
const { openAnnotationEditor: s } = await Promise.resolve().then(() =>
|
|
792
|
+
const { openAnnotationEditor: s } = await Promise.resolve().then(() => mt);
|
|
773
793
|
return await s({
|
|
774
794
|
dataUrl: t,
|
|
775
795
|
root: e,
|
|
@@ -792,10 +812,10 @@ class _e {
|
|
|
792
812
|
if (this.config.captureScreenshot || this.config.feedbackMode === "annotate")
|
|
793
813
|
try {
|
|
794
814
|
if (this.shouldCaptureViaDom()) {
|
|
795
|
-
const { captureDomScreenshot: a } = await Promise.resolve().then(() =>
|
|
815
|
+
const { captureDomScreenshot: a } = await Promise.resolve().then(() => pt);
|
|
796
816
|
t = await a(this.config.screenshotOptions);
|
|
797
817
|
} else {
|
|
798
|
-
const { captureScreenshot: a } = await Promise.resolve().then(() =>
|
|
818
|
+
const { captureScreenshot: a } = await Promise.resolve().then(() => gt);
|
|
799
819
|
t = await a(this.config.screenshotOptions);
|
|
800
820
|
}
|
|
801
821
|
t && this.announceMsg("Screenshot captured");
|
|
@@ -873,7 +893,7 @@ class _e {
|
|
|
873
893
|
const o = this.questIdFor(t);
|
|
874
894
|
if (!o) return !1;
|
|
875
895
|
try {
|
|
876
|
-
return this.activeQuest?.destroy(), this.activeQuest = await
|
|
896
|
+
return this.activeQuest?.destroy(), this.activeQuest = await Ue({
|
|
877
897
|
questId: o,
|
|
878
898
|
base: this.config.quests.base,
|
|
879
899
|
apiKey: this.config.quests.apiKey || void 0,
|
|
@@ -902,7 +922,7 @@ class _e {
|
|
|
902
922
|
*/
|
|
903
923
|
async ensureModal() {
|
|
904
924
|
if (!this.modal) {
|
|
905
|
-
const { ModalController: t } = await Promise.resolve().then(() =>
|
|
925
|
+
const { ModalController: t } = await Promise.resolve().then(() => vt);
|
|
906
926
|
this.modal = new t(this.makeModalHost());
|
|
907
927
|
}
|
|
908
928
|
return this.modal;
|
|
@@ -948,7 +968,7 @@ class _e {
|
|
|
948
968
|
}
|
|
949
969
|
/** Warm the modal chunk while the user is targeting, so it opens instantly. */
|
|
950
970
|
prewarmModal() {
|
|
951
|
-
this.modalPrewarmed || (this.modalPrewarmed = !0, Promise.resolve().then(() =>
|
|
971
|
+
this.modalPrewarmed || (this.modalPrewarmed = !0, Promise.resolve().then(() => vt).catch(() => {
|
|
952
972
|
}));
|
|
953
973
|
}
|
|
954
974
|
/**
|
|
@@ -958,7 +978,7 @@ class _e {
|
|
|
958
978
|
*/
|
|
959
979
|
async ensureTargeting() {
|
|
960
980
|
if (!this.targeting) {
|
|
961
|
-
const { TargetingController: t } = await Promise.resolve().then(() =>
|
|
981
|
+
const { TargetingController: t } = await Promise.resolve().then(() => yt);
|
|
962
982
|
this.targeting = new t(this.makeTargetingHost());
|
|
963
983
|
}
|
|
964
984
|
return this.targeting;
|
|
@@ -1003,7 +1023,7 @@ class _e {
|
|
|
1003
1023
|
}
|
|
1004
1024
|
/** Warm the targeting chunk on thumb-button hover, before the click. */
|
|
1005
1025
|
prewarmTargeting() {
|
|
1006
|
-
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(() => {
|
|
1007
1027
|
}));
|
|
1008
1028
|
}
|
|
1009
1029
|
// ==================== Video Recording ====================
|
|
@@ -1022,7 +1042,7 @@ class _e {
|
|
|
1022
1042
|
*/
|
|
1023
1043
|
async ensureRecording() {
|
|
1024
1044
|
if (!this.recording) {
|
|
1025
|
-
const { RecordingController: t } = await Promise.resolve().then(() =>
|
|
1045
|
+
const { RecordingController: t } = await Promise.resolve().then(() => bt);
|
|
1026
1046
|
this.recording = new t(this.makeRecordingHost());
|
|
1027
1047
|
}
|
|
1028
1048
|
return this.recording;
|
|
@@ -1078,13 +1098,13 @@ class _e {
|
|
|
1078
1098
|
const t = window;
|
|
1079
1099
|
this.prewarmIsTimeout ? clearTimeout(this.prewarmHandle) : t.cancelIdleCallback?.(this.prewarmHandle), this.prewarmHandle = null;
|
|
1080
1100
|
}
|
|
1081
|
-
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();
|
|
1082
1102
|
}
|
|
1083
1103
|
}
|
|
1084
|
-
function
|
|
1104
|
+
function Ct(i) {
|
|
1085
1105
|
return document.querySelector(i)?.textContent?.trim() ?? "";
|
|
1086
1106
|
}
|
|
1087
|
-
function
|
|
1107
|
+
function Qe() {
|
|
1088
1108
|
const i = document.querySelector(
|
|
1089
1109
|
'script[type="application/json"][data-feedback-config]'
|
|
1090
1110
|
);
|
|
@@ -1093,98 +1113,104 @@ function Fe() {
|
|
|
1093
1113
|
if (!t) return null;
|
|
1094
1114
|
try {
|
|
1095
1115
|
const e = JSON.parse(t);
|
|
1096
|
-
return e.cssSelector && !e.css && (e.css =
|
|
1116
|
+
return e.cssSelector && !e.css && (e.css = Ct(e.cssSelector), delete e.cssSelector), e;
|
|
1097
1117
|
} catch {
|
|
1098
1118
|
return null;
|
|
1099
1119
|
}
|
|
1100
1120
|
}
|
|
1101
|
-
function
|
|
1121
|
+
function Ge(i) {
|
|
1102
1122
|
const t = i.getAttribute("data-endpoint");
|
|
1103
1123
|
if (!t) return null;
|
|
1104
|
-
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-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");
|
|
1105
1125
|
return {
|
|
1106
1126
|
endpoint: t,
|
|
1107
|
-
css:
|
|
1108
|
-
apiKey:
|
|
1109
|
-
captureScreenshot:
|
|
1127
|
+
css: Z ? Ct(Z) : void 0,
|
|
1128
|
+
apiKey: zt ?? void 0,
|
|
1129
|
+
captureScreenshot: $t === "true" ? !0 : void 0,
|
|
1110
1130
|
// Annotation is on by default; only an explicit "false" disables it.
|
|
1111
|
-
annotate:
|
|
1112
|
-
annotationColor:
|
|
1113
|
-
screenshotOptions: H || O ||
|
|
1131
|
+
annotate: _t === "false" ? !1 : void 0,
|
|
1132
|
+
annotationColor: Ft ?? void 0,
|
|
1133
|
+
screenshotOptions: H || O || z ? {
|
|
1114
1134
|
quality: H ? parseFloat(H) : void 0,
|
|
1115
1135
|
maxWidth: O ? parseInt(O, 10) : void 0,
|
|
1116
|
-
maxHeight:
|
|
1136
|
+
maxHeight: z ? parseInt(z, 10) : void 0
|
|
1117
1137
|
} : void 0,
|
|
1118
1138
|
container: c ?? void 0,
|
|
1119
1139
|
buttonClass: l ?? void 0,
|
|
1120
|
-
direction:
|
|
1140
|
+
direction: Kt ?? void 0,
|
|
1121
1141
|
position: e ?? void 0,
|
|
1122
1142
|
zIndex: o ? parseInt(o, 10) : void 0,
|
|
1123
1143
|
skipTargeting: d === "true" ? !0 : void 0,
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1144
|
+
hideConfirmation: r === "true" ? !0 : void 0,
|
|
1145
|
+
singleButton: h === "true" ? !0 : void 0,
|
|
1146
|
+
feedbackMode: f ?? void 0,
|
|
1147
|
+
incognito: b === "true" ? !0 : void 0,
|
|
1148
|
+
buttonSize: y ?? void 0,
|
|
1149
|
+
offset: g || w ? {
|
|
1150
|
+
x: g ? parseInt(g, 10) : void 0,
|
|
1151
|
+
y: w ? parseInt(w, 10) : void 0
|
|
1131
1152
|
} : void 0,
|
|
1132
|
-
modalWidth:
|
|
1133
|
-
backdropOpacity:
|
|
1134
|
-
fontFamily:
|
|
1135
|
-
fontSize:
|
|
1153
|
+
modalWidth: x ? parseInt(x, 10) : void 0,
|
|
1154
|
+
backdropOpacity: u ? parseFloat(u) : void 0,
|
|
1155
|
+
fontFamily: k ?? void 0,
|
|
1156
|
+
fontSize: v ? parseInt(v, 10) : void 0,
|
|
1136
1157
|
colors: {
|
|
1137
1158
|
positive: n ?? void 0,
|
|
1138
1159
|
negative: s ?? void 0,
|
|
1139
1160
|
marker: a ?? void 0
|
|
1140
1161
|
},
|
|
1141
|
-
text:
|
|
1142
|
-
tooltip:
|
|
1143
|
-
modalTitle:
|
|
1144
|
-
modalSubtitle:
|
|
1145
|
-
placeholder:
|
|
1146
|
-
submitButton:
|
|
1147
|
-
skipButton:
|
|
1148
|
-
feedbackLabel:
|
|
1162
|
+
text: C || A || W || X || Y || Q || G || S || m || E || j || K ? {
|
|
1163
|
+
tooltip: C ?? void 0,
|
|
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,
|
|
1170
|
+
confirmationTitle: S ?? void 0,
|
|
1171
|
+
confirmationMessage: m ?? void 0,
|
|
1172
|
+
confirmationClose: E ?? void 0,
|
|
1173
|
+
errorTitle: j ?? void 0,
|
|
1174
|
+
errorMessage: K ?? void 0
|
|
1149
1175
|
} : void 0,
|
|
1150
|
-
positiveIcon:
|
|
1151
|
-
negativeIcon:
|
|
1152
|
-
feedbackIcon:
|
|
1153
|
-
screenshotMethod:
|
|
1154
|
-
captureVideo:
|
|
1155
|
-
hideThumbs:
|
|
1156
|
-
hideDismiss:
|
|
1157
|
-
videoOptions:
|
|
1158
|
-
maxDuration:
|
|
1159
|
-
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
|
|
1160
1186
|
} : void 0,
|
|
1161
|
-
quests:
|
|
1162
|
-
base:
|
|
1163
|
-
up:
|
|
1164
|
-
down:
|
|
1165
|
-
video:
|
|
1166
|
-
apiKey:
|
|
1167
|
-
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
|
|
1168
1194
|
} : void 0
|
|
1169
1195
|
};
|
|
1170
1196
|
}
|
|
1171
|
-
function
|
|
1197
|
+
function Je() {
|
|
1172
1198
|
if (typeof document > "u") return;
|
|
1173
1199
|
const i = () => {
|
|
1174
|
-
const t = document.currentScript ?? document.querySelector("script[data-endpoint]"), e =
|
|
1175
|
-
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);
|
|
1176
1202
|
};
|
|
1177
1203
|
document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", i) : i();
|
|
1178
1204
|
}
|
|
1179
|
-
const
|
|
1205
|
+
const Ze = 20, lt = 4096;
|
|
1180
1206
|
function R(i) {
|
|
1181
1207
|
const t = typeof i == "string" ? i : JSON.stringify(i);
|
|
1182
|
-
return t.length >
|
|
1208
|
+
return t.length > lt ? t.slice(0, lt) + "…[truncated]" : t;
|
|
1183
1209
|
}
|
|
1184
|
-
function
|
|
1185
|
-
i.length >=
|
|
1210
|
+
function ht(i, t) {
|
|
1211
|
+
i.length >= Ze && i.shift(), i.push(t);
|
|
1186
1212
|
}
|
|
1187
|
-
async function
|
|
1213
|
+
async function ti(i) {
|
|
1188
1214
|
try {
|
|
1189
1215
|
const t = await i.clone().text();
|
|
1190
1216
|
return R(t);
|
|
@@ -1192,7 +1218,7 @@ async function je(i) {
|
|
|
1192
1218
|
return;
|
|
1193
1219
|
}
|
|
1194
1220
|
}
|
|
1195
|
-
function
|
|
1221
|
+
function ei() {
|
|
1196
1222
|
const i = [], t = window.fetch;
|
|
1197
1223
|
window.fetch = async function(n, s) {
|
|
1198
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");
|
|
@@ -1200,8 +1226,8 @@ function Ke() {
|
|
|
1200
1226
|
s?.body && (l = R(s.body));
|
|
1201
1227
|
const d = await t.apply(window, [n, s]);
|
|
1202
1228
|
if (d.status >= 400) {
|
|
1203
|
-
const r = await
|
|
1204
|
-
|
|
1229
|
+
const r = await ti(d);
|
|
1230
|
+
ht(i, {
|
|
1205
1231
|
url: a,
|
|
1206
1232
|
method: c.toUpperCase(),
|
|
1207
1233
|
status: d.status,
|
|
@@ -1219,7 +1245,7 @@ function Ke() {
|
|
|
1219
1245
|
}, XMLHttpRequest.prototype.send = function(n) {
|
|
1220
1246
|
const s = this, a = n ? R(n) : void 0;
|
|
1221
1247
|
return s.addEventListener("load", function() {
|
|
1222
|
-
s.status >= 400 &&
|
|
1248
|
+
s.status >= 400 && ht(i, {
|
|
1223
1249
|
url: s._qaid_url,
|
|
1224
1250
|
method: s._qaid_method.toUpperCase(),
|
|
1225
1251
|
status: s.status,
|
|
@@ -1236,27 +1262,27 @@ function Ke() {
|
|
|
1236
1262
|
}
|
|
1237
1263
|
};
|
|
1238
1264
|
}
|
|
1239
|
-
function
|
|
1265
|
+
function ii() {
|
|
1240
1266
|
const i = navigator.userAgent || "";
|
|
1241
1267
|
return /iP(hone|ad|od)/.test(i) || // iPadOS 13+ masquerades as "MacIntel" but is a multi-touch device.
|
|
1242
1268
|
navigator.platform === "MacIntel" && (navigator.maxTouchPoints || 0) > 1;
|
|
1243
1269
|
}
|
|
1244
|
-
function
|
|
1270
|
+
function oi(i, t, e, o, n) {
|
|
1245
1271
|
const s = i >= t, a = e >= o;
|
|
1246
1272
|
return s === a ? { width: i, height: t, rotate: 0 } : { width: t, height: i, rotate: n === 270 ? -90 : 90 };
|
|
1247
1273
|
}
|
|
1248
|
-
function
|
|
1274
|
+
function ni(i, t, e) {
|
|
1249
1275
|
if (e.rotate === 0) {
|
|
1250
1276
|
i.drawImage(t, 0, 0, e.width, e.height);
|
|
1251
1277
|
return;
|
|
1252
1278
|
}
|
|
1253
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();
|
|
1254
1280
|
}
|
|
1255
|
-
function
|
|
1281
|
+
function si() {
|
|
1256
1282
|
const i = typeof screen < "u" ? screen.orientation : void 0;
|
|
1257
1283
|
return i && typeof i.angle == "number" ? i.angle : 0;
|
|
1258
1284
|
}
|
|
1259
|
-
function
|
|
1285
|
+
function St(i) {
|
|
1260
1286
|
return new Promise((t) => {
|
|
1261
1287
|
if (i.videoWidth > 0) {
|
|
1262
1288
|
t();
|
|
@@ -1265,30 +1291,30 @@ function mt(i) {
|
|
|
1265
1291
|
i.addEventListener("loadedmetadata", () => t(), { once: !0 });
|
|
1266
1292
|
});
|
|
1267
1293
|
}
|
|
1268
|
-
async function
|
|
1294
|
+
async function Et(i) {
|
|
1269
1295
|
try {
|
|
1270
1296
|
await i.play();
|
|
1271
1297
|
} catch {
|
|
1272
1298
|
}
|
|
1273
1299
|
}
|
|
1274
|
-
async function
|
|
1300
|
+
async function ai(i, t = 15) {
|
|
1275
1301
|
const e = document.createElement("canvas");
|
|
1276
1302
|
if (typeof e.captureStream != "function") return null;
|
|
1277
1303
|
const o = e.getContext("2d");
|
|
1278
1304
|
if (!o) return null;
|
|
1279
1305
|
const n = document.createElement("video");
|
|
1280
|
-
n.muted = !0, n.playsInline = !0, n.srcObject = i, await
|
|
1281
|
-
const s =
|
|
1306
|
+
n.muted = !0, n.playsInline = !0, n.srcObject = i, await St(n);
|
|
1307
|
+
const s = oi(
|
|
1282
1308
|
n.videoWidth,
|
|
1283
1309
|
n.videoHeight,
|
|
1284
1310
|
window.innerWidth,
|
|
1285
1311
|
window.innerHeight,
|
|
1286
|
-
|
|
1312
|
+
si()
|
|
1287
1313
|
);
|
|
1288
|
-
e.width = s.width, e.height = s.height, await
|
|
1314
|
+
e.width = s.width, e.height = s.height, await Et(n);
|
|
1289
1315
|
let a = 0;
|
|
1290
1316
|
const c = () => {
|
|
1291
|
-
|
|
1317
|
+
ni(o, n, s), a = requestAnimationFrame(c);
|
|
1292
1318
|
};
|
|
1293
1319
|
c();
|
|
1294
1320
|
const l = e.captureStream(t);
|
|
@@ -1299,15 +1325,15 @@ async function Ge(i, t = 15) {
|
|
|
1299
1325
|
}
|
|
1300
1326
|
};
|
|
1301
1327
|
}
|
|
1302
|
-
function
|
|
1328
|
+
function ri(i, t, e, o, n) {
|
|
1303
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;
|
|
1304
1330
|
return d <= 0 || r <= 0 ? null : { x: s, y: a, w: d, h: r };
|
|
1305
1331
|
}
|
|
1306
|
-
function
|
|
1332
|
+
function di(i, t, e, o, n, s, a) {
|
|
1307
1333
|
i.drawImage(t, 0, 0, o, n);
|
|
1308
1334
|
const c = o / Math.max(1, window.innerWidth), l = n / Math.max(1, window.innerHeight);
|
|
1309
1335
|
for (const d of e) {
|
|
1310
|
-
const r =
|
|
1336
|
+
const r = ri(
|
|
1311
1337
|
d.getBoundingClientRect(),
|
|
1312
1338
|
c,
|
|
1313
1339
|
l,
|
|
@@ -1317,16 +1343,16 @@ function Ze(i, t, e, o, n, s, a) {
|
|
|
1317
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());
|
|
1318
1344
|
}
|
|
1319
1345
|
}
|
|
1320
|
-
async function
|
|
1346
|
+
async function ci(i, t, e = {}) {
|
|
1321
1347
|
const o = e.frameRate ?? 15, n = e.blurRadius ?? 12, s = document.createElement("canvas");
|
|
1322
1348
|
if (typeof s.captureStream != "function") return null;
|
|
1323
1349
|
const a = s.getContext("2d");
|
|
1324
1350
|
if (!a) return null;
|
|
1325
1351
|
const c = "filter" in a, l = document.createElement("video");
|
|
1326
|
-
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);
|
|
1327
1353
|
let d = 0;
|
|
1328
1354
|
const r = () => {
|
|
1329
|
-
|
|
1355
|
+
di(
|
|
1330
1356
|
a,
|
|
1331
1357
|
l,
|
|
1332
1358
|
t,
|
|
@@ -1341,14 +1367,15 @@ async function ti(i, t, e = {}) {
|
|
|
1341
1367
|
return {
|
|
1342
1368
|
stream: h,
|
|
1343
1369
|
stop: () => {
|
|
1344
|
-
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;
|
|
1345
1371
|
}
|
|
1346
1372
|
};
|
|
1347
1373
|
}
|
|
1348
|
-
|
|
1374
|
+
const Tt = "This browser cannot blur the areas you picked, so the recording was not started.";
|
|
1375
|
+
function li() {
|
|
1349
1376
|
return typeof navigator < "u" && !!navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia == "function" && typeof MediaRecorder < "u";
|
|
1350
1377
|
}
|
|
1351
|
-
function
|
|
1378
|
+
function At() {
|
|
1352
1379
|
if (typeof MediaRecorder > "u") return "";
|
|
1353
1380
|
const i = [
|
|
1354
1381
|
"video/webm;codecs=vp9",
|
|
@@ -1361,20 +1388,20 @@ function yt() {
|
|
|
1361
1388
|
return t;
|
|
1362
1389
|
return "";
|
|
1363
1390
|
}
|
|
1364
|
-
function
|
|
1391
|
+
function hi(i = {}) {
|
|
1365
1392
|
const t = i.maxDuration ?? 15, e = i.videoBitsPerSecond ?? 8e5, o = i.redactionElements ?? [], n = i.redactionBlurRadius;
|
|
1366
|
-
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;
|
|
1367
1394
|
function u() {
|
|
1368
|
-
|
|
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;
|
|
1369
1396
|
}
|
|
1370
|
-
function
|
|
1371
|
-
|
|
1397
|
+
function k() {
|
|
1398
|
+
w || (w = !0, l && l.state !== "inactive" && l.stop());
|
|
1372
1399
|
}
|
|
1373
1400
|
return {
|
|
1374
1401
|
async start() {
|
|
1375
|
-
|
|
1376
|
-
const
|
|
1377
|
-
if (!
|
|
1402
|
+
w = !1, d = [];
|
|
1403
|
+
const v = At();
|
|
1404
|
+
if (!v)
|
|
1378
1405
|
throw new Error("No supported video MIME type found");
|
|
1379
1406
|
s = await navigator.mediaDevices.getDisplayMedia({
|
|
1380
1407
|
video: {
|
|
@@ -1388,96 +1415,100 @@ function ii(i = {}) {
|
|
|
1388
1415
|
monitorTypeSurfaces: "exclude",
|
|
1389
1416
|
surfaceSwitching: "exclude"
|
|
1390
1417
|
});
|
|
1391
|
-
const C = s.getVideoTracks()[0],
|
|
1392
|
-
if (
|
|
1393
|
-
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(
|
|
1394
1421
|
"qaid records only the current tab — please share this tab, not a window or your whole screen."
|
|
1395
1422
|
);
|
|
1396
1423
|
C && C.addEventListener("ended", () => {
|
|
1397
|
-
|
|
1424
|
+
k();
|
|
1398
1425
|
});
|
|
1399
1426
|
let S = s;
|
|
1400
|
-
if (
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1403
|
-
}
|
|
1404
|
-
|
|
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, {
|
|
1405
1433
|
blurRadius: n
|
|
1406
1434
|
});
|
|
1407
|
-
|
|
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;
|
|
1408
1438
|
}
|
|
1409
1439
|
l = new MediaRecorder(S, {
|
|
1410
|
-
mimeType:
|
|
1440
|
+
mimeType: v,
|
|
1411
1441
|
videoBitsPerSecond: e
|
|
1412
|
-
}), l.ondataavailable = (
|
|
1413
|
-
|
|
1442
|
+
}), l.ondataavailable = (m) => {
|
|
1443
|
+
m.data.size > 0 && d.push(m.data);
|
|
1414
1444
|
}, l.onstop = () => {
|
|
1415
|
-
const
|
|
1416
|
-
|
|
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());
|
|
1417
1447
|
}, l.onerror = () => {
|
|
1418
|
-
|
|
1419
|
-
}, l.start(1e3),
|
|
1420
|
-
const
|
|
1421
|
-
r && r(
|
|
1448
|
+
g && g(new Error("MediaRecorder error"));
|
|
1449
|
+
}, l.start(1e3), b = Date.now(), f = setInterval(() => {
|
|
1450
|
+
const m = Math.floor((Date.now() - b) / 1e3);
|
|
1451
|
+
r && r(m);
|
|
1422
1452
|
}, 1e3), x = setTimeout(() => {
|
|
1423
|
-
|
|
1453
|
+
k();
|
|
1424
1454
|
}, t * 1e3);
|
|
1425
1455
|
},
|
|
1426
1456
|
stop() {
|
|
1427
|
-
return new Promise((
|
|
1428
|
-
|
|
1457
|
+
return new Promise((v, C) => {
|
|
1458
|
+
y = v, g = C, k();
|
|
1429
1459
|
});
|
|
1430
1460
|
},
|
|
1431
|
-
onTick(
|
|
1432
|
-
r =
|
|
1461
|
+
onTick(v) {
|
|
1462
|
+
r = v;
|
|
1433
1463
|
},
|
|
1434
|
-
onStop(
|
|
1435
|
-
h =
|
|
1464
|
+
onStop(v) {
|
|
1465
|
+
h = v;
|
|
1436
1466
|
},
|
|
1437
1467
|
destroy() {
|
|
1438
|
-
|
|
1468
|
+
k(), u();
|
|
1439
1469
|
}
|
|
1440
1470
|
};
|
|
1441
1471
|
}
|
|
1442
|
-
const
|
|
1472
|
+
const It = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1443
1473
|
__proto__: null,
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
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;
|
|
1448
1479
|
let L = null;
|
|
1449
|
-
function
|
|
1480
|
+
function fi() {
|
|
1450
1481
|
if (typeof document > "u" || typeof window > "u")
|
|
1451
1482
|
return !1;
|
|
1452
1483
|
const i = document.createElement("canvas");
|
|
1453
1484
|
return typeof i.getContext == "function" && !!i.getContext("2d");
|
|
1454
1485
|
}
|
|
1455
|
-
function
|
|
1486
|
+
function mi() {
|
|
1456
1487
|
return window.html2canvas ? Promise.resolve(!0) : L || (L = new Promise((i) => {
|
|
1457
1488
|
if (!document.querySelector(
|
|
1458
|
-
`script[src="${
|
|
1489
|
+
`script[src="${ut}"]`
|
|
1459
1490
|
)) {
|
|
1460
1491
|
const n = document.createElement("script");
|
|
1461
|
-
n.src =
|
|
1492
|
+
n.src = ut, n.async = !0, document.head.appendChild(n);
|
|
1462
1493
|
}
|
|
1463
1494
|
const e = Date.now(), o = () => {
|
|
1464
1495
|
if (window.html2canvas) {
|
|
1465
1496
|
i(!0);
|
|
1466
1497
|
return;
|
|
1467
1498
|
}
|
|
1468
|
-
if (Date.now() - e >
|
|
1499
|
+
if (Date.now() - e > ui) {
|
|
1469
1500
|
L = null, i(!1);
|
|
1470
1501
|
return;
|
|
1471
1502
|
}
|
|
1472
|
-
setTimeout(o,
|
|
1503
|
+
setTimeout(o, pi);
|
|
1473
1504
|
};
|
|
1474
1505
|
o();
|
|
1475
1506
|
}), L);
|
|
1476
1507
|
}
|
|
1477
|
-
async function
|
|
1508
|
+
async function bi(i = {}) {
|
|
1478
1509
|
const { quality: t = 0.8, maxWidth: e = 1280, maxHeight: o = 800 } = i;
|
|
1479
1510
|
try {
|
|
1480
|
-
if (!await
|
|
1511
|
+
if (!await mi() || !window.html2canvas)
|
|
1481
1512
|
return console.warn("html2canvas failed to load"), null;
|
|
1482
1513
|
const s = await window.html2canvas(document.body, {
|
|
1483
1514
|
useCORS: !0,
|
|
@@ -1494,31 +1525,34 @@ async function ri(i = {}) {
|
|
|
1494
1525
|
if (l < 1) {
|
|
1495
1526
|
const d = Math.round(a * l), r = Math.round(c * l), h = document.createElement("canvas");
|
|
1496
1527
|
h.width = d, h.height = r;
|
|
1497
|
-
const
|
|
1498
|
-
return
|
|
1528
|
+
const f = h.getContext("2d");
|
|
1529
|
+
return f ? (f.drawImage(s, 0, 0, d, r), h.toDataURL("image/webp", t)) : null;
|
|
1499
1530
|
}
|
|
1500
1531
|
return s.toDataURL("image/webp", t);
|
|
1501
1532
|
} catch (n) {
|
|
1502
1533
|
return console.warn("DOM screenshot capture failed:", n), null;
|
|
1503
1534
|
}
|
|
1504
1535
|
}
|
|
1505
|
-
const
|
|
1536
|
+
const pt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1506
1537
|
__proto__: null,
|
|
1507
|
-
captureDomScreenshot:
|
|
1508
|
-
isDomScreenshotSupported:
|
|
1509
|
-
}, 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 = {
|
|
1510
1541
|
"#ef4444": "red",
|
|
1511
1542
|
"#f59e0b": "amber",
|
|
1512
1543
|
"#22c55e": "green",
|
|
1513
1544
|
"#3b82f6": "blue",
|
|
1514
1545
|
"#111827": "black",
|
|
1515
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",
|
|
1516
1550
|
"#6366f1": "indigo"
|
|
1517
1551
|
};
|
|
1518
|
-
function
|
|
1519
|
-
return
|
|
1552
|
+
function ft(i) {
|
|
1553
|
+
return yi[i.toLowerCase()] ?? i;
|
|
1520
1554
|
}
|
|
1521
|
-
const
|
|
1555
|
+
const wi = 4, ki = 0.8, xi = {
|
|
1522
1556
|
title: "Annotate screenshot",
|
|
1523
1557
|
instructions: "Draw on the screenshot to highlight or hide details, then choose Done to attach it or Skip to send the original.",
|
|
1524
1558
|
rectangle: "Rectangle",
|
|
@@ -1538,12 +1572,12 @@ function P(i, t) {
|
|
|
1538
1572
|
h: Math.abs(i.y - t.y)
|
|
1539
1573
|
};
|
|
1540
1574
|
}
|
|
1541
|
-
function
|
|
1575
|
+
function qi(i) {
|
|
1542
1576
|
if (i.type === "pen") return i.points.length < 2;
|
|
1543
1577
|
const t = P(i.points[0], i.points[1]);
|
|
1544
1578
|
return t.w < 3 && t.h < 3;
|
|
1545
1579
|
}
|
|
1546
|
-
function
|
|
1580
|
+
function Ci(i, t, e, o) {
|
|
1547
1581
|
i.beginPath(), i.moveTo(t.x, t.y), i.lineTo(e.x, e.y), i.stroke();
|
|
1548
1582
|
const n = Math.atan2(e.y - t.y, e.x - t.x), s = Math.max(10, o * 3);
|
|
1549
1583
|
i.beginPath(), i.moveTo(e.x, e.y), i.lineTo(
|
|
@@ -1554,7 +1588,7 @@ function bi(i, t, e, o) {
|
|
|
1554
1588
|
e.y - s * Math.sin(n + Math.PI / 6)
|
|
1555
1589
|
), i.stroke();
|
|
1556
1590
|
}
|
|
1557
|
-
function
|
|
1591
|
+
function Si(i, t) {
|
|
1558
1592
|
if (t.length !== 0) {
|
|
1559
1593
|
i.beginPath(), i.moveTo(t[0].x, t[0].y);
|
|
1560
1594
|
for (let e = 1; e < t.length; e++)
|
|
@@ -1562,15 +1596,15 @@ function gi(i, t) {
|
|
|
1562
1596
|
i.stroke();
|
|
1563
1597
|
}
|
|
1564
1598
|
}
|
|
1565
|
-
function
|
|
1599
|
+
function Ei(i, t, e, o, n) {
|
|
1566
1600
|
i.fillStyle = "rgb(15, 23, 42)", i.fillRect(t, e, o, n), i.fillStyle = "rgb(37, 47, 63)";
|
|
1567
|
-
for (let s = e; s < e + n; s +=
|
|
1568
|
-
for (let a = t; a < t + o; a +=
|
|
1569
|
-
(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(
|
|
1570
1604
|
a,
|
|
1571
1605
|
s,
|
|
1572
|
-
Math.min(
|
|
1573
|
-
Math.min(
|
|
1606
|
+
Math.min(T, t + o - a),
|
|
1607
|
+
Math.min(T, e + n - s)
|
|
1574
1608
|
);
|
|
1575
1609
|
}
|
|
1576
1610
|
function B(i, t) {
|
|
@@ -1581,30 +1615,30 @@ function B(i, t) {
|
|
|
1581
1615
|
break;
|
|
1582
1616
|
}
|
|
1583
1617
|
case "arrow":
|
|
1584
|
-
|
|
1618
|
+
Ci(i, t.points[0], t.points[1], t.strokeWidth);
|
|
1585
1619
|
break;
|
|
1586
1620
|
case "pen":
|
|
1587
|
-
|
|
1621
|
+
Si(i, t.points);
|
|
1588
1622
|
break;
|
|
1589
1623
|
case "blur": {
|
|
1590
1624
|
const e = P(t.points[0], t.points[1]);
|
|
1591
|
-
|
|
1625
|
+
Ei(i, e.x, e.y, e.w, e.h);
|
|
1592
1626
|
break;
|
|
1593
1627
|
}
|
|
1594
1628
|
}
|
|
1595
1629
|
i.restore();
|
|
1596
1630
|
}
|
|
1597
|
-
function
|
|
1631
|
+
function Lt(i) {
|
|
1598
1632
|
return new Promise((t, e) => {
|
|
1599
1633
|
const o = new Image();
|
|
1600
1634
|
o.onload = () => t(o), o.onerror = () => e(new Error("Failed to load screenshot")), o.src = i;
|
|
1601
1635
|
});
|
|
1602
1636
|
}
|
|
1603
|
-
async function
|
|
1604
|
-
const o = e.quality ??
|
|
1637
|
+
async function Dt(i, t, e = {}) {
|
|
1638
|
+
const o = e.quality ?? ki;
|
|
1605
1639
|
let n;
|
|
1606
1640
|
try {
|
|
1607
|
-
n = await
|
|
1641
|
+
n = await Lt(i);
|
|
1608
1642
|
} catch {
|
|
1609
1643
|
return i;
|
|
1610
1644
|
}
|
|
@@ -1617,8 +1651,8 @@ async function xt(i, t, e = {}) {
|
|
|
1617
1651
|
B(a, c);
|
|
1618
1652
|
return s.toDataURL("image/webp", o);
|
|
1619
1653
|
}
|
|
1620
|
-
let
|
|
1621
|
-
class
|
|
1654
|
+
let Ti = 0;
|
|
1655
|
+
class Mt {
|
|
1622
1656
|
shapes = [];
|
|
1623
1657
|
tool = "rect";
|
|
1624
1658
|
opts;
|
|
@@ -1626,7 +1660,7 @@ class qt {
|
|
|
1626
1660
|
color;
|
|
1627
1661
|
palette;
|
|
1628
1662
|
strokeWidth;
|
|
1629
|
-
uid = `qaid-annotate-${++
|
|
1663
|
+
uid = `qaid-annotate-${++Ti}`;
|
|
1630
1664
|
container;
|
|
1631
1665
|
canvas;
|
|
1632
1666
|
ctx = null;
|
|
@@ -1640,7 +1674,7 @@ class qt {
|
|
|
1640
1674
|
// after the editor is mounted).
|
|
1641
1675
|
resolveResult;
|
|
1642
1676
|
constructor(t) {
|
|
1643
|
-
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;
|
|
1644
1678
|
}
|
|
1645
1679
|
/** Mount the editor and resolve when the user commits (Done) or skips. */
|
|
1646
1680
|
open() {
|
|
@@ -1662,7 +1696,7 @@ class qt {
|
|
|
1662
1696
|
}
|
|
1663
1697
|
/** A round colour swatch button for the toolbar's colour group. */
|
|
1664
1698
|
swatchButton(t) {
|
|
1665
|
-
const e =
|
|
1699
|
+
const e = ft(t), o = q("button", {
|
|
1666
1700
|
type: "button",
|
|
1667
1701
|
class: "qaid-annotate-swatch",
|
|
1668
1702
|
"data-qaid-color": t,
|
|
@@ -1702,19 +1736,19 @@ class qt {
|
|
|
1702
1736
|
"aria-label": this.labels.title
|
|
1703
1737
|
});
|
|
1704
1738
|
const a = q("div", { class: "qaid-annotate-tools" });
|
|
1705
|
-
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));
|
|
1706
1740
|
const c = q("div", {
|
|
1707
1741
|
class: "qaid-annotate-colors",
|
|
1708
1742
|
role: "group",
|
|
1709
1743
|
"aria-label": this.labels.colors
|
|
1710
1744
|
});
|
|
1711
1745
|
for (const h of this.palette) c.appendChild(this.swatchButton(h));
|
|
1712
|
-
this.undoBtn = this.actionButton("undo",
|
|
1713
|
-
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" });
|
|
1714
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, {
|
|
1715
1749
|
labelledbyId: t,
|
|
1716
1750
|
describedbyId: e
|
|
1717
|
-
}), this.opts.announce?.(this.labels.instructions),
|
|
1751
|
+
}), this.opts.announce?.(this.labels.instructions), Lt(this.opts.dataUrl).then((h) => {
|
|
1718
1752
|
this.img = h, this.canvas.width = h.naturalWidth || h.width || 1, this.canvas.height = h.naturalHeight || h.height || 1, this.redraw();
|
|
1719
1753
|
}).catch(() => {
|
|
1720
1754
|
this.img = null, this.redraw();
|
|
@@ -1746,7 +1780,7 @@ class qt {
|
|
|
1746
1780
|
n.getAttribute("data-qaid-tool") === t ? "true" : "false"
|
|
1747
1781
|
);
|
|
1748
1782
|
});
|
|
1749
|
-
const o = this.labels[
|
|
1783
|
+
const o = this.labels[Ai[t]];
|
|
1750
1784
|
this.opts.announce?.(`${o} tool selected`);
|
|
1751
1785
|
}
|
|
1752
1786
|
/** Set the active drawing colour; subsequent shapes use it. */
|
|
@@ -1756,7 +1790,7 @@ class qt {
|
|
|
1756
1790
|
"aria-pressed",
|
|
1757
1791
|
(o.getAttribute("data-qaid-color") ?? "").toLowerCase() === t.toLowerCase() ? "true" : "false"
|
|
1758
1792
|
);
|
|
1759
|
-
}), this.opts.announce?.(`${
|
|
1793
|
+
}), this.opts.announce?.(`${ft(t)} colour selected`);
|
|
1760
1794
|
}
|
|
1761
1795
|
onToolbarClick = (t) => {
|
|
1762
1796
|
const o = t.target?.closest(
|
|
@@ -1795,7 +1829,7 @@ class qt {
|
|
|
1795
1829
|
if (!this.drawing || !this.current) return;
|
|
1796
1830
|
this.drawing = !1;
|
|
1797
1831
|
const t = this.current;
|
|
1798
|
-
if (this.current = null,
|
|
1832
|
+
if (this.current = null, qi(t)) {
|
|
1799
1833
|
this.redraw();
|
|
1800
1834
|
return;
|
|
1801
1835
|
}
|
|
@@ -1824,7 +1858,7 @@ class qt {
|
|
|
1824
1858
|
/** Composite the annotations and resolve with the new WebP data URL. */
|
|
1825
1859
|
async done() {
|
|
1826
1860
|
if (this.settled) return;
|
|
1827
|
-
const t = await
|
|
1861
|
+
const t = await Dt(this.opts.dataUrl, this.shapes, {
|
|
1828
1862
|
quality: this.opts.quality
|
|
1829
1863
|
});
|
|
1830
1864
|
this.opts.announce?.("Annotated screenshot attached"), this.settle(t);
|
|
@@ -1840,27 +1874,27 @@ class qt {
|
|
|
1840
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();
|
|
1841
1875
|
}
|
|
1842
1876
|
}
|
|
1843
|
-
const
|
|
1877
|
+
const Ai = {
|
|
1844
1878
|
rect: "rectangle",
|
|
1845
1879
|
arrow: "arrow",
|
|
1846
1880
|
pen: "pen",
|
|
1847
1881
|
blur: "blur"
|
|
1848
1882
|
};
|
|
1849
|
-
function
|
|
1850
|
-
return new
|
|
1883
|
+
function Ii(i) {
|
|
1884
|
+
return new Mt(i).open();
|
|
1851
1885
|
}
|
|
1852
|
-
const
|
|
1886
|
+
const mt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1853
1887
|
__proto__: null,
|
|
1854
|
-
AnnotationEditor:
|
|
1855
|
-
compositeAnnotations:
|
|
1888
|
+
AnnotationEditor: Mt,
|
|
1889
|
+
compositeAnnotations: Dt,
|
|
1856
1890
|
drawShape: B,
|
|
1857
|
-
openAnnotationEditor:
|
|
1891
|
+
openAnnotationEditor: Ii,
|
|
1858
1892
|
rectFromPoints: P
|
|
1859
1893
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1860
|
-
|
|
1861
|
-
const
|
|
1862
|
-
function
|
|
1863
|
-
const o =
|
|
1894
|
+
Je();
|
|
1895
|
+
const Li = document;
|
|
1896
|
+
function p(i, t, ...e) {
|
|
1897
|
+
const o = Li.createElement(i);
|
|
1864
1898
|
if (t) {
|
|
1865
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)
|
|
1866
1900
|
for (const n in t.attrs) o.setAttribute(n, t.attrs[n]);
|
|
@@ -1871,10 +1905,11 @@ function b(i, t, ...e) {
|
|
|
1871
1905
|
n != null && n !== !1 && o.append(n);
|
|
1872
1906
|
return o;
|
|
1873
1907
|
}
|
|
1874
|
-
class
|
|
1908
|
+
class Di {
|
|
1875
1909
|
constructor(t) {
|
|
1876
1910
|
this.host = t;
|
|
1877
1911
|
}
|
|
1912
|
+
host;
|
|
1878
1913
|
videoRecorder = null;
|
|
1879
1914
|
networkCapture = null;
|
|
1880
1915
|
recordedBlob = null;
|
|
@@ -1897,8 +1932,8 @@ class xi {
|
|
|
1897
1932
|
async startRecording(t = []) {
|
|
1898
1933
|
if (!(this.isRecording || this.host.state !== "IDLE"))
|
|
1899
1934
|
try {
|
|
1900
|
-
this.networkCapture =
|
|
1901
|
-
const { createVideoRecorder: e } = await Promise.resolve().then(() =>
|
|
1935
|
+
this.networkCapture = ei();
|
|
1936
|
+
const { createVideoRecorder: e } = await Promise.resolve().then(() => It);
|
|
1902
1937
|
this.videoRecorder = e({
|
|
1903
1938
|
maxDuration: this.host.config.videoOptions.maxDuration,
|
|
1904
1939
|
redactionElements: t
|
|
@@ -1908,7 +1943,7 @@ class xi {
|
|
|
1908
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());
|
|
1909
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);
|
|
1910
1945
|
} catch (e) {
|
|
1911
|
-
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();
|
|
1912
1947
|
}
|
|
1913
1948
|
}
|
|
1914
1949
|
async stopRecording() {
|
|
@@ -1928,27 +1963,27 @@ class xi {
|
|
|
1928
1963
|
startPicking() {
|
|
1929
1964
|
if (this.isRecording || this.host.state !== "IDLE") return;
|
|
1930
1965
|
this.host.setState("REDACT_PICKING"), this.redactPicks = [];
|
|
1931
|
-
const t = this.host.ensureOverlayHost(), e =
|
|
1966
|
+
const t = this.host.ensureOverlayHost(), e = p("div", { style: "position:absolute;inset:0;" }), o = p(
|
|
1932
1967
|
"div",
|
|
1933
1968
|
{ class: "qaid-redact-picker", style: "position:fixed;inset:0;pointer-events:none;" },
|
|
1934
1969
|
e,
|
|
1935
1970
|
// Control bar — the only pointer-interactive part of the overlay.
|
|
1936
|
-
|
|
1971
|
+
p(
|
|
1937
1972
|
"div",
|
|
1938
1973
|
{
|
|
1939
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);"
|
|
1940
1975
|
},
|
|
1941
|
-
|
|
1976
|
+
p("span", {
|
|
1942
1977
|
text: "Click sensitive areas to blur",
|
|
1943
1978
|
attrs: { "data-qaid-redact-label": "" }
|
|
1944
1979
|
}),
|
|
1945
|
-
|
|
1980
|
+
p("button", {
|
|
1946
1981
|
text: "Start recording",
|
|
1947
1982
|
attrs: { type: "button" },
|
|
1948
1983
|
style: "cursor:pointer;border:0;border-radius:9999px;padding:8px 14px;background:#ff6b6b;color:#0b1220;font:inherit;",
|
|
1949
1984
|
on: { click: () => this.finishRedactionPicking(!0) }
|
|
1950
1985
|
}),
|
|
1951
|
-
|
|
1986
|
+
p("button", {
|
|
1952
1987
|
text: "Cancel",
|
|
1953
1988
|
attrs: { type: "button" },
|
|
1954
1989
|
style: "cursor:pointer;border:0;background:transparent;color:#9fb3c8;font:inherit;",
|
|
@@ -1979,7 +2014,7 @@ class xi {
|
|
|
1979
2014
|
for (const e of this.redactPicks) {
|
|
1980
2015
|
const o = e.getBoundingClientRect();
|
|
1981
2016
|
o.width <= 0 || o.height <= 0 || t.appendChild(
|
|
1982
|
-
|
|
2017
|
+
p("div", {
|
|
1983
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;`
|
|
1984
2019
|
})
|
|
1985
2020
|
);
|
|
@@ -1992,15 +2027,15 @@ class xi {
|
|
|
1992
2027
|
}
|
|
1993
2028
|
showRecordingIndicator() {
|
|
1994
2029
|
const t = this.host.ensureOverlayHost();
|
|
1995
|
-
this.recordingIndicator =
|
|
2030
|
+
this.recordingIndicator = p(
|
|
1996
2031
|
"div",
|
|
1997
2032
|
{ class: "qaid-recording-indicator", style: `z-index:${this.host.config.zIndex + 100}` },
|
|
1998
|
-
|
|
1999
|
-
|
|
2033
|
+
p("div", { class: "qaid-recording-dot" }),
|
|
2034
|
+
p("span", {
|
|
2000
2035
|
class: "qaid-recording-time",
|
|
2001
2036
|
text: this.formatTime(this.host.config.videoOptions.maxDuration)
|
|
2002
2037
|
}),
|
|
2003
|
-
|
|
2038
|
+
p("button", {
|
|
2004
2039
|
class: "qaid-recording-stop",
|
|
2005
2040
|
text: "Stop",
|
|
2006
2041
|
attrs: { type: "button" },
|
|
@@ -2024,34 +2059,34 @@ class xi {
|
|
|
2024
2059
|
this.recordingIndicator && (this.recordingIndicator.remove(), this.recordingIndicator = null);
|
|
2025
2060
|
}
|
|
2026
2061
|
showRecordingPreview() {
|
|
2027
|
-
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");
|
|
2028
2063
|
s.src = e, s.controls = !0, s.autoplay = !0, s.muted = !0;
|
|
2029
|
-
const a =
|
|
2064
|
+
const a = p("textarea", {
|
|
2030
2065
|
attrs: {
|
|
2031
2066
|
placeholder: "Optional: Describe the issue you recorded...",
|
|
2032
2067
|
"aria-label": "Describe the issue you recorded"
|
|
2033
2068
|
}
|
|
2034
|
-
}), c =
|
|
2069
|
+
}), c = p("button", {
|
|
2035
2070
|
class: "qaid-video-btn qaid-video-btn-send",
|
|
2036
2071
|
text: "Send",
|
|
2037
2072
|
attrs: { type: "button" },
|
|
2038
2073
|
on: { click: () => this.submitVideoFeedback(a.value.trim() || null, c) }
|
|
2039
|
-
}), l =
|
|
2074
|
+
}), l = p(
|
|
2040
2075
|
"div",
|
|
2041
2076
|
{ class: "qaid-video-preview-box" },
|
|
2042
2077
|
n,
|
|
2043
2078
|
s,
|
|
2044
2079
|
a,
|
|
2045
|
-
|
|
2080
|
+
p(
|
|
2046
2081
|
"div",
|
|
2047
2082
|
{ class: "qaid-video-preview-actions" },
|
|
2048
|
-
|
|
2083
|
+
p("button", {
|
|
2049
2084
|
class: "qaid-video-btn qaid-video-btn-cancel",
|
|
2050
2085
|
text: "Cancel",
|
|
2051
2086
|
attrs: { type: "button" },
|
|
2052
2087
|
on: { click: () => this.cancelRecordingPreview() }
|
|
2053
2088
|
}),
|
|
2054
|
-
|
|
2089
|
+
p("button", {
|
|
2055
2090
|
class: "qaid-video-btn qaid-video-btn-rerecord",
|
|
2056
2091
|
text: "Re-record",
|
|
2057
2092
|
attrs: { type: "button" },
|
|
@@ -2064,7 +2099,7 @@ class xi {
|
|
|
2064
2099
|
c
|
|
2065
2100
|
)
|
|
2066
2101
|
);
|
|
2067
|
-
this.videoPreview =
|
|
2102
|
+
this.videoPreview = p(
|
|
2068
2103
|
"div",
|
|
2069
2104
|
{ class: "qaid-video-preview", style: `z-index:${this.host.config.zIndex + 100}` },
|
|
2070
2105
|
l
|
|
@@ -2085,35 +2120,52 @@ class xi {
|
|
|
2085
2120
|
this.isSendingVideo = !0, e.disabled = !0, e.textContent = "Sending...";
|
|
2086
2121
|
const o = new FormData();
|
|
2087
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));
|
|
2088
|
-
let n = null;
|
|
2123
|
+
let n = null, s = null;
|
|
2089
2124
|
try {
|
|
2090
|
-
const
|
|
2125
|
+
const a = await fetch(`${this.host.config.endpoint}/video`, {
|
|
2091
2126
|
method: "POST",
|
|
2092
2127
|
body: o
|
|
2093
2128
|
});
|
|
2094
|
-
if (
|
|
2129
|
+
if (a.ok) {
|
|
2095
2130
|
this.host.announceMsg("Recording sent");
|
|
2096
2131
|
try {
|
|
2097
|
-
n = (await
|
|
2132
|
+
n = (await a.json())?.id ?? null;
|
|
2098
2133
|
} catch {
|
|
2099
2134
|
}
|
|
2100
2135
|
} else
|
|
2101
|
-
console.error("Failed to submit video feedback:", await
|
|
2102
|
-
} catch (
|
|
2103
|
-
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;
|
|
2104
2157
|
}
|
|
2105
|
-
this.isSendingVideo = !1, this.removeVideoPreview(), this.cleanupRecording(), await this.host.tryLaunchQuest("video", n);
|
|
2106
2158
|
}
|
|
2107
2159
|
cleanupRecording() {
|
|
2108
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");
|
|
2109
2161
|
}
|
|
2110
2162
|
}
|
|
2111
|
-
const
|
|
2163
|
+
const bt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2112
2164
|
__proto__: null,
|
|
2113
|
-
RecordingController:
|
|
2165
|
+
RecordingController: Di
|
|
2114
2166
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2115
|
-
async function
|
|
2116
|
-
const { quality: t =
|
|
2167
|
+
async function Mi(i = {}) {
|
|
2168
|
+
const { quality: t = 0.8, maxWidth: e = 1280, maxHeight: o = 800 } = i;
|
|
2117
2169
|
try {
|
|
2118
2170
|
if (!navigator.mediaDevices?.getDisplayMedia)
|
|
2119
2171
|
return console.warn("Screen Capture API not available"), null;
|
|
@@ -2123,32 +2175,33 @@ async function qi(i = {}) {
|
|
|
2123
2175
|
displaySurface: "browser"
|
|
2124
2176
|
}
|
|
2125
2177
|
}), s = n.getVideoTracks()[0], a = s.getSettings(), c = document.createElement("video");
|
|
2126
|
-
c.srcObject = n, c.muted = !0, await new Promise((
|
|
2178
|
+
c.srcObject = n, c.muted = !0, await new Promise((g) => {
|
|
2127
2179
|
c.onloadedmetadata = () => {
|
|
2128
|
-
c.play(),
|
|
2180
|
+
c.play(), g();
|
|
2129
2181
|
};
|
|
2130
|
-
}), await new Promise((
|
|
2131
|
-
const
|
|
2132
|
-
c.readyState >= 2 ?
|
|
2182
|
+
}), await new Promise((g) => {
|
|
2183
|
+
const w = () => {
|
|
2184
|
+
c.readyState >= 2 ? g() : requestAnimationFrame(w);
|
|
2133
2185
|
};
|
|
2134
|
-
|
|
2135
|
-
}), await new Promise((
|
|
2136
|
-
const l = a.width || c.videoWidth, d = a.height || c.videoHeight, r = Math.min(e / l, o / d, 1), h = Math.round(l * r),
|
|
2137
|
-
|
|
2138
|
-
const
|
|
2139
|
-
return
|
|
2186
|
+
w();
|
|
2187
|
+
}), await new Promise((g) => setTimeout(g, 100));
|
|
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;
|
|
2190
|
+
const y = b.getContext("2d");
|
|
2191
|
+
return y ? (y.drawImage(c, 0, 0, h, f), s.stop(), b.toDataURL("image/webp", t)) : (s.stop(), null);
|
|
2140
2192
|
} catch (n) {
|
|
2141
2193
|
return console.warn("Screenshot capture failed:", n), null;
|
|
2142
2194
|
}
|
|
2143
2195
|
}
|
|
2144
|
-
const
|
|
2196
|
+
const gt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2145
2197
|
__proto__: null,
|
|
2146
|
-
captureScreenshot:
|
|
2198
|
+
captureScreenshot: Mi
|
|
2147
2199
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2148
|
-
class
|
|
2200
|
+
class Ri {
|
|
2149
2201
|
constructor(t) {
|
|
2150
2202
|
this.host = t;
|
|
2151
2203
|
}
|
|
2204
|
+
host;
|
|
2152
2205
|
modalContainer = null;
|
|
2153
2206
|
backdrop = null;
|
|
2154
2207
|
open() {
|
|
@@ -2172,15 +2225,17 @@ class Ci {
|
|
|
2172
2225
|
}
|
|
2173
2226
|
showBottomSheet() {
|
|
2174
2227
|
const t = this.host.ensureOverlayHost(), e = document.createElement("div");
|
|
2175
|
-
e.className = "qaid-bottom-sheet", e.style.zIndex = String(this.host.config.zIndex + 3), e.
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
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();
|
|
2181
2236
|
}
|
|
2182
2237
|
showPositionedModal() {
|
|
2183
|
-
const t = this.host.ensureOverlayHost(), { modal: e, arrow: o } =
|
|
2238
|
+
const t = this.host.ensureOverlayHost(), { modal: e, arrow: o } = He(
|
|
2184
2239
|
this.host.selectedBounds,
|
|
2185
2240
|
window.innerWidth,
|
|
2186
2241
|
window.innerHeight,
|
|
@@ -2196,25 +2251,65 @@ class Ci {
|
|
|
2196
2251
|
const n = document.createElement("div");
|
|
2197
2252
|
n.className = "qaid-modal-arrow", n.style.left = `${o.left}px`;
|
|
2198
2253
|
const s = document.createElement("div");
|
|
2199
|
-
s.className = "qaid-modal-box", s.
|
|
2200
|
-
}
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
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;
|
|
2218
2313
|
}
|
|
2219
2314
|
setupModalInteractions() {
|
|
2220
2315
|
this.host.openDialogA11y(this.modalContainer, {
|
|
@@ -2243,29 +2338,79 @@ class Ci {
|
|
|
2243
2338
|
});
|
|
2244
2339
|
}
|
|
2245
2340
|
async submitMessage(t) {
|
|
2341
|
+
let e = null;
|
|
2246
2342
|
if (this.host.feedbackId) {
|
|
2247
2343
|
try {
|
|
2248
|
-
await fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
|
|
2344
|
+
const o = await fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
|
|
2249
2345
|
method: "PATCH",
|
|
2250
2346
|
headers: { "Content-Type": "application/json" },
|
|
2251
2347
|
body: JSON.stringify({ message: t })
|
|
2252
2348
|
});
|
|
2253
|
-
|
|
2254
|
-
|
|
2349
|
+
e = o.ok, o.ok || console.error("Failed to submit feedback message: HTTP", o.status);
|
|
2350
|
+
} catch (o) {
|
|
2351
|
+
console.error("Failed to submit feedback message:", o), e = !1;
|
|
2255
2352
|
}
|
|
2256
2353
|
this.host.setFeedbackId(null);
|
|
2257
2354
|
}
|
|
2355
|
+
if (e === !1) {
|
|
2356
|
+
this.showResult(!1);
|
|
2357
|
+
return;
|
|
2358
|
+
}
|
|
2359
|
+
if (e && !this.host.config.hideConfirmation) {
|
|
2360
|
+
this.showResult(!0);
|
|
2361
|
+
return;
|
|
2362
|
+
}
|
|
2258
2363
|
this.close();
|
|
2259
2364
|
}
|
|
2365
|
+
/**
|
|
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.
|
|
2368
|
+
*
|
|
2369
|
+
* The submit button that had focus is gone by this point, so focus moves to
|
|
2370
|
+
* the heading (WCAG 2.4.3) and the message is announced. Mirrors the quests
|
|
2371
|
+
* embed's thank-you screen so the two products confirm the same way. Copy
|
|
2372
|
+
* goes in as text, never markup.
|
|
2373
|
+
*/
|
|
2374
|
+
showResult(t) {
|
|
2375
|
+
const e = this.modalContainer?.querySelector(".qaid-modal-box") ?? this.modalContainer?.querySelector(".qaid-bottom-sheet-content") ?? this.modalContainer;
|
|
2376
|
+
if (!e) {
|
|
2377
|
+
this.close();
|
|
2378
|
+
return;
|
|
2379
|
+
}
|
|
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);
|
|
2404
|
+
}
|
|
2260
2405
|
}
|
|
2261
|
-
const
|
|
2406
|
+
const vt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2262
2407
|
__proto__: null,
|
|
2263
|
-
ModalController:
|
|
2264
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
2265
|
-
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) {
|
|
2266
2411
|
let e = i;
|
|
2267
2412
|
for (; e && e !== t; ) {
|
|
2268
|
-
for (const o of
|
|
2413
|
+
for (const o of Rt) {
|
|
2269
2414
|
const n = e.getAttribute(o);
|
|
2270
2415
|
if (n)
|
|
2271
2416
|
return `${o}="${n}"`;
|
|
@@ -2274,37 +2419,37 @@ function St(i, t = document.body) {
|
|
|
2274
2419
|
}
|
|
2275
2420
|
return null;
|
|
2276
2421
|
}
|
|
2277
|
-
function
|
|
2422
|
+
function Pi(i, t = 100) {
|
|
2278
2423
|
const e = i.textContent?.trim().slice(0, t) || "";
|
|
2279
2424
|
return e.length === t ? e + "..." : e;
|
|
2280
2425
|
}
|
|
2281
|
-
function
|
|
2426
|
+
function Bi(i) {
|
|
2282
2427
|
let t = 1, e = i.previousElementSibling;
|
|
2283
2428
|
for (; e; )
|
|
2284
2429
|
t++, e = e.previousElementSibling;
|
|
2285
2430
|
return t;
|
|
2286
2431
|
}
|
|
2287
|
-
function
|
|
2432
|
+
function Hi(i) {
|
|
2288
2433
|
const t = [];
|
|
2289
2434
|
let e = i;
|
|
2290
2435
|
for (; e && e !== document.body && e !== document.documentElement; ) {
|
|
2291
|
-
const o = e.tagName.toLowerCase(), n =
|
|
2436
|
+
const o = e.tagName.toLowerCase(), n = Bi(e);
|
|
2292
2437
|
t.unshift(`${o}:nth-child(${n})`), e = e.parentElement;
|
|
2293
2438
|
}
|
|
2294
2439
|
return t.length > 0 ? `body > ${t.join(" > ")}` : "body";
|
|
2295
2440
|
}
|
|
2296
|
-
function
|
|
2441
|
+
function Oi(i) {
|
|
2297
2442
|
return i.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1");
|
|
2298
2443
|
}
|
|
2299
|
-
function
|
|
2300
|
-
const t =
|
|
2301
|
-
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);
|
|
2302
2447
|
}
|
|
2303
2448
|
function F(i) {
|
|
2304
|
-
const t =
|
|
2305
|
-
return { selector:
|
|
2449
|
+
const t = Pi(i), e = Pt(i);
|
|
2450
|
+
return { selector: zi(i), text: t, dataAttr: e };
|
|
2306
2451
|
}
|
|
2307
|
-
const
|
|
2452
|
+
const $i = [
|
|
2308
2453
|
"a[href]",
|
|
2309
2454
|
"button",
|
|
2310
2455
|
"input:not([type=hidden])",
|
|
@@ -2323,9 +2468,9 @@ const Ii = [
|
|
|
2323
2468
|
"p",
|
|
2324
2469
|
"li",
|
|
2325
2470
|
"label",
|
|
2326
|
-
...
|
|
2327
|
-
].join(","),
|
|
2328
|
-
function
|
|
2471
|
+
...Rt.map((i) => `[${i}]`)
|
|
2472
|
+
].join(","), _i = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
|
|
2473
|
+
function Fi(i) {
|
|
2329
2474
|
if (i.hasAttribute("hidden") || i.getAttribute("aria-hidden") === "true") return !1;
|
|
2330
2475
|
const t = i.ownerDocument?.defaultView;
|
|
2331
2476
|
if (t && typeof t.getComputedStyle == "function") {
|
|
@@ -2334,14 +2479,14 @@ function Mi(i) {
|
|
|
2334
2479
|
}
|
|
2335
2480
|
return !0;
|
|
2336
2481
|
}
|
|
2337
|
-
function
|
|
2338
|
-
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;
|
|
2339
2484
|
return Array.from(t.querySelectorAll(e)).filter(
|
|
2340
2485
|
(s) => !o(s) && n(s)
|
|
2341
2486
|
);
|
|
2342
2487
|
}
|
|
2343
|
-
function
|
|
2344
|
-
const t = i.candidates ??
|
|
2488
|
+
function Ni(i) {
|
|
2489
|
+
const t = i.candidates ?? Vi({
|
|
2345
2490
|
root: i.root,
|
|
2346
2491
|
selector: i.selector,
|
|
2347
2492
|
isExcluded: i.isExcluded,
|
|
@@ -2356,11 +2501,11 @@ function Pi(i) {
|
|
|
2356
2501
|
s < 0 && t.length > 0 && (s = 0);
|
|
2357
2502
|
function l(u) {
|
|
2358
2503
|
if (!e) return;
|
|
2359
|
-
const
|
|
2360
|
-
if (typeof
|
|
2361
|
-
u.getAttribute("tabindex") === null && !
|
|
2504
|
+
const k = u;
|
|
2505
|
+
if (typeof k.focus == "function") {
|
|
2506
|
+
u.getAttribute("tabindex") === null && !_i.test(u.tagName) && (u.setAttribute("tabindex", "-1"), n.add(u));
|
|
2362
2507
|
try {
|
|
2363
|
-
|
|
2508
|
+
k.focus();
|
|
2364
2509
|
} catch {
|
|
2365
2510
|
}
|
|
2366
2511
|
}
|
|
@@ -2371,34 +2516,34 @@ function Pi(i) {
|
|
|
2371
2516
|
}
|
|
2372
2517
|
function r(u) {
|
|
2373
2518
|
if (a || t.length === 0) return;
|
|
2374
|
-
const
|
|
2375
|
-
s = (u %
|
|
2519
|
+
const k = t.length;
|
|
2520
|
+
s = (u % k + k) % k, d();
|
|
2376
2521
|
}
|
|
2377
2522
|
function h() {
|
|
2378
2523
|
r(s + 1);
|
|
2379
2524
|
}
|
|
2380
|
-
function
|
|
2525
|
+
function f() {
|
|
2381
2526
|
r(s - 1);
|
|
2382
2527
|
}
|
|
2383
|
-
function
|
|
2528
|
+
function b() {
|
|
2384
2529
|
return t[s] ?? null;
|
|
2385
2530
|
}
|
|
2386
|
-
function
|
|
2531
|
+
function y() {
|
|
2387
2532
|
a || (a = !0, o.removeEventListener("keydown", x, !0), n.forEach((u) => u.removeAttribute("tabindex")), n.clear());
|
|
2388
2533
|
}
|
|
2389
|
-
function
|
|
2534
|
+
function g() {
|
|
2390
2535
|
if (a) return;
|
|
2391
|
-
const u =
|
|
2392
|
-
|
|
2536
|
+
const u = b();
|
|
2537
|
+
y(), u && i.onSelect(u);
|
|
2393
2538
|
}
|
|
2394
|
-
function
|
|
2395
|
-
a || (
|
|
2539
|
+
function w() {
|
|
2540
|
+
a || (y(), i.onCancel?.());
|
|
2396
2541
|
}
|
|
2397
2542
|
function x(u) {
|
|
2398
2543
|
if (!a)
|
|
2399
2544
|
switch (u.key) {
|
|
2400
2545
|
case "Tab":
|
|
2401
|
-
u.preventDefault(), u.stopPropagation(), u.shiftKey ?
|
|
2546
|
+
u.preventDefault(), u.stopPropagation(), u.shiftKey ? f() : h();
|
|
2402
2547
|
break;
|
|
2403
2548
|
case "ArrowDown":
|
|
2404
2549
|
case "ArrowRight":
|
|
@@ -2406,37 +2551,38 @@ function Pi(i) {
|
|
|
2406
2551
|
break;
|
|
2407
2552
|
case "ArrowUp":
|
|
2408
2553
|
case "ArrowLeft":
|
|
2409
|
-
u.preventDefault(), u.stopPropagation(),
|
|
2554
|
+
u.preventDefault(), u.stopPropagation(), f();
|
|
2410
2555
|
break;
|
|
2411
2556
|
case "Enter":
|
|
2412
2557
|
case " ":
|
|
2413
2558
|
case "Spacebar":
|
|
2414
|
-
u.preventDefault(), u.stopPropagation(),
|
|
2559
|
+
u.preventDefault(), u.stopPropagation(), g();
|
|
2415
2560
|
break;
|
|
2416
2561
|
case "Escape":
|
|
2417
2562
|
case "Esc":
|
|
2418
|
-
u.preventDefault(), u.stopPropagation(),
|
|
2563
|
+
u.preventDefault(), u.stopPropagation(), w();
|
|
2419
2564
|
break;
|
|
2420
2565
|
}
|
|
2421
2566
|
}
|
|
2422
2567
|
return o.addEventListener("keydown", x, !0), s >= 0 && d(), {
|
|
2423
2568
|
candidates: t,
|
|
2424
2569
|
getIndex: () => s,
|
|
2425
|
-
getCurrent:
|
|
2570
|
+
getCurrent: b,
|
|
2426
2571
|
next: h,
|
|
2427
|
-
prev:
|
|
2572
|
+
prev: f,
|
|
2428
2573
|
moveTo: r,
|
|
2429
|
-
select:
|
|
2430
|
-
cancel:
|
|
2574
|
+
select: g,
|
|
2575
|
+
cancel: w,
|
|
2431
2576
|
handleKey: x,
|
|
2432
|
-
stop:
|
|
2577
|
+
stop: y
|
|
2433
2578
|
};
|
|
2434
2579
|
}
|
|
2435
|
-
const
|
|
2436
|
-
class
|
|
2580
|
+
const Ui = 12;
|
|
2581
|
+
class ji {
|
|
2437
2582
|
constructor(t) {
|
|
2438
2583
|
this.host = t;
|
|
2439
2584
|
}
|
|
2585
|
+
host;
|
|
2440
2586
|
mousePos = { x: 0, y: 0 };
|
|
2441
2587
|
touchStartPos = null;
|
|
2442
2588
|
overlayContainer = null;
|
|
@@ -2461,7 +2607,7 @@ class Hi {
|
|
|
2461
2607
|
* KeyboardTargetingController owns Tab/Arrow/Enter/Space/Escape.
|
|
2462
2608
|
*/
|
|
2463
2609
|
startKeyboard(t) {
|
|
2464
|
-
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({
|
|
2465
2611
|
isExcluded: (e) => M(e),
|
|
2466
2612
|
onHighlight: (e) => {
|
|
2467
2613
|
const o = e.getBoundingClientRect(), n = this.highlightBox;
|
|
@@ -2474,7 +2620,7 @@ class Hi {
|
|
|
2474
2620
|
});
|
|
2475
2621
|
}
|
|
2476
2622
|
selectKeyboardTarget(t) {
|
|
2477
|
-
const e =
|
|
2623
|
+
const e = st(t, 8);
|
|
2478
2624
|
Object.assign(this.host.selectedBounds, e, {
|
|
2479
2625
|
clickX: e.x + e.width / 2,
|
|
2480
2626
|
clickY: e.y + e.height / 2,
|
|
@@ -2499,7 +2645,7 @@ class Hi {
|
|
|
2499
2645
|
/** Move the crosshair/scope reticle and highlight the element under (x, y). */
|
|
2500
2646
|
updateReticleAt(t, e) {
|
|
2501
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) {
|
|
2502
|
-
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);
|
|
2503
2649
|
if (n && !M(n)) {
|
|
2504
2650
|
if (this.highlightBox) {
|
|
2505
2651
|
const s = n.getBoundingClientRect();
|
|
@@ -2518,14 +2664,14 @@ class Hi {
|
|
|
2518
2664
|
}
|
|
2519
2665
|
handleTouchEnd(t) {
|
|
2520
2666
|
const e = t.changedTouches[0], o = this.touchStartPos;
|
|
2521
|
-
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));
|
|
2522
2668
|
}
|
|
2523
2669
|
/** Select the element under (x, y) and tear down targeting. */
|
|
2524
2670
|
selectAt(t, e) {
|
|
2525
|
-
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);
|
|
2526
2672
|
if (!n || M(n))
|
|
2527
2673
|
return;
|
|
2528
|
-
const s =
|
|
2674
|
+
const s = st(n, 8);
|
|
2529
2675
|
Object.assign(this.host.selectedBounds, s, { clickX: t, clickY: e, visible: !0 });
|
|
2530
2676
|
const { selector: a, text: c } = F(n);
|
|
2531
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();
|
|
@@ -2551,22 +2697,22 @@ class Hi {
|
|
|
2551
2697
|
this.keyboardController?.stop(), this.keyboardController = null, this.stopTargetingListeners(), this.hideMarker();
|
|
2552
2698
|
}
|
|
2553
2699
|
}
|
|
2554
|
-
const
|
|
2700
|
+
const yt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2555
2701
|
__proto__: null,
|
|
2556
|
-
TargetingController:
|
|
2702
|
+
TargetingController: ji
|
|
2557
2703
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2558
2704
|
export {
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2705
|
+
Mt as AnnotationEditor,
|
|
2706
|
+
Ye as QaidFeedback,
|
|
2707
|
+
bi as captureDomScreenshot,
|
|
2708
|
+
ei as captureNetworkErrors,
|
|
2709
|
+
Dt as compositeAnnotations,
|
|
2710
|
+
hi as createVideoRecorder,
|
|
2565
2711
|
B as drawShape,
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2712
|
+
At as getSupportedMimeType,
|
|
2713
|
+
fi as isDomScreenshotSupported,
|
|
2714
|
+
li as isVideoRecordingSupported,
|
|
2715
|
+
Ii as openAnnotationEditor,
|
|
2570
2716
|
P as rectFromPoints
|
|
2571
2717
|
};
|
|
2572
2718
|
//# sourceMappingURL=index.js.map
|