@qaiddev/thumbs-embed 1.1.1 → 1.2.1
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 +29 -0
- package/dist/embed.d.ts +34 -0
- package/dist/index.d.ts +1 -1
- package/dist/qaid.js +531 -334
- package/dist/qaid.js.map +1 -1
- package/dist/qaid.umd.cjs +7 -7
- package/dist/qaid.umd.cjs.map +1 -1
- package/dist/quest-launcher.d.ts +66 -0
- package/dist/types.d.ts +49 -0
- package/dist/video-orientation.d.ts +48 -0
- package/package.json +1 -1
package/dist/qaid.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
const
|
|
1
|
+
const I = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
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
|
-
</svg>`,
|
|
3
|
+
</svg>`, A = `<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>`, bt = `<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>`, ct = "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-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;display:flex;align-items:center;justify-content:center;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:calc(100vw - 32px);max-height:calc(100vh - 32px);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%;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)}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}}", lt = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
|
|
8
|
-
let
|
|
9
|
-
const
|
|
7
|
+
</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-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)}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}}", vt = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
|
|
8
|
+
let k = 0;
|
|
9
|
+
const yt = "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 svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", wt = {
|
|
10
10
|
small: 36,
|
|
11
11
|
medium: 48,
|
|
12
12
|
large: 64
|
|
13
|
-
},
|
|
13
|
+
}, xt = {
|
|
14
14
|
small: 18,
|
|
15
15
|
medium: 24,
|
|
16
16
|
large: 32
|
|
17
17
|
};
|
|
18
|
-
function
|
|
18
|
+
function qt(e, t, i) {
|
|
19
19
|
const [o, n, s] = [e, t, i].map((a) => (a = a / 255, a <= 0.03928 ? a / 12.92 : Math.pow((a + 0.055) / 1.055, 2.4)));
|
|
20
20
|
return 0.2126 * o + 0.7152 * n + 0.0722 * s;
|
|
21
21
|
}
|
|
22
|
-
function
|
|
22
|
+
function kt(e) {
|
|
23
23
|
if (e.startsWith("#")) {
|
|
24
24
|
const i = e.slice(1), o = i.length === 3 ? i.split("").map((s) => s + s).join("") : i, n = parseInt(o, 16);
|
|
25
25
|
return {
|
|
@@ -35,11 +35,11 @@ function ft(e) {
|
|
|
35
35
|
b: parseInt(t[3])
|
|
36
36
|
} : null;
|
|
37
37
|
}
|
|
38
|
-
function
|
|
39
|
-
const t =
|
|
40
|
-
return t &&
|
|
38
|
+
function Ct(e) {
|
|
39
|
+
const t = kt(e);
|
|
40
|
+
return t && qt(t.r, t.g, t.b) > 0.4 ? "black" : "white";
|
|
41
41
|
}
|
|
42
|
-
function
|
|
42
|
+
function St(e = {}) {
|
|
43
43
|
const {
|
|
44
44
|
positiveColor: t = "rgb(0, 200, 83)",
|
|
45
45
|
negativeColor: i = "rgb(255, 0, 0)",
|
|
@@ -47,42 +47,42 @@ function gt(e = {}) {
|
|
|
47
47
|
buttonSize: n = "medium",
|
|
48
48
|
modalWidth: s = 400,
|
|
49
49
|
backdropOpacity: a = 0.3,
|
|
50
|
-
fontFamily:
|
|
50
|
+
fontFamily: d = "system-ui, -apple-system, sans-serif",
|
|
51
51
|
fontSize: l = 16
|
|
52
|
-
} = e, r =
|
|
52
|
+
} = e, r = wt[n], c = xt[n], p = Ct(o);
|
|
53
53
|
return {
|
|
54
54
|
"--qaid-positive": t,
|
|
55
55
|
"--qaid-negative": i,
|
|
56
56
|
"--qaid-marker": o,
|
|
57
57
|
"--qaid-marker-text": p,
|
|
58
58
|
"--qaid-btn-size": `${r}px`,
|
|
59
|
-
"--qaid-icon-size": `${
|
|
59
|
+
"--qaid-icon-size": `${c}px`,
|
|
60
60
|
"--qaid-modal-width": `${s}px`,
|
|
61
61
|
"--qaid-backdrop-opacity": String(a),
|
|
62
|
-
"--qaid-font-family":
|
|
62
|
+
"--qaid-font-family": d,
|
|
63
63
|
"--qaid-font-size": `${l}px`
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
function
|
|
66
|
+
function Et(e, t) {
|
|
67
67
|
for (const [i, o] of Object.entries(t))
|
|
68
68
|
e.style.setProperty(i, o);
|
|
69
69
|
}
|
|
70
|
-
function
|
|
71
|
-
return
|
|
70
|
+
function N() {
|
|
71
|
+
return gt + yt;
|
|
72
72
|
}
|
|
73
|
-
function
|
|
74
|
-
if (
|
|
73
|
+
function Tt() {
|
|
74
|
+
if (k++, k > 1) return;
|
|
75
75
|
const e = document.createElement("style");
|
|
76
|
-
e.id = "qaid-styles", e.textContent =
|
|
76
|
+
e.id = "qaid-styles", e.textContent = vt, document.head.appendChild(e);
|
|
77
77
|
}
|
|
78
|
-
function
|
|
79
|
-
|
|
78
|
+
function Lt() {
|
|
79
|
+
k <= 0 || (k--, k === 0 && document.getElementById("qaid-styles").remove());
|
|
80
80
|
}
|
|
81
|
-
const
|
|
82
|
-
function
|
|
81
|
+
const G = ["data-comp", "data-qa", "data-testid", "data-id"];
|
|
82
|
+
function J(e, t = document.body) {
|
|
83
83
|
let i = e;
|
|
84
84
|
for (; i && i !== t; ) {
|
|
85
|
-
for (const o of
|
|
85
|
+
for (const o of G) {
|
|
86
86
|
const n = i.getAttribute(o);
|
|
87
87
|
if (n)
|
|
88
88
|
return `${o}="${n}"`;
|
|
@@ -91,37 +91,37 @@ function Y(e, t = document.body) {
|
|
|
91
91
|
}
|
|
92
92
|
return null;
|
|
93
93
|
}
|
|
94
|
-
function
|
|
94
|
+
function It(e, t = 100) {
|
|
95
95
|
const i = e.textContent?.trim().slice(0, t) || "";
|
|
96
96
|
return i.length === t ? i + "..." : i;
|
|
97
97
|
}
|
|
98
|
-
function
|
|
98
|
+
function At(e) {
|
|
99
99
|
let t = 1, i = e.previousElementSibling;
|
|
100
100
|
for (; i; )
|
|
101
101
|
t++, i = i.previousElementSibling;
|
|
102
102
|
return t;
|
|
103
103
|
}
|
|
104
|
-
function
|
|
104
|
+
function Dt(e) {
|
|
105
105
|
const t = [];
|
|
106
106
|
let i = e;
|
|
107
107
|
for (; i && i !== document.body && i !== document.documentElement; ) {
|
|
108
|
-
const o = i.tagName.toLowerCase(), n =
|
|
108
|
+
const o = i.tagName.toLowerCase(), n = At(i);
|
|
109
109
|
t.unshift(`${o}:nth-child(${n})`), i = i.parentElement;
|
|
110
110
|
}
|
|
111
111
|
return t.length > 0 ? `body > ${t.join(" > ")}` : "body";
|
|
112
112
|
}
|
|
113
|
-
function
|
|
113
|
+
function Mt(e) {
|
|
114
114
|
return e.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1");
|
|
115
115
|
}
|
|
116
|
-
function
|
|
117
|
-
const t =
|
|
118
|
-
return t ? `[${t}]` : e.id ? `#${
|
|
116
|
+
function Rt(e) {
|
|
117
|
+
const t = J(e);
|
|
118
|
+
return t ? `[${t}]` : e.id ? `#${Mt(e.id)}` : Dt(e);
|
|
119
119
|
}
|
|
120
|
-
function
|
|
121
|
-
const t =
|
|
122
|
-
return { selector:
|
|
120
|
+
function D(e) {
|
|
121
|
+
const t = It(e), i = J(e);
|
|
122
|
+
return { selector: Rt(e), text: t, dataAttr: i };
|
|
123
123
|
}
|
|
124
|
-
const
|
|
124
|
+
const Ht = [
|
|
125
125
|
"a[href]",
|
|
126
126
|
"button",
|
|
127
127
|
"input:not([type=hidden])",
|
|
@@ -140,9 +140,9 @@ const Et = [
|
|
|
140
140
|
"p",
|
|
141
141
|
"li",
|
|
142
142
|
"label",
|
|
143
|
-
...
|
|
144
|
-
].join(","),
|
|
145
|
-
function
|
|
143
|
+
...G.map((e) => `[${e}]`)
|
|
144
|
+
].join(","), Bt = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
|
|
145
|
+
function Pt(e) {
|
|
146
146
|
if (e.hasAttribute("hidden") || e.getAttribute("aria-hidden") === "true") return !1;
|
|
147
147
|
const t = e.ownerDocument?.defaultView;
|
|
148
148
|
if (t && typeof t.getComputedStyle == "function") {
|
|
@@ -151,33 +151,33 @@ function Lt(e) {
|
|
|
151
151
|
}
|
|
152
152
|
return !0;
|
|
153
153
|
}
|
|
154
|
-
function
|
|
155
|
-
const t = e.root ?? document.body, i = e.selector ??
|
|
154
|
+
function zt(e = {}) {
|
|
155
|
+
const t = e.root ?? document.body, i = e.selector ?? Ht, o = e.isExcluded ?? (() => !1), n = e.isVisible ?? Pt;
|
|
156
156
|
return Array.from(t.querySelectorAll(i)).filter(
|
|
157
157
|
(s) => !o(s) && n(s)
|
|
158
158
|
);
|
|
159
159
|
}
|
|
160
|
-
function
|
|
161
|
-
const t = e.candidates ??
|
|
160
|
+
function Ot(e) {
|
|
161
|
+
const t = e.candidates ?? zt({
|
|
162
162
|
root: e.root,
|
|
163
163
|
selector: e.selector,
|
|
164
164
|
isExcluded: e.isExcluded,
|
|
165
165
|
isVisible: e.isVisible
|
|
166
166
|
}), i = e.moveFocus ?? !0, o = e.eventTarget ?? document, n = /* @__PURE__ */ new Set();
|
|
167
167
|
let s = -1, a = !1;
|
|
168
|
-
const
|
|
169
|
-
if (
|
|
170
|
-
const h = t.indexOf(
|
|
168
|
+
const d = e.initial !== void 0 ? e.initial : typeof document < "u" ? document.activeElement : null;
|
|
169
|
+
if (d) {
|
|
170
|
+
const h = t.indexOf(d);
|
|
171
171
|
h >= 0 && (s = h);
|
|
172
172
|
}
|
|
173
173
|
s < 0 && t.length > 0 && (s = 0);
|
|
174
174
|
function l(h) {
|
|
175
175
|
if (!i) return;
|
|
176
|
-
const
|
|
177
|
-
if (typeof
|
|
178
|
-
h.getAttribute("tabindex") === null && !
|
|
176
|
+
const w = h;
|
|
177
|
+
if (typeof w.focus == "function") {
|
|
178
|
+
h.getAttribute("tabindex") === null && !Bt.test(h.tagName) && (h.setAttribute("tabindex", "-1"), n.add(h));
|
|
179
179
|
try {
|
|
180
|
-
|
|
180
|
+
w.focus();
|
|
181
181
|
} catch {
|
|
182
182
|
}
|
|
183
183
|
}
|
|
@@ -186,32 +186,32 @@ function Dt(e) {
|
|
|
186
186
|
const h = t[s];
|
|
187
187
|
h && (l(h), e.onHighlight?.(h, s));
|
|
188
188
|
}
|
|
189
|
-
function
|
|
189
|
+
function c(h) {
|
|
190
190
|
if (a || t.length === 0) return;
|
|
191
|
-
const
|
|
192
|
-
s = (h %
|
|
191
|
+
const w = t.length;
|
|
192
|
+
s = (h % w + w) % w, r();
|
|
193
193
|
}
|
|
194
194
|
function p() {
|
|
195
|
-
|
|
195
|
+
c(s + 1);
|
|
196
196
|
}
|
|
197
197
|
function u() {
|
|
198
|
-
|
|
198
|
+
c(s - 1);
|
|
199
199
|
}
|
|
200
200
|
function m() {
|
|
201
201
|
return t[s] ?? null;
|
|
202
202
|
}
|
|
203
|
-
function g() {
|
|
204
|
-
a || (a = !0, o.removeEventListener("keydown", v, !0), n.forEach((h) => h.removeAttribute("tabindex")), n.clear());
|
|
205
|
-
}
|
|
206
203
|
function b() {
|
|
204
|
+
a || (a = !0, o.removeEventListener("keydown", f, !0), n.forEach((h) => h.removeAttribute("tabindex")), n.clear());
|
|
205
|
+
}
|
|
206
|
+
function v() {
|
|
207
207
|
if (a) return;
|
|
208
208
|
const h = m();
|
|
209
|
-
|
|
209
|
+
b(), h && e.onSelect(h);
|
|
210
210
|
}
|
|
211
|
-
function
|
|
212
|
-
a || (
|
|
211
|
+
function y() {
|
|
212
|
+
a || (b(), e.onCancel?.());
|
|
213
213
|
}
|
|
214
|
-
function
|
|
214
|
+
function f(h) {
|
|
215
215
|
if (!a)
|
|
216
216
|
switch (h.key) {
|
|
217
217
|
case "Tab":
|
|
@@ -228,28 +228,28 @@ function Dt(e) {
|
|
|
228
228
|
case "Enter":
|
|
229
229
|
case " ":
|
|
230
230
|
case "Spacebar":
|
|
231
|
-
h.preventDefault(), h.stopPropagation(),
|
|
231
|
+
h.preventDefault(), h.stopPropagation(), v();
|
|
232
232
|
break;
|
|
233
233
|
case "Escape":
|
|
234
234
|
case "Esc":
|
|
235
|
-
h.preventDefault(), h.stopPropagation(),
|
|
235
|
+
h.preventDefault(), h.stopPropagation(), y();
|
|
236
236
|
break;
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
|
-
return o.addEventListener("keydown",
|
|
239
|
+
return o.addEventListener("keydown", f, !0), s >= 0 && r(), {
|
|
240
240
|
candidates: t,
|
|
241
241
|
getIndex: () => s,
|
|
242
242
|
getCurrent: m,
|
|
243
243
|
next: p,
|
|
244
244
|
prev: u,
|
|
245
|
-
moveTo:
|
|
246
|
-
select:
|
|
247
|
-
cancel:
|
|
248
|
-
handleKey:
|
|
249
|
-
stop:
|
|
245
|
+
moveTo: c,
|
|
246
|
+
select: v,
|
|
247
|
+
cancel: y,
|
|
248
|
+
handleKey: f,
|
|
249
|
+
stop: b
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
|
-
const
|
|
252
|
+
const F = "data-qaid-a11y-live", $t = "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;", Nt = [
|
|
253
253
|
"a[href]",
|
|
254
254
|
"button",
|
|
255
255
|
"input",
|
|
@@ -257,25 +257,25 @@ const O = "data-qaid-a11y-live", At = "position:absolute;width:1px;height:1px;ma
|
|
|
257
257
|
"select",
|
|
258
258
|
"[tabindex]"
|
|
259
259
|
].join(",");
|
|
260
|
-
function
|
|
260
|
+
function Ft(e) {
|
|
261
261
|
return e.ownerDocument || document;
|
|
262
262
|
}
|
|
263
|
-
function
|
|
263
|
+
function Vt(e, t) {
|
|
264
264
|
const i = t ? "assertive" : "polite", o = e.querySelector(
|
|
265
|
-
`[${
|
|
265
|
+
`[${F}="${i}"]`
|
|
266
266
|
);
|
|
267
267
|
if (o) return o;
|
|
268
|
-
const s =
|
|
269
|
-
return s.setAttribute(
|
|
268
|
+
const s = Ft(e).createElement("div");
|
|
269
|
+
return s.setAttribute(F, i), s.setAttribute("role", t ? "alert" : "status"), s.setAttribute("aria-live", t ? "assertive" : "polite"), s.setAttribute("aria-atomic", "true"), s.style.cssText = $t, e.appendChild(s), s;
|
|
270
270
|
}
|
|
271
|
-
function
|
|
272
|
-
const o =
|
|
271
|
+
function Ut(e, t, i = {}) {
|
|
272
|
+
const o = Vt(e, !!i.assertive);
|
|
273
273
|
o.textContent = "", o.textContent = t;
|
|
274
274
|
}
|
|
275
|
-
function
|
|
275
|
+
function _t(e) {
|
|
276
276
|
return e.hasAttribute("disabled") ? !0 : e.disabled === !0;
|
|
277
277
|
}
|
|
278
|
-
function
|
|
278
|
+
function Kt(e) {
|
|
279
279
|
let t = e;
|
|
280
280
|
for (; t; ) {
|
|
281
281
|
if (t.hasAttribute("hidden")) return !0;
|
|
@@ -286,52 +286,52 @@ function Pt(e) {
|
|
|
286
286
|
}
|
|
287
287
|
return !1;
|
|
288
288
|
}
|
|
289
|
-
function
|
|
289
|
+
function V(e) {
|
|
290
290
|
return Array.from(
|
|
291
|
-
e.querySelectorAll(
|
|
292
|
-
).filter((i) => !(i.getAttribute("tabindex") === "-1" || i instanceof HTMLInputElement && i.type === "hidden" || i instanceof HTMLAnchorElement && !i.getAttribute("href") ||
|
|
291
|
+
e.querySelectorAll(Nt)
|
|
292
|
+
).filter((i) => !(i.getAttribute("tabindex") === "-1" || i instanceof HTMLInputElement && i.type === "hidden" || i instanceof HTMLAnchorElement && !i.getAttribute("href") || _t(i) || Kt(i)));
|
|
293
293
|
}
|
|
294
|
-
function
|
|
294
|
+
function Z(e) {
|
|
295
295
|
let t = e.activeElement;
|
|
296
296
|
for (; t && t.shadowRoot && t.shadowRoot.activeElement; )
|
|
297
297
|
t = t.shadowRoot.activeElement;
|
|
298
298
|
return t instanceof HTMLElement ? t : null;
|
|
299
299
|
}
|
|
300
|
-
function
|
|
300
|
+
function jt(e) {
|
|
301
301
|
const t = e.ownerDocument || document;
|
|
302
302
|
let i = !1;
|
|
303
303
|
const o = (s) => {
|
|
304
304
|
if (s.key !== "Tab") return;
|
|
305
|
-
const a =
|
|
305
|
+
const a = V(e);
|
|
306
306
|
if (a.length === 0) {
|
|
307
307
|
s.preventDefault(), e.focus();
|
|
308
308
|
return;
|
|
309
309
|
}
|
|
310
|
-
const
|
|
311
|
-
s.shiftKey ? (!
|
|
310
|
+
const d = a[0], l = a[a.length - 1], r = Z(t), c = r ? a.indexOf(r) !== -1 : !1;
|
|
311
|
+
s.shiftKey ? (!c || r === d) && (s.preventDefault(), l.focus()) : (!c || r === l) && (s.preventDefault(), d.focus());
|
|
312
312
|
};
|
|
313
313
|
e.addEventListener("keydown", o);
|
|
314
|
-
const n =
|
|
314
|
+
const n = V(e);
|
|
315
315
|
return n.length > 0 ? n[0].focus() : (e.hasAttribute("tabindex") || (e.setAttribute("tabindex", "-1"), i = !0), e.focus()), {
|
|
316
316
|
release() {
|
|
317
317
|
e.removeEventListener("keydown", o), i && (e.removeAttribute("tabindex"), i = !1);
|
|
318
318
|
}
|
|
319
319
|
};
|
|
320
320
|
}
|
|
321
|
-
function
|
|
322
|
-
return
|
|
321
|
+
function Xt() {
|
|
322
|
+
return Z(document);
|
|
323
323
|
}
|
|
324
|
-
function
|
|
324
|
+
function Wt(e) {
|
|
325
325
|
if (!(!e || typeof e.focus != "function"))
|
|
326
326
|
try {
|
|
327
327
|
e.focus();
|
|
328
328
|
} catch {
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
|
-
function
|
|
331
|
+
function Yt(e, t = {}) {
|
|
332
332
|
e.setAttribute("role", "dialog"), e.setAttribute("aria-modal", "true"), t.labelledbyId && e.setAttribute("aria-labelledby", t.labelledbyId), t.describedbyId && e.setAttribute("aria-describedby", t.describedbyId), t.label && e.setAttribute("aria-label", t.label);
|
|
333
333
|
}
|
|
334
|
-
function
|
|
334
|
+
function Qt(e, t) {
|
|
335
335
|
let i = e;
|
|
336
336
|
for (; i && i !== t; ) {
|
|
337
337
|
const o = i.parentNode;
|
|
@@ -345,15 +345,15 @@ function Ft(e, t) {
|
|
|
345
345
|
}
|
|
346
346
|
return null;
|
|
347
347
|
}
|
|
348
|
-
function
|
|
348
|
+
function Gt(e) {
|
|
349
349
|
const i = (e.ownerDocument || document).body;
|
|
350
350
|
if (!i) return () => {
|
|
351
351
|
};
|
|
352
|
-
const o =
|
|
352
|
+
const o = Qt(e, i), n = [];
|
|
353
353
|
return Array.from(i.children).forEach((s) => {
|
|
354
354
|
if (!(s instanceof HTMLElement) || o && s === o) return;
|
|
355
|
-
const a = s.inert === !0,
|
|
356
|
-
a &&
|
|
355
|
+
const a = s.inert === !0, d = s.getAttribute("aria-hidden");
|
|
356
|
+
a && d === "true" || (s.inert = !0, s.setAttribute("aria-hidden", "true"), n.push({ el: s, prevInert: a, prevAriaHidden: d }));
|
|
357
357
|
}), function() {
|
|
358
358
|
for (; n.length; ) {
|
|
359
359
|
const a = n.pop();
|
|
@@ -361,14 +361,14 @@ function _t(e) {
|
|
|
361
361
|
}
|
|
362
362
|
};
|
|
363
363
|
}
|
|
364
|
-
const
|
|
364
|
+
const tt = {
|
|
365
365
|
width: 400,
|
|
366
366
|
height: 280,
|
|
367
367
|
arrowHeight: 12,
|
|
368
368
|
gap: 8,
|
|
369
369
|
viewportPadding: 16
|
|
370
370
|
};
|
|
371
|
-
function
|
|
371
|
+
function Jt(e, t, i, o, n) {
|
|
372
372
|
const s = e.y, a = t - (e.y + e.height);
|
|
373
373
|
if (a >= i + o)
|
|
374
374
|
return {
|
|
@@ -380,29 +380,29 @@ function Ut(e, t, i, o, n) {
|
|
|
380
380
|
top: e.y - i - o,
|
|
381
381
|
position: "above"
|
|
382
382
|
};
|
|
383
|
-
const
|
|
383
|
+
const d = a > s ? "below" : "above";
|
|
384
384
|
let l;
|
|
385
|
-
return
|
|
385
|
+
return d === "below" ? l = Math.min(
|
|
386
386
|
e.y + e.height + o,
|
|
387
387
|
t - i - n
|
|
388
|
-
) : l = Math.max(n, e.y - i - o), { top: l, position:
|
|
388
|
+
) : l = Math.max(n, e.y - i - o), { top: l, position: d };
|
|
389
389
|
}
|
|
390
|
-
function
|
|
390
|
+
function Zt(e, t, i, o) {
|
|
391
391
|
let s = e.x + e.width / 2 - i / 2;
|
|
392
392
|
return s = Math.max(o, Math.min(s, t - i - o)), s;
|
|
393
393
|
}
|
|
394
|
-
function
|
|
394
|
+
function te(e, t, i, o = 24, n = 24) {
|
|
395
395
|
const a = e.clickX - t - n / 2;
|
|
396
396
|
return Math.max(o, Math.min(a, i - o - n / 2));
|
|
397
397
|
}
|
|
398
|
-
function
|
|
399
|
-
const n = o.height + o.arrowHeight, s =
|
|
398
|
+
function ee(e, t, i, o = tt) {
|
|
399
|
+
const n = o.height + o.arrowHeight, s = Jt(
|
|
400
400
|
e,
|
|
401
401
|
i,
|
|
402
402
|
n,
|
|
403
403
|
o.gap,
|
|
404
404
|
o.viewportPadding
|
|
405
|
-
), a =
|
|
405
|
+
), a = Zt(
|
|
406
406
|
e,
|
|
407
407
|
t,
|
|
408
408
|
o.width,
|
|
@@ -414,15 +414,15 @@ function Wt(e, t, i, o = J) {
|
|
|
414
414
|
position: s.position
|
|
415
415
|
};
|
|
416
416
|
}
|
|
417
|
-
function
|
|
417
|
+
function ie(e, t, i, o = {}) {
|
|
418
418
|
const n = o.gap ?? 8;
|
|
419
419
|
let s = e.bottom + n;
|
|
420
420
|
s + t.height > i.height - n && (s = e.top - t.height - n);
|
|
421
421
|
let a = e.left;
|
|
422
422
|
return a < n ? a = n : a + t.width > i.width - n && (a = i.width - t.width - n), s < n ? s = n : s + t.height > i.height - n && (s = i.height - t.height - n), { top: s, left: a };
|
|
423
423
|
}
|
|
424
|
-
function
|
|
425
|
-
const n =
|
|
424
|
+
function oe(e, t, i, o = tt) {
|
|
425
|
+
const n = ee(e, t, i, o), s = te(
|
|
426
426
|
e,
|
|
427
427
|
n.left,
|
|
428
428
|
o.width
|
|
@@ -432,15 +432,15 @@ function Yt(e, t, i, o = J) {
|
|
|
432
432
|
arrow: { left: s }
|
|
433
433
|
};
|
|
434
434
|
}
|
|
435
|
-
const
|
|
436
|
-
function
|
|
437
|
-
const t = [], i = console.error, o = console.warn, n = console.log, s = (a,
|
|
435
|
+
const ne = 20;
|
|
436
|
+
function se(e) {
|
|
437
|
+
const t = [], i = console.error, o = console.warn, n = console.log, s = (a, d) => {
|
|
438
438
|
const l = {
|
|
439
|
-
message:
|
|
439
|
+
message: d.map((r) => String(r)).join(" "),
|
|
440
440
|
timestamp: Date.now(),
|
|
441
441
|
level: a
|
|
442
442
|
};
|
|
443
|
-
t.length >=
|
|
443
|
+
t.length >= ne && t.shift(), t.push(l), e && e(l);
|
|
444
444
|
};
|
|
445
445
|
return console.error = function(...a) {
|
|
446
446
|
s("error", a), i.apply(console, a);
|
|
@@ -455,38 +455,38 @@ function Jt(e) {
|
|
|
455
455
|
}
|
|
456
456
|
};
|
|
457
457
|
}
|
|
458
|
-
const
|
|
459
|
-
function
|
|
458
|
+
const ae = 20, U = 4096;
|
|
459
|
+
function S(e) {
|
|
460
460
|
const t = typeof e == "string" ? e : JSON.stringify(e);
|
|
461
|
-
return t.length >
|
|
461
|
+
return t.length > U ? t.slice(0, U) + "…[truncated]" : t;
|
|
462
462
|
}
|
|
463
|
-
function
|
|
464
|
-
e.length >=
|
|
463
|
+
function _(e, t) {
|
|
464
|
+
e.length >= ae && e.shift(), e.push(t);
|
|
465
465
|
}
|
|
466
|
-
async function
|
|
466
|
+
async function re(e) {
|
|
467
467
|
try {
|
|
468
468
|
const t = await e.clone().text();
|
|
469
|
-
return
|
|
469
|
+
return S(t);
|
|
470
470
|
} catch {
|
|
471
471
|
return;
|
|
472
472
|
}
|
|
473
473
|
}
|
|
474
|
-
function
|
|
474
|
+
function de() {
|
|
475
475
|
const e = [], t = window.fetch;
|
|
476
476
|
window.fetch = async function(n, s) {
|
|
477
|
-
const a = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url,
|
|
477
|
+
const a = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url, d = s?.method ?? (typeof n == "object" && "method" in n ? n.method : "GET");
|
|
478
478
|
let l;
|
|
479
|
-
s?.body && (l =
|
|
479
|
+
s?.body && (l = S(s.body));
|
|
480
480
|
const r = await t.apply(window, [n, s]);
|
|
481
481
|
if (r.status >= 400) {
|
|
482
|
-
const
|
|
483
|
-
|
|
482
|
+
const c = await re(r);
|
|
483
|
+
_(e, {
|
|
484
484
|
url: a,
|
|
485
|
-
method:
|
|
485
|
+
method: d.toUpperCase(),
|
|
486
486
|
status: r.status,
|
|
487
487
|
statusText: r.statusText,
|
|
488
488
|
requestBody: l,
|
|
489
|
-
responseBody:
|
|
489
|
+
responseBody: c,
|
|
490
490
|
timestamp: Date.now()
|
|
491
491
|
});
|
|
492
492
|
}
|
|
@@ -496,15 +496,15 @@ function te() {
|
|
|
496
496
|
return XMLHttpRequest.prototype.open = function(n, s, ...a) {
|
|
497
497
|
return this._qaid_method = n, this._qaid_url = typeof s == "string" ? s : s.toString(), i.apply(this, [n, s, ...a]);
|
|
498
498
|
}, XMLHttpRequest.prototype.send = function(n) {
|
|
499
|
-
const s = this, a = n ?
|
|
499
|
+
const s = this, a = n ? S(n) : void 0;
|
|
500
500
|
return s.addEventListener("load", function() {
|
|
501
|
-
s.status >= 400 &&
|
|
501
|
+
s.status >= 400 && _(e, {
|
|
502
502
|
url: s._qaid_url,
|
|
503
503
|
method: s._qaid_method.toUpperCase(),
|
|
504
504
|
status: s.status,
|
|
505
505
|
statusText: s.statusText,
|
|
506
506
|
requestBody: a,
|
|
507
|
-
responseBody:
|
|
507
|
+
responseBody: S(s.responseText),
|
|
508
508
|
timestamp: Date.now()
|
|
509
509
|
});
|
|
510
510
|
}), o.apply(this, [n]);
|
|
@@ -515,10 +515,73 @@ function te() {
|
|
|
515
515
|
}
|
|
516
516
|
};
|
|
517
517
|
}
|
|
518
|
-
function
|
|
518
|
+
function ce() {
|
|
519
|
+
const e = navigator.userAgent || "";
|
|
520
|
+
return /iP(hone|ad|od)/.test(e) || // iPadOS 13+ masquerades as "MacIntel" but is a multi-touch device.
|
|
521
|
+
navigator.platform === "MacIntel" && (navigator.maxTouchPoints || 0) > 1;
|
|
522
|
+
}
|
|
523
|
+
function le(e, t, i, o, n) {
|
|
524
|
+
const s = e >= t, a = i >= o;
|
|
525
|
+
return s === a ? { width: e, height: t, rotate: 0 } : { width: t, height: e, rotate: n === 270 ? -90 : 90 };
|
|
526
|
+
}
|
|
527
|
+
function he(e, t, i) {
|
|
528
|
+
if (i.rotate === 0) {
|
|
529
|
+
e.drawImage(t, 0, 0, i.width, i.height);
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
e.save(), i.rotate === 90 ? (e.translate(i.width, 0), e.rotate(Math.PI / 2)) : (e.translate(0, i.height), e.rotate(-Math.PI / 2)), e.drawImage(t, 0, 0, i.height, i.width), e.restore();
|
|
533
|
+
}
|
|
534
|
+
function ue() {
|
|
535
|
+
const e = typeof screen < "u" ? screen.orientation : void 0;
|
|
536
|
+
return e && typeof e.angle == "number" ? e.angle : 0;
|
|
537
|
+
}
|
|
538
|
+
function pe(e) {
|
|
539
|
+
return new Promise((t) => {
|
|
540
|
+
if (e.videoWidth > 0) {
|
|
541
|
+
t();
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
e.addEventListener("loadedmetadata", () => t(), { once: !0 });
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
async function me(e) {
|
|
548
|
+
try {
|
|
549
|
+
await e.play();
|
|
550
|
+
} catch {
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
async function fe(e, t = 15) {
|
|
554
|
+
const i = document.createElement("canvas");
|
|
555
|
+
if (typeof i.captureStream != "function") return null;
|
|
556
|
+
const o = i.getContext("2d");
|
|
557
|
+
if (!o) return null;
|
|
558
|
+
const n = document.createElement("video");
|
|
559
|
+
n.muted = !0, n.playsInline = !0, n.srcObject = e, await pe(n);
|
|
560
|
+
const s = le(
|
|
561
|
+
n.videoWidth,
|
|
562
|
+
n.videoHeight,
|
|
563
|
+
window.innerWidth,
|
|
564
|
+
window.innerHeight,
|
|
565
|
+
ue()
|
|
566
|
+
);
|
|
567
|
+
i.width = s.width, i.height = s.height, await me(n);
|
|
568
|
+
let a = 0;
|
|
569
|
+
const d = () => {
|
|
570
|
+
he(o, n, s), a = requestAnimationFrame(d);
|
|
571
|
+
};
|
|
572
|
+
d();
|
|
573
|
+
const l = i.captureStream(t);
|
|
574
|
+
return {
|
|
575
|
+
stream: l,
|
|
576
|
+
stop: () => {
|
|
577
|
+
a && cancelAnimationFrame(a), a = 0, l.getTracks().forEach((r) => r.stop()), n.pause(), n.srcObject = null;
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
function be() {
|
|
519
582
|
return typeof navigator < "u" && !!navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia == "function" && typeof MediaRecorder < "u";
|
|
520
583
|
}
|
|
521
|
-
function
|
|
584
|
+
function ge() {
|
|
522
585
|
if (typeof MediaRecorder > "u") return "";
|
|
523
586
|
const e = [
|
|
524
587
|
"video/webm;codecs=vp9",
|
|
@@ -531,19 +594,19 @@ function ie() {
|
|
|
531
594
|
return t;
|
|
532
595
|
return "";
|
|
533
596
|
}
|
|
534
|
-
function
|
|
597
|
+
function ve(e = {}) {
|
|
535
598
|
const t = e.maxDuration ?? 15, i = e.videoBitsPerSecond ?? 8e5;
|
|
536
|
-
let o = null, n = null, s =
|
|
537
|
-
function
|
|
538
|
-
|
|
599
|
+
let o = null, n = null, s = null, a = [], d = null, l = null, r = null, c = 0, p = null, u = null, m = !1, b = null;
|
|
600
|
+
function v() {
|
|
601
|
+
r !== null && (clearInterval(r), r = null), b !== null && (clearTimeout(b), b = null), n && (n.stop(), n = null), o && (o.getTracks().forEach((f) => f.stop()), o = null), s = null, a = [], d = null, l = null, p = null, u = null;
|
|
539
602
|
}
|
|
540
|
-
function
|
|
541
|
-
|
|
603
|
+
function y() {
|
|
604
|
+
m || (m = !0, s && s.state !== "inactive" && s.stop());
|
|
542
605
|
}
|
|
543
606
|
return {
|
|
544
607
|
async start() {
|
|
545
|
-
|
|
546
|
-
const f =
|
|
608
|
+
m = !1, a = [];
|
|
609
|
+
const f = ge();
|
|
547
610
|
if (!f)
|
|
548
611
|
throw new Error("No supported video MIME type found");
|
|
549
612
|
o = await navigator.mediaDevices.getDisplayMedia({
|
|
@@ -554,55 +617,61 @@ function oe(e = {}) {
|
|
|
554
617
|
// @ts-expect-error preferCurrentTab is not in the TS types yet
|
|
555
618
|
preferCurrentTab: !0
|
|
556
619
|
});
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
})
|
|
620
|
+
const h = o.getVideoTracks()[0];
|
|
621
|
+
h && h.addEventListener("ended", () => {
|
|
622
|
+
y();
|
|
623
|
+
});
|
|
624
|
+
let w = o;
|
|
625
|
+
if (ce()) {
|
|
626
|
+
const g = await fe(o);
|
|
627
|
+
g && (n = g, w = g.stream);
|
|
628
|
+
}
|
|
629
|
+
s = new MediaRecorder(w, {
|
|
561
630
|
mimeType: f,
|
|
562
631
|
videoBitsPerSecond: i
|
|
563
|
-
}),
|
|
564
|
-
|
|
565
|
-
},
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
},
|
|
569
|
-
|
|
570
|
-
},
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
}, 1e3),
|
|
574
|
-
|
|
632
|
+
}), s.ondataavailable = (g) => {
|
|
633
|
+
g.data.size > 0 && a.push(g.data);
|
|
634
|
+
}, s.onstop = () => {
|
|
635
|
+
const g = new Blob(a, { type: f });
|
|
636
|
+
p && p(g), l && l(g), n && (n.stop(), n = null), o && o.getTracks().forEach((C) => C.stop());
|
|
637
|
+
}, s.onerror = () => {
|
|
638
|
+
u && u(new Error("MediaRecorder error"));
|
|
639
|
+
}, s.start(1e3), c = Date.now(), r = setInterval(() => {
|
|
640
|
+
const g = Math.floor((Date.now() - c) / 1e3);
|
|
641
|
+
d && d(g);
|
|
642
|
+
}, 1e3), b = setTimeout(() => {
|
|
643
|
+
y();
|
|
575
644
|
}, t * 1e3);
|
|
576
645
|
},
|
|
577
646
|
stop() {
|
|
578
|
-
return new Promise((f,
|
|
579
|
-
|
|
647
|
+
return new Promise((f, h) => {
|
|
648
|
+
p = f, u = h, y();
|
|
580
649
|
});
|
|
581
650
|
},
|
|
582
651
|
onTick(f) {
|
|
583
|
-
|
|
652
|
+
d = f;
|
|
584
653
|
},
|
|
585
654
|
onStop(f) {
|
|
586
|
-
|
|
655
|
+
l = f;
|
|
587
656
|
},
|
|
588
657
|
destroy() {
|
|
589
|
-
|
|
658
|
+
y(), v();
|
|
590
659
|
}
|
|
591
660
|
};
|
|
592
661
|
}
|
|
593
|
-
function
|
|
662
|
+
function ye(e = 640) {
|
|
594
663
|
return typeof window < "u" && window.innerWidth < e;
|
|
595
664
|
}
|
|
596
|
-
function
|
|
665
|
+
function K(e, t, i) {
|
|
597
666
|
const o = i.map((s) => s.style.visibility);
|
|
598
667
|
i.forEach((s) => s.style.visibility = "hidden");
|
|
599
668
|
const n = document.elementFromPoint(e, t);
|
|
600
669
|
return i.forEach((s, a) => s.style.visibility = o[a]), n;
|
|
601
670
|
}
|
|
602
|
-
function
|
|
671
|
+
function M(e) {
|
|
603
672
|
return e ? e.hasAttribute("data-qaid-embed") || e.hasAttribute("data-qaid-embed-overlay") ? !0 : !!e.closest("[data-qaid-embed], [data-qaid-embed-overlay]") : !1;
|
|
604
673
|
}
|
|
605
|
-
function
|
|
674
|
+
function j(e, t = 0) {
|
|
606
675
|
const i = e.getBoundingClientRect();
|
|
607
676
|
return {
|
|
608
677
|
x: i.left - t,
|
|
@@ -611,7 +680,7 @@ function _(e, t = 0) {
|
|
|
611
680
|
height: i.height + t * 2
|
|
612
681
|
};
|
|
613
682
|
}
|
|
614
|
-
async function
|
|
683
|
+
async function we(e = {}) {
|
|
615
684
|
const { quality: t = 1, maxWidth: i = 1280, maxHeight: o = 800 } = e;
|
|
616
685
|
try {
|
|
617
686
|
if (!navigator.mediaDevices?.getDisplayMedia)
|
|
@@ -621,59 +690,59 @@ async function se(e = {}) {
|
|
|
621
690
|
video: {
|
|
622
691
|
displaySurface: "browser"
|
|
623
692
|
}
|
|
624
|
-
}), s = n.getVideoTracks()[0], a = s.getSettings(),
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
693
|
+
}), s = n.getVideoTracks()[0], a = s.getSettings(), d = document.createElement("video");
|
|
694
|
+
d.srcObject = n, d.muted = !0, await new Promise((v) => {
|
|
695
|
+
d.onloadedmetadata = () => {
|
|
696
|
+
d.play(), v();
|
|
628
697
|
};
|
|
629
|
-
}), await new Promise((
|
|
630
|
-
const
|
|
631
|
-
|
|
698
|
+
}), await new Promise((v) => {
|
|
699
|
+
const y = () => {
|
|
700
|
+
d.readyState >= 2 ? v() : requestAnimationFrame(y);
|
|
632
701
|
};
|
|
633
|
-
|
|
634
|
-
}), await new Promise((
|
|
635
|
-
const l = a.width ||
|
|
702
|
+
y();
|
|
703
|
+
}), await new Promise((v) => setTimeout(v, 100));
|
|
704
|
+
const l = a.width || d.videoWidth, r = a.height || d.videoHeight, c = Math.min(i / l, o / r, 1), p = Math.round(l * c), u = Math.round(r * c), m = document.createElement("canvas");
|
|
636
705
|
m.width = p, m.height = u;
|
|
637
|
-
const
|
|
638
|
-
return
|
|
706
|
+
const b = m.getContext("2d");
|
|
707
|
+
return b ? (b.drawImage(d, 0, 0, p, u), s.stop(), m.toDataURL("image/webp", t)) : (s.stop(), null);
|
|
639
708
|
} catch (n) {
|
|
640
709
|
return console.warn("Screenshot capture failed:", n), null;
|
|
641
710
|
}
|
|
642
711
|
}
|
|
643
|
-
const
|
|
644
|
-
let
|
|
645
|
-
function
|
|
712
|
+
const X = "https://qaid.dev/lib/html2canvas.min.js", xe = 1e4, qe = 50;
|
|
713
|
+
let x = null;
|
|
714
|
+
function Pe() {
|
|
646
715
|
if (typeof document > "u" || typeof window > "u")
|
|
647
716
|
return !1;
|
|
648
717
|
const e = document.createElement("canvas");
|
|
649
718
|
return typeof e.getContext == "function" && !!e.getContext("2d");
|
|
650
719
|
}
|
|
651
|
-
function
|
|
652
|
-
return window.html2canvas ? Promise.resolve(!0) :
|
|
720
|
+
function ke() {
|
|
721
|
+
return window.html2canvas ? Promise.resolve(!0) : x || (x = new Promise((e) => {
|
|
653
722
|
if (!document.querySelector(
|
|
654
|
-
`script[src="${
|
|
723
|
+
`script[src="${X}"]`
|
|
655
724
|
)) {
|
|
656
725
|
const n = document.createElement("script");
|
|
657
|
-
n.src =
|
|
726
|
+
n.src = X, n.async = !0, document.head.appendChild(n);
|
|
658
727
|
}
|
|
659
728
|
const i = Date.now(), o = () => {
|
|
660
729
|
if (window.html2canvas) {
|
|
661
730
|
e(!0);
|
|
662
731
|
return;
|
|
663
732
|
}
|
|
664
|
-
if (Date.now() - i >
|
|
665
|
-
|
|
733
|
+
if (Date.now() - i > xe) {
|
|
734
|
+
x = null, e(!1);
|
|
666
735
|
return;
|
|
667
736
|
}
|
|
668
|
-
setTimeout(o,
|
|
737
|
+
setTimeout(o, qe);
|
|
669
738
|
};
|
|
670
739
|
o();
|
|
671
|
-
}),
|
|
740
|
+
}), x);
|
|
672
741
|
}
|
|
673
|
-
async function
|
|
742
|
+
async function Ce(e = {}) {
|
|
674
743
|
const { quality: t = 0.8, maxWidth: i = 1280, maxHeight: o = 800 } = e;
|
|
675
744
|
try {
|
|
676
|
-
if (!await
|
|
745
|
+
if (!await ke() || !window.html2canvas)
|
|
677
746
|
return console.warn("html2canvas failed to load"), null;
|
|
678
747
|
const s = await window.html2canvas(document.body, {
|
|
679
748
|
useCORS: !0,
|
|
@@ -686,44 +755,73 @@ async function ce(e = {}) {
|
|
|
686
755
|
x: window.scrollX,
|
|
687
756
|
y: window.scrollY,
|
|
688
757
|
ignoreElements: (r) => r instanceof HTMLElement ? r.classList.contains("qaid-buttons") || r.classList.contains("qaid-targeting-overlay") || r.classList.contains("qaid-modal-container") || r.classList.contains("qaid-bottom-sheet") || r.classList.contains("qaid-backdrop") || r.classList.contains("qaid-selected-marker") || r.classList.contains("qaid-tooltip-text") || r.classList.contains("qaid-recording-indicator") || r.classList.contains("qaid-video-preview") || r.className?.toString().startsWith?.("qaid-") : !1
|
|
689
|
-
}), a = s.width,
|
|
758
|
+
}), a = s.width, d = s.height, l = Math.min(i / a, o / d, 1);
|
|
690
759
|
if (l < 1) {
|
|
691
|
-
const r = Math.round(a * l),
|
|
692
|
-
p.width = r, p.height =
|
|
760
|
+
const r = Math.round(a * l), c = Math.round(d * l), p = document.createElement("canvas");
|
|
761
|
+
p.width = r, p.height = c;
|
|
693
762
|
const u = p.getContext("2d");
|
|
694
|
-
return u ? (u.drawImage(s, 0, 0, r,
|
|
763
|
+
return u ? (u.drawImage(s, 0, 0, r, c), p.toDataURL("image/webp", t)) : null;
|
|
695
764
|
}
|
|
696
765
|
return s.toDataURL("image/webp", t);
|
|
697
766
|
} catch (n) {
|
|
698
767
|
return console.warn("DOM screenshot capture failed:", n), null;
|
|
699
768
|
}
|
|
700
769
|
}
|
|
701
|
-
const
|
|
702
|
-
|
|
703
|
-
|
|
770
|
+
const Se = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", Ee = (e) => (
|
|
771
|
+
// The URL is a runtime value, not a static specifier — keep Vite from
|
|
772
|
+
// trying to analyze/bundle it.
|
|
773
|
+
import(
|
|
774
|
+
/* @vite-ignore */
|
|
775
|
+
e
|
|
776
|
+
)
|
|
777
|
+
);
|
|
778
|
+
let Te = Ee, q = null, R = null;
|
|
779
|
+
function Le(e) {
|
|
780
|
+
return q && R === e || (R = e, q = Promise.resolve(Te(e)).then((t) => {
|
|
781
|
+
const i = t;
|
|
782
|
+
if (!i || typeof i.QaidQuests != "function")
|
|
783
|
+
throw new Error("quests module has no QaidQuests export");
|
|
784
|
+
return i;
|
|
785
|
+
}).catch((t) => {
|
|
786
|
+
throw q = null, R = null, t;
|
|
787
|
+
})), q;
|
|
788
|
+
}
|
|
789
|
+
async function Ie(e) {
|
|
790
|
+
const t = await Le(e.moduleUrl), i = e.base.replace(/\/+$/, ""), o = e.feedbackId != null ? { feedbackId: e.feedbackId } : void 0;
|
|
791
|
+
return new t.QaidQuests({
|
|
792
|
+
endpoint: `${i}/responses`,
|
|
793
|
+
configUrl: `${i}/${encodeURIComponent(e.questId)}/definition`,
|
|
794
|
+
apiKey: e.apiKey || void 0,
|
|
795
|
+
metadata: o,
|
|
796
|
+
onClose: e.onClose
|
|
797
|
+
});
|
|
704
798
|
}
|
|
705
|
-
|
|
799
|
+
const W = "qaid_visitor_id", Y = "qaid_hide_feedback", Ae = 12;
|
|
800
|
+
function H(e) {
|
|
801
|
+
return e ? `${Y}_${e}` : Y;
|
|
802
|
+
}
|
|
803
|
+
function De(e) {
|
|
706
804
|
try {
|
|
707
|
-
return localStorage.getItem(
|
|
805
|
+
return localStorage.getItem(H(e)) === "1";
|
|
708
806
|
} catch {
|
|
709
807
|
return !1;
|
|
710
808
|
}
|
|
711
809
|
}
|
|
712
|
-
function
|
|
810
|
+
function Q(e, t = !0) {
|
|
713
811
|
try {
|
|
714
|
-
t ? localStorage.setItem(
|
|
812
|
+
t ? localStorage.setItem(H(e), "1") : localStorage.removeItem(H(e));
|
|
715
813
|
} catch {
|
|
716
814
|
}
|
|
717
815
|
}
|
|
718
|
-
function
|
|
816
|
+
function Me() {
|
|
719
817
|
try {
|
|
720
|
-
let e = localStorage.getItem(
|
|
721
|
-
return e || (e = crypto.randomUUID(), localStorage.setItem(
|
|
818
|
+
let e = localStorage.getItem(W);
|
|
819
|
+
return e || (e = crypto.randomUUID(), localStorage.setItem(W, e)), e;
|
|
722
820
|
} catch {
|
|
723
821
|
return crypto.randomUUID();
|
|
724
822
|
}
|
|
725
823
|
}
|
|
726
|
-
class
|
|
824
|
+
class Re {
|
|
727
825
|
config;
|
|
728
826
|
state = "IDLE";
|
|
729
827
|
feedbackData = {
|
|
@@ -742,6 +840,8 @@ class ue {
|
|
|
742
840
|
visible: !1
|
|
743
841
|
};
|
|
744
842
|
feedbackId = null;
|
|
843
|
+
// A quest launched from a button (in place of the message box), if any.
|
|
844
|
+
activeQuest = null;
|
|
745
845
|
mousePos = { x: 0, y: 0 };
|
|
746
846
|
isMobile = !1;
|
|
747
847
|
visitorId;
|
|
@@ -792,6 +892,13 @@ class ue {
|
|
|
792
892
|
boundKeyDown;
|
|
793
893
|
boundMouseMove;
|
|
794
894
|
boundClick;
|
|
895
|
+
// Touch equivalents for targeting. iOS/iPadOS does not synthesise `click`
|
|
896
|
+
// (or `mousemove`) for taps on non-interactive page elements, so targeting
|
|
897
|
+
// must be driven by touch events there.
|
|
898
|
+
boundTouchStart;
|
|
899
|
+
boundTouchEnd;
|
|
900
|
+
// Where the current targeting touch began, to tell a tap from a scroll.
|
|
901
|
+
touchStartPos = null;
|
|
795
902
|
boundResize;
|
|
796
903
|
// Start with buttons slid off-screen (localStorage dismiss, no animation)
|
|
797
904
|
_startDismissed = !1;
|
|
@@ -852,11 +959,20 @@ class ue {
|
|
|
852
959
|
videoOptions: {
|
|
853
960
|
maxDuration: t.videoOptions?.maxDuration ?? 15
|
|
854
961
|
},
|
|
855
|
-
recordIcon: t.recordIcon ?? ""
|
|
856
|
-
|
|
962
|
+
recordIcon: t.recordIcon ?? "",
|
|
963
|
+
quests: {
|
|
964
|
+
base: t.quests?.base ?? "",
|
|
965
|
+
up: t.quests?.up ?? "",
|
|
966
|
+
down: t.quests?.down ?? "",
|
|
967
|
+
video: t.quests?.video ?? "",
|
|
968
|
+
// Quest service reuses the feedback API key unless overridden.
|
|
969
|
+
apiKey: t.quests?.apiKey ?? t.apiKey ?? "",
|
|
970
|
+
moduleUrl: t.quests?.moduleUrl ?? Se
|
|
971
|
+
}
|
|
972
|
+
}, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundMouseMove = this.handleMouseMove.bind(this), this.boundClick = this.handleClick.bind(this), this.boundTouchStart = this.handleTouchStart.bind(this), this.boundTouchEnd = this.handleTouchEnd.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = Me(), this.init();
|
|
857
973
|
}
|
|
858
974
|
applyVars(t) {
|
|
859
|
-
|
|
975
|
+
Et(t, this.cssVars);
|
|
860
976
|
}
|
|
861
977
|
/**
|
|
862
978
|
* Announce a message via the shared visually-hidden live regions.
|
|
@@ -866,7 +982,7 @@ class ue {
|
|
|
866
982
|
*/
|
|
867
983
|
announceMsg(t, i = !1) {
|
|
868
984
|
const o = this.overlayShadowRoot ?? this.shadowRoot;
|
|
869
|
-
o &&
|
|
985
|
+
o && Ut(o, t, { assertive: i });
|
|
870
986
|
}
|
|
871
987
|
/**
|
|
872
988
|
* Turn a transient surface into an accessible modal dialog: save the
|
|
@@ -874,16 +990,16 @@ class ue {
|
|
|
874
990
|
* background. Paired with closeDialogA11y() on every close path.
|
|
875
991
|
*/
|
|
876
992
|
openDialogA11y(t, i) {
|
|
877
|
-
this.dialogTrigger =
|
|
993
|
+
this.dialogTrigger = Xt(), Yt(t, i), this.dialogTrap = jt(t), this.dialogRestoreInert = Gt(t);
|
|
878
994
|
}
|
|
879
995
|
closeDialogA11y() {
|
|
880
|
-
this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null),
|
|
996
|
+
this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null), Wt(this.dialogTrigger), this.dialogTrigger = null;
|
|
881
997
|
}
|
|
882
998
|
clearActiveThumb() {
|
|
883
999
|
this.activeThumbBtn && (this.activeThumbBtn.setAttribute("aria-pressed", "false"), this.activeThumbBtn = null);
|
|
884
1000
|
}
|
|
885
1001
|
init() {
|
|
886
|
-
|
|
1002
|
+
Tt(), this.cssVars = St({
|
|
887
1003
|
positiveColor: this.config.colors.positive,
|
|
888
1004
|
negativeColor: this.config.colors.negative,
|
|
889
1005
|
markerColor: this.config.colors.marker,
|
|
@@ -892,7 +1008,7 @@ class ue {
|
|
|
892
1008
|
backdropOpacity: this.config.backdropOpacity,
|
|
893
1009
|
fontFamily: this.config.fontFamily,
|
|
894
1010
|
fontSize: this.config.fontSize
|
|
895
|
-
}), !this.config.hideDismiss &&
|
|
1011
|
+
}), !this.config.hideDismiss && De(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = se((t) => {
|
|
896
1012
|
this.feedbackData.consoleErrors = this.consoleCapture?.errors ?? [];
|
|
897
1013
|
}), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom();
|
|
898
1014
|
}
|
|
@@ -915,7 +1031,7 @@ class ue {
|
|
|
915
1031
|
}), this.domObserver.observe(document.body, { childList: !0 });
|
|
916
1032
|
}
|
|
917
1033
|
checkMobile() {
|
|
918
|
-
this.isMobile =
|
|
1034
|
+
this.isMobile = ye();
|
|
919
1035
|
}
|
|
920
1036
|
handleResize() {
|
|
921
1037
|
this.checkMobile();
|
|
@@ -925,7 +1041,7 @@ class ue {
|
|
|
925
1041
|
let t = null;
|
|
926
1042
|
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" });
|
|
927
1043
|
const i = document.createElement("style");
|
|
928
|
-
if (i.textContent =
|
|
1044
|
+
if (i.textContent = N(), this.shadowRoot.appendChild(i), this.config.css) {
|
|
929
1045
|
const r = document.createElement("style");
|
|
930
1046
|
r.textContent = this.config.css, this.shadowRoot.appendChild(r);
|
|
931
1047
|
}
|
|
@@ -934,8 +1050,8 @@ class ue {
|
|
|
934
1050
|
this.buttonsContainer = document.createElement("div"), this.buttonsContainer.className = `qaid-buttons qaid-${this.config.position} ${o}`.trim(), this.config.incognito && this.buttonsContainer.classList.add("qaid-incognito");
|
|
935
1051
|
else {
|
|
936
1052
|
this.buttonsContainer = document.createElement("div"), this.buttonsContainer.className = `qaid-buttons qaid-auto-container qaid-${this.config.position} ${o}${this.config.incognito ? " qaid-incognito" : ""}`.trim(), this.buttonsContainer.style.pointerEvents = "auto";
|
|
937
|
-
const { x: r, y:
|
|
938
|
-
this.config.position.includes("right") ? this.buttonsContainer.style.right = `${r}px` : this.buttonsContainer.style.left = `${r}px`, this.config.position.includes("bottom") ? this.buttonsContainer.style.bottom = `${
|
|
1053
|
+
const { x: r, y: c } = this.config.offset;
|
|
1054
|
+
this.config.position.includes("right") ? this.buttonsContainer.style.right = `${r}px` : this.buttonsContainer.style.left = `${r}px`, this.config.position.includes("bottom") ? this.buttonsContainer.style.bottom = `${c}px` : this.buttonsContainer.style.top = `${c}px`;
|
|
939
1055
|
}
|
|
940
1056
|
this.applyVars(this.buttonsContainer), this.shadowRoot.appendChild(this.buttonsContainer), this.buttonsContainer.addEventListener("keydown", (r) => {
|
|
941
1057
|
(r.key === "Enter" || r.key === " " || r.key === "Spacebar") && (this.keyboardActivation = !0);
|
|
@@ -944,22 +1060,22 @@ class ue {
|
|
|
944
1060
|
}), this.buttonsContainer.addEventListener("pointerdown", () => {
|
|
945
1061
|
this.keyboardActivation = !1;
|
|
946
1062
|
});
|
|
947
|
-
const n = !!this.config.buttonClass, s = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn",
|
|
948
|
-
if (l.className = "qaid-tooltip-text", l.textContent =
|
|
1063
|
+
const n = !!this.config.buttonClass, s = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn", d = this.config.text.tooltip || "Feedback for us?", l = document.createElement("div");
|
|
1064
|
+
if (l.className = "qaid-tooltip-text", l.textContent = d, this.applyVars(l), this.shadowRoot.appendChild(l), this.tooltipElement = l, !this.config.hideThumbs) {
|
|
949
1065
|
const r = document.createElement("div");
|
|
950
1066
|
r.className = "qaid-tooltip-wrapper";
|
|
951
|
-
const
|
|
952
|
-
|
|
1067
|
+
const c = document.createElement("button");
|
|
1068
|
+
c.type = "button", c.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", c.setAttribute("aria-label", this.config.text.positiveLabel), c.innerHTML = this.config.positiveIcon || I, c.addEventListener("click", (m) => this.handleThumbClick("up", m.currentTarget, m)), c.addEventListener("mouseenter", () => this.showTooltip(c)), c.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(c);
|
|
953
1069
|
const p = document.createElement("div");
|
|
954
1070
|
p.className = "qaid-tooltip-wrapper";
|
|
955
1071
|
const u = document.createElement("button");
|
|
956
|
-
u.type = "button", u.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", u.setAttribute("aria-label", this.config.text.negativeLabel), u.innerHTML = this.config.negativeIcon ||
|
|
1072
|
+
u.type = "button", u.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", u.setAttribute("aria-label", this.config.text.negativeLabel), u.innerHTML = this.config.negativeIcon || A, u.addEventListener("click", (m) => this.handleThumbClick("down", m.currentTarget, m)), u.addEventListener("mouseenter", () => this.showTooltip(u)), u.addEventListener("mouseleave", () => this.hideTooltip()), p.appendChild(u), this.buttonsContainer.appendChild(r), this.buttonsContainer.appendChild(p);
|
|
957
1073
|
}
|
|
958
|
-
if (this.config.captureVideo &&
|
|
1074
|
+
if (this.config.captureVideo && be()) {
|
|
959
1075
|
const r = document.createElement("div");
|
|
960
1076
|
r.className = "qaid-tooltip-wrapper";
|
|
961
|
-
const
|
|
962
|
-
|
|
1077
|
+
const c = document.createElement("button");
|
|
1078
|
+
c.type = "button", c.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", c.setAttribute("aria-label", this.config.text.recordLabel), c.innerHTML = this.config.recordIcon || bt, c.addEventListener("click", () => this.startRecording()), c.addEventListener("mouseenter", () => this.showTooltip(c)), c.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(c), this.buttonsContainer.appendChild(r);
|
|
963
1079
|
}
|
|
964
1080
|
this.config.hideDismiss || (this.dismissBtn = document.createElement("button"), this.dismissBtn.type = "button", this.dismissBtn.className = "qaid-dismiss-btn", this.dismissBtn.setAttribute("aria-label", this.config.text.dismissLabel), this.dismissBtn.title = this.config.text.dismissLabel, this.dismissBtn.innerHTML = '<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 2l8 8M10 2l-8 8" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>', this.dismissBtn.addEventListener("click", (r) => {
|
|
965
1081
|
r.stopPropagation(), this.handleDismiss();
|
|
@@ -975,7 +1091,7 @@ class ue {
|
|
|
975
1091
|
if (this.overlayShadowRoot) return this.overlayShadowRoot;
|
|
976
1092
|
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" });
|
|
977
1093
|
const t = document.createElement("style");
|
|
978
|
-
if (t.textContent =
|
|
1094
|
+
if (t.textContent = N(), this.overlayShadowRoot.appendChild(t), this.config.css) {
|
|
979
1095
|
const i = document.createElement("style");
|
|
980
1096
|
i.textContent = this.config.css, this.overlayShadowRoot.appendChild(i);
|
|
981
1097
|
}
|
|
@@ -985,7 +1101,7 @@ class ue {
|
|
|
985
1101
|
showTooltip(t) {
|
|
986
1102
|
const i = this.tooltipElement;
|
|
987
1103
|
i.style.visibility = "hidden", i.classList.add("qaid-tooltip-visible");
|
|
988
|
-
const o = t.getBoundingClientRect(), n = i.getBoundingClientRect(), { top: s, left: a } =
|
|
1104
|
+
const o = t.getBoundingClientRect(), n = i.getBoundingClientRect(), { top: s, left: a } = ie(
|
|
989
1105
|
o,
|
|
990
1106
|
n,
|
|
991
1107
|
{ width: window.innerWidth, height: window.innerHeight }
|
|
@@ -996,10 +1112,10 @@ class ue {
|
|
|
996
1112
|
this.tooltipElement.classList.remove("qaid-tooltip-visible");
|
|
997
1113
|
}
|
|
998
1114
|
handleDismiss() {
|
|
999
|
-
this.buttonsContainer.classList.add("qaid-dismissed"),
|
|
1115
|
+
this.buttonsContainer.classList.add("qaid-dismissed"), Q(this.config.apiKey, !0);
|
|
1000
1116
|
}
|
|
1001
1117
|
handleThumbClick(t, i, o) {
|
|
1002
|
-
if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"),
|
|
1118
|
+
if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"), Q(this.config.apiKey, !1)), this.config.skipTargeting)
|
|
1003
1119
|
this.submitDirectFeedback(t, i);
|
|
1004
1120
|
else {
|
|
1005
1121
|
this.activeThumbBtn = i, i.setAttribute("aria-pressed", "true");
|
|
@@ -1021,7 +1137,7 @@ class ue {
|
|
|
1021
1137
|
}, this.submitFeedback();
|
|
1022
1138
|
}
|
|
1023
1139
|
startTargeting(t, i) {
|
|
1024
|
-
this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, this.mousePos.x = i.clientX, this.mousePos.y = i.clientY, document.body.classList.add("qaid-targeting"), t === "up" ? document.body.classList.add("qaid-type-up") : document.body.classList.remove("qaid-type-up"), document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.cssVars["--qaid-negative"]), this.createTargetingOverlay(), document.addEventListener("keydown", this.boundKeyDown), document.addEventListener("mousemove", this.boundMouseMove), document.addEventListener("click", this.boundClick, !0);
|
|
1140
|
+
this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, this.mousePos.x = i.clientX, this.mousePos.y = i.clientY, document.body.classList.add("qaid-targeting"), t === "up" ? document.body.classList.add("qaid-type-up") : document.body.classList.remove("qaid-type-up"), document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.cssVars["--qaid-negative"]), this.createTargetingOverlay(), document.addEventListener("keydown", this.boundKeyDown), document.addEventListener("mousemove", this.boundMouseMove), document.addEventListener("click", this.boundClick, !0), document.addEventListener("touchstart", this.boundTouchStart, { passive: !0 }), document.addEventListener("touchend", this.boundTouchEnd, { passive: !1 });
|
|
1025
1141
|
}
|
|
1026
1142
|
/**
|
|
1027
1143
|
* Keyboard-driven targeting. Mirrors startTargeting minus the mouse
|
|
@@ -1030,12 +1146,12 @@ class ue {
|
|
|
1030
1146
|
* The KeyboardTargetingController owns Tab/Arrow/Enter/Space/Escape.
|
|
1031
1147
|
*/
|
|
1032
1148
|
startKeyboardTargetingFlow(t) {
|
|
1033
|
-
this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.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 =
|
|
1034
|
-
isExcluded: (i) =>
|
|
1149
|
+
this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.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 = Ot({
|
|
1150
|
+
isExcluded: (i) => M(i),
|
|
1035
1151
|
onHighlight: (i) => {
|
|
1036
1152
|
const o = i.getBoundingClientRect(), n = this.highlightBox;
|
|
1037
1153
|
n && (n.style.transform = `translate(${o.left}px, ${o.top}px)`, n.style.width = `${o.width}px`, n.style.height = `${o.height}px`, n.style.display = "block");
|
|
1038
|
-
const { text: s } =
|
|
1154
|
+
const { text: s } = D(i);
|
|
1039
1155
|
this.announceMsg(`Targeting ${s || i.tagName.toLowerCase()}`);
|
|
1040
1156
|
},
|
|
1041
1157
|
onSelect: (i) => this.selectKeyboardTarget(i),
|
|
@@ -1043,14 +1159,14 @@ class ue {
|
|
|
1043
1159
|
});
|
|
1044
1160
|
}
|
|
1045
1161
|
selectKeyboardTarget(t) {
|
|
1046
|
-
const i =
|
|
1162
|
+
const i = j(t, 8);
|
|
1047
1163
|
this.selectedBounds = {
|
|
1048
1164
|
...i,
|
|
1049
1165
|
clickX: i.x + i.width / 2,
|
|
1050
1166
|
clickY: i.y + i.height / 2,
|
|
1051
1167
|
visible: !0
|
|
1052
1168
|
};
|
|
1053
|
-
const { selector: o, text: n } =
|
|
1169
|
+
const { selector: o, text: n } = D(t);
|
|
1054
1170
|
this.feedbackData.elementSelector = o, this.feedbackData.elementText = n, this.removeTargetingOverlay(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.keyboardController = null, this.clearActiveThumb(), this.state = "SELECTED", this.showSelectedMarker(), this.submitFeedback();
|
|
1055
1171
|
}
|
|
1056
1172
|
createTargetingOverlay() {
|
|
@@ -1067,42 +1183,61 @@ class ue {
|
|
|
1067
1183
|
t.key === "Escape" && (this.isRecording ? this.stopRecording() : this.videoPreview ? this.cancelRecordingPreview() : this.state === "TARGETING" ? this.cancelTargeting() : this.state === "MODAL_OPEN" && this.closeModal());
|
|
1068
1184
|
}
|
|
1069
1185
|
handleMouseMove(t) {
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1186
|
+
this.updateReticleAt(t.clientX, t.clientY);
|
|
1187
|
+
}
|
|
1188
|
+
/** Move the crosshair/scope reticle and highlight the element under (x, y).
|
|
1189
|
+
* Shared by the mouse (hover) and touch (drag) targeting paths. */
|
|
1190
|
+
updateReticleAt(t, i) {
|
|
1191
|
+
if (this.mousePos.x = t, this.mousePos.y = i, this.crosshairH && (this.crosshairH.style.top = `${i}px`), this.crosshairV && (this.crosshairV.style.left = `${t}px`), this.scope && (this.scope.style.left = `${t}px`, this.scope.style.top = `${i}px`), this.captureLayer && this.shadowHost) {
|
|
1192
|
+
const o = [this.shadowHost, this.overlayShadowHost].filter(Boolean), n = K(t, i, o);
|
|
1193
|
+
if (n && !M(n)) {
|
|
1077
1194
|
if (this.highlightBox) {
|
|
1078
|
-
const
|
|
1079
|
-
this.highlightBox.style.transform = `translate(${
|
|
1195
|
+
const s = n.getBoundingClientRect();
|
|
1196
|
+
this.highlightBox.style.transform = `translate(${s.left}px, ${s.top}px)`, this.highlightBox.style.width = `${s.width}px`, this.highlightBox.style.height = `${s.height}px`, this.highlightBox.style.display = "block";
|
|
1080
1197
|
}
|
|
1081
1198
|
} else
|
|
1082
1199
|
this.highlightBox && (this.highlightBox.style.display = "none");
|
|
1083
1200
|
}
|
|
1084
1201
|
}
|
|
1085
1202
|
handleClick(t) {
|
|
1086
|
-
t.preventDefault(), t.stopPropagation();
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1203
|
+
t.preventDefault(), t.stopPropagation(), this.selectAt(t.clientX, t.clientY);
|
|
1204
|
+
}
|
|
1205
|
+
// ---- Touch targeting (iOS/iPadOS) ----
|
|
1206
|
+
// iOS/iPadOS taps on non-interactive elements don't fire click, so touch
|
|
1207
|
+
// drives targeting here. Scrolling stays enabled (the page may need to scroll
|
|
1208
|
+
// to bring the target into view); a low-movement touch is treated as a tap
|
|
1209
|
+
// that selects, distinguishing it from a scroll/drag.
|
|
1210
|
+
handleTouchStart(t) {
|
|
1211
|
+
const i = t.touches[0];
|
|
1212
|
+
i && (this.touchStartPos = { x: i.clientX, y: i.clientY }, this.updateReticleAt(i.clientX, i.clientY));
|
|
1213
|
+
}
|
|
1214
|
+
handleTouchEnd(t) {
|
|
1215
|
+
const i = t.changedTouches[0], o = this.touchStartPos;
|
|
1216
|
+
this.touchStartPos = null, !(!i || !o || Math.hypot(i.clientX - o.x, i.clientY - o.y) > Ae) && (t.preventDefault(), this.selectAt(i.clientX, i.clientY));
|
|
1217
|
+
}
|
|
1218
|
+
/** Select the element under (x, y) and tear down targeting.
|
|
1219
|
+
* Shared by the mouse (click) and touch (touchend) targeting paths. */
|
|
1220
|
+
selectAt(t, i) {
|
|
1221
|
+
const o = [this.shadowHost, this.overlayShadowHost].filter(Boolean), n = K(t, i, o);
|
|
1222
|
+
if (!n || M(n))
|
|
1093
1223
|
return;
|
|
1094
|
-
const
|
|
1224
|
+
const s = j(n, 8);
|
|
1095
1225
|
this.selectedBounds = {
|
|
1096
|
-
...
|
|
1097
|
-
clickX: t
|
|
1098
|
-
clickY:
|
|
1226
|
+
...s,
|
|
1227
|
+
clickX: t,
|
|
1228
|
+
clickY: i,
|
|
1099
1229
|
visible: !0
|
|
1100
1230
|
};
|
|
1101
|
-
const { selector:
|
|
1102
|
-
this.feedbackData.elementSelector =
|
|
1231
|
+
const { selector: a, text: d } = D(n);
|
|
1232
|
+
this.feedbackData.elementSelector = a, this.feedbackData.elementText = d, this.stopTargetingListeners(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.state = "SELECTED", this.clearActiveThumb(), this.showSelectedMarker(), this.submitFeedback();
|
|
1233
|
+
}
|
|
1234
|
+
/** Remove the targeting overlay and every mouse/touch/keyboard listener the
|
|
1235
|
+
* pointer-targeting flow attaches to the document. */
|
|
1236
|
+
stopTargetingListeners() {
|
|
1237
|
+
this.removeTargetingOverlay(), this.touchStartPos = null, document.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), document.removeEventListener("touchstart", this.boundTouchStart), document.removeEventListener("touchend", this.boundTouchEnd), document.removeEventListener("keydown", this.boundKeyDown);
|
|
1103
1238
|
}
|
|
1104
1239
|
cancelTargeting() {
|
|
1105
|
-
this.keyboardController?.stop(), this.keyboardController = null, this.
|
|
1240
|
+
this.keyboardController?.stop(), this.keyboardController = null, this.stopTargetingListeners(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.clearActiveThumb(), this.state = "IDLE", this.feedbackData.feedbackType = null, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1;
|
|
1106
1241
|
}
|
|
1107
1242
|
removeTargetingOverlay() {
|
|
1108
1243
|
this.overlayContainer && (this.overlayContainer.remove(), this.overlayContainer = null), this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null;
|
|
@@ -1116,7 +1251,7 @@ class ue {
|
|
|
1116
1251
|
}
|
|
1117
1252
|
async submitFeedback() {
|
|
1118
1253
|
let t = null;
|
|
1119
|
-
this.config.captureScreenshot && (this.config.screenshotMethod === "dom" ? t = await
|
|
1254
|
+
this.config.captureScreenshot && (this.config.screenshotMethod === "dom" ? t = await Ce(this.config.screenshotOptions) : t = await we(this.config.screenshotOptions), t && this.announceMsg("Screenshot captured"));
|
|
1120
1255
|
const i = this.feedbackData.elementSelector ? {
|
|
1121
1256
|
x: this.selectedBounds.x,
|
|
1122
1257
|
y: this.selectedBounds.y,
|
|
@@ -1142,20 +1277,66 @@ class ue {
|
|
|
1142
1277
|
userAgent: navigator.userAgent
|
|
1143
1278
|
};
|
|
1144
1279
|
try {
|
|
1145
|
-
const
|
|
1280
|
+
const s = await fetch(this.config.endpoint, {
|
|
1146
1281
|
method: "POST",
|
|
1147
1282
|
headers: { "Content-Type": "application/json" },
|
|
1148
1283
|
body: JSON.stringify(o)
|
|
1149
1284
|
});
|
|
1150
|
-
if (
|
|
1151
|
-
const
|
|
1152
|
-
this.feedbackId =
|
|
1285
|
+
if (s.ok) {
|
|
1286
|
+
const a = await s.json();
|
|
1287
|
+
this.feedbackId = a.id, this.announceMsg("Feedback sent");
|
|
1153
1288
|
}
|
|
1154
|
-
} catch (
|
|
1155
|
-
console.error("Failed to submit feedback:",
|
|
1289
|
+
} catch (s) {
|
|
1290
|
+
console.error("Failed to submit feedback:", s), this.announceMsg("Failed to send feedback", !0);
|
|
1291
|
+
}
|
|
1292
|
+
const n = this.feedbackData.feedbackType;
|
|
1293
|
+
if (n && await this.tryLaunchQuest(n, this.feedbackId)) {
|
|
1294
|
+
this.resetFeedbackUi();
|
|
1295
|
+
return;
|
|
1156
1296
|
}
|
|
1157
1297
|
this.state = "MODAL_OPEN", this.showModal(), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "auto");
|
|
1158
1298
|
}
|
|
1299
|
+
/**
|
|
1300
|
+
* Quest id linked to `type`, or "" when quest launching is disabled
|
|
1301
|
+
* (no `base`) or this button has no quest configured.
|
|
1302
|
+
*/
|
|
1303
|
+
questIdFor(t) {
|
|
1304
|
+
const i = this.config.quests;
|
|
1305
|
+
return i.base && i[t] || "";
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Launch the quest linked to `type`, if any. Resolves `true` when a quest
|
|
1309
|
+
* was configured and the widget launched; `false` when no quest is
|
|
1310
|
+
* configured or the widget failed to load (caller falls back to its
|
|
1311
|
+
* normal UI). The created feedback record id is passed through so the
|
|
1312
|
+
* quest response can be joined back to it server-side.
|
|
1313
|
+
*/
|
|
1314
|
+
async tryLaunchQuest(t, i) {
|
|
1315
|
+
const o = this.questIdFor(t);
|
|
1316
|
+
if (!o) return !1;
|
|
1317
|
+
try {
|
|
1318
|
+
return this.activeQuest?.destroy(), this.activeQuest = await Ie({
|
|
1319
|
+
questId: o,
|
|
1320
|
+
base: this.config.quests.base,
|
|
1321
|
+
apiKey: this.config.quests.apiKey || void 0,
|
|
1322
|
+
moduleUrl: this.config.quests.moduleUrl,
|
|
1323
|
+
feedbackId: i,
|
|
1324
|
+
onClose: () => {
|
|
1325
|
+
this.activeQuest = null;
|
|
1326
|
+
}
|
|
1327
|
+
}), !0;
|
|
1328
|
+
} catch (n) {
|
|
1329
|
+
return console.error("Failed to launch quest:", n), this.activeQuest = null, !1;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
/**
|
|
1333
|
+
* Reset the thumbs targeting/marker UI back to idle without opening or
|
|
1334
|
+
* closing the message modal. Shared by closeModal() and the quest-launch
|
|
1335
|
+
* path (which bypasses the modal entirely).
|
|
1336
|
+
*/
|
|
1337
|
+
resetFeedbackUi() {
|
|
1338
|
+
this.hideSelectedMarker(), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "none"), this.state = "IDLE", this.feedbackId = null, this.feedbackData.feedbackType = null, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1;
|
|
1339
|
+
}
|
|
1159
1340
|
showModal() {
|
|
1160
1341
|
const t = this.ensureOverlayHost();
|
|
1161
1342
|
this.backdrop = document.createElement("div"), this.backdrop.className = "qaid-backdrop", this.backdrop.style.zIndex = String(this.config.zIndex + 2), this.backdrop.style.background = `rgba(0, 0, 0, ${this.config.backdropOpacity})`, this.backdrop.addEventListener("click", () => this.closeModal()), this.applyVars(this.backdrop), this.isMobile ? this.showBottomSheet() : this.showPositionedModal(), t.appendChild(this.backdrop), document.addEventListener("keydown", this.boundKeyDown);
|
|
@@ -1170,7 +1351,7 @@ class ue {
|
|
|
1170
1351
|
`, this.applyVars(i), t.appendChild(i), this.modalContainer = i, this.setupModalInteractions();
|
|
1171
1352
|
}
|
|
1172
1353
|
showPositionedModal() {
|
|
1173
|
-
const t = this.ensureOverlayHost(), { modal: i, arrow: o } =
|
|
1354
|
+
const t = this.ensureOverlayHost(), { modal: i, arrow: o } = oe(
|
|
1174
1355
|
this.selectedBounds,
|
|
1175
1356
|
window.innerWidth,
|
|
1176
1357
|
window.innerHeight,
|
|
@@ -1189,7 +1370,7 @@ class ue {
|
|
|
1189
1370
|
s.className = "qaid-modal-box", s.innerHTML = this.getModalContent(), this.modalContainer.appendChild(n), this.modalContainer.appendChild(s), this.applyVars(this.modalContainer), t.appendChild(this.modalContainer), this.setupModalInteractions();
|
|
1190
1371
|
}
|
|
1191
1372
|
getModalContent() {
|
|
1192
|
-
const t = this.feedbackData.feedbackType === "up", i = this.config.positiveIcon ||
|
|
1373
|
+
const t = this.feedbackData.feedbackType === "up", i = this.config.positiveIcon || I, o = this.config.negativeIcon || A;
|
|
1193
1374
|
return `
|
|
1194
1375
|
<div class="qaid-modal-header">
|
|
1195
1376
|
<button type="button" class="${this.config.buttonClass ? `qaid-type-toggle qaid-type-toggle-custom ${this.config.buttonClass} ${t ? "qaid-btn-up" : "qaid-btn-down"}` : `qaid-type-toggle ${t ? "qaid-type-up" : "qaid-type-down"}`}" title="Click to switch" aria-pressed="${t}" aria-label="${t ? "Feedback type: positive" : "Feedback type: negative"}">
|
|
@@ -1222,10 +1403,10 @@ class ue {
|
|
|
1222
1403
|
o && o.addEventListener("click", () => {
|
|
1223
1404
|
const n = this.feedbackData.feedbackType === "up" ? "down" : "up";
|
|
1224
1405
|
this.feedbackData.feedbackType = n, this.config.buttonClass ? (o.classList.toggle("qaid-btn-up", n === "up"), o.classList.toggle("qaid-btn-down", n === "down")) : (o.classList.toggle("qaid-type-up", n === "up"), o.classList.toggle("qaid-type-down", n === "down"));
|
|
1225
|
-
const s = this.config.positiveIcon ||
|
|
1406
|
+
const s = this.config.positiveIcon || I, a = this.config.negativeIcon || A;
|
|
1226
1407
|
o.innerHTML = n === "up" ? s : a;
|
|
1227
|
-
const
|
|
1228
|
-
o.setAttribute("aria-pressed", String(n === "up")), o.setAttribute("aria-label",
|
|
1408
|
+
const d = n === "up" ? "Feedback type: positive" : "Feedback type: negative";
|
|
1409
|
+
o.setAttribute("aria-pressed", String(n === "up")), o.setAttribute("aria-label", d), this.announceMsg(d), this.feedbackId && fetch(`${this.config.endpoint}/${this.feedbackId}`, {
|
|
1229
1410
|
method: "PATCH",
|
|
1230
1411
|
headers: { "Content-Type": "application/json" },
|
|
1231
1412
|
body: JSON.stringify({ feedbackType: n })
|
|
@@ -1252,13 +1433,13 @@ class ue {
|
|
|
1252
1433
|
method: "PATCH",
|
|
1253
1434
|
headers: { "Content-Type": "application/json" },
|
|
1254
1435
|
body: JSON.stringify({ message: null })
|
|
1255
|
-
}).catch((t) => console.error("Failed to finalize feedback:", t)), this.closeDialogA11y(), this.modalContainer && (this.modalContainer.remove(), this.modalContainer = null), this.backdrop && (this.backdrop.remove(), this.backdrop = null), document.removeEventListener("keydown", this.boundKeyDown), this.
|
|
1436
|
+
}).catch((t) => console.error("Failed to finalize feedback:", t)), this.closeDialogA11y(), this.modalContainer && (this.modalContainer.remove(), this.modalContainer = null), this.backdrop && (this.backdrop.remove(), this.backdrop = null), document.removeEventListener("keydown", this.boundKeyDown), this.resetFeedbackUi();
|
|
1256
1437
|
}
|
|
1257
1438
|
// ==================== Video Recording ====================
|
|
1258
1439
|
async startRecording() {
|
|
1259
1440
|
if (!(this.isRecording || this.state !== "IDLE"))
|
|
1260
1441
|
try {
|
|
1261
|
-
this.networkCapture =
|
|
1442
|
+
this.networkCapture = de(), this.videoRecorder = ve({
|
|
1262
1443
|
maxDuration: this.config.videoOptions.maxDuration
|
|
1263
1444
|
}), this.videoRecorder.onTick((t) => {
|
|
1264
1445
|
this.updateRecordingTimer(t);
|
|
@@ -1313,19 +1494,19 @@ class ue {
|
|
|
1313
1494
|
s.src = i, s.controls = !0, s.autoplay = !0, s.muted = !0;
|
|
1314
1495
|
const a = document.createElement("textarea");
|
|
1315
1496
|
a.placeholder = "Optional: Describe the issue you recorded...", a.setAttribute("aria-label", "Describe the issue you recorded");
|
|
1316
|
-
const
|
|
1317
|
-
|
|
1497
|
+
const d = document.createElement("div");
|
|
1498
|
+
d.className = "qaid-video-preview-actions";
|
|
1318
1499
|
const l = document.createElement("button");
|
|
1319
1500
|
l.type = "button", l.className = "qaid-video-btn qaid-video-btn-cancel", l.textContent = "Cancel", l.addEventListener("click", () => this.cancelRecordingPreview());
|
|
1320
1501
|
const r = document.createElement("button");
|
|
1321
1502
|
r.type = "button", r.className = "qaid-video-btn qaid-video-btn-rerecord", r.textContent = "Re-record", r.addEventListener("click", () => {
|
|
1322
1503
|
this.cancelRecordingPreview(), this.startRecording();
|
|
1323
1504
|
});
|
|
1324
|
-
const
|
|
1325
|
-
|
|
1505
|
+
const c = document.createElement("button");
|
|
1506
|
+
c.type = "button", c.className = "qaid-video-btn qaid-video-btn-send", c.textContent = "Send", c.addEventListener("click", () => {
|
|
1326
1507
|
const p = a.value.trim() || null;
|
|
1327
|
-
this.submitVideoFeedback(p,
|
|
1328
|
-
}),
|
|
1508
|
+
this.submitVideoFeedback(p, c);
|
|
1509
|
+
}), d.appendChild(l), d.appendChild(r), d.appendChild(c), o.appendChild(n), o.appendChild(s), o.appendChild(a), o.appendChild(d), this.videoPreview.appendChild(o), this.applyVars(this.videoPreview), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "auto"), t.appendChild(this.videoPreview), this.openDialogA11y(o, { labelledbyId: n.id }), document.addEventListener("keydown", this.boundKeyDown);
|
|
1329
1510
|
}
|
|
1330
1511
|
cancelRecordingPreview() {
|
|
1331
1512
|
this.removeVideoPreview(), this.cleanupRecording();
|
|
@@ -1342,16 +1523,24 @@ class ue {
|
|
|
1342
1523
|
this.isSendingVideo = !0, i.disabled = !0, i.textContent = "Sending...";
|
|
1343
1524
|
const o = new FormData();
|
|
1344
1525
|
o.append("video", this.recordedBlob, `recording.${this.recordedBlob.type.includes("mp4") ? "mp4" : "webm"}`), o.append("pageUrl", window.location.href), o.append("visitorId", this.visitorId), this.config.apiKey && o.append("apiKey", this.config.apiKey), t && o.append("message", t), this.consoleCapture && o.append("consoleErrors", JSON.stringify(this.consoleCapture.errors)), this.networkCapture && o.append("networkErrors", JSON.stringify(this.networkCapture.errors));
|
|
1526
|
+
let n = null;
|
|
1345
1527
|
try {
|
|
1346
|
-
const
|
|
1528
|
+
const s = await fetch(`${this.config.endpoint}/video`, {
|
|
1347
1529
|
method: "POST",
|
|
1348
1530
|
body: o
|
|
1349
1531
|
});
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1532
|
+
if (s.ok) {
|
|
1533
|
+
this.announceMsg("Recording sent");
|
|
1534
|
+
try {
|
|
1535
|
+
n = (await s.json())?.id ?? null;
|
|
1536
|
+
} catch {
|
|
1537
|
+
}
|
|
1538
|
+
} else
|
|
1539
|
+
console.error("Failed to submit video feedback:", await s.text()), this.announceMsg("Failed to send recording", !0);
|
|
1540
|
+
} catch (s) {
|
|
1541
|
+
console.error("Failed to submit video feedback:", s), this.announceMsg("Failed to send recording", !0);
|
|
1353
1542
|
}
|
|
1354
|
-
this.isSendingVideo = !1, this.removeVideoPreview(), this.cleanupRecording();
|
|
1543
|
+
this.isSendingVideo = !1, this.removeVideoPreview(), this.cleanupRecording(), await this.tryLaunchQuest("video", n);
|
|
1355
1544
|
}
|
|
1356
1545
|
cleanupRecording() {
|
|
1357
1546
|
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.setButtonsDisabled(!1), this.overlayShadowHost && this.state === "IDLE" && (this.overlayShadowHost.style.pointerEvents = "none");
|
|
@@ -1366,13 +1555,13 @@ class ue {
|
|
|
1366
1555
|
* Destroy the embed and clean up all resources
|
|
1367
1556
|
*/
|
|
1368
1557
|
destroy() {
|
|
1369
|
-
this.destroyed = !0, this.domObserver && (this.domObserver.disconnect(), this.domObserver = null), this.boundBeforeSwap && (document.removeEventListener("astro:before-swap", this.boundBeforeSwap), this.boundBeforeSwap = null), this.keyboardController?.stop(), this.keyboardController = null, this.clearActiveThumb(), this.closeDialogA11y(), this.cleanupRecording(), this.removeVideoPreview(), this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), 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.overlayContainer = null, this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null, this.marker = null, this.modalContainer = null, this.backdrop = null, this.dismissBtn = null, this.tooltipElement = null,
|
|
1558
|
+
this.destroyed = !0, this.domObserver && (this.domObserver.disconnect(), this.domObserver = null), this.boundBeforeSwap && (document.removeEventListener("astro:before-swap", this.boundBeforeSwap), this.boundBeforeSwap = null), this.keyboardController?.stop(), this.keyboardController = null, this.clearActiveThumb(), this.closeDialogA11y(), this.cleanupRecording(), this.removeVideoPreview(), 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.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), document.removeEventListener("touchstart", this.boundTouchStart), document.removeEventListener("touchend", this.boundTouchEnd), 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.overlayContainer = null, this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null, this.marker = null, this.modalContainer = null, this.backdrop = null, this.dismissBtn = null, this.tooltipElement = null, Lt();
|
|
1370
1559
|
}
|
|
1371
1560
|
}
|
|
1372
|
-
function
|
|
1561
|
+
function et(e) {
|
|
1373
1562
|
return document.querySelector(e)?.textContent?.trim() ?? "";
|
|
1374
1563
|
}
|
|
1375
|
-
function
|
|
1564
|
+
function He() {
|
|
1376
1565
|
const e = document.querySelector(
|
|
1377
1566
|
'script[type="application/json"][data-feedback-config]'
|
|
1378
1567
|
);
|
|
@@ -1381,79 +1570,87 @@ function pe() {
|
|
|
1381
1570
|
if (!t) return null;
|
|
1382
1571
|
try {
|
|
1383
1572
|
const i = JSON.parse(t);
|
|
1384
|
-
return i.cssSelector && !i.css && (i.css =
|
|
1573
|
+
return i.cssSelector && !i.css && (i.css = et(i.cssSelector), delete i.cssSelector), i;
|
|
1385
1574
|
} catch {
|
|
1386
1575
|
return null;
|
|
1387
1576
|
}
|
|
1388
1577
|
}
|
|
1389
|
-
function
|
|
1578
|
+
function Be(e) {
|
|
1390
1579
|
const t = e.getAttribute("data-endpoint");
|
|
1391
1580
|
if (!t) return null;
|
|
1392
|
-
const i = e.getAttribute("data-position"), o = e.getAttribute("data-zindex"), n = e.getAttribute("data-positive-color"), s = e.getAttribute("data-negative-color"), a = e.getAttribute("data-marker-color"),
|
|
1581
|
+
const i = e.getAttribute("data-position"), o = e.getAttribute("data-zindex"), n = e.getAttribute("data-positive-color"), s = e.getAttribute("data-negative-color"), a = e.getAttribute("data-marker-color"), d = e.getAttribute("data-container"), l = e.getAttribute("data-button-class"), r = e.getAttribute("data-skip-targeting"), c = e.getAttribute("data-incognito"), p = e.getAttribute("data-button-size"), u = e.getAttribute("data-offset-x"), m = e.getAttribute("data-offset-y"), b = e.getAttribute("data-modal-width"), v = e.getAttribute("data-backdrop-opacity"), y = e.getAttribute("data-font-family"), f = e.getAttribute("data-font-size"), h = e.getAttribute("data-tooltip"), w = e.getAttribute("data-modal-title"), g = e.getAttribute("data-modal-subtitle"), C = e.getAttribute("data-placeholder"), B = e.getAttribute("data-submit-button"), P = e.getAttribute("data-skip-button"), it = e.getAttribute("data-positive-icon"), ot = e.getAttribute("data-negative-icon"), nt = e.getAttribute("data-api-key"), st = e.getAttribute("data-capture-screenshot"), E = e.getAttribute("data-screenshot-quality"), T = e.getAttribute("data-screenshot-max-width"), L = e.getAttribute("data-screenshot-max-height"), at = e.getAttribute("data-capture-video"), rt = e.getAttribute("data-hide-thumbs"), dt = e.getAttribute("data-hide-dismiss"), z = e.getAttribute("data-video-max-duration"), ct = e.getAttribute("data-screenshot-method"), lt = e.getAttribute("data-direction"), O = e.getAttribute("data-css-selector"), $ = e.getAttribute("data-quest-base"), ht = e.getAttribute("data-quest-up"), ut = e.getAttribute("data-quest-down"), pt = e.getAttribute("data-quest-video"), mt = e.getAttribute("data-quest-api-key"), ft = e.getAttribute("data-quest-module-url");
|
|
1393
1582
|
return {
|
|
1394
1583
|
endpoint: t,
|
|
1395
|
-
css:
|
|
1396
|
-
apiKey:
|
|
1397
|
-
captureScreenshot:
|
|
1398
|
-
screenshotOptions:
|
|
1399
|
-
quality:
|
|
1400
|
-
maxWidth:
|
|
1401
|
-
maxHeight:
|
|
1584
|
+
css: O ? et(O) : void 0,
|
|
1585
|
+
apiKey: nt ?? void 0,
|
|
1586
|
+
captureScreenshot: st === "true" ? !0 : void 0,
|
|
1587
|
+
screenshotOptions: E || T || L ? {
|
|
1588
|
+
quality: E ? parseFloat(E) : void 0,
|
|
1589
|
+
maxWidth: T ? parseInt(T, 10) : void 0,
|
|
1590
|
+
maxHeight: L ? parseInt(L, 10) : void 0
|
|
1402
1591
|
} : void 0,
|
|
1403
|
-
container:
|
|
1592
|
+
container: d ?? void 0,
|
|
1404
1593
|
buttonClass: l ?? void 0,
|
|
1405
|
-
direction:
|
|
1594
|
+
direction: lt ?? void 0,
|
|
1406
1595
|
position: i ?? void 0,
|
|
1407
1596
|
zIndex: o ? parseInt(o, 10) : void 0,
|
|
1408
1597
|
skipTargeting: r === "true" ? !0 : void 0,
|
|
1409
|
-
incognito:
|
|
1598
|
+
incognito: c === "true" ? !0 : void 0,
|
|
1410
1599
|
buttonSize: p ?? void 0,
|
|
1411
1600
|
offset: u || m ? {
|
|
1412
1601
|
x: u ? parseInt(u, 10) : void 0,
|
|
1413
1602
|
y: m ? parseInt(m, 10) : void 0
|
|
1414
1603
|
} : void 0,
|
|
1415
|
-
modalWidth:
|
|
1416
|
-
backdropOpacity:
|
|
1417
|
-
fontFamily:
|
|
1418
|
-
fontSize:
|
|
1604
|
+
modalWidth: b ? parseInt(b, 10) : void 0,
|
|
1605
|
+
backdropOpacity: v ? parseFloat(v) : void 0,
|
|
1606
|
+
fontFamily: y ?? void 0,
|
|
1607
|
+
fontSize: f ? parseInt(f, 10) : void 0,
|
|
1419
1608
|
colors: {
|
|
1420
1609
|
positive: n ?? void 0,
|
|
1421
1610
|
negative: s ?? void 0,
|
|
1422
1611
|
marker: a ?? void 0
|
|
1423
1612
|
},
|
|
1424
|
-
text: h ||
|
|
1613
|
+
text: h || w || g || C || B || P ? {
|
|
1425
1614
|
tooltip: h ?? void 0,
|
|
1426
|
-
modalTitle:
|
|
1427
|
-
modalSubtitle:
|
|
1428
|
-
placeholder:
|
|
1429
|
-
submitButton:
|
|
1430
|
-
skipButton:
|
|
1615
|
+
modalTitle: w ?? void 0,
|
|
1616
|
+
modalSubtitle: g ?? void 0,
|
|
1617
|
+
placeholder: C ?? void 0,
|
|
1618
|
+
submitButton: B ?? void 0,
|
|
1619
|
+
skipButton: P ?? void 0
|
|
1620
|
+
} : void 0,
|
|
1621
|
+
positiveIcon: it ?? void 0,
|
|
1622
|
+
negativeIcon: ot ?? void 0,
|
|
1623
|
+
screenshotMethod: ct ?? void 0,
|
|
1624
|
+
captureVideo: at === "true" ? !0 : void 0,
|
|
1625
|
+
hideThumbs: rt === "true" ? !0 : void 0,
|
|
1626
|
+
hideDismiss: dt === "true" ? !0 : void 0,
|
|
1627
|
+
videoOptions: z ? {
|
|
1628
|
+
maxDuration: parseInt(z, 10)
|
|
1431
1629
|
} : void 0,
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
maxDuration: parseInt(B, 10)
|
|
1630
|
+
quests: $ ? {
|
|
1631
|
+
base: $,
|
|
1632
|
+
up: ht ?? void 0,
|
|
1633
|
+
down: ut ?? void 0,
|
|
1634
|
+
video: pt ?? void 0,
|
|
1635
|
+
apiKey: mt ?? void 0,
|
|
1636
|
+
moduleUrl: ft ?? void 0
|
|
1440
1637
|
} : void 0
|
|
1441
1638
|
};
|
|
1442
1639
|
}
|
|
1443
1640
|
if (typeof document < "u") {
|
|
1444
1641
|
const e = () => {
|
|
1445
|
-
const t = document.currentScript, i =
|
|
1446
|
-
n?.endpoint && new
|
|
1642
|
+
const t = document.currentScript, i = He(), o = t ? Be(t) : null, n = i ?? o;
|
|
1643
|
+
n?.endpoint && new Re(n);
|
|
1447
1644
|
};
|
|
1448
1645
|
document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", e) : e();
|
|
1449
1646
|
}
|
|
1450
1647
|
export {
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1648
|
+
Re as QaidFeedback,
|
|
1649
|
+
Ce as captureDomScreenshot,
|
|
1650
|
+
de as captureNetworkErrors,
|
|
1651
|
+
ve as createVideoRecorder,
|
|
1652
|
+
ge as getSupportedMimeType,
|
|
1653
|
+
Pe as isDomScreenshotSupported,
|
|
1654
|
+
be as isVideoRecordingSupported
|
|
1458
1655
|
};
|
|
1459
1656
|
//# sourceMappingURL=qaid.js.map
|