makethisbetter 1.4.0 → 1.4.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/dist/index.d.cts
ADDED
|
@@ -82,4 +82,4 @@
|
|
|
82
82
|
<span class="mtb-record-timer">00:00</span>
|
|
83
83
|
<button class="mtb-record-stop" type="button">${e.record.stop}</button>
|
|
84
84
|
`,t.append(this.el),this.timerEl=this.el.querySelector(".mtb-record-timer"),this.el.querySelector(".mtb-record-stop").addEventListener("click",r),this.intervalId=setInterval(()=>this.updateTimer(),1e3)}updateTimer(){const t=this.getDuration(),e=String(Math.floor(t/60)).padStart(2,"0"),s=String(t%60).padStart(2,"0");this.timerEl.textContent=`${e}:${s}`}destroy(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null),this.el.remove()}}class di{constructor(){this.session=null,this.bar=null,this.result=null}async start(t,e,s){this.session=new ci(t,s),this.bar=new hi(t,e,()=>this.session?.getDuration()??0,s),await this.session.start()}stop(){return this.session?(this.result=this.session.stop(),this.teardownUI(),this.result):null}getRecording(){return this.result}destroy(){this.teardownUI(),this.result=null}teardownUI(){this.session?.destroy(),this.session=null,this.bar?.destroy(),this.bar=null}}class Y{constructor(t){this.tab=null,this.toolbar=null,this.session=null,this.popup=null,this.clarify=null,this.success=null,this.frustrationPrompt=null,this.frustrationDetector=null,this.mode="idle",this.currentAnnotation=null,this.recordingManager=null,this.config=t,this.messages=ii(t.locale??"en"),this.apiClient=new Ve(t.projectKey,t.apiUrl,void 0,t.userToken,t.userTokenFn),this.consoleCollector=new Pe,this.consoleCollector.start(),this.buildUI(),t.frustrationDetection!==!1&&(this.frustrationDetector=new D(()=>this.handleFrustration()),this.frustrationDetector.start())}buildUI(){this.shadow=new mt(this.config.theme??"auto"),this.tab=new ft(this.shadow,this.messages,this.config.position??"right",()=>this.handleTabClick(),this.config.tabText)}handleTabClick(){this.mode==="idle"?(this.dismissFrustrationPrompt(),this.enterAnnotationMode()):this.exitAll()}handleFrustration(){this.mode!=="idle"||this.frustrationPrompt||(this.frustrationPrompt=new gt(this.shadow,this.messages,{onTell:()=>{this.dismissFrustrationPrompt(),this.enterAnnotationMode()},onDismiss:()=>this.dismissFrustrationPrompt()}))}dismissFrustrationPrompt(){this.frustrationPrompt?.destroy(),this.frustrationPrompt=null}enterAnnotationMode(){this.mode="annotating",this.tab?.setActive(!0),this.toolbar=new yt(this.shadow,this.messages,()=>this.exitAll(),t=>this.handleToolbarModeChange(t)),this.session=new $(this.shadow,this.messages,(t,e)=>{this.currentAnnotation=t,this.showPopup(t.x,t.y,e)})}handleToolbarModeChange(t){t==="record"?(this.mode="recording",this.session?.destroy(),this.session=null,this.recordingManager=new di,this.recordingManager.start(this.shadow,this.messages,()=>{this.recordingManager&&(this.recordingManager.stop(),this.showPopup(window.innerWidth/2,window.innerHeight/2,this.messages.record.timer_label))}).catch(e=>{console.warn("[MakeThisBetter] Screen recording unavailable, falling back to markup:",e),this.mode==="recording"&&(this.toolbar?.setMode("markup"),this.handleToolbarModeChange("markup"))})):(this.recordingManager?.destroy(),this.recordingManager=null,this.session||(this.session=new $(this.shadow,this.messages,(e,s)=>{this.currentAnnotation=e,this.showPopup(e.x,e.y,s)})),this.mode="annotating")}showPopup(t,e,s){this.mode="popup",this.session?.dismissInteraction(),this.popup=new Mt(this.shadow,{targetName:s,x:t,y:e,messages:this.messages,onSubmit:r=>this.handleSubmit(r),onClose:()=>this.exitAll()})}async handleSubmit(t){if(!this.popup)return;this.popup.setLoading(!0);const e=this.currentAnnotation,s=this.recordingManager?.getRecording()??void 0,[r,n]=await Promise.all([Ce(e?[e]:[]),Promise.resolve(Be())]),o=Xe(t,n,this.consoleCollector.getErrors(),e,this.config.user,s);try{const a=await this.apiClient.submitFeedback(o,r);this.popup?.destroy(),this.popup=null,this.session?.destroy(),this.session=null,this.toolbar?.destroy(),this.toolbar=null,this.recordingManager?.destroy(),this.recordingManager=null,a.skip_followup===!0||a.ai_clarify_available===!1?this.showSuccess(a.project_id,{skipFollowup:!0}):this.showClarify(a.id,a.project_id)}catch{this.popup?.setLoading(!1),this.popup?.setError(this.messages.error.submit)}}showClarify(t,e){this.mode="idle",this.tab?.setActive(!1),this.clarify=new _t(this.shadow,{feedbackId:t,apiClient:this.apiClient,messages:this.messages,onDone:()=>{this.clarify?.destroy(),this.clarify=null,this.showSuccess(e)}})}showSuccess(t,e){this.mode="idle",this.tab?.setActive(!1);const r=`${this.config.apiUrl?this.config.apiUrl.replace(/\/api\/v1\/?$/,""):"https://makethisbetter.dev"}/board/projects/${t}/feedbacks`,n=!!(this.config.userToken||this.config.userTokenFn);this.success=new At(this.shadow,this.messages,()=>{this.success?.destroy(),this.success=null},n?async()=>{const o=await this.apiClient.resolveUserToken();o&&window.open(`${r}?identity=${encodeURIComponent(o)}`,"_blank")}:void 0,e)}exitAll(){this.mode="idle",this.tab?.setActive(!1),this.toolbar?.destroy(),this.toolbar=null,this.session?.destroy(),this.session=null,this.popup?.destroy(),this.popup=null,this.clarify?.destroy(),this.clarify=null,this.currentAnnotation=null,this.recordingManager?.destroy(),this.recordingManager=null}destroy(){this.exitAll(),this.consoleCollector.stop(),this.frustrationDetector?.stop(),this.dismissFrustrationPrompt(),this.clarify?.destroy(),this.success?.destroy(),this.tab?.destroy(),this.recordingManager?.destroy(),this.shadow.destroy()}}let m=null;const rt={init(i){m&&(m.destroy(),m=null),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{m=new Y(i)}):m=new Y(i)},destroy(){m?.destroy(),m=null}};typeof window<"u"&&(window.MakeThisBetter=rt);exports.MakeThisBetter=rt;
|
|
85
|
-
//# sourceMappingURL=makethisbetter.cjs.
|
|
85
|
+
//# sourceMappingURL=makethisbetter.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"makethisbetter.cjs","sources":["../src/widget/shadow.ts","../src/widget/tab.ts","../src/widget/frustration-prompt.ts","../src/annotate/toolbar.ts","../src/annotate/overlay.ts","../src/annotate/highlighter.ts","../src/annotate/pin.ts","../src/styles.ts","../src/annotate/draw.ts","../src/annotate/session.ts","../src/popup/comment.ts","../src/popup/clarify.ts","../src/popup/success.ts","../node_modules/html-to-image/es/util.js","../node_modules/html-to-image/es/clone-pseudos.js","../node_modules/html-to-image/es/mimes.js","../node_modules/html-to-image/es/dataurl.js","../node_modules/html-to-image/es/clone-node.js","../node_modules/html-to-image/es/embed-resources.js","../node_modules/html-to-image/es/embed-images.js","../node_modules/html-to-image/es/apply-style.js","../node_modules/html-to-image/es/embed-webfonts.js","../node_modules/html-to-image/es/index.js","../src/screenshot/capture.ts","../src/context/error-source.ts","../src/context/console.ts","../src/context/frustration.ts","../src/context/collector.ts","../src/api/client.ts","../src/widget/payload.ts","../src/i18n/en.ts","../src/i18n/zh-CN.ts","../src/i18n/ja.ts","../src/i18n/ko.ts","../src/i18n/es.ts","../src/i18n/fr.ts","../src/i18n/de.ts","../src/i18n/index.ts","../src/record/session.ts","../src/record/control-bar.ts","../src/widget/recording-manager.ts","../src/widget/controller.ts","../src/index.ts"],"sourcesContent":["import cssText from '../styles/widget.css?inline'\nimport type { MakeThisBetterConfig } from '../types'\n\nexport class ShadowContainer {\n private host: HTMLElement\n readonly root: ShadowRoot\n\n constructor(theme: MakeThisBetterConfig['theme'] = 'auto') {\n this.host = document.createElement('div')\n this.host.id = 'mtb-widget-host'\n this.host.style.cssText = 'position:fixed;top:0;left:0;width:0;height:0;overflow:visible;z-index:2147483646;'\n this.host.setAttribute('data-mtb-theme', theme)\n document.body.appendChild(this.host)\n\n this.root = this.host.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = cssText\n this.root.appendChild(style)\n }\n\n el<T extends HTMLElement = HTMLElement>(tag: string, className?: string): T {\n const el = document.createElement(tag) as T\n if (className) el.className = className\n return el\n }\n\n append(...nodes: Node[]): void {\n for (const n of nodes) this.root.appendChild(n)\n }\n\n remove(...nodes: Node[]): void {\n for (const n of nodes) {\n if (n.parentNode === this.root) this.root.removeChild(n)\n }\n }\n\n destroy(): void {\n document.body.removeChild(this.host)\n }\n}\n","import type { ShadowContainer } from './shadow'\nimport type { I18nMessages } from '../i18n'\n\nexport class FeedbackTab {\n private el: HTMLButtonElement\n private onClick: () => void\n\n constructor(\n shadow: ShadowContainer,\n messages: I18nMessages,\n position: 'left' | 'right',\n onClick: () => void,\n customText?: string,\n ) {\n this.onClick = onClick\n this.el = shadow.el<HTMLButtonElement>('button', 'mtb-tab')\n if (position === 'left') this.el.classList.add('left')\n const label = customText ?? messages.tab\n this.el.textContent = label\n this.el.setAttribute('aria-label', label)\n this.el.addEventListener('click', onClick)\n shadow.append(this.el)\n }\n\n setActive(active: boolean): void {\n this.el.classList.toggle('active', active)\n }\n\n destroy(): void {\n this.el.removeEventListener('click', this.onClick)\n this.el.remove()\n }\n}\n","import type { ShadowContainer } from './shadow'\nimport type { I18nMessages } from '../i18n'\n\nconst FRUSTRATION_DISMISS_MS = 8000\n\nexport class FrustrationPromptCard {\n private el: HTMLDivElement\n\n constructor(\n shadow: ShadowContainer,\n messages: I18nMessages,\n handlers: { onTell: () => void; onDismiss: () => void },\n ) {\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-frustration-prompt')\n this.el.innerHTML = `\n <div class=\"mtb-frustration-icon\">⚠️</div>\n <span class=\"mtb-frustration-text\">${messages.frustration.prompt}</span>\n <div class=\"mtb-frustration-actions\">\n <button class=\"mtb-frustration-tell\">${messages.frustration.action}</button>\n <button class=\"mtb-frustration-dismiss\">${messages.frustration.dismiss}</button>\n </div>\n `\n\n this.el.querySelector('.mtb-frustration-tell')!.addEventListener('click', handlers.onTell)\n this.el.querySelector('.mtb-frustration-dismiss')!.addEventListener('click', handlers.onDismiss)\n\n shadow.append(this.el)\n setTimeout(handlers.onDismiss, FRUSTRATION_DISMISS_MS)\n }\n\n destroy(): void {\n this.el.remove()\n }\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\n\nexport type ToolbarMode = 'markup' | 'record'\n\nexport class AnnotationToolbar {\n private el: HTMLDivElement\n private hintEl!: HTMLSpanElement\n private markupBtn!: HTMLButtonElement\n private recordBtn!: HTMLButtonElement\n private messages: I18nMessages\n private currentMode: ToolbarMode = 'markup'\n\n constructor(\n shadow: ShadowContainer,\n messages: I18nMessages,\n onExit: () => void,\n onModeChange?: (mode: ToolbarMode) => void,\n ) {\n this.messages = messages\n\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-toolbar')\n this.el.innerHTML = this.buildHTML(messages)\n shadow.append(this.el)\n\n this.hintEl = this.el.querySelector('.mtb-toolbar-hint')!\n this.markupBtn = this.el.querySelector('.mtb-toolbar-mode-markup')!\n this.recordBtn = this.el.querySelector('.mtb-toolbar-mode-record')!\n\n this.markupBtn.addEventListener('click', () => {\n this.setMode('markup')\n onModeChange?.('markup')\n })\n this.recordBtn.addEventListener('click', () => {\n this.setMode('record')\n onModeChange?.('record')\n })\n this.el.querySelector('.mtb-exit-btn')!.addEventListener('click', onExit)\n }\n\n private buildHTML(m: I18nMessages): string {\n return `\n <div class=\"mtb-toolbar-modes\">\n <button class=\"mtb-toolbar-mode-btn mtb-toolbar-mode-markup active\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"7\"/><line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"/><line x1=\"3\" y1=\"12\" x2=\"7\" y2=\"12\"/><line x1=\"17\" y1=\"12\" x2=\"21\" y2=\"12\"/></svg>${m.toolbar.markup}\n </button>\n <button class=\"mtb-toolbar-mode-btn mtb-toolbar-mode-record\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><circle cx=\"12\" cy=\"12\" r=\"4\" fill=\"currentColor\" stroke=\"none\"/></svg>${m.toolbar.record}\n </button>\n </div>\n <span class=\"mtb-toolbar-hint\">${m.toolbar.hint}</span>\n <span class=\"mtb-toolbar-sep\"></span>\n <button class=\"mtb-exit-btn\">\n <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>${m.toolbar.exit}\n </button>\n `\n }\n\n setMode(mode: ToolbarMode): void {\n this.currentMode = mode\n if (mode === 'markup') {\n this.markupBtn.classList.add('active')\n this.recordBtn.classList.remove('active')\n this.hintEl.textContent = this.messages.toolbar.hint\n } else {\n this.markupBtn.classList.remove('active')\n this.recordBtn.classList.add('active')\n this.hintEl.textContent = this.messages.toolbar.hintRecord\n }\n }\n\n getMode(): ToolbarMode {\n return this.currentMode\n }\n\n destroy(): void {\n this.el.remove()\n }\n}\n","import type { ShadowContainer } from '../widget/shadow'\n\nexport class AnnotationOverlay {\n private overlayEl: HTMLDivElement\n private dimEl: HTMLDivElement\n private onMouseDown: (e: MouseEvent) => void\n private onMouseMove: (e: MouseEvent) => void\n private onMouseUp: (e: MouseEvent) => void\n private onMouseLeave: (e: MouseEvent) => void\n\n constructor(\n shadow: ShadowContainer,\n handlers: {\n onMouseDown: (e: MouseEvent) => void\n onMouseMove: (e: MouseEvent) => void\n onMouseUp: (e: MouseEvent) => void\n onMouseLeave: (e: MouseEvent) => void\n },\n ) {\n this.onMouseDown = handlers.onMouseDown\n this.onMouseMove = handlers.onMouseMove\n this.onMouseUp = handlers.onMouseUp\n this.onMouseLeave = handlers.onMouseLeave\n\n this.overlayEl = shadow.el<HTMLDivElement>('div', 'mtb-overlay')\n this.overlayEl.addEventListener('mousedown', this.onMouseDown)\n this.overlayEl.addEventListener('mousemove', this.onMouseMove)\n this.overlayEl.addEventListener('mouseup', this.onMouseUp)\n this.overlayEl.addEventListener('mouseleave', this.onMouseLeave)\n shadow.append(this.overlayEl)\n\n this.dimEl = shadow.el<HTMLDivElement>('div', 'mtb-dim')\n shadow.append(this.dimEl)\n }\n\n destroy(): void {\n this.overlayEl.removeEventListener('mousedown', this.onMouseDown)\n this.overlayEl.removeEventListener('mousemove', this.onMouseMove)\n this.overlayEl.removeEventListener('mouseup', this.onMouseUp)\n this.overlayEl.removeEventListener('mouseleave', this.onMouseLeave)\n this.overlayEl.remove()\n this.dimEl.remove()\n }\n}\n","import type { ShadowContainer } from '../widget/shadow'\n\nexport class ElementHighlighter {\n private highlightEl: HTMLDivElement\n\n constructor(shadow: ShadowContainer) {\n this.highlightEl = shadow.el<HTMLDivElement>('div', 'mtb-highlight')\n this.hide()\n shadow.append(this.highlightEl)\n }\n\n highlight(el: Element): void {\n const rect = el.getBoundingClientRect()\n this.highlightEl.style.top = `${rect.top - 2}px`\n this.highlightEl.style.left = `${rect.left - 2}px`\n this.highlightEl.style.width = `${rect.width + 4}px`\n this.highlightEl.style.height = `${rect.height + 4}px`\n this.highlightEl.style.display = 'block'\n }\n\n hide(): void {\n this.highlightEl.style.display = 'none'\n }\n\n destroy(): void {\n this.highlightEl.remove()\n }\n}\n\nexport function getElementName(el: Element): string {\n if (el instanceof HTMLElement) {\n const label = el.getAttribute('aria-label')\n if (label) return label\n\n const title = el.getAttribute('title')\n if (title) return title\n\n const text = el.textContent?.trim().slice(0, 40)\n if (text) return text\n\n const placeholder = (el as HTMLInputElement).placeholder\n if (placeholder) return placeholder\n\n const alt = (el as HTMLImageElement).alt\n if (alt) return alt\n\n const dataMark = el.getAttribute('data-mark')\n if (dataMark) return dataMark\n }\n return el.tagName.toLowerCase()\n}\n\nexport function getCssSelector(el: Element): string {\n const parts: string[] = []\n let current: Element | null = el\n while (current && current !== document.body && parts.length < 5) {\n let selector = current.tagName.toLowerCase()\n if (current.id) {\n selector = `#${current.id}`\n parts.unshift(selector)\n break\n }\n const classNames = Array.from(current.classList)\n .filter(c => !c.startsWith('mtb-'))\n .slice(0, 2)\n .join('.')\n if (classNames) selector += `.${classNames}`\n\n const parent = current.parentElement\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n c => c.tagName === current!.tagName,\n )\n if (siblings.length > 1) {\n const idx = siblings.indexOf(current) + 1\n selector += `:nth-child(${idx})`\n }\n }\n\n parts.unshift(selector)\n current = current.parentElement\n }\n return parts.join(' > ')\n}\n","import type { ShadowContainer } from '../widget/shadow'\n\nexport class PinMarker {\n private pins: HTMLDivElement[] = []\n private shadow: ShadowContainer\n\n constructor(shadow: ShadowContainer) {\n this.shadow = shadow\n }\n\n addPin(x: number, y: number, index: number): void {\n const pin = this.shadow.el<HTMLDivElement>('div', 'mtb-pin')\n pin.textContent = String(index)\n pin.style.top = `${y}px`\n pin.style.left = `${x}px`\n this.shadow.append(pin)\n this.pins.push(pin)\n }\n\n clearAll(): void {\n for (const pin of this.pins) pin.remove()\n this.pins = []\n }\n\n destroy(): void {\n this.clearAll()\n }\n}\n","export const BRAND_COLOR = '#059669'\n\nexport const DRAW_STROKE = {\n color: BRAND_COLOR,\n width: '3.5',\n linecap: 'round',\n linejoin: 'round',\n filter: 'drop-shadow(0 1px 2px rgba(5,150,105,0.35))',\n} as const\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { Annotation } from '../types'\nimport { DRAW_STROKE } from '../styles'\n\nexport class DrawLayer {\n private svg: SVGSVGElement\n private path: SVGPathElement | null = null\n private points: [number, number][] = []\n private isDrawing = false\n private onDrawComplete: (annotation: Annotation) => void\n\n constructor(shadow: ShadowContainer, onDrawComplete: (annotation: Annotation) => void) {\n this.onDrawComplete = onDrawComplete\n\n this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n this.svg.setAttribute('class', 'mtb-draw-svg')\n shadow.append(this.svg)\n }\n\n startDraw(x: number, y: number): void {\n this.isDrawing = true\n this.points = [[x, y]]\n\n this.path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n this.path.setAttribute('fill', 'none')\n this.path.setAttribute('stroke', DRAW_STROKE.color)\n this.path.setAttribute('stroke-width', DRAW_STROKE.width)\n this.path.setAttribute('stroke-linecap', DRAW_STROKE.linecap)\n this.path.setAttribute('stroke-linejoin', DRAW_STROKE.linejoin)\n this.path.setAttribute('style', `filter:${DRAW_STROKE.filter}`)\n this.svg.appendChild(this.path)\n }\n\n continueDraw(x: number, y: number): void {\n if (!this.isDrawing || !this.path) return\n this.points.push([x, y])\n this.path.setAttribute('d', this.buildPathD())\n }\n\n endDraw(): void {\n if (!this.isDrawing || this.points.length < 2) {\n this.isDrawing = false\n if (this.path) {\n this.path.remove()\n this.path = null\n }\n return\n }\n this.isDrawing = false\n\n const center = this.getCenter()\n const pathD = this.buildPathD()\n\n const annotation: Annotation = {\n type: 'draw',\n x: center[0],\n y: center[1],\n drawPath: pathD,\n }\n\n this.onDrawComplete(annotation)\n }\n\n private buildPathD(): string {\n if (this.points.length === 0) return ''\n const [fx, fy] = this.points[0]\n let d = `M ${fx} ${fy}`\n for (let i = 1; i < this.points.length; i++) {\n const [x, y] = this.points[i]\n d += ` L ${x} ${y}`\n }\n return d\n }\n\n private getCenter(): [number, number] {\n const xs = this.points.map(p => p[0])\n const ys = this.points.map(p => p[1])\n const cx = (Math.min(...xs) + Math.max(...xs)) / 2\n const cy = (Math.min(...ys) + Math.max(...ys)) / 2\n return [cx, cy]\n }\n\n clearAll(): void {\n while (this.svg.firstChild) this.svg.removeChild(this.svg.firstChild)\n this.path = null\n this.isDrawing = false\n this.points = []\n }\n\n cancelCurrentDraw(): void {\n this.path?.remove()\n this.path = null\n this.isDrawing = false\n this.points = []\n }\n\n isCurrentlyDrawing(): boolean {\n return this.isDrawing\n }\n\n getPointCount(): number {\n return this.points.length\n }\n\n destroy(): void {\n this.svg.remove()\n }\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\nimport type { Annotation } from '../types'\nimport { AnnotationOverlay } from './overlay'\nimport { ElementHighlighter, getElementName, getCssSelector } from './highlighter'\nimport { PinMarker } from './pin'\nimport { DrawLayer } from './draw'\n\nconst DRAW_MIN_POINTS = 5\n\nexport class AnnotationSession {\n private overlay: AnnotationOverlay\n private highlighter: ElementHighlighter\n private pinMarker: PinMarker\n private drawLayer: DrawLayer\n private pinCount = 0\n private interactionActive = true\n private pendingHighlightFrame: number | null = null\n private lastMoveX = 0\n private lastMoveY = 0\n\n constructor(\n shadow: ShadowContainer,\n private messages: I18nMessages,\n private onReady: (annotation: Annotation, targetName: string) => void,\n ) {\n this.highlighter = new ElementHighlighter(shadow)\n this.pinMarker = new PinMarker(shadow)\n this.drawLayer = new DrawLayer(shadow, (annotation) => {\n this.onReady(annotation, this.messages.annotation.drawing)\n })\n this.overlay = new AnnotationOverlay(shadow, {\n onMouseDown: (e) => this.handleMouseDown(e),\n onMouseMove: (e) => this.handleMouseMove(e),\n onMouseUp: (e) => this.handleMouseUp(e),\n onMouseLeave: () => {\n if (this.drawLayer.isCurrentlyDrawing()) this.drawLayer.endDraw()\n this.cancelPendingHighlight()\n this.highlighter.hide()\n },\n })\n }\n\n private handleMouseDown(e: MouseEvent): void {\n e.preventDefault()\n this.drawLayer.startDraw(e.clientX, e.clientY)\n }\n\n private handleMouseMove(e: MouseEvent): void {\n if (this.drawLayer.isCurrentlyDrawing()) {\n this.cancelPendingHighlight()\n this.drawLayer.continueDraw(e.clientX, e.clientY)\n this.highlighter.hide()\n return\n }\n\n this.lastMoveX = e.clientX\n this.lastMoveY = e.clientY\n if (this.pendingHighlightFrame !== null) return\n this.pendingHighlightFrame = requestAnimationFrame(() => {\n this.pendingHighlightFrame = null\n this.updateHighlight()\n })\n }\n\n private updateHighlight(): void {\n if (!this.interactionActive || this.drawLayer.isCurrentlyDrawing()) return\n const underEl = getElementUnder(this.lastMoveX, this.lastMoveY)\n if (underEl) this.highlighter.highlight(underEl)\n else this.highlighter.hide()\n }\n\n private cancelPendingHighlight(): void {\n if (this.pendingHighlightFrame === null) return\n cancelAnimationFrame(this.pendingHighlightFrame)\n this.pendingHighlightFrame = null\n }\n\n private handleMouseUp(e: MouseEvent): void {\n if (!this.drawLayer.isCurrentlyDrawing()) return\n\n if (this.drawLayer.getPointCount() >= DRAW_MIN_POINTS) {\n this.drawLayer.endDraw()\n return\n }\n\n this.drawLayer.cancelCurrentDraw()\n const underEl = getElementUnder(e.clientX, e.clientY)\n const targetName = underEl ? getElementName(underEl) : this.messages.annotation.element\n const annotation: Annotation = {\n type: 'pin',\n x: e.clientX,\n y: e.clientY,\n targetSelector: underEl ? getCssSelector(underEl) : undefined,\n targetText: underEl?.textContent?.trim().slice(0, 200) ?? '',\n targetName,\n }\n this.pinMarker.addPin(e.clientX, e.clientY, ++this.pinCount)\n this.drawLayer.clearAll()\n this.highlighter.hide()\n this.onReady(annotation, targetName)\n }\n\n dismissInteraction(): void {\n if (!this.interactionActive) return\n this.interactionActive = false\n this.cancelPendingHighlight()\n this.overlay.destroy()\n this.highlighter.destroy()\n }\n\n destroy(): void {\n this.dismissInteraction()\n this.pinMarker.destroy()\n this.drawLayer.destroy()\n }\n}\n\n// Skips the widget host via elementsFromPoint instead of toggling its\n// display — hiding the host on every mousemove flickered the toolbar.\nfunction getElementUnder(x: number, y: number): Element | null {\n return document.elementsFromPoint(x, y).find(el => el.id !== 'mtb-widget-host') ?? null\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\n\ninterface PopupOptions {\n targetName: string\n x: number\n y: number\n onSubmit: (description: string) => void\n onClose: () => void\n messages: I18nMessages\n}\n\nexport class CommentPopup {\n private el: HTMLDivElement\n private textarea!: HTMLTextAreaElement\n private submitBtn!: HTMLButtonElement\n private errorEl!: HTMLDivElement\n private onSubmit: (description: string) => void\n private onClose: () => void\n private submitLabel: string\n private loading = false\n\n constructor(shadow: ShadowContainer, opts: PopupOptions) {\n this.onSubmit = opts.onSubmit\n this.onClose = opts.onClose\n this.submitLabel = opts.messages.popup.submit\n\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-popup')\n this.el.innerHTML = this.buildHTML(opts)\n shadow.append(this.el)\n\n this.textarea = this.el.querySelector('.mtb-textarea')!\n this.submitBtn = this.el.querySelector('.mtb-submit-btn')!\n\n this.positionPopup(opts.x, opts.y)\n this.bindEvents(opts.messages)\n this.textarea.focus()\n }\n\n private buildHTML(opts: PopupOptions): string {\n const m = opts.messages\n const quickOpts = m.popup.quickOptions\n .map(\n o => `\n <button class=\"mtb-quick-option\" data-quick=\"${escapeHtml(o.label)}\">\n <span class=\"mtb-quick-option-emoji\">${o.emoji}</span>\n <span>${escapeHtml(o.label)}</span>\n </button>`,\n )\n .join('')\n\n return `\n <div class=\"mtb-popup-header\">\n <div class=\"mtb-popup-icon\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#059669\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\"/><circle cx=\"12\" cy=\"10\" r=\"3\"/>\n </svg>\n </div>\n <span class=\"mtb-popup-title\">${m.popup.about} \"${escapeHtml(opts.targetName)}\"</span>\n <button class=\"mtb-popup-close\" aria-label=\"Close\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>\n </button>\n </div>\n <div class=\"mtb-popup-body\">\n <div class=\"mtb-quick-options\">\n ${quickOpts}\n </div>\n <div class=\"mtb-textarea-wrap\">\n <textarea class=\"mtb-textarea\" placeholder=\"${escapeHtml(m.popup.placeholder)}\"></textarea>\n </div>\n <div class=\"mtb-popup-error\" role=\"alert\"></div>\n <div class=\"mtb-popup-actions\">\n <button class=\"mtb-cancel-btn\" type=\"button\">${escapeHtml(m.popup.cancel)}</button>\n <button class=\"mtb-submit-btn\" type=\"button\" disabled>${escapeHtml(m.popup.submit)}</button>\n </div>\n </div>\n `\n }\n\n private positionPopup(x: number, y: number): void {\n const popupW = 320\n const popupH = 260\n const vw = window.innerWidth\n const vh = window.innerHeight\n const margin = 12\n\n let left = x + 12\n let top = y + 12\n\n if (left + popupW > vw - margin) {\n left = x - popupW - 12\n }\n if (left < margin) left = margin\n\n if (top + popupH > vh - margin) {\n top = vh - popupH - margin\n }\n if (top < margin) top = margin\n\n this.el.style.left = `${left}px`\n this.el.style.top = `${top}px`\n }\n\n private bindEvents(messages: I18nMessages): void {\n this.el.querySelector('.mtb-popup-close')!.addEventListener('click', () => this.onClose())\n this.el.querySelector('.mtb-cancel-btn')!.addEventListener('click', () => this.onClose())\n this.errorEl = this.el.querySelector('.mtb-popup-error')!\n\n this.el.querySelectorAll('.mtb-quick-option').forEach(btn => {\n btn.addEventListener('click', () => {\n const label = (btn as HTMLElement).dataset['quick'] ?? ''\n this.textarea.value = label\n this.updateSubmitState()\n this.textarea.focus()\n })\n })\n\n this.textarea.addEventListener('input', () => this.updateSubmitState())\n\n this.textarea.addEventListener('keydown', (e: KeyboardEvent) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n this.submit()\n }\n })\n\n this.submitBtn.addEventListener('click', () => this.submit())\n }\n\n private updateSubmitState(): void {\n const hasText = this.textarea.value.trim().length > 0\n this.submitBtn.classList.toggle('ready', hasText && !this.loading)\n this.submitBtn.disabled = !hasText || this.loading\n this.errorEl.hidden = true\n this.errorEl.textContent = ''\n }\n\n private submit(): void {\n const text = this.textarea.value.trim()\n if (!text || this.loading) return\n this.onSubmit(text)\n }\n\n setLoading(loading: boolean): void {\n this.loading = loading\n if (loading) {\n this.submitBtn.classList.add('loading')\n this.submitBtn.innerHTML = `<span class=\"mtb-dot\"></span><span class=\"mtb-dot\"></span><span class=\"mtb-dot\"></span>`\n this.textarea.disabled = true\n } else {\n this.submitBtn.classList.remove('loading')\n this.submitBtn.textContent = this.submitLabel\n this.textarea.disabled = false\n }\n this.updateSubmitState()\n }\n\n setError(message: string): void {\n this.errorEl.textContent = message\n this.errorEl.hidden = false\n }\n\n destroy(): void {\n this.el.remove()\n }\n}\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\nimport type { ApiClient } from '../api/client'\nimport type { ClarifyMessage } from '../types'\nimport { BRAND_COLOR } from '../styles'\n\nconst POLL_INTERVAL_MS = 2000\nconst DONE_DELAY_MS = 2000\n\ninterface ClarifyCardOptions {\n feedbackId: string\n apiClient: ApiClient\n messages: I18nMessages\n onDone: () => void\n}\n\nexport class ClarifyCard {\n private el: HTMLDivElement\n private messagesEl!: HTMLDivElement\n private inputEl!: HTMLInputElement\n private sendBtn!: HTMLButtonElement\n private pollTimer: ReturnType<typeof setInterval> | null = null\n private doneTimer: ReturnType<typeof setTimeout> | null = null\n private feedbackId: string\n private apiClient: ApiClient\n private onDone: () => void\n private sending = false\n private destroyed = false\n\n constructor(shadow: ShadowContainer, opts: ClarifyCardOptions) {\n this.feedbackId = opts.feedbackId\n this.apiClient = opts.apiClient\n this.onDone = opts.onDone\n\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-clarify')\n this.el.style.right = '20px'\n this.el.style.bottom = '20px'\n this.el.innerHTML = this.buildHTML(opts.messages)\n shadow.append(this.el)\n\n this.messagesEl = this.el.querySelector('.mtb-clarify-messages')!\n this.inputEl = this.el.querySelector('.mtb-clarify-input')!\n this.sendBtn = this.el.querySelector('.mtb-clarify-send')!\n\n this.bindEvents(opts.messages)\n this.startConversation()\n }\n\n private buildHTML(m: I18nMessages): string {\n return `\n <div class=\"mtb-clarify-header\">\n <div class=\"mtb-clarify-icon\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${BRAND_COLOR}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/>\n </svg>\n </div>\n <button class=\"mtb-clarify-skip\">${escapeHtml(m.clarify.skip)}</button>\n </div>\n <div class=\"mtb-clarify-messages\"></div>\n <div class=\"mtb-clarify-footer\">\n <input class=\"mtb-clarify-input\" type=\"text\" placeholder=\"${escapeHtml(m.clarify.placeholder)}\" />\n <button class=\"mtb-clarify-send\" disabled>${escapeHtml(m.clarify.send)}</button>\n </div>\n `\n }\n\n private bindEvents(m: I18nMessages): void {\n this.el.querySelector('.mtb-clarify-skip')!.addEventListener('click', () => {\n this.stopPolling()\n this.onDone()\n })\n\n this.inputEl.addEventListener('input', () => {\n const hasText = this.inputEl.value.trim().length > 0\n this.sendBtn.disabled = !hasText || this.sending\n })\n\n this.inputEl.addEventListener('keydown', (e: KeyboardEvent) => {\n // keyCode 229: IME composition fallback for browsers without isComposing\n if (e.isComposing || e.keyCode === 229) return\n if (e.key === 'Enter') {\n e.preventDefault()\n this.sendMessage(m)\n }\n })\n\n this.sendBtn.addEventListener('click', () => this.sendMessage(m))\n }\n\n private async startConversation(): Promise<void> {\n this.showThinking()\n try {\n const res = await this.apiClient.startClarification(this.feedbackId)\n if (this.destroyed) return\n this.renderConversation(res.messages, res.done)\n if (res.done) {\n this.handleDone()\n } else {\n this.startPolling()\n }\n } catch {\n if (this.destroyed) return\n this.onDone()\n }\n }\n\n private async sendMessage(m: I18nMessages): Promise<void> {\n const text = this.inputEl.value.trim()\n if (!text || this.sending) return\n\n this.sending = true\n this.inputEl.disabled = true\n this.sendBtn.disabled = true\n this.stopPolling()\n\n this.appendMessage({ role: 'user', content: text })\n this.inputEl.value = ''\n this.showThinking()\n\n try {\n const res = await this.apiClient.startClarification(this.feedbackId, text)\n if (this.destroyed) return\n this.renderConversation(res.messages, res.done)\n if (res.done) {\n this.handleDone()\n } else {\n this.startPolling()\n }\n } catch {\n if (this.destroyed) return\n this.onDone()\n } finally {\n this.sending = false\n this.inputEl.disabled = false\n this.sendBtn.disabled = this.inputEl.value.trim().length === 0\n this.inputEl.focus()\n }\n }\n\n private startPolling(): void {\n this.stopPolling()\n this.pollTimer = setInterval(() => this.poll(), POLL_INTERVAL_MS)\n }\n\n private stopPolling(): void {\n if (this.pollTimer !== null) {\n clearInterval(this.pollTimer)\n this.pollTimer = null\n }\n }\n\n private async poll(): Promise<void> {\n try {\n const res = await this.apiClient.getClarification(this.feedbackId)\n if (this.destroyed) return\n this.renderConversation(res.messages, res.done)\n if (res.done) {\n this.stopPolling()\n this.handleDone()\n }\n } catch {\n if (this.destroyed) return\n this.stopPolling()\n }\n }\n\n private handleDone(): void {\n this.inputEl.disabled = true\n this.sendBtn.disabled = true\n this.doneTimer = setTimeout(() => {\n if (!this.destroyed) this.onDone()\n }, DONE_DELAY_MS)\n }\n\n private renderConversation(messages: ClarifyMessage[], done: boolean): void {\n this.renderMessages(messages)\n const last = messages[messages.length - 1]\n if (!done && (!last || last.role === 'user')) this.showThinking()\n }\n\n private renderMessages(messages: ClarifyMessage[]): void {\n this.messagesEl.innerHTML = ''\n for (const msg of messages) {\n this.appendMessage(msg)\n }\n this.messagesEl.scrollTop = this.messagesEl.scrollHeight\n }\n\n private appendMessage(msg: ClarifyMessage): void {\n const bubble = document.createElement('div')\n bubble.className = msg.role === 'user' ? 'mtb-clarify-bubble mtb-clarify-user' : 'mtb-clarify-bubble mtb-clarify-ai'\n bubble.textContent = msg.content\n this.messagesEl.appendChild(bubble)\n this.messagesEl.scrollTop = this.messagesEl.scrollHeight\n }\n\n private showThinking(): void {\n const dots = document.createElement('div')\n dots.className = 'mtb-clarify-bubble mtb-clarify-ai mtb-clarify-thinking'\n dots.innerHTML = '<span class=\"mtb-dot\"></span><span class=\"mtb-dot\"></span><span class=\"mtb-dot\"></span>'\n this.messagesEl.appendChild(dots)\n this.messagesEl.scrollTop = this.messagesEl.scrollHeight\n }\n\n destroy(): void {\n this.destroyed = true\n this.stopPolling()\n if (this.doneTimer !== null) {\n clearTimeout(this.doneTimer)\n this.doneTimer = null\n }\n this.el.remove()\n }\n}\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\nimport { BRAND_COLOR } from '../styles'\n\nconst SUCCESS_AUTO_CLOSE_MS = 5000\n\nexport interface SuccessCardOptions {\n skipFollowup?: boolean\n}\n\nexport class SuccessCard {\n private el: HTMLDivElement\n\n constructor(shadow: ShadowContainer, messages: I18nMessages, onClose: () => void, onViewFeedback?: () => void, options?: SuccessCardOptions) {\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-success')\n this.el.style.right = '20px'\n this.el.style.bottom = '20px'\n\n const title = options?.skipFollowup ? messages.success.title_no_ai : messages.success.title\n const msg = options?.skipFollowup ? messages.success.message_no_ai : messages.success.message\n\n const viewLink = onViewFeedback\n ? `<button class=\"mtb-view-feedback-link\">${messages.success.view_feedback}</button>`\n : ''\n\n this.el.innerHTML = `\n <div class=\"mtb-success-icon\">\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${BRAND_COLOR}\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\"/>\n </svg>\n </div>\n <div class=\"mtb-success-title\">${title}</div>\n <div class=\"mtb-success-msg\">${msg}</div>\n ${viewLink}\n <button class=\"mtb-close-link\">${messages.success.close}</button>\n `\n shadow.append(this.el)\n this.el.querySelector('.mtb-close-link')!.addEventListener('click', onClose)\n\n if (onViewFeedback) {\n this.el.querySelector('.mtb-view-feedback-link')!.addEventListener('click', onViewFeedback)\n }\n\n setTimeout(() => onClose(), SUCCESS_AUTO_CLOSE_MS)\n }\n\n destroy(): void {\n this.el.remove()\n }\n}\n","export function resolveUrl(url, baseUrl) {\n // url is absolute already\n if (url.match(/^[a-z]+:\\/\\//i)) {\n return url;\n }\n // url is absolute already, without protocol\n if (url.match(/^\\/\\//)) {\n return window.location.protocol + url;\n }\n // dataURI, mailto:, tel:, etc.\n if (url.match(/^[a-z]+:/i)) {\n return url;\n }\n const doc = document.implementation.createHTMLDocument();\n const base = doc.createElement('base');\n const a = doc.createElement('a');\n doc.head.appendChild(base);\n doc.body.appendChild(a);\n if (baseUrl) {\n base.href = baseUrl;\n }\n a.href = url;\n return a.href;\n}\nexport const uuid = (() => {\n // generate uuid for className of pseudo elements.\n // We should not use GUIDs, otherwise pseudo elements sometimes cannot be captured.\n let counter = 0;\n // ref: http://stackoverflow.com/a/6248722/2519373\n const random = () => \n // eslint-disable-next-line no-bitwise\n `0000${((Math.random() * 36 ** 4) << 0).toString(36)}`.slice(-4);\n return () => {\n counter += 1;\n return `u${random()}${counter}`;\n };\n})();\nexport function delay(ms) {\n return (args) => new Promise((resolve) => {\n setTimeout(() => resolve(args), ms);\n });\n}\nexport function toArray(arrayLike) {\n const arr = [];\n for (let i = 0, l = arrayLike.length; i < l; i++) {\n arr.push(arrayLike[i]);\n }\n return arr;\n}\nlet styleProps = null;\nexport function getStyleProperties(options = {}) {\n if (styleProps) {\n return styleProps;\n }\n if (options.includeStyleProperties) {\n styleProps = options.includeStyleProperties;\n return styleProps;\n }\n styleProps = toArray(window.getComputedStyle(document.documentElement));\n return styleProps;\n}\nfunction px(node, styleProperty) {\n const win = node.ownerDocument.defaultView || window;\n const val = win.getComputedStyle(node).getPropertyValue(styleProperty);\n return val ? parseFloat(val.replace('px', '')) : 0;\n}\nfunction getNodeWidth(node) {\n const leftBorder = px(node, 'border-left-width');\n const rightBorder = px(node, 'border-right-width');\n return node.clientWidth + leftBorder + rightBorder;\n}\nfunction getNodeHeight(node) {\n const topBorder = px(node, 'border-top-width');\n const bottomBorder = px(node, 'border-bottom-width');\n return node.clientHeight + topBorder + bottomBorder;\n}\nexport function getImageSize(targetNode, options = {}) {\n const width = options.width || getNodeWidth(targetNode);\n const height = options.height || getNodeHeight(targetNode);\n return { width, height };\n}\nexport function getPixelRatio() {\n let ratio;\n let FINAL_PROCESS;\n try {\n FINAL_PROCESS = process;\n }\n catch (e) {\n // pass\n }\n const val = FINAL_PROCESS && FINAL_PROCESS.env\n ? FINAL_PROCESS.env.devicePixelRatio\n : null;\n if (val) {\n ratio = parseInt(val, 10);\n if (Number.isNaN(ratio)) {\n ratio = 1;\n }\n }\n return ratio || window.devicePixelRatio || 1;\n}\n// @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas#maximum_canvas_size\nconst canvasDimensionLimit = 16384;\nexport function checkCanvasDimensions(canvas) {\n if (canvas.width > canvasDimensionLimit ||\n canvas.height > canvasDimensionLimit) {\n if (canvas.width > canvasDimensionLimit &&\n canvas.height > canvasDimensionLimit) {\n if (canvas.width > canvas.height) {\n canvas.height *= canvasDimensionLimit / canvas.width;\n canvas.width = canvasDimensionLimit;\n }\n else {\n canvas.width *= canvasDimensionLimit / canvas.height;\n canvas.height = canvasDimensionLimit;\n }\n }\n else if (canvas.width > canvasDimensionLimit) {\n canvas.height *= canvasDimensionLimit / canvas.width;\n canvas.width = canvasDimensionLimit;\n }\n else {\n canvas.width *= canvasDimensionLimit / canvas.height;\n canvas.height = canvasDimensionLimit;\n }\n }\n}\nexport function canvasToBlob(canvas, options = {}) {\n if (canvas.toBlob) {\n return new Promise((resolve) => {\n canvas.toBlob(resolve, options.type ? options.type : 'image/png', options.quality ? options.quality : 1);\n });\n }\n return new Promise((resolve) => {\n const binaryString = window.atob(canvas\n .toDataURL(options.type ? options.type : undefined, options.quality ? options.quality : undefined)\n .split(',')[1]);\n const len = binaryString.length;\n const binaryArray = new Uint8Array(len);\n for (let i = 0; i < len; i += 1) {\n binaryArray[i] = binaryString.charCodeAt(i);\n }\n resolve(new Blob([binaryArray], {\n type: options.type ? options.type : 'image/png',\n }));\n });\n}\nexport function createImage(url) {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n img.decode().then(() => {\n requestAnimationFrame(() => resolve(img));\n });\n };\n img.onerror = reject;\n img.crossOrigin = 'anonymous';\n img.decoding = 'async';\n img.src = url;\n });\n}\nexport async function svgToDataURL(svg) {\n return Promise.resolve()\n .then(() => new XMLSerializer().serializeToString(svg))\n .then(encodeURIComponent)\n .then((html) => `data:image/svg+xml;charset=utf-8,${html}`);\n}\nexport async function nodeToDataURL(node, width, height) {\n const xmlns = 'http://www.w3.org/2000/svg';\n const svg = document.createElementNS(xmlns, 'svg');\n const foreignObject = document.createElementNS(xmlns, 'foreignObject');\n svg.setAttribute('width', `${width}`);\n svg.setAttribute('height', `${height}`);\n svg.setAttribute('viewBox', `0 0 ${width} ${height}`);\n foreignObject.setAttribute('width', '100%');\n foreignObject.setAttribute('height', '100%');\n foreignObject.setAttribute('x', '0');\n foreignObject.setAttribute('y', '0');\n foreignObject.setAttribute('externalResourcesRequired', 'true');\n svg.appendChild(foreignObject);\n foreignObject.appendChild(node);\n return svgToDataURL(svg);\n}\nexport const isInstanceOfElement = (node, instance) => {\n if (node instanceof instance)\n return true;\n const nodePrototype = Object.getPrototypeOf(node);\n if (nodePrototype === null)\n return false;\n return (nodePrototype.constructor.name === instance.name ||\n isInstanceOfElement(nodePrototype, instance));\n};\n//# sourceMappingURL=util.js.map","import { uuid, getStyleProperties } from './util';\nfunction formatCSSText(style) {\n const content = style.getPropertyValue('content');\n return `${style.cssText} content: '${content.replace(/'|\"/g, '')}';`;\n}\nfunction formatCSSProperties(style, options) {\n return getStyleProperties(options)\n .map((name) => {\n const value = style.getPropertyValue(name);\n const priority = style.getPropertyPriority(name);\n return `${name}: ${value}${priority ? ' !important' : ''};`;\n })\n .join(' ');\n}\nfunction getPseudoElementStyle(className, pseudo, style, options) {\n const selector = `.${className}:${pseudo}`;\n const cssText = style.cssText\n ? formatCSSText(style)\n : formatCSSProperties(style, options);\n return document.createTextNode(`${selector}{${cssText}}`);\n}\nfunction clonePseudoElement(nativeNode, clonedNode, pseudo, options) {\n const style = window.getComputedStyle(nativeNode, pseudo);\n const content = style.getPropertyValue('content');\n if (content === '' || content === 'none') {\n return;\n }\n const className = uuid();\n try {\n clonedNode.className = `${clonedNode.className} ${className}`;\n }\n catch (err) {\n return;\n }\n const styleElement = document.createElement('style');\n styleElement.appendChild(getPseudoElementStyle(className, pseudo, style, options));\n clonedNode.appendChild(styleElement);\n}\nexport function clonePseudoElements(nativeNode, clonedNode, options) {\n clonePseudoElement(nativeNode, clonedNode, ':before', options);\n clonePseudoElement(nativeNode, clonedNode, ':after', options);\n}\n//# sourceMappingURL=clone-pseudos.js.map","const WOFF = 'application/font-woff';\nconst JPEG = 'image/jpeg';\nconst mimes = {\n woff: WOFF,\n woff2: WOFF,\n ttf: 'application/font-truetype',\n eot: 'application/vnd.ms-fontobject',\n png: 'image/png',\n jpg: JPEG,\n jpeg: JPEG,\n gif: 'image/gif',\n tiff: 'image/tiff',\n svg: 'image/svg+xml',\n webp: 'image/webp',\n};\nfunction getExtension(url) {\n const match = /\\.([^./]*?)$/g.exec(url);\n return match ? match[1] : '';\n}\nexport function getMimeType(url) {\n const extension = getExtension(url).toLowerCase();\n return mimes[extension] || '';\n}\n//# sourceMappingURL=mimes.js.map","function getContentFromDataUrl(dataURL) {\n return dataURL.split(/,/)[1];\n}\nexport function isDataUrl(url) {\n return url.search(/^(data:)/) !== -1;\n}\nexport function makeDataUrl(content, mimeType) {\n return `data:${mimeType};base64,${content}`;\n}\nexport async function fetchAsDataURL(url, init, process) {\n const res = await fetch(url, init);\n if (res.status === 404) {\n throw new Error(`Resource \"${res.url}\" not found`);\n }\n const blob = await res.blob();\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = () => {\n try {\n resolve(process({ res, result: reader.result }));\n }\n catch (error) {\n reject(error);\n }\n };\n reader.readAsDataURL(blob);\n });\n}\nconst cache = {};\nfunction getCacheKey(url, contentType, includeQueryParams) {\n let key = url.replace(/\\?.*/, '');\n if (includeQueryParams) {\n key = url;\n }\n // font resource\n if (/ttf|otf|eot|woff2?/i.test(key)) {\n key = key.replace(/.*\\//, '');\n }\n return contentType ? `[${contentType}]${key}` : key;\n}\nexport async function resourceToDataURL(resourceUrl, contentType, options) {\n const cacheKey = getCacheKey(resourceUrl, contentType, options.includeQueryParams);\n if (cache[cacheKey] != null) {\n return cache[cacheKey];\n }\n // ref: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache\n if (options.cacheBust) {\n // eslint-disable-next-line no-param-reassign\n resourceUrl += (/\\?/.test(resourceUrl) ? '&' : '?') + new Date().getTime();\n }\n let dataURL;\n try {\n const content = await fetchAsDataURL(resourceUrl, options.fetchRequestInit, ({ res, result }) => {\n if (!contentType) {\n // eslint-disable-next-line no-param-reassign\n contentType = res.headers.get('Content-Type') || '';\n }\n return getContentFromDataUrl(result);\n });\n dataURL = makeDataUrl(content, contentType);\n }\n catch (error) {\n dataURL = options.imagePlaceholder || '';\n let msg = `Failed to fetch resource: ${resourceUrl}`;\n if (error) {\n msg = typeof error === 'string' ? error : error.message;\n }\n if (msg) {\n console.warn(msg);\n }\n }\n cache[cacheKey] = dataURL;\n return dataURL;\n}\n//# sourceMappingURL=dataurl.js.map","import { clonePseudoElements } from './clone-pseudos';\nimport { createImage, toArray, isInstanceOfElement, getStyleProperties, } from './util';\nimport { getMimeType } from './mimes';\nimport { resourceToDataURL } from './dataurl';\nasync function cloneCanvasElement(canvas) {\n const dataURL = canvas.toDataURL();\n if (dataURL === 'data:,') {\n return canvas.cloneNode(false);\n }\n return createImage(dataURL);\n}\nasync function cloneVideoElement(video, options) {\n if (video.currentSrc) {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n canvas.width = video.clientWidth;\n canvas.height = video.clientHeight;\n ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(video, 0, 0, canvas.width, canvas.height);\n const dataURL = canvas.toDataURL();\n return createImage(dataURL);\n }\n const poster = video.poster;\n const contentType = getMimeType(poster);\n const dataURL = await resourceToDataURL(poster, contentType, options);\n return createImage(dataURL);\n}\nasync function cloneIFrameElement(iframe, options) {\n var _a;\n try {\n if ((_a = iframe === null || iframe === void 0 ? void 0 : iframe.contentDocument) === null || _a === void 0 ? void 0 : _a.body) {\n return (await cloneNode(iframe.contentDocument.body, options, true));\n }\n }\n catch (_b) {\n // Failed to clone iframe\n }\n return iframe.cloneNode(false);\n}\nasync function cloneSingleNode(node, options) {\n if (isInstanceOfElement(node, HTMLCanvasElement)) {\n return cloneCanvasElement(node);\n }\n if (isInstanceOfElement(node, HTMLVideoElement)) {\n return cloneVideoElement(node, options);\n }\n if (isInstanceOfElement(node, HTMLIFrameElement)) {\n return cloneIFrameElement(node, options);\n }\n return node.cloneNode(isSVGElement(node));\n}\nconst isSlotElement = (node) => node.tagName != null && node.tagName.toUpperCase() === 'SLOT';\nconst isSVGElement = (node) => node.tagName != null && node.tagName.toUpperCase() === 'SVG';\nasync function cloneChildren(nativeNode, clonedNode, options) {\n var _a, _b;\n if (isSVGElement(clonedNode)) {\n return clonedNode;\n }\n let children = [];\n if (isSlotElement(nativeNode) && nativeNode.assignedNodes) {\n children = toArray(nativeNode.assignedNodes());\n }\n else if (isInstanceOfElement(nativeNode, HTMLIFrameElement) &&\n ((_a = nativeNode.contentDocument) === null || _a === void 0 ? void 0 : _a.body)) {\n children = toArray(nativeNode.contentDocument.body.childNodes);\n }\n else {\n children = toArray(((_b = nativeNode.shadowRoot) !== null && _b !== void 0 ? _b : nativeNode).childNodes);\n }\n if (children.length === 0 ||\n isInstanceOfElement(nativeNode, HTMLVideoElement)) {\n return clonedNode;\n }\n await children.reduce((deferred, child) => deferred\n .then(() => cloneNode(child, options))\n .then((clonedChild) => {\n if (clonedChild) {\n clonedNode.appendChild(clonedChild);\n }\n }), Promise.resolve());\n return clonedNode;\n}\nfunction cloneCSSStyle(nativeNode, clonedNode, options) {\n const targetStyle = clonedNode.style;\n if (!targetStyle) {\n return;\n }\n const sourceStyle = window.getComputedStyle(nativeNode);\n if (sourceStyle.cssText) {\n targetStyle.cssText = sourceStyle.cssText;\n targetStyle.transformOrigin = sourceStyle.transformOrigin;\n }\n else {\n getStyleProperties(options).forEach((name) => {\n let value = sourceStyle.getPropertyValue(name);\n if (name === 'font-size' && value.endsWith('px')) {\n const reducedFont = Math.floor(parseFloat(value.substring(0, value.length - 2))) - 0.1;\n value = `${reducedFont}px`;\n }\n if (isInstanceOfElement(nativeNode, HTMLIFrameElement) &&\n name === 'display' &&\n value === 'inline') {\n value = 'block';\n }\n if (name === 'd' && clonedNode.getAttribute('d')) {\n value = `path(${clonedNode.getAttribute('d')})`;\n }\n targetStyle.setProperty(name, value, sourceStyle.getPropertyPriority(name));\n });\n }\n}\nfunction cloneInputValue(nativeNode, clonedNode) {\n if (isInstanceOfElement(nativeNode, HTMLTextAreaElement)) {\n clonedNode.innerHTML = nativeNode.value;\n }\n if (isInstanceOfElement(nativeNode, HTMLInputElement)) {\n clonedNode.setAttribute('value', nativeNode.value);\n }\n}\nfunction cloneSelectValue(nativeNode, clonedNode) {\n if (isInstanceOfElement(nativeNode, HTMLSelectElement)) {\n const clonedSelect = clonedNode;\n const selectedOption = Array.from(clonedSelect.children).find((child) => nativeNode.value === child.getAttribute('value'));\n if (selectedOption) {\n selectedOption.setAttribute('selected', '');\n }\n }\n}\nfunction decorate(nativeNode, clonedNode, options) {\n if (isInstanceOfElement(clonedNode, Element)) {\n cloneCSSStyle(nativeNode, clonedNode, options);\n clonePseudoElements(nativeNode, clonedNode, options);\n cloneInputValue(nativeNode, clonedNode);\n cloneSelectValue(nativeNode, clonedNode);\n }\n return clonedNode;\n}\nasync function ensureSVGSymbols(clone, options) {\n const uses = clone.querySelectorAll ? clone.querySelectorAll('use') : [];\n if (uses.length === 0) {\n return clone;\n }\n const processedDefs = {};\n for (let i = 0; i < uses.length; i++) {\n const use = uses[i];\n const id = use.getAttribute('xlink:href');\n if (id) {\n const exist = clone.querySelector(id);\n const definition = document.querySelector(id);\n if (!exist && definition && !processedDefs[id]) {\n // eslint-disable-next-line no-await-in-loop\n processedDefs[id] = (await cloneNode(definition, options, true));\n }\n }\n }\n const nodes = Object.values(processedDefs);\n if (nodes.length) {\n const ns = 'http://www.w3.org/1999/xhtml';\n const svg = document.createElementNS(ns, 'svg');\n svg.setAttribute('xmlns', ns);\n svg.style.position = 'absolute';\n svg.style.width = '0';\n svg.style.height = '0';\n svg.style.overflow = 'hidden';\n svg.style.display = 'none';\n const defs = document.createElementNS(ns, 'defs');\n svg.appendChild(defs);\n for (let i = 0; i < nodes.length; i++) {\n defs.appendChild(nodes[i]);\n }\n clone.appendChild(svg);\n }\n return clone;\n}\nexport async function cloneNode(node, options, isRoot) {\n if (!isRoot && options.filter && !options.filter(node)) {\n return null;\n }\n return Promise.resolve(node)\n .then((clonedNode) => cloneSingleNode(clonedNode, options))\n .then((clonedNode) => cloneChildren(node, clonedNode, options))\n .then((clonedNode) => decorate(node, clonedNode, options))\n .then((clonedNode) => ensureSVGSymbols(clonedNode, options));\n}\n//# sourceMappingURL=clone-node.js.map","import { resolveUrl } from './util';\nimport { getMimeType } from './mimes';\nimport { isDataUrl, makeDataUrl, resourceToDataURL } from './dataurl';\nconst URL_REGEX = /url\\((['\"]?)([^'\"]+?)\\1\\)/g;\nconst URL_WITH_FORMAT_REGEX = /url\\([^)]+\\)\\s*format\\(([\"']?)([^\"']+)\\1\\)/g;\nconst FONT_SRC_REGEX = /src:\\s*(?:url\\([^)]+\\)\\s*format\\([^)]+\\)[,;]\\s*)+/g;\nfunction toRegex(url) {\n // eslint-disable-next-line no-useless-escape\n const escaped = url.replace(/([.*+?^${}()|\\[\\]\\/\\\\])/g, '\\\\$1');\n return new RegExp(`(url\\\\(['\"]?)(${escaped})(['\"]?\\\\))`, 'g');\n}\nexport function parseURLs(cssText) {\n const urls = [];\n cssText.replace(URL_REGEX, (raw, quotation, url) => {\n urls.push(url);\n return raw;\n });\n return urls.filter((url) => !isDataUrl(url));\n}\nexport async function embed(cssText, resourceURL, baseURL, options, getContentFromUrl) {\n try {\n const resolvedURL = baseURL ? resolveUrl(resourceURL, baseURL) : resourceURL;\n const contentType = getMimeType(resourceURL);\n let dataURL;\n if (getContentFromUrl) {\n const content = await getContentFromUrl(resolvedURL);\n dataURL = makeDataUrl(content, contentType);\n }\n else {\n dataURL = await resourceToDataURL(resolvedURL, contentType, options);\n }\n return cssText.replace(toRegex(resourceURL), `$1${dataURL}$3`);\n }\n catch (error) {\n // pass\n }\n return cssText;\n}\nfunction filterPreferredFontFormat(str, { preferredFontFormat }) {\n return !preferredFontFormat\n ? str\n : str.replace(FONT_SRC_REGEX, (match) => {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const [src, , format] = URL_WITH_FORMAT_REGEX.exec(match) || [];\n if (!format) {\n return '';\n }\n if (format === preferredFontFormat) {\n return `src: ${src};`;\n }\n }\n });\n}\nexport function shouldEmbed(url) {\n return url.search(URL_REGEX) !== -1;\n}\nexport async function embedResources(cssText, baseUrl, options) {\n if (!shouldEmbed(cssText)) {\n return cssText;\n }\n const filteredCSSText = filterPreferredFontFormat(cssText, options);\n const urls = parseURLs(filteredCSSText);\n return urls.reduce((deferred, url) => deferred.then((css) => embed(css, url, baseUrl, options)), Promise.resolve(filteredCSSText));\n}\n//# sourceMappingURL=embed-resources.js.map","import { embedResources } from './embed-resources';\nimport { toArray, isInstanceOfElement } from './util';\nimport { isDataUrl, resourceToDataURL } from './dataurl';\nimport { getMimeType } from './mimes';\nasync function embedProp(propName, node, options) {\n var _a;\n const propValue = (_a = node.style) === null || _a === void 0 ? void 0 : _a.getPropertyValue(propName);\n if (propValue) {\n const cssString = await embedResources(propValue, null, options);\n node.style.setProperty(propName, cssString, node.style.getPropertyPriority(propName));\n return true;\n }\n return false;\n}\nasync function embedBackground(clonedNode, options) {\n ;\n (await embedProp('background', clonedNode, options)) ||\n (await embedProp('background-image', clonedNode, options));\n (await embedProp('mask', clonedNode, options)) ||\n (await embedProp('-webkit-mask', clonedNode, options)) ||\n (await embedProp('mask-image', clonedNode, options)) ||\n (await embedProp('-webkit-mask-image', clonedNode, options));\n}\nasync function embedImageNode(clonedNode, options) {\n const isImageElement = isInstanceOfElement(clonedNode, HTMLImageElement);\n if (!(isImageElement && !isDataUrl(clonedNode.src)) &&\n !(isInstanceOfElement(clonedNode, SVGImageElement) &&\n !isDataUrl(clonedNode.href.baseVal))) {\n return;\n }\n const url = isImageElement ? clonedNode.src : clonedNode.href.baseVal;\n const dataURL = await resourceToDataURL(url, getMimeType(url), options);\n await new Promise((resolve, reject) => {\n clonedNode.onload = resolve;\n clonedNode.onerror = options.onImageErrorHandler\n ? (...attributes) => {\n try {\n resolve(options.onImageErrorHandler(...attributes));\n }\n catch (error) {\n reject(error);\n }\n }\n : reject;\n const image = clonedNode;\n if (image.decode) {\n image.decode = resolve;\n }\n if (image.loading === 'lazy') {\n image.loading = 'eager';\n }\n if (isImageElement) {\n clonedNode.srcset = '';\n clonedNode.src = dataURL;\n }\n else {\n clonedNode.href.baseVal = dataURL;\n }\n });\n}\nasync function embedChildren(clonedNode, options) {\n const children = toArray(clonedNode.childNodes);\n const deferreds = children.map((child) => embedImages(child, options));\n await Promise.all(deferreds).then(() => clonedNode);\n}\nexport async function embedImages(clonedNode, options) {\n if (isInstanceOfElement(clonedNode, Element)) {\n await embedBackground(clonedNode, options);\n await embedImageNode(clonedNode, options);\n await embedChildren(clonedNode, options);\n }\n}\n//# sourceMappingURL=embed-images.js.map","export function applyStyle(node, options) {\n const { style } = node;\n if (options.backgroundColor) {\n style.backgroundColor = options.backgroundColor;\n }\n if (options.width) {\n style.width = `${options.width}px`;\n }\n if (options.height) {\n style.height = `${options.height}px`;\n }\n const manual = options.style;\n if (manual != null) {\n Object.keys(manual).forEach((key) => {\n style[key] = manual[key];\n });\n }\n return node;\n}\n//# sourceMappingURL=apply-style.js.map","import { toArray } from './util';\nimport { fetchAsDataURL } from './dataurl';\nimport { shouldEmbed, embedResources } from './embed-resources';\nconst cssFetchCache = {};\nasync function fetchCSS(url) {\n let cache = cssFetchCache[url];\n if (cache != null) {\n return cache;\n }\n const res = await fetch(url);\n const cssText = await res.text();\n cache = { url, cssText };\n cssFetchCache[url] = cache;\n return cache;\n}\nasync function embedFonts(data, options) {\n let cssText = data.cssText;\n const regexUrl = /url\\([\"']?([^\"')]+)[\"']?\\)/g;\n const fontLocs = cssText.match(/url\\([^)]+\\)/g) || [];\n const loadFonts = fontLocs.map(async (loc) => {\n let url = loc.replace(regexUrl, '$1');\n if (!url.startsWith('https://')) {\n url = new URL(url, data.url).href;\n }\n return fetchAsDataURL(url, options.fetchRequestInit, ({ result }) => {\n cssText = cssText.replace(loc, `url(${result})`);\n return [loc, result];\n });\n });\n return Promise.all(loadFonts).then(() => cssText);\n}\nfunction parseCSS(source) {\n if (source == null) {\n return [];\n }\n const result = [];\n const commentsRegex = /(\\/\\*[\\s\\S]*?\\*\\/)/gi;\n // strip out comments\n let cssText = source.replace(commentsRegex, '');\n // eslint-disable-next-line prefer-regex-literals\n const keyframesRegex = new RegExp('((@.*?keyframes [\\\\s\\\\S]*?){([\\\\s\\\\S]*?}\\\\s*?)})', 'gi');\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const matches = keyframesRegex.exec(cssText);\n if (matches === null) {\n break;\n }\n result.push(matches[0]);\n }\n cssText = cssText.replace(keyframesRegex, '');\n const importRegex = /@import[\\s\\S]*?url\\([^)]*\\)[\\s\\S]*?;/gi;\n // to match css & media queries together\n const combinedCSSRegex = '((\\\\s*?(?:\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)?\\\\s*?@media[\\\\s\\\\S]' +\n '*?){([\\\\s\\\\S]*?)}\\\\s*?})|(([\\\\s\\\\S]*?){([\\\\s\\\\S]*?)})';\n // unified regex\n const unifiedRegex = new RegExp(combinedCSSRegex, 'gi');\n // eslint-disable-next-line no-constant-condition\n while (true) {\n let matches = importRegex.exec(cssText);\n if (matches === null) {\n matches = unifiedRegex.exec(cssText);\n if (matches === null) {\n break;\n }\n else {\n importRegex.lastIndex = unifiedRegex.lastIndex;\n }\n }\n else {\n unifiedRegex.lastIndex = importRegex.lastIndex;\n }\n result.push(matches[0]);\n }\n return result;\n}\nasync function getCSSRules(styleSheets, options) {\n const ret = [];\n const deferreds = [];\n // First loop inlines imports\n styleSheets.forEach((sheet) => {\n if ('cssRules' in sheet) {\n try {\n toArray(sheet.cssRules || []).forEach((item, index) => {\n if (item.type === CSSRule.IMPORT_RULE) {\n let importIndex = index + 1;\n const url = item.href;\n const deferred = fetchCSS(url)\n .then((metadata) => embedFonts(metadata, options))\n .then((cssText) => parseCSS(cssText).forEach((rule) => {\n try {\n sheet.insertRule(rule, rule.startsWith('@import')\n ? (importIndex += 1)\n : sheet.cssRules.length);\n }\n catch (error) {\n console.error('Error inserting rule from remote css', {\n rule,\n error,\n });\n }\n }))\n .catch((e) => {\n console.error('Error loading remote css', e.toString());\n });\n deferreds.push(deferred);\n }\n });\n }\n catch (e) {\n const inline = styleSheets.find((a) => a.href == null) || document.styleSheets[0];\n if (sheet.href != null) {\n deferreds.push(fetchCSS(sheet.href)\n .then((metadata) => embedFonts(metadata, options))\n .then((cssText) => parseCSS(cssText).forEach((rule) => {\n inline.insertRule(rule, inline.cssRules.length);\n }))\n .catch((err) => {\n console.error('Error loading remote stylesheet', err);\n }));\n }\n console.error('Error inlining remote css file', e);\n }\n }\n });\n return Promise.all(deferreds).then(() => {\n // Second loop parses rules\n styleSheets.forEach((sheet) => {\n if ('cssRules' in sheet) {\n try {\n toArray(sheet.cssRules || []).forEach((item) => {\n ret.push(item);\n });\n }\n catch (e) {\n console.error(`Error while reading CSS rules from ${sheet.href}`, e);\n }\n }\n });\n return ret;\n });\n}\nfunction getWebFontRules(cssRules) {\n return cssRules\n .filter((rule) => rule.type === CSSRule.FONT_FACE_RULE)\n .filter((rule) => shouldEmbed(rule.style.getPropertyValue('src')));\n}\nasync function parseWebFontRules(node, options) {\n if (node.ownerDocument == null) {\n throw new Error('Provided element is not within a Document');\n }\n const styleSheets = toArray(node.ownerDocument.styleSheets);\n const cssRules = await getCSSRules(styleSheets, options);\n return getWebFontRules(cssRules);\n}\nfunction normalizeFontFamily(font) {\n return font.trim().replace(/[\"']/g, '');\n}\nfunction getUsedFonts(node) {\n const fonts = new Set();\n function traverse(node) {\n const fontFamily = node.style.fontFamily || getComputedStyle(node).fontFamily;\n fontFamily.split(',').forEach((font) => {\n fonts.add(normalizeFontFamily(font));\n });\n Array.from(node.children).forEach((child) => {\n if (child instanceof HTMLElement) {\n traverse(child);\n }\n });\n }\n traverse(node);\n return fonts;\n}\nexport async function getWebFontCSS(node, options) {\n const rules = await parseWebFontRules(node, options);\n const usedFonts = getUsedFonts(node);\n const cssTexts = await Promise.all(rules\n .filter((rule) => usedFonts.has(normalizeFontFamily(rule.style.fontFamily)))\n .map((rule) => {\n const baseUrl = rule.parentStyleSheet\n ? rule.parentStyleSheet.href\n : null;\n return embedResources(rule.cssText, baseUrl, options);\n }));\n return cssTexts.join('\\n');\n}\nexport async function embedWebFonts(clonedNode, options) {\n const cssText = options.fontEmbedCSS != null\n ? options.fontEmbedCSS\n : options.skipFonts\n ? null\n : await getWebFontCSS(clonedNode, options);\n if (cssText) {\n const styleNode = document.createElement('style');\n const sytleContent = document.createTextNode(cssText);\n styleNode.appendChild(sytleContent);\n if (clonedNode.firstChild) {\n clonedNode.insertBefore(styleNode, clonedNode.firstChild);\n }\n else {\n clonedNode.appendChild(styleNode);\n }\n }\n}\n//# sourceMappingURL=embed-webfonts.js.map","import { cloneNode } from './clone-node';\nimport { embedImages } from './embed-images';\nimport { applyStyle } from './apply-style';\nimport { embedWebFonts, getWebFontCSS } from './embed-webfonts';\nimport { getImageSize, getPixelRatio, createImage, canvasToBlob, nodeToDataURL, checkCanvasDimensions, } from './util';\nexport async function toSvg(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const clonedNode = (await cloneNode(node, options, true));\n await embedWebFonts(clonedNode, options);\n await embedImages(clonedNode, options);\n applyStyle(clonedNode, options);\n const datauri = await nodeToDataURL(clonedNode, width, height);\n return datauri;\n}\nexport async function toCanvas(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const svg = await toSvg(node, options);\n const img = await createImage(svg);\n const canvas = document.createElement('canvas');\n const context = canvas.getContext('2d');\n const ratio = options.pixelRatio || getPixelRatio();\n const canvasWidth = options.canvasWidth || width;\n const canvasHeight = options.canvasHeight || height;\n canvas.width = canvasWidth * ratio;\n canvas.height = canvasHeight * ratio;\n if (!options.skipAutoScale) {\n checkCanvasDimensions(canvas);\n }\n canvas.style.width = `${canvasWidth}`;\n canvas.style.height = `${canvasHeight}`;\n if (options.backgroundColor) {\n context.fillStyle = options.backgroundColor;\n context.fillRect(0, 0, canvas.width, canvas.height);\n }\n context.drawImage(img, 0, 0, canvas.width, canvas.height);\n return canvas;\n}\nexport async function toPixelData(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const canvas = await toCanvas(node, options);\n const ctx = canvas.getContext('2d');\n return ctx.getImageData(0, 0, width, height).data;\n}\nexport async function toPng(node, options = {}) {\n const canvas = await toCanvas(node, options);\n return canvas.toDataURL();\n}\nexport async function toJpeg(node, options = {}) {\n const canvas = await toCanvas(node, options);\n return canvas.toDataURL('image/jpeg', options.quality || 1);\n}\nexport async function toBlob(node, options = {}) {\n const canvas = await toCanvas(node, options);\n const blob = await canvasToBlob(canvas);\n return blob;\n}\nexport async function getFontEmbedCSS(node, options = {}) {\n return getWebFontCSS(node, options);\n}\n//# sourceMappingURL=index.js.map","import { toPng } from 'html-to-image'\nimport type { Annotation } from '../types'\n\nexport async function captureScreenshot(annotations: Annotation[] = []): Promise<Blob | null> {\n const annotationLayer = mountCaptureAnnotations(annotations)\n\n try {\n const dataUrl = await toPng(document.body, {\n cacheBust: true,\n skipAutoScale: false,\n filter: (node) => {\n if (node instanceof HTMLElement && node.id === 'mtb-widget-host') return false\n return true\n },\n })\n return dataUrlToBlob(dataUrl)\n } catch {\n return null\n } finally {\n annotationLayer?.remove()\n }\n}\n\nfunction mountCaptureAnnotations(annotations: Annotation[]): HTMLDivElement | null {\n if (annotations.length === 0) return null\n\n const layer = document.createElement('div')\n layer.setAttribute('data-mtb-capture-annotations', 'true')\n layer.setAttribute('aria-hidden', 'true')\n layer.style.cssText = 'position:fixed;inset:0;pointer-events:none;z-index:2147483645;'\n\n for (const [index, annotation] of annotations.entries()) {\n if (annotation.type === 'pin') {\n layer.appendChild(buildCapturePin(annotation, index + 1))\n } else if (annotation.type === 'draw' && annotation.drawPath) {\n layer.appendChild(buildCaptureDraw(annotation.drawPath))\n }\n }\n\n document.body.appendChild(layer)\n return layer\n}\n\nfunction buildCapturePin(annotation: Annotation, index: number): HTMLDivElement {\n const pin = document.createElement('div')\n pin.textContent = String(index)\n pin.style.cssText = [\n 'position:fixed',\n `left:${annotation.x}px`,\n `top:${annotation.y}px`,\n 'width:22px',\n 'height:22px',\n 'border-radius:50% 50% 50% 2px',\n 'background:#059669',\n 'border:2px solid #fff',\n 'display:flex',\n 'align-items:center',\n 'justify-content:center',\n 'font:700 10px -apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif',\n 'color:#fff',\n 'box-shadow:0 2px 8px rgba(5,150,105,0.45)',\n 'transform:translate(-50%,-50%)',\n ].join(';')\n return pin\n}\n\nfunction buildCaptureDraw(drawPath: string): SVGSVGElement {\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('width', '100%')\n svg.setAttribute('height', '100%')\n svg.setAttribute('viewBox', `0 0 ${window.innerWidth} ${window.innerHeight}`)\n svg.style.cssText = 'position:fixed;inset:0;width:100%;height:100%;overflow:visible;'\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('d', drawPath)\n path.setAttribute('fill', 'none')\n path.setAttribute('stroke', '#059669')\n path.setAttribute('stroke-width', '3.5')\n path.setAttribute('stroke-linecap', 'round')\n path.setAttribute('stroke-linejoin', 'round')\n path.setAttribute('filter', 'drop-shadow(0 1px 2px rgba(5,150,105,0.35))')\n svg.appendChild(path)\n\n return svg\n}\n\nfunction dataUrlToBlob(dataUrl: string): Blob {\n const [header, data] = dataUrl.split(',')\n const mime = header.match(/:(.*?);/)?.[1] ?? 'image/png'\n const binary = atob(data)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return new Blob([bytes], { type: mime })\n}\n","export interface ErrorSourceEvent {\n message: string\n source?: string\n line?: number\n col?: number\n error?: unknown\n}\n\ntype ErrorListener = (event: ErrorSourceEvent) => void\n\nclass ErrorSource {\n private listeners = new Set<ErrorListener>()\n private originalOnError: OnErrorEventHandler | null = null\n private installedOnError: OnErrorEventHandler | null = null\n private rejectionHandler: ((e: PromiseRejectionEvent) => void) | null = null\n private hooked = false\n\n subscribe(listener: ErrorListener): () => void {\n this.listeners.add(listener)\n this.hook()\n return () => {\n this.listeners.delete(listener)\n if (this.listeners.size === 0) this.unhook()\n }\n }\n\n private hook(): void {\n if (this.hooked) return\n this.hooked = true\n\n this.originalOnError = window.onerror\n this.installedOnError = (msg, source, line, col, error) => {\n this.emit({ message: String(msg), source, line, col, error })\n if (this.originalOnError) {\n return this.originalOnError.call(window, msg, source, line, col, error)\n }\n return false\n }\n window.onerror = this.installedOnError\n\n this.rejectionHandler = (e: PromiseRejectionEvent) => {\n const reason = e.reason instanceof Error ? e.reason.message : String(e.reason)\n this.emit({ message: `Unhandled rejection: ${reason}` })\n }\n window.addEventListener('unhandledrejection', this.rejectionHandler)\n }\n\n private unhook(): void {\n if (!this.hooked) return\n this.hooked = false\n // Only restore if nothing replaced our handler meanwhile — restoring\n // the stale snapshot would clobber a handler the page installed later.\n if (window.onerror === this.installedOnError) {\n window.onerror = this.originalOnError\n }\n this.installedOnError = null\n this.originalOnError = null\n if (this.rejectionHandler) {\n window.removeEventListener('unhandledrejection', this.rejectionHandler)\n this.rejectionHandler = null\n }\n }\n\n private emit(event: ErrorSourceEvent): void {\n for (const listener of this.listeners) listener(event)\n }\n}\n\nexport const errorSource = new ErrorSource()\n","import { errorSource, type ErrorSourceEvent } from './error-source'\n\nconst MAX_CONSOLE_ERRORS = 20\n\nexport class ConsoleErrorCollector {\n private errors: string[] = []\n private unsubscribe: (() => void) | null = null\n\n start(): void {\n if (this.unsubscribe) return\n this.unsubscribe = errorSource.subscribe((e) => this.record(e))\n }\n\n private record(e: ErrorSourceEvent): void {\n const location = e.line != null ? ` (${e.line}:${e.col ?? 0})` : ''\n this.addError(`${e.message}${location}`)\n }\n\n private addError(msg: string): void {\n if (this.errors.length >= MAX_CONSOLE_ERRORS) return\n if (!this.errors.includes(msg)) {\n this.errors.push(msg)\n }\n }\n\n getErrors(): string[] {\n return [...this.errors]\n }\n\n stop(): void {\n this.unsubscribe?.()\n this.unsubscribe = null\n }\n}\n","import { errorSource } from './error-source'\n\nexport type FrustrationSignal =\n | 'rage_click'\n | 'dead_click'\n | 'rapid_navigation'\n | 'form_failure'\n | 'error_page'\n | 'dead_click_dom'\n\nexport interface FrustrationEvent {\n signal: FrustrationSignal\n target?: string\n detail?: string\n timestamp: number\n}\n\ninterface ClickRecord {\n target: EventTarget | null\n time: number\n}\n\nconst RAGE_CLICK_THRESHOLD = 3\nconst RAGE_CLICK_WINDOW_MS = 1000\nconst RAPID_NAV_THRESHOLD = 3\nconst RAPID_NAV_WINDOW_MS = 5000\nconst FORM_CHECK_DELAY_MS = 500\nconst DEAD_CLICK_DOM_DELAY_MS = 500\nconst ERROR_PAGE_CHECK_DELAY_MS = 300\n\nconst INTERACTIVE_TAGS = new Set([\n 'A', 'BUTTON', 'INPUT', 'SELECT', 'TEXTAREA', 'LABEL', 'SUMMARY', 'DETAILS',\n])\n\nconst INTERACTIVE_ROLES = new Set([\n 'button', 'link', 'checkbox', 'radio', 'tab', 'menuitem', 'option',\n 'switch', 'textbox', 'combobox', 'listbox', 'slider', 'spinbutton',\n])\n\nconst ERROR_PAGE_PATTERNS = [\n '404', '500', 'not found', 'page not found',\n 'server error', 'internal server error',\n]\n\nexport class FrustrationDetector {\n private clickHistory: ClickRecord[] = []\n private onFrustration: (event: FrustrationEvent) => void\n private boundClickHandler: (e: MouseEvent) => void\n private unsubscribeErrors: (() => void) | null = null\n private active = false\n private errorCount = 0\n private deadClickCount = 0\n private cooldownUntil = 0\n private static readonly COOLDOWN_MS = 60_000\n\n private navTimestamps: number[] = []\n private boundPopstateHandler: (() => void) | null = null\n private originalPushState: History['pushState'] | null = null\n private originalReplaceState: History['replaceState'] | null = null\n private installedPushState: History['pushState'] | null = null\n private installedReplaceState: History['replaceState'] | null = null\n private boundSubmitHandler: ((e: Event) => void) | null = null\n private boundInvalidHandler: ((e: Event) => void) | null = null\n private errorPageUrls = new Set<string>()\n private domObserver: MutationObserver | null = null\n private pendingDomChecks = 0\n private lastMutationAt = -1\n\n constructor(onFrustration: (event: FrustrationEvent) => void) {\n this.onFrustration = onFrustration\n this.boundClickHandler = (e: MouseEvent) => this.handleClick(e)\n }\n\n start(): void {\n if (this.active) return\n this.active = true\n document.addEventListener('click', this.boundClickHandler, true)\n this.unsubscribeErrors = errorSource.subscribe((_e) => {\n this.errorCount++\n })\n\n this.startNavigationTracking()\n this.startFormTracking()\n this.checkErrorPage()\n }\n\n stop(): void {\n if (!this.active) return\n this.active = false\n document.removeEventListener('click', this.boundClickHandler, true)\n this.unsubscribeErrors?.()\n this.unsubscribeErrors = null\n this.clickHistory = []\n\n this.stopNavigationTracking()\n this.stopFormTracking()\n this.errorPageUrls.clear()\n\n this.disconnectDomObserver()\n }\n\n private startNavigationTracking(): void {\n this.boundPopstateHandler = () => this.handleNavigation()\n window.addEventListener('popstate', this.boundPopstateHandler)\n\n this.originalPushState = history.pushState.bind(history)\n this.originalReplaceState = history.replaceState.bind(history)\n const pushOrig = this.originalPushState\n const replaceOrig = this.originalReplaceState\n const onNav = () => this.handleNavigation()\n\n this.installedPushState = function (data: unknown, unused: string, url?: string | URL | null) {\n pushOrig(data, unused, url)\n onNav()\n }\n this.installedReplaceState = function (data: unknown, unused: string, url?: string | URL | null) {\n replaceOrig(data, unused, url)\n onNav()\n }\n history.pushState = this.installedPushState\n history.replaceState = this.installedReplaceState\n }\n\n private stopNavigationTracking(): void {\n if (this.boundPopstateHandler) {\n window.removeEventListener('popstate', this.boundPopstateHandler)\n this.boundPopstateHandler = null\n }\n // Only restore if nothing (e.g. an SPA router) re-wrapped the functions\n // after us — restoring the stale snapshot would discard their wrapper.\n if (this.originalPushState && history.pushState === this.installedPushState) {\n history.pushState = this.originalPushState\n }\n if (this.originalReplaceState && history.replaceState === this.installedReplaceState) {\n history.replaceState = this.originalReplaceState\n }\n this.originalPushState = null\n this.originalReplaceState = null\n this.installedPushState = null\n this.installedReplaceState = null\n this.navTimestamps = []\n }\n\n private startFormTracking(): void {\n this.boundSubmitHandler = (e: Event) => this.handleFormSubmit(e)\n this.boundInvalidHandler = (e: Event) => this.handleFormInvalid(e)\n document.addEventListener('submit', this.boundSubmitHandler, true)\n document.addEventListener('invalid', this.boundInvalidHandler, true)\n }\n\n private stopFormTracking(): void {\n if (this.boundSubmitHandler) {\n document.removeEventListener('submit', this.boundSubmitHandler, true)\n this.boundSubmitHandler = null\n }\n if (this.boundInvalidHandler) {\n document.removeEventListener('invalid', this.boundInvalidHandler, true)\n this.boundInvalidHandler = null\n }\n }\n\n private handleClick(e: MouseEvent): void {\n const target = e.target as Element | null\n if (!target) return\n\n if (this.isWidgetElement(target)) return\n\n const now = Date.now()\n this.clickHistory.push({ target, time: now })\n\n const cutoff = now - RAGE_CLICK_WINDOW_MS\n this.clickHistory = this.clickHistory.filter(r => r.time > cutoff)\n\n const sameTargetClicks = this.clickHistory.filter(r => r.target === target)\n if (sameTargetClicks.length >= RAGE_CLICK_THRESHOLD) {\n this.clickHistory = []\n this.emitHighPriority({\n signal: 'rage_click',\n target: describeElement(target),\n timestamp: now,\n })\n return\n }\n\n if (!this.isInteractive(target)) {\n this.deadClickCount++\n if (this.deadClickCount >= 3 && this.errorCount > 0) {\n this.deadClickCount = 0\n this.errorCount = 0\n this.emitIfReady({\n signal: 'dead_click',\n target: describeElement(target),\n timestamp: now,\n })\n }\n }\n\n this.checkDeadClickDom(target, now)\n }\n\n private handleNavigation(): void {\n const now = Date.now()\n this.navTimestamps.push(now)\n const cutoff = now - RAPID_NAV_WINDOW_MS\n this.navTimestamps = this.navTimestamps.filter(t => t > cutoff)\n if (this.navTimestamps.length >= RAPID_NAV_THRESHOLD) {\n this.navTimestamps = []\n this.emitIfReady({\n signal: 'rapid_navigation',\n timestamp: now,\n })\n }\n setTimeout(() => {\n if (this.active) this.checkErrorPage()\n }, ERROR_PAGE_CHECK_DELAY_MS)\n }\n\n private handleFormSubmit(e: Event): void {\n const form = e.target\n if (!(form instanceof HTMLFormElement)) return\n if (this.isWidgetElement(form)) return\n\n setTimeout(() => {\n if (!this.active) return\n if (form.querySelector('[aria-invalid=\"true\"], .is-invalid')) {\n this.emitIfReady({\n signal: 'form_failure',\n target: describeElement(form),\n timestamp: Date.now(),\n })\n }\n }, FORM_CHECK_DELAY_MS)\n }\n\n private handleFormInvalid(e: Event): void {\n const el = e.target as Element | null\n if (!el) return\n if (this.isWidgetElement(el)) return\n const form = el.closest('form')\n this.emitIfReady({\n signal: 'form_failure',\n target: form ? describeElement(form) : describeElement(el),\n timestamp: Date.now(),\n })\n }\n\n private checkErrorPage(): void {\n const url = location.href\n if (this.errorPageUrls.has(url)) return\n\n const title = document.title.toLowerCase()\n if (ERROR_PAGE_PATTERNS.some(p => title.includes(p))) {\n this.errorPageUrls.add(url)\n this.emitHighPriority({\n signal: 'error_page',\n detail: document.title,\n timestamp: Date.now(),\n })\n return\n }\n\n const candidates = document.querySelectorAll(\n 'h1, h2, [class*=\"error\"], [class*=\"not-found\"], [id*=\"error\"], [id*=\"not-found\"]'\n )\n for (const el of candidates) {\n const text = el.textContent ?? ''\n if (text.length < 200 && ERROR_PAGE_PATTERNS.some(p => text.toLowerCase().includes(p))) {\n this.errorPageUrls.add(url)\n this.emitHighPriority({\n signal: 'error_page',\n detail: text.trim().slice(0, 60),\n timestamp: Date.now(),\n })\n return\n }\n }\n }\n\n // One shared observer for all in-flight dead-click checks, connected only\n // while at least one check is pending — a full-page observer per click was\n // too heavy on mutation-busy pages.\n private checkDeadClickDom(target: Element, clickTime: number): void {\n if (!this.looksInteractive(target)) return\n\n this.pendingDomChecks++\n this.ensureDomObserver()\n\n setTimeout(() => {\n this.pendingDomChecks--\n const mutated = this.lastMutationAt >= clickTime\n if (this.pendingDomChecks === 0) this.disconnectDomObserver()\n\n if (!mutated && this.active) {\n this.emitIfReady({\n signal: 'dead_click_dom',\n target: describeElement(target),\n timestamp: clickTime,\n })\n }\n }, DEAD_CLICK_DOM_DELAY_MS)\n }\n\n private ensureDomObserver(): void {\n if (this.domObserver) return\n this.domObserver = new MutationObserver(() => {\n this.lastMutationAt = Date.now()\n })\n this.domObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n })\n }\n\n private disconnectDomObserver(): void {\n this.domObserver?.disconnect()\n this.domObserver = null\n }\n\n private looksInteractive(el: Element): boolean {\n const style = window.getComputedStyle(el)\n if (style.cursor === 'pointer') return true\n\n if (el.classList) {\n for (const cls of el.classList) {\n const lower = cls.toLowerCase()\n if (lower.includes('btn') || lower.includes('button')) return true\n }\n }\n\n return false\n }\n\n private isInteractive(el: Element): boolean {\n if (INTERACTIVE_TAGS.has(el.tagName)) return true\n\n const role = el.getAttribute('role')\n if (role && INTERACTIVE_ROLES.has(role)) return true\n\n if (el.hasAttribute('onclick') || el.hasAttribute('tabindex')) return true\n if ((el as HTMLElement).contentEditable === 'true') return true\n\n const style = window.getComputedStyle(el)\n if (style.cursor === 'pointer') return true\n\n const parent = el.closest('a, button, [role=\"button\"], [role=\"link\"], label')\n if (parent) return true\n\n return false\n }\n\n private isWidgetElement(el: Element): boolean {\n const host = document.getElementById('mtb-widget-host')\n if (!host) return false\n return host === el || host.contains(el)\n }\n\n private emitIfReady(event: FrustrationEvent): void {\n const now = Date.now()\n if (now < this.cooldownUntil) return\n this.cooldownUntil = now + FrustrationDetector.COOLDOWN_MS\n this.onFrustration(event)\n }\n\n private emitHighPriority(event: FrustrationEvent): void {\n this.cooldownUntil = Date.now() + FrustrationDetector.COOLDOWN_MS\n this.onFrustration(event)\n }\n}\n\nfunction describeElement(el: Element): string {\n const tag = el.tagName.toLowerCase()\n const id = el.id ? `#${el.id}` : ''\n const cls = el.className && typeof el.className === 'string'\n ? '.' + el.className.trim().split(/\\s+/).slice(0, 2).join('.')\n : ''\n const text = el.textContent?.trim().slice(0, 30) ?? ''\n return `<${tag}${id}${cls}>${text ? ` \"${text}\"` : ''}`\n}\n","export interface PageContext {\n page_url: string\n user_agent: string\n browser: string\n os: string\n screen_width: number\n screen_height: number\n}\n\nexport function collectPageContext(): PageContext {\n return {\n page_url: window.location.href,\n user_agent: navigator.userAgent,\n browser: detectBrowser(),\n os: detectOS(),\n screen_width: window.screen.width,\n screen_height: window.screen.height,\n }\n}\n\nfunction detectBrowser(): string {\n const ua = navigator.userAgent\n if (/Edg\\//.test(ua)) return `Edge ${ua.match(/Edg\\/(\\S+)/)?.[1] ?? ''}`\n if (/OPR\\//.test(ua)) return `Opera ${ua.match(/OPR\\/(\\S+)/)?.[1] ?? ''}`\n if (/Chrome\\//.test(ua)) return `Chrome ${ua.match(/Chrome\\/(\\S+)/)?.[1] ?? ''}`\n if (/Safari\\//.test(ua) && /Version\\//.test(ua)) return `Safari ${ua.match(/Version\\/(\\S+)/)?.[1] ?? ''}`\n if (/Firefox\\//.test(ua)) return `Firefox ${ua.match(/Firefox\\/(\\S+)/)?.[1] ?? ''}`\n return 'Unknown'\n}\n\nfunction detectOS(): string {\n const ua = navigator.userAgent\n if (/Windows NT 10/.test(ua)) return 'Windows 10/11'\n if (/Windows NT/.test(ua)) return 'Windows'\n if (/Mac OS X 10_15|macOS 1[56789]/.test(ua)) return 'macOS'\n if (/Mac OS X/.test(ua)) return 'macOS'\n if (/Android/.test(ua)) return `Android ${ua.match(/Android (\\d+)/)?.[1] ?? ''}`\n if (/iPhone|iPad|iPod/.test(ua)) return 'iOS'\n if (/Linux/.test(ua)) return 'Linux'\n return 'Unknown'\n}\n","import type { FeedbackPayload, FeedbackResponse, ClarifyResponse } from '../types'\n\nconst DEFAULT_API_URL = 'https://makethisbetter.dev/api/v1'\n\nexport class ApiClient {\n private apiUrl: string\n private projectKey: string\n private retryDelayMs: number\n private userToken?: string\n private userTokenFn?: () => Promise<string>\n\n constructor(projectKey: string, apiUrl?: string, retryDelayMs = 1000, userToken?: string, userTokenFn?: () => Promise<string>) {\n this.projectKey = projectKey\n this.apiUrl = (apiUrl ?? DEFAULT_API_URL).replace(/\\/$/, '')\n this.retryDelayMs = retryDelayMs\n this.userToken = userToken\n this.userTokenFn = userTokenFn\n }\n\n async resolveUserToken(): Promise<string | undefined> {\n if (this.userTokenFn) return this.userTokenFn()\n return this.userToken\n }\n\n private async authHeaders(contentType?: string): Promise<Record<string, string>> {\n const headers: Record<string, string> = { 'X-Project-Key': this.projectKey }\n const token = await this.resolveUserToken()\n if (token) headers['X-User-Token'] = token\n if (contentType) headers['Content-Type'] = contentType\n return headers\n }\n\n async submitFeedback(payload: FeedbackPayload, screenshot: Blob | null): Promise<FeedbackResponse> {\n const form = new FormData()\n form.append('feedback[description]', payload.description)\n form.append('feedback[page_url]', payload.page_url)\n form.append('feedback[user_agent]', payload.user_agent)\n form.append('feedback[browser]', payload.browser)\n form.append('feedback[os]', payload.os)\n form.append('feedback[screen_width]', String(payload.screen_width))\n form.append('feedback[screen_height]', String(payload.screen_height))\n form.append('feedback[console_errors]', JSON.stringify(payload.console_errors))\n form.append('feedback[annotations]', JSON.stringify(payload.annotations))\n\n if (payload.target_element) {\n form.append('feedback[target_element]', JSON.stringify(payload.target_element))\n }\n if (payload.user_id) form.append('feedback[user_id]', payload.user_id)\n if (payload.user_email) form.append('feedback[user_email]', payload.user_email)\n if (payload.user_name) form.append('feedback[user_name]', payload.user_name)\n\n if (payload.recording_events && payload.recording_events.length > 0) {\n const json = JSON.stringify(payload.recording_events)\n const blob = new Blob([json], { type: 'application/json' })\n form.append('feedback[recording]', blob, 'recording.json')\n form.append('feedback[recording_duration]', String(payload.recording_duration ?? 0))\n }\n\n if (screenshot) {\n form.append('feedback[screenshot]', screenshot, 'screenshot.png')\n }\n\n const headers = await this.authHeaders()\n // One key per submission, reused across retries: if the first POST\n // reached the server but the response was lost, the retry must not\n // create a second feedback.\n headers['X-Idempotency-Key'] = generateIdempotencyKey()\n const res = await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks`, {\n method: 'POST',\n headers,\n body: form,\n })\n return res.json() as Promise<FeedbackResponse>\n }\n\n async startClarification(feedbackId: string, message?: string): Promise<ClarifyResponse> {\n const body: Record<string, string> = {}\n if (message) body.message = message\n const headers = await this.authHeaders('application/json')\n const res = await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks/${feedbackId}/clarify`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n return res.json() as Promise<ClarifyResponse>\n }\n\n async getClarification(feedbackId: string): Promise<ClarifyResponse> {\n const headers = await this.authHeaders()\n const res = await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks/${feedbackId}/clarify`, {\n method: 'GET',\n headers,\n })\n return res.json() as Promise<ClarifyResponse>\n }\n\n private async fetchWithRetry(url: string, init: RequestInit, retries = 1): Promise<Response> {\n let res: Response\n try {\n res = await fetch(url, init)\n } catch (err) {\n if (retries > 0) {\n await delay(this.retryDelayMs)\n return this.fetchWithRetry(url, init, retries - 1)\n }\n throw err\n }\n\n if (res.ok) return res\n if (res.status >= 500 && retries > 0) {\n await delay(this.retryDelayMs)\n return this.fetchWithRetry(url, init, retries - 1)\n }\n throw new Error(`HTTP ${res.status}`)\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n if (ms <= 0) return Promise.resolve()\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nfunction generateIdempotencyKey(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`\n}\n","import type { PageContext } from '../context/collector'\nimport type { Annotation, FeedbackPayload, MakeThisBetterConfig } from '../types'\nimport type { RecordingResult } from '../record/session'\n\nexport function buildPayload(\n description: string,\n pageContext: PageContext,\n consoleErrors: string[],\n annotation: Annotation | null,\n user: MakeThisBetterConfig['user'],\n recording?: RecordingResult,\n): FeedbackPayload {\n return {\n description,\n ...pageContext,\n console_errors: consoleErrors,\n annotations: annotation ? [annotation] : [],\n target_element: annotation?.targetSelector\n ? {\n selector: annotation.targetSelector,\n text: annotation.targetText ?? '',\n name: annotation.targetName ?? '',\n }\n : undefined,\n user_id: user?.id,\n user_email: user?.email,\n user_name: user?.name,\n recording_events: recording?.events,\n recording_duration: recording?.duration,\n }\n}\n","export default {\n tab: 'Feedback',\n toolbar: {\n markup: 'Mark up',\n record: 'Record',\n hint: 'Click any element to annotate · drag to draw',\n hintRecord: 'Recording your screen',\n exit: 'Exit',\n },\n popup: {\n about: 'About',\n placeholder: 'Describe the issue or suggestion...',\n submit: 'Submit',\n cancel: 'Cancel',\n quickOptions: [\n { emoji: '🐛', label: 'Something is broken' },\n { emoji: '💡', label: 'I wish this worked differently' },\n { emoji: '🤔', label: \"I don't understand this\" },\n { emoji: '✨', label: 'I have an idea' },\n ],\n },\n success: {\n title: 'Thanks!',\n message: 'Your feedback has been received.',\n title_no_ai: 'Sent — thanks!',\n message_no_ai: \"We'll take it from here. You'll hear back when it's resolved.\",\n view_feedback: 'View my feedback',\n close: 'Close',\n },\n error: {\n submit: 'Failed to submit. Please try again.',\n },\n pet: {\n bubble: 'Need help?',\n },\n frustration: {\n prompt: 'Something not working? Tell us.',\n action: 'Annotate',\n dismiss: 'Dismiss',\n },\n annotation: {\n drawing: 'Drawing',\n element: 'element',\n },\n record: {\n stop: 'Stop',\n timer_label: 'Recording',\n max_reached: 'Maximum recording time reached',\n },\n clarify: {\n thinking: 'Thinking...',\n placeholder: 'Type your response...',\n send: 'Send',\n skip: 'Skip',\n },\n}\n","export default {\n tab: '反馈',\n toolbar: {\n markup: '标注',\n record: '录屏',\n hint: '点击任意元素进行标注 · 拖拽可自由绘制',\n hintRecord: '正在录制屏幕',\n exit: '退出',\n },\n popup: {\n about: '关于',\n placeholder: '描述问题或建议...',\n submit: '提交',\n cancel: '取消',\n quickOptions: [\n { emoji: '🐛', label: '这里有问题' },\n { emoji: '💡', label: '我希望它能更好用' },\n { emoji: '🤔', label: '我看不懂这里' },\n { emoji: '✨', label: '我有个想法' },\n ],\n },\n success: {\n title: '感谢!',\n message: '您的反馈已收到。',\n title_no_ai: '已发送,感谢!',\n message_no_ai: '我们会跟进处理,解决后会通知您。',\n view_feedback: '查看我的反馈',\n close: '关闭',\n },\n error: {\n submit: '提交失败,请重试。',\n },\n pet: {\n bubble: '需要帮助吗?',\n },\n frustration: {\n prompt: '遇到问题了?告诉我们。',\n action: '标注',\n dismiss: '关闭',\n },\n annotation: {\n drawing: '绘制',\n element: '元素',\n },\n record: {\n stop: '停止',\n timer_label: '录制中',\n max_reached: '已达到最大录制时长',\n },\n clarify: {\n thinking: '思考中...',\n placeholder: '输入你的回复...',\n send: '发送',\n skip: '跳过',\n },\n}\n","export default {\n tab: 'フィードバック',\n toolbar: {\n markup: 'マークアップ',\n record: '録画',\n hint: '要素をクリックして注釈 · ドラッグで描画',\n hintRecord: '画面を録画中',\n exit: '終了',\n },\n popup: {\n about: '概要',\n placeholder: '問題や提案を入力してください...',\n submit: '送信',\n cancel: 'キャンセル',\n quickOptions: [\n { emoji: '🐛', label: '不具合があります' },\n { emoji: '💡', label: 'もっと使いやすくしてほしい' },\n { emoji: '🤔', label: 'ここがわかりにくい' },\n { emoji: '✨', label: 'アイデアがあります' },\n ],\n },\n success: {\n title: 'ありがとうございます!',\n message: 'フィードバックを受け付けました。',\n title_no_ai: '送信しました!',\n message_no_ai: 'チームが対応します。解決次第お知らせします。',\n view_feedback: 'フィードバックを確認',\n close: '閉じる',\n },\n error: {\n submit: '送信に失敗しました。もう一度お試しください。',\n },\n pet: {\n bubble: 'お困りですか?',\n },\n frustration: {\n prompt: 'うまくいかないことがありますか?お知らせください。',\n action: '注釈',\n dismiss: '閉じる',\n },\n annotation: {\n drawing: '描画',\n element: '要素',\n },\n record: {\n stop: '停止',\n timer_label: '録画中',\n max_reached: '最大録画時間に達しました',\n },\n clarify: {\n thinking: '考え中...',\n placeholder: '回答を入力...',\n send: '送信',\n skip: 'スキップ',\n },\n}\n","export default {\n tab: '피드백',\n toolbar: {\n markup: '마크업',\n record: '녹화',\n hint: '요소를 클릭하여 주석 · 드래그하여 그리기',\n hintRecord: '화면을 녹화 중입니다',\n exit: '나가기',\n },\n popup: {\n about: '정보',\n placeholder: '문제 또는 제안 사항을 설명해 주세요...',\n submit: '제출',\n cancel: '취소',\n quickOptions: [\n { emoji: '🐛', label: '오류가 있어요' },\n { emoji: '💡', label: '이 기능을 개선해 주세요' },\n { emoji: '🤔', label: '이 부분을 모르겠어요' },\n { emoji: '✨', label: '아이디어가 있어요' },\n ],\n },\n success: {\n title: '감사합니다!',\n message: '피드백이 접수되었습니다.',\n title_no_ai: '전송 완료!',\n message_no_ai: '팀에서 처리 후 알려드리겠습니다.',\n view_feedback: '내 피드백 보기',\n close: '닫기',\n },\n error: {\n submit: '제출에 실패했습니다. 다시 시도해 주세요.',\n },\n pet: {\n bubble: '도움이 필요하신가요?',\n },\n frustration: {\n prompt: '문제가 있으신가요? 알려 주세요.',\n action: '주석',\n dismiss: '닫기',\n },\n annotation: {\n drawing: '그리기',\n element: '요소',\n },\n record: {\n stop: '중지',\n timer_label: '녹화 중',\n max_reached: '최대 녹화 시간에 도달했습니다',\n },\n clarify: {\n thinking: '생각 중...',\n placeholder: '답변을 입력하세요...',\n send: '보내기',\n skip: '건너뛰기',\n },\n}\n","export default {\n tab: 'Comentarios',\n toolbar: {\n markup: 'Anotar',\n record: 'Grabar',\n hint: 'Haz clic en cualquier elemento para anotar · arrastra para dibujar',\n hintRecord: 'Grabando tu pantalla',\n exit: 'Salir',\n },\n popup: {\n about: 'Acerca de',\n placeholder: 'Describe el problema o sugerencia...',\n submit: 'Enviar',\n cancel: 'Cancelar',\n quickOptions: [\n { emoji: '🐛', label: 'Algo no funciona' },\n { emoji: '💡', label: 'Me gustaría que funcionara diferente' },\n { emoji: '🤔', label: 'No entiendo esto' },\n { emoji: '✨', label: 'Tengo una idea' },\n ],\n },\n success: {\n title: '¡Gracias!',\n message: 'Tu comentario ha sido recibido.',\n title_no_ai: '¡Enviado!',\n message_no_ai: 'Nos encargamos. Te avisaremos cuando se resuelva.',\n view_feedback: 'Ver mis comentarios',\n close: 'Cerrar',\n },\n error: {\n submit: 'Error al enviar. Por favor, inténtalo de nuevo.',\n },\n pet: {\n bubble: '¿Necesitas ayuda?',\n },\n frustration: {\n prompt: '¿Algo no funciona? Cuéntanos.',\n action: 'Anotar',\n dismiss: 'Cerrar',\n },\n annotation: {\n drawing: 'Dibujo',\n element: 'elemento',\n },\n record: {\n stop: 'Detener',\n timer_label: 'Grabando',\n max_reached: 'Se alcanzó el tiempo máximo de grabación',\n },\n clarify: {\n thinking: 'Pensando...',\n placeholder: 'Escribe tu respuesta...',\n send: 'Enviar',\n skip: 'Omitir',\n },\n}\n","export default {\n tab: 'Avis',\n toolbar: {\n markup: 'Annoter',\n record: 'Enregistrer',\n hint: \"Cliquez sur un élément pour l'annoter · glissez pour dessiner\",\n hintRecord: \"Enregistrement de l'écran en cours\",\n exit: 'Quitter',\n },\n popup: {\n about: 'À propos',\n placeholder: 'Décrivez le problème ou votre suggestion...',\n submit: 'Envoyer',\n cancel: 'Annuler',\n quickOptions: [\n { emoji: '🐛', label: 'Quelque chose ne fonctionne pas' },\n { emoji: '💡', label: \"J'aimerais que cela fonctionne autrement\" },\n { emoji: '🤔', label: 'Je ne comprends pas ceci' },\n { emoji: '✨', label: \"J'ai une idée\" },\n ],\n },\n success: {\n title: 'Merci !',\n message: 'Votre avis a bien été reçu.',\n title_no_ai: 'Envoyé !',\n message_no_ai: \"On s'en occupe. Vous serez informé(e) dès que ce sera résolu.\",\n view_feedback: 'Voir mes avis',\n close: 'Fermer',\n },\n error: {\n submit: \"Échec de l'envoi. Veuillez réessayer.\",\n },\n pet: {\n bubble: \"Besoin d'aide ?\",\n },\n frustration: {\n prompt: 'Un problème ? Dites-le-nous.',\n action: 'Annoter',\n dismiss: 'Fermer',\n },\n annotation: {\n drawing: 'Dessin',\n element: 'élément',\n },\n record: {\n stop: 'Arrêter',\n timer_label: 'Enregistrement',\n max_reached: \"Durée maximale d'enregistrement atteinte\",\n },\n clarify: {\n thinking: 'Réflexion...',\n placeholder: 'Tapez votre réponse...',\n send: 'Envoyer',\n skip: 'Passer',\n },\n}\n","export default {\n tab: 'Feedback',\n toolbar: {\n markup: 'Markieren',\n record: 'Aufnehmen',\n hint: 'Klicken Sie auf ein Element zum Kommentieren · ziehen Sie zum Zeichnen',\n hintRecord: 'Bildschirmaufnahme läuft',\n exit: 'Beenden',\n },\n popup: {\n about: 'Info',\n placeholder: 'Beschreiben Sie das Problem oder Ihren Vorschlag...',\n submit: 'Absenden',\n cancel: 'Abbrechen',\n quickOptions: [\n { emoji: '🐛', label: 'Etwas funktioniert nicht' },\n { emoji: '💡', label: 'Ich wünsche mir das anders' },\n { emoji: '🤔', label: 'Das verstehe ich nicht' },\n { emoji: '✨', label: 'Ich habe eine Idee' },\n ],\n },\n success: {\n title: 'Vielen Dank!',\n message: 'Ihr Feedback wurde empfangen.',\n title_no_ai: 'Gesendet!',\n message_no_ai: 'Wir kümmern uns darum. Sie werden benachrichtigt, sobald es gelöst ist.',\n view_feedback: 'Mein Feedback ansehen',\n close: 'Schließen',\n },\n error: {\n submit: 'Senden fehlgeschlagen. Bitte versuchen Sie es erneut.',\n },\n pet: {\n bubble: 'Brauchen Sie Hilfe?',\n },\n frustration: {\n prompt: 'Etwas funktioniert nicht? Sagen Sie es uns.',\n action: 'Kommentieren',\n dismiss: 'Schließen',\n },\n annotation: {\n drawing: 'Zeichnung',\n element: 'Element',\n },\n record: {\n stop: 'Stopp',\n timer_label: 'Aufnahme',\n max_reached: 'Maximale Aufnahmezeit erreicht',\n },\n clarify: {\n thinking: 'Einen Moment...',\n placeholder: 'Antwort eingeben...',\n send: 'Senden',\n skip: 'Überspringen',\n },\n}\n","import en from './en'\nimport zhCN from './zh-CN'\nimport ja from './ja'\nimport ko from './ko'\nimport es from './es'\nimport fr from './fr'\nimport de from './de'\n\nexport type I18nMessages = typeof en\n\nconst locales: Record<string, I18nMessages> = {\n en,\n 'zh-CN': zhCN,\n ja,\n ko,\n es,\n fr,\n de,\n}\n\nexport function getMessages(locale: string): I18nMessages {\n if (locales[locale]) return locales[locale]\n const lang = locale.split('-')[0]\n if (locales[lang]) return locales[lang]\n return locales['en']\n}\n","import type { ShadowContainer } from '../widget/shadow'\n\ntype RRWebEvent = Record<string, unknown>\ntype StopFn = () => void\n\ninterface RRWebRecordFn {\n (options: { emit: (event: RRWebEvent) => void }): StopFn\n addCustomEvent: (tag: string, payload: Record<string, unknown>) => void\n}\n\nexport interface RecordingResult {\n events: RRWebEvent[]\n duration: number\n}\n\nconst MAX_DURATION_S = 60\n// Pinned version + SRI: this script executes on customers' pages, so a\n// floating tag or unverified content would be a supply-chain hole. Bumping\n// the version requires recomputing the hash from the exact CDN file:\n// curl -sL <url> | openssl dgst -sha384 -binary | openssl base64 -A\n// Must stay on @rrweb/record's static /umd/ build: the `rrweb` package ships\n// no UMD in 2.x (its dist files are ESM and throw \"Unexpected token 'export'\"\n// in a classic script tag), and jsDelivr's auto-minified files are unsafe for\n// SRI because their hash changes when jsDelivr upgrades its minifier.\nconst RRWEB_CDN = 'https://cdn.jsdelivr.net/npm/@rrweb/record@2.1.0/umd/record.min.js'\nconst RRWEB_SRI = 'sha384-MrD66HBNSykaP2N95+6hQCFlF5oH2tvL3TD/zyvHNkP/sAFWZx98DX9MEDy8MdVT'\n\nlet rrwebLoaded: Promise<RRWebRecordFn> | null = null\n\nfunction loadRrweb(): Promise<RRWebRecordFn> {\n if (rrwebLoaded) return rrwebLoaded\n rrwebLoaded = loadViaImport().catch(() => loadViaCdn())\n return rrwebLoaded\n}\n\nasync function loadViaImport(): Promise<RRWebRecordFn> {\n const mod = await import('@rrweb/record')\n return mod.record as unknown as RRWebRecordFn\n}\n\ninterface RRWebGlobals {\n rrwebRecord?: { record: RRWebRecordFn }\n rrweb?: { record: RRWebRecordFn }\n}\n\nfunction findGlobalRecord(): RRWebRecordFn | undefined {\n const win = globalThis as unknown as Window & RRWebGlobals\n return win.rrwebRecord?.record ?? win.rrweb?.record\n}\n\nfunction loadViaCdn(): Promise<RRWebRecordFn> {\n return new Promise((resolve, reject) => {\n const existing = findGlobalRecord()\n if (existing) { resolve(existing); return }\n const script = document.createElement('script')\n script.src = RRWEB_CDN\n script.integrity = RRWEB_SRI\n script.crossOrigin = 'anonymous'\n script.onload = () => {\n const record = findGlobalRecord()\n if (record) resolve(record)\n else reject(new Error('rrweb record global not found after script load'))\n }\n script.onerror = () => reject(new Error('Failed to load rrweb from CDN'))\n document.head.appendChild(script)\n })\n}\n\nexport class RecordSession {\n private events: RRWebEvent[] = []\n private stopFn: StopFn | null = null\n private startedAt = 0\n private timer: ReturnType<typeof setTimeout> | null = null\n private clickHandler: ((e: MouseEvent) => void) | null = null\n private shadow: ShadowContainer\n private onMaxReached?: () => void\n private stopped = false\n\n constructor(shadow: ShadowContainer, onMaxReached?: () => void) {\n this.shadow = shadow\n this.onMaxReached = onMaxReached\n }\n\n async start(): Promise<void> {\n const record = await loadRrweb()\n\n this.startedAt = Date.now()\n this.stopped = false\n\n this.stopFn = record({\n emit: (event: RRWebEvent) => {\n if (!this.stopped) this.events.push(event)\n },\n })\n\n this.clickHandler = (e: MouseEvent) => {\n this.showClickRipple(e.clientX, e.clientY)\n record.addCustomEvent?.('mtb-click', {\n x: e.clientX,\n y: e.clientY,\n target: e.target instanceof HTMLElement ? e.target.tagName : '',\n })\n }\n document.addEventListener('click', this.clickHandler, true)\n\n this.timer = setTimeout(() => {\n this.onMaxReached?.()\n }, MAX_DURATION_S * 1000)\n }\n\n stop(): RecordingResult {\n this.stopped = true\n this.stopFn?.()\n this.stopFn = null\n this.cleanupTimer()\n this.cleanupClickHandler()\n\n return {\n events: this.events,\n duration: this.getDuration(),\n }\n }\n\n getDuration(): number {\n if (this.startedAt === 0) return 0\n return Math.round((Date.now() - this.startedAt) / 1000)\n }\n\n destroy(): void {\n this.stopped = true\n this.stopFn?.()\n this.stopFn = null\n this.cleanupTimer()\n this.cleanupClickHandler()\n this.events = []\n this.startedAt = 0\n }\n\n private cleanupTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer)\n this.timer = null\n }\n }\n\n private cleanupClickHandler(): void {\n if (this.clickHandler) {\n document.removeEventListener('click', this.clickHandler, true)\n this.clickHandler = null\n }\n }\n\n private showClickRipple(x: number, y: number): void {\n const ripple = this.shadow.el<HTMLDivElement>('div', 'mtb-click-ripple')\n ripple.style.left = `${x}px`\n ripple.style.top = `${y}px`\n this.shadow.append(ripple)\n ripple.addEventListener('animationend', () => ripple.remove())\n }\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\n\nexport class RecordControlBar {\n private el: HTMLDivElement\n private timerEl!: HTMLSpanElement\n private intervalId: ReturnType<typeof setInterval> | null = null\n private getDuration: () => number\n\n constructor(\n shadow: ShadowContainer,\n messages: I18nMessages,\n getDuration: () => number,\n onStop: () => void,\n ) {\n this.getDuration = getDuration\n\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-record-bar')\n this.el.innerHTML = `\n <span class=\"mtb-record-dot\"></span>\n <span class=\"mtb-record-timer\">00:00</span>\n <button class=\"mtb-record-stop\" type=\"button\">${messages.record.stop}</button>\n `\n shadow.append(this.el)\n\n this.timerEl = this.el.querySelector('.mtb-record-timer')!\n this.el.querySelector('.mtb-record-stop')!.addEventListener('click', onStop)\n\n this.intervalId = setInterval(() => this.updateTimer(), 1000)\n }\n\n private updateTimer(): void {\n const secs = this.getDuration()\n const mm = String(Math.floor(secs / 60)).padStart(2, '0')\n const ss = String(secs % 60).padStart(2, '0')\n this.timerEl.textContent = `${mm}:${ss}`\n }\n\n destroy(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId)\n this.intervalId = null\n }\n this.el.remove()\n }\n}\n","import { RecordSession } from '../record/session'\nimport type { RecordingResult } from '../record/session'\nimport { RecordControlBar } from '../record/control-bar'\nimport type { ShadowContainer } from './shadow'\nimport type { I18nMessages } from '../i18n'\n\nexport type { RecordingResult }\n\nexport class RecordingManager {\n private session: RecordSession | null = null\n private bar: RecordControlBar | null = null\n private result: RecordingResult | null = null\n\n async start(\n shadow: ShadowContainer,\n messages: I18nMessages,\n onStop: () => void,\n ): Promise<void> {\n this.session = new RecordSession(shadow, onStop)\n this.bar = new RecordControlBar(\n shadow,\n messages,\n () => this.session?.getDuration() ?? 0,\n onStop,\n )\n await this.session.start()\n }\n\n stop(): RecordingResult | null {\n if (!this.session) return null\n this.result = this.session.stop()\n this.teardownUI()\n return this.result\n }\n\n getRecording(): RecordingResult | null {\n return this.result\n }\n\n destroy(): void {\n this.teardownUI()\n this.result = null\n }\n\n private teardownUI(): void {\n this.session?.destroy()\n this.session = null\n this.bar?.destroy()\n this.bar = null\n }\n}\n","import { ShadowContainer } from './shadow'\nimport { FeedbackTab } from './tab'\nimport { FrustrationPromptCard } from './frustration-prompt'\nimport { AnnotationToolbar } from '../annotate/toolbar'\nimport type { ToolbarMode } from '../annotate/toolbar'\nimport { AnnotationSession } from '../annotate/session'\nimport { CommentPopup } from '../popup/comment'\nimport { ClarifyCard } from '../popup/clarify'\nimport { SuccessCard } from '../popup/success'\nimport type { SuccessCardOptions } from '../popup/success'\nimport { captureScreenshot } from '../screenshot/capture'\nimport { ConsoleErrorCollector } from '../context/console'\nimport { FrustrationDetector } from '../context/frustration'\nimport { collectPageContext } from '../context/collector'\nimport { ApiClient } from '../api/client'\nimport { buildPayload } from './payload'\nimport { getMessages } from '../i18n'\nimport { RecordingManager } from './recording-manager'\nimport type { MakeThisBetterConfig, Annotation } from '../types'\n\ntype Mode = 'idle' | 'annotating' | 'recording' | 'popup'\n\nexport class WidgetController {\n private config: MakeThisBetterConfig\n private shadow!: ShadowContainer\n private tab: FeedbackTab | null = null\n private toolbar: AnnotationToolbar | null = null\n private session: AnnotationSession | null = null\n private popup: CommentPopup | null = null\n private clarify: ClarifyCard | null = null\n private success: SuccessCard | null = null\n private frustrationPrompt: FrustrationPromptCard | null = null\n private apiClient: ApiClient\n private consoleCollector: ConsoleErrorCollector\n private frustrationDetector: FrustrationDetector | null = null\n private messages: ReturnType<typeof getMessages>\n private mode: Mode = 'idle'\n private currentAnnotation: Annotation | null = null\n private recordingManager: RecordingManager | null = null\n\n constructor(config: MakeThisBetterConfig) {\n this.config = config\n this.messages = getMessages(config.locale ?? 'en')\n this.apiClient = new ApiClient(config.projectKey, config.apiUrl, undefined, config.userToken, config.userTokenFn)\n this.consoleCollector = new ConsoleErrorCollector()\n this.consoleCollector.start()\n this.buildUI()\n\n if (config.frustrationDetection !== false) {\n this.frustrationDetector = new FrustrationDetector(() => this.handleFrustration())\n this.frustrationDetector.start()\n }\n }\n\n private buildUI(): void {\n this.shadow = new ShadowContainer(this.config.theme ?? 'auto')\n\n this.tab = new FeedbackTab(\n this.shadow,\n this.messages,\n this.config.position ?? 'right',\n () => this.handleTabClick(),\n this.config.tabText,\n )\n }\n\n private handleTabClick(): void {\n if (this.mode === 'idle') {\n this.dismissFrustrationPrompt()\n this.enterAnnotationMode()\n } else {\n this.exitAll()\n }\n }\n\n private handleFrustration(): void {\n if (this.mode !== 'idle' || this.frustrationPrompt) return\n\n this.frustrationPrompt = new FrustrationPromptCard(this.shadow, this.messages, {\n onTell: () => {\n this.dismissFrustrationPrompt()\n this.enterAnnotationMode()\n },\n onDismiss: () => this.dismissFrustrationPrompt(),\n })\n }\n\n private dismissFrustrationPrompt(): void {\n this.frustrationPrompt?.destroy()\n this.frustrationPrompt = null\n }\n\n private enterAnnotationMode(): void {\n this.mode = 'annotating'\n this.tab?.setActive(true)\n\n this.toolbar = new AnnotationToolbar(\n this.shadow,\n this.messages,\n () => this.exitAll(),\n (mode: ToolbarMode) => this.handleToolbarModeChange(mode),\n )\n this.session = new AnnotationSession(this.shadow, this.messages, (annotation, targetName) => {\n this.currentAnnotation = annotation\n this.showPopup(annotation.x, annotation.y, targetName)\n })\n }\n\n private handleToolbarModeChange(mode: ToolbarMode): void {\n if (mode === 'record') {\n this.mode = 'recording'\n this.session?.destroy()\n this.session = null\n this.recordingManager = new RecordingManager()\n this.recordingManager.start(this.shadow, this.messages, () => {\n if (!this.recordingManager) return\n this.recordingManager.stop()\n this.showPopup(window.innerWidth / 2, window.innerHeight / 2, this.messages.record.timer_label)\n }).catch((error) => {\n // rrweb failed to load (network / SRI mismatch) — fall back to markup\n console.warn('[MakeThisBetter] Screen recording unavailable, falling back to markup:', error)\n if (this.mode !== 'recording') return\n this.toolbar?.setMode('markup')\n this.handleToolbarModeChange('markup')\n })\n } else {\n this.recordingManager?.destroy()\n this.recordingManager = null\n if (!this.session) {\n this.session = new AnnotationSession(this.shadow, this.messages, (annotation, targetName) => {\n this.currentAnnotation = annotation\n this.showPopup(annotation.x, annotation.y, targetName)\n })\n }\n this.mode = 'annotating'\n }\n }\n\n private showPopup(x: number, y: number, targetName: string): void {\n this.mode = 'popup'\n this.session?.dismissInteraction()\n\n this.popup = new CommentPopup(this.shadow, {\n targetName,\n x,\n y,\n messages: this.messages,\n onSubmit: (description) => this.handleSubmit(description),\n onClose: () => this.exitAll(),\n })\n }\n\n private async handleSubmit(description: string): Promise<void> {\n if (!this.popup) return\n this.popup.setLoading(true)\n const annotation = this.currentAnnotation\n const recording = this.recordingManager?.getRecording() ?? undefined\n\n const [screenshot, pageContext] = await Promise.all([\n captureScreenshot(annotation ? [annotation] : []),\n Promise.resolve(collectPageContext()),\n ])\n\n const payload = buildPayload(\n description,\n pageContext,\n this.consoleCollector.getErrors(),\n annotation,\n this.config.user,\n recording,\n )\n\n try {\n const feedback = await this.apiClient.submitFeedback(payload, screenshot)\n this.popup?.destroy()\n this.popup = null\n this.session?.destroy()\n this.session = null\n this.toolbar?.destroy()\n this.toolbar = null\n this.recordingManager?.destroy()\n this.recordingManager = null\n const skipFollowup = feedback.skip_followup === true || feedback.ai_clarify_available === false\n if (skipFollowup) {\n this.showSuccess(feedback.project_id, { skipFollowup: true })\n } else {\n this.showClarify(feedback.id, feedback.project_id)\n }\n } catch {\n this.popup?.setLoading(false)\n this.popup?.setError(this.messages.error.submit)\n }\n }\n\n private showClarify(feedbackId: string, projectId: string): void {\n this.mode = 'idle'\n this.tab?.setActive(false)\n this.clarify = new ClarifyCard(this.shadow, {\n feedbackId,\n apiClient: this.apiClient,\n messages: this.messages,\n onDone: () => {\n this.clarify?.destroy()\n this.clarify = null\n this.showSuccess(projectId)\n },\n })\n }\n\n private showSuccess(projectId: string, options?: SuccessCardOptions): void {\n this.mode = 'idle'\n this.tab?.setActive(false)\n const baseUrl = this.config.apiUrl\n ? this.config.apiUrl.replace(/\\/api\\/v1\\/?$/, '')\n : 'https://makethisbetter.dev'\n const boardUrl = `${baseUrl}/board/projects/${projectId}/feedbacks`\n const hasIdentity = !!(this.config.userToken || this.config.userTokenFn)\n this.success = new SuccessCard(this.shadow, this.messages, () => {\n this.success?.destroy()\n this.success = null\n }, hasIdentity ? async () => {\n const token = await this.apiClient.resolveUserToken()\n if (token) window.open(`${boardUrl}?identity=${encodeURIComponent(token)}`, '_blank')\n } : undefined, options)\n }\n\n private exitAll(): void {\n this.mode = 'idle'\n this.tab?.setActive(false)\n this.toolbar?.destroy()\n this.toolbar = null\n this.session?.destroy()\n this.session = null\n this.popup?.destroy()\n this.popup = null\n this.clarify?.destroy()\n this.clarify = null\n this.currentAnnotation = null\n this.recordingManager?.destroy()\n this.recordingManager = null\n }\n\n destroy(): void {\n this.exitAll()\n this.consoleCollector.stop()\n this.frustrationDetector?.stop()\n this.dismissFrustrationPrompt()\n this.clarify?.destroy()\n this.success?.destroy()\n this.tab?.destroy()\n this.recordingManager?.destroy()\n this.shadow.destroy()\n }\n}\n","import { WidgetController } from './widget/controller'\nimport type { MakeThisBetterConfig } from './types'\n\nlet instance: WidgetController | null = null\n\nconst MakeThisBetter = {\n init(config: MakeThisBetterConfig): void {\n if (instance) {\n instance.destroy()\n instance = null\n }\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n instance = new WidgetController(config)\n })\n } else {\n instance = new WidgetController(config)\n }\n },\n\n destroy(): void {\n instance?.destroy()\n instance = null\n },\n}\n\nexport { MakeThisBetter }\nexport type { MakeThisBetterConfig }\n\nif (typeof window !== 'undefined') {\n (window as Window & { MakeThisBetter?: typeof MakeThisBetter }).MakeThisBetter = MakeThisBetter\n}\n"],"names":["ShadowContainer","theme","style","cssText","tag","className","el","nodes","n","FeedbackTab","shadow","messages","position","onClick","customText","label","active","FRUSTRATION_DISMISS_MS","FrustrationPromptCard","handlers","AnnotationToolbar","onExit","onModeChange","m","mode","AnnotationOverlay","ElementHighlighter","rect","getElementName","title","text","placeholder","alt","dataMark","getCssSelector","parts","current","selector","classNames","c","parent","siblings","idx","PinMarker","x","y","index","pin","BRAND_COLOR","DRAW_STROKE","DrawLayer","onDrawComplete","center","pathD","annotation","fx","fy","d","i","xs","p","ys","cx","cy","DRAW_MIN_POINTS","AnnotationSession","onReady","e","underEl","getElementUnder","targetName","CommentPopup","opts","quickOpts","o","escapeHtml","vw","vh","margin","left","top","btn","hasText","loading","message","POLL_INTERVAL_MS","DONE_DELAY_MS","ClarifyCard","res","done","last","msg","bubble","dots","SUCCESS_AUTO_CLOSE_MS","SuccessCard","onClose","onViewFeedback","options","viewLink","resolveUrl","url","baseUrl","doc","base","a","uuid","counter","random","toArray","arrayLike","arr","l","styleProps","getStyleProperties","px","node","styleProperty","val","getNodeWidth","leftBorder","rightBorder","getNodeHeight","topBorder","bottomBorder","getImageSize","targetNode","width","height","getPixelRatio","ratio","FINAL_PROCESS","canvasDimensionLimit","checkCanvasDimensions","canvas","createImage","resolve","reject","img","svgToDataURL","svg","html","nodeToDataURL","xmlns","foreignObject","isInstanceOfElement","instance","nodePrototype","formatCSSText","content","formatCSSProperties","name","value","priority","getPseudoElementStyle","pseudo","clonePseudoElement","nativeNode","clonedNode","styleElement","clonePseudoElements","WOFF","JPEG","mimes","getExtension","match","getMimeType","extension","getContentFromDataUrl","dataURL","isDataUrl","makeDataUrl","mimeType","fetchAsDataURL","init","process","blob","reader","error","cache","getCacheKey","contentType","includeQueryParams","key","resourceToDataURL","resourceUrl","cacheKey","result","cloneCanvasElement","cloneVideoElement","video","ctx","poster","cloneIFrameElement","iframe","_a","cloneNode","cloneSingleNode","isSVGElement","isSlotElement","cloneChildren","_b","children","deferred","child","clonedChild","cloneCSSStyle","targetStyle","sourceStyle","cloneInputValue","cloneSelectValue","clonedSelect","selectedOption","decorate","ensureSVGSymbols","clone","uses","processedDefs","id","exist","definition","ns","defs","isRoot","URL_REGEX","URL_WITH_FORMAT_REGEX","FONT_SRC_REGEX","toRegex","escaped","parseURLs","urls","raw","quotation","embed","resourceURL","baseURL","getContentFromUrl","resolvedURL","filterPreferredFontFormat","str","preferredFontFormat","src","format","shouldEmbed","embedResources","filteredCSSText","css","embedProp","propName","propValue","cssString","embedBackground","embedImageNode","isImageElement","attributes","image","embedChildren","deferreds","embedImages","applyStyle","manual","cssFetchCache","fetchCSS","embedFonts","data","regexUrl","loadFonts","loc","parseCSS","source","commentsRegex","keyframesRegex","matches","importRegex","combinedCSSRegex","unifiedRegex","getCSSRules","styleSheets","ret","sheet","item","importIndex","metadata","rule","inline","err","getWebFontRules","cssRules","parseWebFontRules","normalizeFontFamily","font","getUsedFonts","fonts","traverse","getWebFontCSS","rules","usedFonts","embedWebFonts","styleNode","sytleContent","toSvg","toCanvas","context","canvasWidth","canvasHeight","toPng","captureScreenshot","annotations","annotationLayer","mountCaptureAnnotations","dataUrl","dataUrlToBlob","layer","buildCapturePin","buildCaptureDraw","drawPath","path","header","mime","binary","bytes","ErrorSource","listener","line","col","reason","event","errorSource","MAX_CONSOLE_ERRORS","ConsoleErrorCollector","location","RAGE_CLICK_THRESHOLD","RAGE_CLICK_WINDOW_MS","RAPID_NAV_THRESHOLD","RAPID_NAV_WINDOW_MS","FORM_CHECK_DELAY_MS","DEAD_CLICK_DOM_DELAY_MS","ERROR_PAGE_CHECK_DELAY_MS","INTERACTIVE_TAGS","INTERACTIVE_ROLES","ERROR_PAGE_PATTERNS","_FrustrationDetector","onFrustration","_e","pushOrig","replaceOrig","onNav","unused","target","now","cutoff","r","describeElement","t","form","candidates","clickTime","mutated","cls","lower","role","host","FrustrationDetector","collectPageContext","detectBrowser","detectOS","ua","DEFAULT_API_URL","ApiClient","projectKey","apiUrl","retryDelayMs","userToken","userTokenFn","headers","token","payload","screenshot","json","generateIdempotencyKey","feedbackId","body","retries","delay","ms","buildPayload","description","pageContext","consoleErrors","user","recording","en","zhCN","ja","ko","es","fr","de","locales","getMessages","locale","lang","MAX_DURATION_S","RRWEB_CDN","RRWEB_SRI","rrwebLoaded","loadRrweb","loadViaImport","loadViaCdn","findGlobalRecord","win","existing","script","record","RecordSession","onMaxReached","ripple","RecordControlBar","getDuration","onStop","secs","mm","ss","RecordingManager","WidgetController","config","feedback","projectId","boardUrl","hasIdentity","MakeThisBetter"],"mappings":"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","x_google_ignoreList":[13,14,15,16,17,18,19,20,21,22]}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "makethisbetter",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Make This Better JS Widget SDK — embed user feedback collection in any website",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./dist/makethisbetter.cjs
|
|
6
|
+
"main": "./dist/makethisbetter.cjs",
|
|
7
7
|
"module": "./dist/makethisbetter.esm.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"unpkg": "./dist/makethisbetter.js",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"default": "./dist/makethisbetter.esm.js"
|
|
17
17
|
},
|
|
18
18
|
"require": {
|
|
19
|
-
"types": "./dist/index.d.
|
|
20
|
-
"default": "./dist/makethisbetter.cjs
|
|
19
|
+
"types": "./dist/index.d.cts",
|
|
20
|
+
"default": "./dist/makethisbetter.cjs"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"./package.json": "./package.json"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
],
|
|
29
29
|
"scripts": {
|
|
30
30
|
"dev": "vite serve demo",
|
|
31
|
-
"build": "vite build && vite build --config vite.iife.config.ts && tsc --emitDeclarationOnly --declaration --declarationDir dist && cp dist/index.d.ts dist/index.d.mts",
|
|
31
|
+
"build": "vite build && vite build --config vite.iife.config.ts && tsc --emitDeclarationOnly --declaration --declarationDir dist && cp dist/index.d.ts dist/index.d.mts && cp dist/index.d.ts dist/index.d.cts",
|
|
32
32
|
"test": "vitest run",
|
|
33
33
|
"test:watch": "vitest",
|
|
34
34
|
"type-check": "tsc --noEmit",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"makethisbetter.cjs.js","sources":["../src/widget/shadow.ts","../src/widget/tab.ts","../src/widget/frustration-prompt.ts","../src/annotate/toolbar.ts","../src/annotate/overlay.ts","../src/annotate/highlighter.ts","../src/annotate/pin.ts","../src/styles.ts","../src/annotate/draw.ts","../src/annotate/session.ts","../src/popup/comment.ts","../src/popup/clarify.ts","../src/popup/success.ts","../node_modules/html-to-image/es/util.js","../node_modules/html-to-image/es/clone-pseudos.js","../node_modules/html-to-image/es/mimes.js","../node_modules/html-to-image/es/dataurl.js","../node_modules/html-to-image/es/clone-node.js","../node_modules/html-to-image/es/embed-resources.js","../node_modules/html-to-image/es/embed-images.js","../node_modules/html-to-image/es/apply-style.js","../node_modules/html-to-image/es/embed-webfonts.js","../node_modules/html-to-image/es/index.js","../src/screenshot/capture.ts","../src/context/error-source.ts","../src/context/console.ts","../src/context/frustration.ts","../src/context/collector.ts","../src/api/client.ts","../src/widget/payload.ts","../src/i18n/en.ts","../src/i18n/zh-CN.ts","../src/i18n/ja.ts","../src/i18n/ko.ts","../src/i18n/es.ts","../src/i18n/fr.ts","../src/i18n/de.ts","../src/i18n/index.ts","../src/record/session.ts","../src/record/control-bar.ts","../src/widget/recording-manager.ts","../src/widget/controller.ts","../src/index.ts"],"sourcesContent":["import cssText from '../styles/widget.css?inline'\nimport type { MakeThisBetterConfig } from '../types'\n\nexport class ShadowContainer {\n private host: HTMLElement\n readonly root: ShadowRoot\n\n constructor(theme: MakeThisBetterConfig['theme'] = 'auto') {\n this.host = document.createElement('div')\n this.host.id = 'mtb-widget-host'\n this.host.style.cssText = 'position:fixed;top:0;left:0;width:0;height:0;overflow:visible;z-index:2147483646;'\n this.host.setAttribute('data-mtb-theme', theme)\n document.body.appendChild(this.host)\n\n this.root = this.host.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = cssText\n this.root.appendChild(style)\n }\n\n el<T extends HTMLElement = HTMLElement>(tag: string, className?: string): T {\n const el = document.createElement(tag) as T\n if (className) el.className = className\n return el\n }\n\n append(...nodes: Node[]): void {\n for (const n of nodes) this.root.appendChild(n)\n }\n\n remove(...nodes: Node[]): void {\n for (const n of nodes) {\n if (n.parentNode === this.root) this.root.removeChild(n)\n }\n }\n\n destroy(): void {\n document.body.removeChild(this.host)\n }\n}\n","import type { ShadowContainer } from './shadow'\nimport type { I18nMessages } from '../i18n'\n\nexport class FeedbackTab {\n private el: HTMLButtonElement\n private onClick: () => void\n\n constructor(\n shadow: ShadowContainer,\n messages: I18nMessages,\n position: 'left' | 'right',\n onClick: () => void,\n customText?: string,\n ) {\n this.onClick = onClick\n this.el = shadow.el<HTMLButtonElement>('button', 'mtb-tab')\n if (position === 'left') this.el.classList.add('left')\n const label = customText ?? messages.tab\n this.el.textContent = label\n this.el.setAttribute('aria-label', label)\n this.el.addEventListener('click', onClick)\n shadow.append(this.el)\n }\n\n setActive(active: boolean): void {\n this.el.classList.toggle('active', active)\n }\n\n destroy(): void {\n this.el.removeEventListener('click', this.onClick)\n this.el.remove()\n }\n}\n","import type { ShadowContainer } from './shadow'\nimport type { I18nMessages } from '../i18n'\n\nconst FRUSTRATION_DISMISS_MS = 8000\n\nexport class FrustrationPromptCard {\n private el: HTMLDivElement\n\n constructor(\n shadow: ShadowContainer,\n messages: I18nMessages,\n handlers: { onTell: () => void; onDismiss: () => void },\n ) {\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-frustration-prompt')\n this.el.innerHTML = `\n <div class=\"mtb-frustration-icon\">⚠️</div>\n <span class=\"mtb-frustration-text\">${messages.frustration.prompt}</span>\n <div class=\"mtb-frustration-actions\">\n <button class=\"mtb-frustration-tell\">${messages.frustration.action}</button>\n <button class=\"mtb-frustration-dismiss\">${messages.frustration.dismiss}</button>\n </div>\n `\n\n this.el.querySelector('.mtb-frustration-tell')!.addEventListener('click', handlers.onTell)\n this.el.querySelector('.mtb-frustration-dismiss')!.addEventListener('click', handlers.onDismiss)\n\n shadow.append(this.el)\n setTimeout(handlers.onDismiss, FRUSTRATION_DISMISS_MS)\n }\n\n destroy(): void {\n this.el.remove()\n }\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\n\nexport type ToolbarMode = 'markup' | 'record'\n\nexport class AnnotationToolbar {\n private el: HTMLDivElement\n private hintEl!: HTMLSpanElement\n private markupBtn!: HTMLButtonElement\n private recordBtn!: HTMLButtonElement\n private messages: I18nMessages\n private currentMode: ToolbarMode = 'markup'\n\n constructor(\n shadow: ShadowContainer,\n messages: I18nMessages,\n onExit: () => void,\n onModeChange?: (mode: ToolbarMode) => void,\n ) {\n this.messages = messages\n\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-toolbar')\n this.el.innerHTML = this.buildHTML(messages)\n shadow.append(this.el)\n\n this.hintEl = this.el.querySelector('.mtb-toolbar-hint')!\n this.markupBtn = this.el.querySelector('.mtb-toolbar-mode-markup')!\n this.recordBtn = this.el.querySelector('.mtb-toolbar-mode-record')!\n\n this.markupBtn.addEventListener('click', () => {\n this.setMode('markup')\n onModeChange?.('markup')\n })\n this.recordBtn.addEventListener('click', () => {\n this.setMode('record')\n onModeChange?.('record')\n })\n this.el.querySelector('.mtb-exit-btn')!.addEventListener('click', onExit)\n }\n\n private buildHTML(m: I18nMessages): string {\n return `\n <div class=\"mtb-toolbar-modes\">\n <button class=\"mtb-toolbar-mode-btn mtb-toolbar-mode-markup active\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"7\"/><line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"/><line x1=\"3\" y1=\"12\" x2=\"7\" y2=\"12\"/><line x1=\"17\" y1=\"12\" x2=\"21\" y2=\"12\"/></svg>${m.toolbar.markup}\n </button>\n <button class=\"mtb-toolbar-mode-btn mtb-toolbar-mode-record\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><circle cx=\"12\" cy=\"12\" r=\"4\" fill=\"currentColor\" stroke=\"none\"/></svg>${m.toolbar.record}\n </button>\n </div>\n <span class=\"mtb-toolbar-hint\">${m.toolbar.hint}</span>\n <span class=\"mtb-toolbar-sep\"></span>\n <button class=\"mtb-exit-btn\">\n <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>${m.toolbar.exit}\n </button>\n `\n }\n\n setMode(mode: ToolbarMode): void {\n this.currentMode = mode\n if (mode === 'markup') {\n this.markupBtn.classList.add('active')\n this.recordBtn.classList.remove('active')\n this.hintEl.textContent = this.messages.toolbar.hint\n } else {\n this.markupBtn.classList.remove('active')\n this.recordBtn.classList.add('active')\n this.hintEl.textContent = this.messages.toolbar.hintRecord\n }\n }\n\n getMode(): ToolbarMode {\n return this.currentMode\n }\n\n destroy(): void {\n this.el.remove()\n }\n}\n","import type { ShadowContainer } from '../widget/shadow'\n\nexport class AnnotationOverlay {\n private overlayEl: HTMLDivElement\n private dimEl: HTMLDivElement\n private onMouseDown: (e: MouseEvent) => void\n private onMouseMove: (e: MouseEvent) => void\n private onMouseUp: (e: MouseEvent) => void\n private onMouseLeave: (e: MouseEvent) => void\n\n constructor(\n shadow: ShadowContainer,\n handlers: {\n onMouseDown: (e: MouseEvent) => void\n onMouseMove: (e: MouseEvent) => void\n onMouseUp: (e: MouseEvent) => void\n onMouseLeave: (e: MouseEvent) => void\n },\n ) {\n this.onMouseDown = handlers.onMouseDown\n this.onMouseMove = handlers.onMouseMove\n this.onMouseUp = handlers.onMouseUp\n this.onMouseLeave = handlers.onMouseLeave\n\n this.overlayEl = shadow.el<HTMLDivElement>('div', 'mtb-overlay')\n this.overlayEl.addEventListener('mousedown', this.onMouseDown)\n this.overlayEl.addEventListener('mousemove', this.onMouseMove)\n this.overlayEl.addEventListener('mouseup', this.onMouseUp)\n this.overlayEl.addEventListener('mouseleave', this.onMouseLeave)\n shadow.append(this.overlayEl)\n\n this.dimEl = shadow.el<HTMLDivElement>('div', 'mtb-dim')\n shadow.append(this.dimEl)\n }\n\n destroy(): void {\n this.overlayEl.removeEventListener('mousedown', this.onMouseDown)\n this.overlayEl.removeEventListener('mousemove', this.onMouseMove)\n this.overlayEl.removeEventListener('mouseup', this.onMouseUp)\n this.overlayEl.removeEventListener('mouseleave', this.onMouseLeave)\n this.overlayEl.remove()\n this.dimEl.remove()\n }\n}\n","import type { ShadowContainer } from '../widget/shadow'\n\nexport class ElementHighlighter {\n private highlightEl: HTMLDivElement\n\n constructor(shadow: ShadowContainer) {\n this.highlightEl = shadow.el<HTMLDivElement>('div', 'mtb-highlight')\n this.hide()\n shadow.append(this.highlightEl)\n }\n\n highlight(el: Element): void {\n const rect = el.getBoundingClientRect()\n this.highlightEl.style.top = `${rect.top - 2}px`\n this.highlightEl.style.left = `${rect.left - 2}px`\n this.highlightEl.style.width = `${rect.width + 4}px`\n this.highlightEl.style.height = `${rect.height + 4}px`\n this.highlightEl.style.display = 'block'\n }\n\n hide(): void {\n this.highlightEl.style.display = 'none'\n }\n\n destroy(): void {\n this.highlightEl.remove()\n }\n}\n\nexport function getElementName(el: Element): string {\n if (el instanceof HTMLElement) {\n const label = el.getAttribute('aria-label')\n if (label) return label\n\n const title = el.getAttribute('title')\n if (title) return title\n\n const text = el.textContent?.trim().slice(0, 40)\n if (text) return text\n\n const placeholder = (el as HTMLInputElement).placeholder\n if (placeholder) return placeholder\n\n const alt = (el as HTMLImageElement).alt\n if (alt) return alt\n\n const dataMark = el.getAttribute('data-mark')\n if (dataMark) return dataMark\n }\n return el.tagName.toLowerCase()\n}\n\nexport function getCssSelector(el: Element): string {\n const parts: string[] = []\n let current: Element | null = el\n while (current && current !== document.body && parts.length < 5) {\n let selector = current.tagName.toLowerCase()\n if (current.id) {\n selector = `#${current.id}`\n parts.unshift(selector)\n break\n }\n const classNames = Array.from(current.classList)\n .filter(c => !c.startsWith('mtb-'))\n .slice(0, 2)\n .join('.')\n if (classNames) selector += `.${classNames}`\n\n const parent = current.parentElement\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n c => c.tagName === current!.tagName,\n )\n if (siblings.length > 1) {\n const idx = siblings.indexOf(current) + 1\n selector += `:nth-child(${idx})`\n }\n }\n\n parts.unshift(selector)\n current = current.parentElement\n }\n return parts.join(' > ')\n}\n","import type { ShadowContainer } from '../widget/shadow'\n\nexport class PinMarker {\n private pins: HTMLDivElement[] = []\n private shadow: ShadowContainer\n\n constructor(shadow: ShadowContainer) {\n this.shadow = shadow\n }\n\n addPin(x: number, y: number, index: number): void {\n const pin = this.shadow.el<HTMLDivElement>('div', 'mtb-pin')\n pin.textContent = String(index)\n pin.style.top = `${y}px`\n pin.style.left = `${x}px`\n this.shadow.append(pin)\n this.pins.push(pin)\n }\n\n clearAll(): void {\n for (const pin of this.pins) pin.remove()\n this.pins = []\n }\n\n destroy(): void {\n this.clearAll()\n }\n}\n","export const BRAND_COLOR = '#059669'\n\nexport const DRAW_STROKE = {\n color: BRAND_COLOR,\n width: '3.5',\n linecap: 'round',\n linejoin: 'round',\n filter: 'drop-shadow(0 1px 2px rgba(5,150,105,0.35))',\n} as const\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { Annotation } from '../types'\nimport { DRAW_STROKE } from '../styles'\n\nexport class DrawLayer {\n private svg: SVGSVGElement\n private path: SVGPathElement | null = null\n private points: [number, number][] = []\n private isDrawing = false\n private onDrawComplete: (annotation: Annotation) => void\n\n constructor(shadow: ShadowContainer, onDrawComplete: (annotation: Annotation) => void) {\n this.onDrawComplete = onDrawComplete\n\n this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n this.svg.setAttribute('class', 'mtb-draw-svg')\n shadow.append(this.svg)\n }\n\n startDraw(x: number, y: number): void {\n this.isDrawing = true\n this.points = [[x, y]]\n\n this.path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n this.path.setAttribute('fill', 'none')\n this.path.setAttribute('stroke', DRAW_STROKE.color)\n this.path.setAttribute('stroke-width', DRAW_STROKE.width)\n this.path.setAttribute('stroke-linecap', DRAW_STROKE.linecap)\n this.path.setAttribute('stroke-linejoin', DRAW_STROKE.linejoin)\n this.path.setAttribute('style', `filter:${DRAW_STROKE.filter}`)\n this.svg.appendChild(this.path)\n }\n\n continueDraw(x: number, y: number): void {\n if (!this.isDrawing || !this.path) return\n this.points.push([x, y])\n this.path.setAttribute('d', this.buildPathD())\n }\n\n endDraw(): void {\n if (!this.isDrawing || this.points.length < 2) {\n this.isDrawing = false\n if (this.path) {\n this.path.remove()\n this.path = null\n }\n return\n }\n this.isDrawing = false\n\n const center = this.getCenter()\n const pathD = this.buildPathD()\n\n const annotation: Annotation = {\n type: 'draw',\n x: center[0],\n y: center[1],\n drawPath: pathD,\n }\n\n this.onDrawComplete(annotation)\n }\n\n private buildPathD(): string {\n if (this.points.length === 0) return ''\n const [fx, fy] = this.points[0]\n let d = `M ${fx} ${fy}`\n for (let i = 1; i < this.points.length; i++) {\n const [x, y] = this.points[i]\n d += ` L ${x} ${y}`\n }\n return d\n }\n\n private getCenter(): [number, number] {\n const xs = this.points.map(p => p[0])\n const ys = this.points.map(p => p[1])\n const cx = (Math.min(...xs) + Math.max(...xs)) / 2\n const cy = (Math.min(...ys) + Math.max(...ys)) / 2\n return [cx, cy]\n }\n\n clearAll(): void {\n while (this.svg.firstChild) this.svg.removeChild(this.svg.firstChild)\n this.path = null\n this.isDrawing = false\n this.points = []\n }\n\n cancelCurrentDraw(): void {\n this.path?.remove()\n this.path = null\n this.isDrawing = false\n this.points = []\n }\n\n isCurrentlyDrawing(): boolean {\n return this.isDrawing\n }\n\n getPointCount(): number {\n return this.points.length\n }\n\n destroy(): void {\n this.svg.remove()\n }\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\nimport type { Annotation } from '../types'\nimport { AnnotationOverlay } from './overlay'\nimport { ElementHighlighter, getElementName, getCssSelector } from './highlighter'\nimport { PinMarker } from './pin'\nimport { DrawLayer } from './draw'\n\nconst DRAW_MIN_POINTS = 5\n\nexport class AnnotationSession {\n private overlay: AnnotationOverlay\n private highlighter: ElementHighlighter\n private pinMarker: PinMarker\n private drawLayer: DrawLayer\n private pinCount = 0\n private interactionActive = true\n private pendingHighlightFrame: number | null = null\n private lastMoveX = 0\n private lastMoveY = 0\n\n constructor(\n shadow: ShadowContainer,\n private messages: I18nMessages,\n private onReady: (annotation: Annotation, targetName: string) => void,\n ) {\n this.highlighter = new ElementHighlighter(shadow)\n this.pinMarker = new PinMarker(shadow)\n this.drawLayer = new DrawLayer(shadow, (annotation) => {\n this.onReady(annotation, this.messages.annotation.drawing)\n })\n this.overlay = new AnnotationOverlay(shadow, {\n onMouseDown: (e) => this.handleMouseDown(e),\n onMouseMove: (e) => this.handleMouseMove(e),\n onMouseUp: (e) => this.handleMouseUp(e),\n onMouseLeave: () => {\n if (this.drawLayer.isCurrentlyDrawing()) this.drawLayer.endDraw()\n this.cancelPendingHighlight()\n this.highlighter.hide()\n },\n })\n }\n\n private handleMouseDown(e: MouseEvent): void {\n e.preventDefault()\n this.drawLayer.startDraw(e.clientX, e.clientY)\n }\n\n private handleMouseMove(e: MouseEvent): void {\n if (this.drawLayer.isCurrentlyDrawing()) {\n this.cancelPendingHighlight()\n this.drawLayer.continueDraw(e.clientX, e.clientY)\n this.highlighter.hide()\n return\n }\n\n this.lastMoveX = e.clientX\n this.lastMoveY = e.clientY\n if (this.pendingHighlightFrame !== null) return\n this.pendingHighlightFrame = requestAnimationFrame(() => {\n this.pendingHighlightFrame = null\n this.updateHighlight()\n })\n }\n\n private updateHighlight(): void {\n if (!this.interactionActive || this.drawLayer.isCurrentlyDrawing()) return\n const underEl = getElementUnder(this.lastMoveX, this.lastMoveY)\n if (underEl) this.highlighter.highlight(underEl)\n else this.highlighter.hide()\n }\n\n private cancelPendingHighlight(): void {\n if (this.pendingHighlightFrame === null) return\n cancelAnimationFrame(this.pendingHighlightFrame)\n this.pendingHighlightFrame = null\n }\n\n private handleMouseUp(e: MouseEvent): void {\n if (!this.drawLayer.isCurrentlyDrawing()) return\n\n if (this.drawLayer.getPointCount() >= DRAW_MIN_POINTS) {\n this.drawLayer.endDraw()\n return\n }\n\n this.drawLayer.cancelCurrentDraw()\n const underEl = getElementUnder(e.clientX, e.clientY)\n const targetName = underEl ? getElementName(underEl) : this.messages.annotation.element\n const annotation: Annotation = {\n type: 'pin',\n x: e.clientX,\n y: e.clientY,\n targetSelector: underEl ? getCssSelector(underEl) : undefined,\n targetText: underEl?.textContent?.trim().slice(0, 200) ?? '',\n targetName,\n }\n this.pinMarker.addPin(e.clientX, e.clientY, ++this.pinCount)\n this.drawLayer.clearAll()\n this.highlighter.hide()\n this.onReady(annotation, targetName)\n }\n\n dismissInteraction(): void {\n if (!this.interactionActive) return\n this.interactionActive = false\n this.cancelPendingHighlight()\n this.overlay.destroy()\n this.highlighter.destroy()\n }\n\n destroy(): void {\n this.dismissInteraction()\n this.pinMarker.destroy()\n this.drawLayer.destroy()\n }\n}\n\n// Skips the widget host via elementsFromPoint instead of toggling its\n// display — hiding the host on every mousemove flickered the toolbar.\nfunction getElementUnder(x: number, y: number): Element | null {\n return document.elementsFromPoint(x, y).find(el => el.id !== 'mtb-widget-host') ?? null\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\n\ninterface PopupOptions {\n targetName: string\n x: number\n y: number\n onSubmit: (description: string) => void\n onClose: () => void\n messages: I18nMessages\n}\n\nexport class CommentPopup {\n private el: HTMLDivElement\n private textarea!: HTMLTextAreaElement\n private submitBtn!: HTMLButtonElement\n private errorEl!: HTMLDivElement\n private onSubmit: (description: string) => void\n private onClose: () => void\n private submitLabel: string\n private loading = false\n\n constructor(shadow: ShadowContainer, opts: PopupOptions) {\n this.onSubmit = opts.onSubmit\n this.onClose = opts.onClose\n this.submitLabel = opts.messages.popup.submit\n\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-popup')\n this.el.innerHTML = this.buildHTML(opts)\n shadow.append(this.el)\n\n this.textarea = this.el.querySelector('.mtb-textarea')!\n this.submitBtn = this.el.querySelector('.mtb-submit-btn')!\n\n this.positionPopup(opts.x, opts.y)\n this.bindEvents(opts.messages)\n this.textarea.focus()\n }\n\n private buildHTML(opts: PopupOptions): string {\n const m = opts.messages\n const quickOpts = m.popup.quickOptions\n .map(\n o => `\n <button class=\"mtb-quick-option\" data-quick=\"${escapeHtml(o.label)}\">\n <span class=\"mtb-quick-option-emoji\">${o.emoji}</span>\n <span>${escapeHtml(o.label)}</span>\n </button>`,\n )\n .join('')\n\n return `\n <div class=\"mtb-popup-header\">\n <div class=\"mtb-popup-icon\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#059669\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\"/><circle cx=\"12\" cy=\"10\" r=\"3\"/>\n </svg>\n </div>\n <span class=\"mtb-popup-title\">${m.popup.about} \"${escapeHtml(opts.targetName)}\"</span>\n <button class=\"mtb-popup-close\" aria-label=\"Close\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>\n </button>\n </div>\n <div class=\"mtb-popup-body\">\n <div class=\"mtb-quick-options\">\n ${quickOpts}\n </div>\n <div class=\"mtb-textarea-wrap\">\n <textarea class=\"mtb-textarea\" placeholder=\"${escapeHtml(m.popup.placeholder)}\"></textarea>\n </div>\n <div class=\"mtb-popup-error\" role=\"alert\"></div>\n <div class=\"mtb-popup-actions\">\n <button class=\"mtb-cancel-btn\" type=\"button\">${escapeHtml(m.popup.cancel)}</button>\n <button class=\"mtb-submit-btn\" type=\"button\" disabled>${escapeHtml(m.popup.submit)}</button>\n </div>\n </div>\n `\n }\n\n private positionPopup(x: number, y: number): void {\n const popupW = 320\n const popupH = 260\n const vw = window.innerWidth\n const vh = window.innerHeight\n const margin = 12\n\n let left = x + 12\n let top = y + 12\n\n if (left + popupW > vw - margin) {\n left = x - popupW - 12\n }\n if (left < margin) left = margin\n\n if (top + popupH > vh - margin) {\n top = vh - popupH - margin\n }\n if (top < margin) top = margin\n\n this.el.style.left = `${left}px`\n this.el.style.top = `${top}px`\n }\n\n private bindEvents(messages: I18nMessages): void {\n this.el.querySelector('.mtb-popup-close')!.addEventListener('click', () => this.onClose())\n this.el.querySelector('.mtb-cancel-btn')!.addEventListener('click', () => this.onClose())\n this.errorEl = this.el.querySelector('.mtb-popup-error')!\n\n this.el.querySelectorAll('.mtb-quick-option').forEach(btn => {\n btn.addEventListener('click', () => {\n const label = (btn as HTMLElement).dataset['quick'] ?? ''\n this.textarea.value = label\n this.updateSubmitState()\n this.textarea.focus()\n })\n })\n\n this.textarea.addEventListener('input', () => this.updateSubmitState())\n\n this.textarea.addEventListener('keydown', (e: KeyboardEvent) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n this.submit()\n }\n })\n\n this.submitBtn.addEventListener('click', () => this.submit())\n }\n\n private updateSubmitState(): void {\n const hasText = this.textarea.value.trim().length > 0\n this.submitBtn.classList.toggle('ready', hasText && !this.loading)\n this.submitBtn.disabled = !hasText || this.loading\n this.errorEl.hidden = true\n this.errorEl.textContent = ''\n }\n\n private submit(): void {\n const text = this.textarea.value.trim()\n if (!text || this.loading) return\n this.onSubmit(text)\n }\n\n setLoading(loading: boolean): void {\n this.loading = loading\n if (loading) {\n this.submitBtn.classList.add('loading')\n this.submitBtn.innerHTML = `<span class=\"mtb-dot\"></span><span class=\"mtb-dot\"></span><span class=\"mtb-dot\"></span>`\n this.textarea.disabled = true\n } else {\n this.submitBtn.classList.remove('loading')\n this.submitBtn.textContent = this.submitLabel\n this.textarea.disabled = false\n }\n this.updateSubmitState()\n }\n\n setError(message: string): void {\n this.errorEl.textContent = message\n this.errorEl.hidden = false\n }\n\n destroy(): void {\n this.el.remove()\n }\n}\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\nimport type { ApiClient } from '../api/client'\nimport type { ClarifyMessage } from '../types'\nimport { BRAND_COLOR } from '../styles'\n\nconst POLL_INTERVAL_MS = 2000\nconst DONE_DELAY_MS = 2000\n\ninterface ClarifyCardOptions {\n feedbackId: string\n apiClient: ApiClient\n messages: I18nMessages\n onDone: () => void\n}\n\nexport class ClarifyCard {\n private el: HTMLDivElement\n private messagesEl!: HTMLDivElement\n private inputEl!: HTMLInputElement\n private sendBtn!: HTMLButtonElement\n private pollTimer: ReturnType<typeof setInterval> | null = null\n private doneTimer: ReturnType<typeof setTimeout> | null = null\n private feedbackId: string\n private apiClient: ApiClient\n private onDone: () => void\n private sending = false\n private destroyed = false\n\n constructor(shadow: ShadowContainer, opts: ClarifyCardOptions) {\n this.feedbackId = opts.feedbackId\n this.apiClient = opts.apiClient\n this.onDone = opts.onDone\n\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-clarify')\n this.el.style.right = '20px'\n this.el.style.bottom = '20px'\n this.el.innerHTML = this.buildHTML(opts.messages)\n shadow.append(this.el)\n\n this.messagesEl = this.el.querySelector('.mtb-clarify-messages')!\n this.inputEl = this.el.querySelector('.mtb-clarify-input')!\n this.sendBtn = this.el.querySelector('.mtb-clarify-send')!\n\n this.bindEvents(opts.messages)\n this.startConversation()\n }\n\n private buildHTML(m: I18nMessages): string {\n return `\n <div class=\"mtb-clarify-header\">\n <div class=\"mtb-clarify-icon\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${BRAND_COLOR}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/>\n </svg>\n </div>\n <button class=\"mtb-clarify-skip\">${escapeHtml(m.clarify.skip)}</button>\n </div>\n <div class=\"mtb-clarify-messages\"></div>\n <div class=\"mtb-clarify-footer\">\n <input class=\"mtb-clarify-input\" type=\"text\" placeholder=\"${escapeHtml(m.clarify.placeholder)}\" />\n <button class=\"mtb-clarify-send\" disabled>${escapeHtml(m.clarify.send)}</button>\n </div>\n `\n }\n\n private bindEvents(m: I18nMessages): void {\n this.el.querySelector('.mtb-clarify-skip')!.addEventListener('click', () => {\n this.stopPolling()\n this.onDone()\n })\n\n this.inputEl.addEventListener('input', () => {\n const hasText = this.inputEl.value.trim().length > 0\n this.sendBtn.disabled = !hasText || this.sending\n })\n\n this.inputEl.addEventListener('keydown', (e: KeyboardEvent) => {\n // keyCode 229: IME composition fallback for browsers without isComposing\n if (e.isComposing || e.keyCode === 229) return\n if (e.key === 'Enter') {\n e.preventDefault()\n this.sendMessage(m)\n }\n })\n\n this.sendBtn.addEventListener('click', () => this.sendMessage(m))\n }\n\n private async startConversation(): Promise<void> {\n this.showThinking()\n try {\n const res = await this.apiClient.startClarification(this.feedbackId)\n if (this.destroyed) return\n this.renderConversation(res.messages, res.done)\n if (res.done) {\n this.handleDone()\n } else {\n this.startPolling()\n }\n } catch {\n if (this.destroyed) return\n this.onDone()\n }\n }\n\n private async sendMessage(m: I18nMessages): Promise<void> {\n const text = this.inputEl.value.trim()\n if (!text || this.sending) return\n\n this.sending = true\n this.inputEl.disabled = true\n this.sendBtn.disabled = true\n this.stopPolling()\n\n this.appendMessage({ role: 'user', content: text })\n this.inputEl.value = ''\n this.showThinking()\n\n try {\n const res = await this.apiClient.startClarification(this.feedbackId, text)\n if (this.destroyed) return\n this.renderConversation(res.messages, res.done)\n if (res.done) {\n this.handleDone()\n } else {\n this.startPolling()\n }\n } catch {\n if (this.destroyed) return\n this.onDone()\n } finally {\n this.sending = false\n this.inputEl.disabled = false\n this.sendBtn.disabled = this.inputEl.value.trim().length === 0\n this.inputEl.focus()\n }\n }\n\n private startPolling(): void {\n this.stopPolling()\n this.pollTimer = setInterval(() => this.poll(), POLL_INTERVAL_MS)\n }\n\n private stopPolling(): void {\n if (this.pollTimer !== null) {\n clearInterval(this.pollTimer)\n this.pollTimer = null\n }\n }\n\n private async poll(): Promise<void> {\n try {\n const res = await this.apiClient.getClarification(this.feedbackId)\n if (this.destroyed) return\n this.renderConversation(res.messages, res.done)\n if (res.done) {\n this.stopPolling()\n this.handleDone()\n }\n } catch {\n if (this.destroyed) return\n this.stopPolling()\n }\n }\n\n private handleDone(): void {\n this.inputEl.disabled = true\n this.sendBtn.disabled = true\n this.doneTimer = setTimeout(() => {\n if (!this.destroyed) this.onDone()\n }, DONE_DELAY_MS)\n }\n\n private renderConversation(messages: ClarifyMessage[], done: boolean): void {\n this.renderMessages(messages)\n const last = messages[messages.length - 1]\n if (!done && (!last || last.role === 'user')) this.showThinking()\n }\n\n private renderMessages(messages: ClarifyMessage[]): void {\n this.messagesEl.innerHTML = ''\n for (const msg of messages) {\n this.appendMessage(msg)\n }\n this.messagesEl.scrollTop = this.messagesEl.scrollHeight\n }\n\n private appendMessage(msg: ClarifyMessage): void {\n const bubble = document.createElement('div')\n bubble.className = msg.role === 'user' ? 'mtb-clarify-bubble mtb-clarify-user' : 'mtb-clarify-bubble mtb-clarify-ai'\n bubble.textContent = msg.content\n this.messagesEl.appendChild(bubble)\n this.messagesEl.scrollTop = this.messagesEl.scrollHeight\n }\n\n private showThinking(): void {\n const dots = document.createElement('div')\n dots.className = 'mtb-clarify-bubble mtb-clarify-ai mtb-clarify-thinking'\n dots.innerHTML = '<span class=\"mtb-dot\"></span><span class=\"mtb-dot\"></span><span class=\"mtb-dot\"></span>'\n this.messagesEl.appendChild(dots)\n this.messagesEl.scrollTop = this.messagesEl.scrollHeight\n }\n\n destroy(): void {\n this.destroyed = true\n this.stopPolling()\n if (this.doneTimer !== null) {\n clearTimeout(this.doneTimer)\n this.doneTimer = null\n }\n this.el.remove()\n }\n}\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\nimport { BRAND_COLOR } from '../styles'\n\nconst SUCCESS_AUTO_CLOSE_MS = 5000\n\nexport interface SuccessCardOptions {\n skipFollowup?: boolean\n}\n\nexport class SuccessCard {\n private el: HTMLDivElement\n\n constructor(shadow: ShadowContainer, messages: I18nMessages, onClose: () => void, onViewFeedback?: () => void, options?: SuccessCardOptions) {\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-success')\n this.el.style.right = '20px'\n this.el.style.bottom = '20px'\n\n const title = options?.skipFollowup ? messages.success.title_no_ai : messages.success.title\n const msg = options?.skipFollowup ? messages.success.message_no_ai : messages.success.message\n\n const viewLink = onViewFeedback\n ? `<button class=\"mtb-view-feedback-link\">${messages.success.view_feedback}</button>`\n : ''\n\n this.el.innerHTML = `\n <div class=\"mtb-success-icon\">\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${BRAND_COLOR}\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\"/>\n </svg>\n </div>\n <div class=\"mtb-success-title\">${title}</div>\n <div class=\"mtb-success-msg\">${msg}</div>\n ${viewLink}\n <button class=\"mtb-close-link\">${messages.success.close}</button>\n `\n shadow.append(this.el)\n this.el.querySelector('.mtb-close-link')!.addEventListener('click', onClose)\n\n if (onViewFeedback) {\n this.el.querySelector('.mtb-view-feedback-link')!.addEventListener('click', onViewFeedback)\n }\n\n setTimeout(() => onClose(), SUCCESS_AUTO_CLOSE_MS)\n }\n\n destroy(): void {\n this.el.remove()\n }\n}\n","export function resolveUrl(url, baseUrl) {\n // url is absolute already\n if (url.match(/^[a-z]+:\\/\\//i)) {\n return url;\n }\n // url is absolute already, without protocol\n if (url.match(/^\\/\\//)) {\n return window.location.protocol + url;\n }\n // dataURI, mailto:, tel:, etc.\n if (url.match(/^[a-z]+:/i)) {\n return url;\n }\n const doc = document.implementation.createHTMLDocument();\n const base = doc.createElement('base');\n const a = doc.createElement('a');\n doc.head.appendChild(base);\n doc.body.appendChild(a);\n if (baseUrl) {\n base.href = baseUrl;\n }\n a.href = url;\n return a.href;\n}\nexport const uuid = (() => {\n // generate uuid for className of pseudo elements.\n // We should not use GUIDs, otherwise pseudo elements sometimes cannot be captured.\n let counter = 0;\n // ref: http://stackoverflow.com/a/6248722/2519373\n const random = () => \n // eslint-disable-next-line no-bitwise\n `0000${((Math.random() * 36 ** 4) << 0).toString(36)}`.slice(-4);\n return () => {\n counter += 1;\n return `u${random()}${counter}`;\n };\n})();\nexport function delay(ms) {\n return (args) => new Promise((resolve) => {\n setTimeout(() => resolve(args), ms);\n });\n}\nexport function toArray(arrayLike) {\n const arr = [];\n for (let i = 0, l = arrayLike.length; i < l; i++) {\n arr.push(arrayLike[i]);\n }\n return arr;\n}\nlet styleProps = null;\nexport function getStyleProperties(options = {}) {\n if (styleProps) {\n return styleProps;\n }\n if (options.includeStyleProperties) {\n styleProps = options.includeStyleProperties;\n return styleProps;\n }\n styleProps = toArray(window.getComputedStyle(document.documentElement));\n return styleProps;\n}\nfunction px(node, styleProperty) {\n const win = node.ownerDocument.defaultView || window;\n const val = win.getComputedStyle(node).getPropertyValue(styleProperty);\n return val ? parseFloat(val.replace('px', '')) : 0;\n}\nfunction getNodeWidth(node) {\n const leftBorder = px(node, 'border-left-width');\n const rightBorder = px(node, 'border-right-width');\n return node.clientWidth + leftBorder + rightBorder;\n}\nfunction getNodeHeight(node) {\n const topBorder = px(node, 'border-top-width');\n const bottomBorder = px(node, 'border-bottom-width');\n return node.clientHeight + topBorder + bottomBorder;\n}\nexport function getImageSize(targetNode, options = {}) {\n const width = options.width || getNodeWidth(targetNode);\n const height = options.height || getNodeHeight(targetNode);\n return { width, height };\n}\nexport function getPixelRatio() {\n let ratio;\n let FINAL_PROCESS;\n try {\n FINAL_PROCESS = process;\n }\n catch (e) {\n // pass\n }\n const val = FINAL_PROCESS && FINAL_PROCESS.env\n ? FINAL_PROCESS.env.devicePixelRatio\n : null;\n if (val) {\n ratio = parseInt(val, 10);\n if (Number.isNaN(ratio)) {\n ratio = 1;\n }\n }\n return ratio || window.devicePixelRatio || 1;\n}\n// @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas#maximum_canvas_size\nconst canvasDimensionLimit = 16384;\nexport function checkCanvasDimensions(canvas) {\n if (canvas.width > canvasDimensionLimit ||\n canvas.height > canvasDimensionLimit) {\n if (canvas.width > canvasDimensionLimit &&\n canvas.height > canvasDimensionLimit) {\n if (canvas.width > canvas.height) {\n canvas.height *= canvasDimensionLimit / canvas.width;\n canvas.width = canvasDimensionLimit;\n }\n else {\n canvas.width *= canvasDimensionLimit / canvas.height;\n canvas.height = canvasDimensionLimit;\n }\n }\n else if (canvas.width > canvasDimensionLimit) {\n canvas.height *= canvasDimensionLimit / canvas.width;\n canvas.width = canvasDimensionLimit;\n }\n else {\n canvas.width *= canvasDimensionLimit / canvas.height;\n canvas.height = canvasDimensionLimit;\n }\n }\n}\nexport function canvasToBlob(canvas, options = {}) {\n if (canvas.toBlob) {\n return new Promise((resolve) => {\n canvas.toBlob(resolve, options.type ? options.type : 'image/png', options.quality ? options.quality : 1);\n });\n }\n return new Promise((resolve) => {\n const binaryString = window.atob(canvas\n .toDataURL(options.type ? options.type : undefined, options.quality ? options.quality : undefined)\n .split(',')[1]);\n const len = binaryString.length;\n const binaryArray = new Uint8Array(len);\n for (let i = 0; i < len; i += 1) {\n binaryArray[i] = binaryString.charCodeAt(i);\n }\n resolve(new Blob([binaryArray], {\n type: options.type ? options.type : 'image/png',\n }));\n });\n}\nexport function createImage(url) {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n img.decode().then(() => {\n requestAnimationFrame(() => resolve(img));\n });\n };\n img.onerror = reject;\n img.crossOrigin = 'anonymous';\n img.decoding = 'async';\n img.src = url;\n });\n}\nexport async function svgToDataURL(svg) {\n return Promise.resolve()\n .then(() => new XMLSerializer().serializeToString(svg))\n .then(encodeURIComponent)\n .then((html) => `data:image/svg+xml;charset=utf-8,${html}`);\n}\nexport async function nodeToDataURL(node, width, height) {\n const xmlns = 'http://www.w3.org/2000/svg';\n const svg = document.createElementNS(xmlns, 'svg');\n const foreignObject = document.createElementNS(xmlns, 'foreignObject');\n svg.setAttribute('width', `${width}`);\n svg.setAttribute('height', `${height}`);\n svg.setAttribute('viewBox', `0 0 ${width} ${height}`);\n foreignObject.setAttribute('width', '100%');\n foreignObject.setAttribute('height', '100%');\n foreignObject.setAttribute('x', '0');\n foreignObject.setAttribute('y', '0');\n foreignObject.setAttribute('externalResourcesRequired', 'true');\n svg.appendChild(foreignObject);\n foreignObject.appendChild(node);\n return svgToDataURL(svg);\n}\nexport const isInstanceOfElement = (node, instance) => {\n if (node instanceof instance)\n return true;\n const nodePrototype = Object.getPrototypeOf(node);\n if (nodePrototype === null)\n return false;\n return (nodePrototype.constructor.name === instance.name ||\n isInstanceOfElement(nodePrototype, instance));\n};\n//# sourceMappingURL=util.js.map","import { uuid, getStyleProperties } from './util';\nfunction formatCSSText(style) {\n const content = style.getPropertyValue('content');\n return `${style.cssText} content: '${content.replace(/'|\"/g, '')}';`;\n}\nfunction formatCSSProperties(style, options) {\n return getStyleProperties(options)\n .map((name) => {\n const value = style.getPropertyValue(name);\n const priority = style.getPropertyPriority(name);\n return `${name}: ${value}${priority ? ' !important' : ''};`;\n })\n .join(' ');\n}\nfunction getPseudoElementStyle(className, pseudo, style, options) {\n const selector = `.${className}:${pseudo}`;\n const cssText = style.cssText\n ? formatCSSText(style)\n : formatCSSProperties(style, options);\n return document.createTextNode(`${selector}{${cssText}}`);\n}\nfunction clonePseudoElement(nativeNode, clonedNode, pseudo, options) {\n const style = window.getComputedStyle(nativeNode, pseudo);\n const content = style.getPropertyValue('content');\n if (content === '' || content === 'none') {\n return;\n }\n const className = uuid();\n try {\n clonedNode.className = `${clonedNode.className} ${className}`;\n }\n catch (err) {\n return;\n }\n const styleElement = document.createElement('style');\n styleElement.appendChild(getPseudoElementStyle(className, pseudo, style, options));\n clonedNode.appendChild(styleElement);\n}\nexport function clonePseudoElements(nativeNode, clonedNode, options) {\n clonePseudoElement(nativeNode, clonedNode, ':before', options);\n clonePseudoElement(nativeNode, clonedNode, ':after', options);\n}\n//# sourceMappingURL=clone-pseudos.js.map","const WOFF = 'application/font-woff';\nconst JPEG = 'image/jpeg';\nconst mimes = {\n woff: WOFF,\n woff2: WOFF,\n ttf: 'application/font-truetype',\n eot: 'application/vnd.ms-fontobject',\n png: 'image/png',\n jpg: JPEG,\n jpeg: JPEG,\n gif: 'image/gif',\n tiff: 'image/tiff',\n svg: 'image/svg+xml',\n webp: 'image/webp',\n};\nfunction getExtension(url) {\n const match = /\\.([^./]*?)$/g.exec(url);\n return match ? match[1] : '';\n}\nexport function getMimeType(url) {\n const extension = getExtension(url).toLowerCase();\n return mimes[extension] || '';\n}\n//# sourceMappingURL=mimes.js.map","function getContentFromDataUrl(dataURL) {\n return dataURL.split(/,/)[1];\n}\nexport function isDataUrl(url) {\n return url.search(/^(data:)/) !== -1;\n}\nexport function makeDataUrl(content, mimeType) {\n return `data:${mimeType};base64,${content}`;\n}\nexport async function fetchAsDataURL(url, init, process) {\n const res = await fetch(url, init);\n if (res.status === 404) {\n throw new Error(`Resource \"${res.url}\" not found`);\n }\n const blob = await res.blob();\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = () => {\n try {\n resolve(process({ res, result: reader.result }));\n }\n catch (error) {\n reject(error);\n }\n };\n reader.readAsDataURL(blob);\n });\n}\nconst cache = {};\nfunction getCacheKey(url, contentType, includeQueryParams) {\n let key = url.replace(/\\?.*/, '');\n if (includeQueryParams) {\n key = url;\n }\n // font resource\n if (/ttf|otf|eot|woff2?/i.test(key)) {\n key = key.replace(/.*\\//, '');\n }\n return contentType ? `[${contentType}]${key}` : key;\n}\nexport async function resourceToDataURL(resourceUrl, contentType, options) {\n const cacheKey = getCacheKey(resourceUrl, contentType, options.includeQueryParams);\n if (cache[cacheKey] != null) {\n return cache[cacheKey];\n }\n // ref: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache\n if (options.cacheBust) {\n // eslint-disable-next-line no-param-reassign\n resourceUrl += (/\\?/.test(resourceUrl) ? '&' : '?') + new Date().getTime();\n }\n let dataURL;\n try {\n const content = await fetchAsDataURL(resourceUrl, options.fetchRequestInit, ({ res, result }) => {\n if (!contentType) {\n // eslint-disable-next-line no-param-reassign\n contentType = res.headers.get('Content-Type') || '';\n }\n return getContentFromDataUrl(result);\n });\n dataURL = makeDataUrl(content, contentType);\n }\n catch (error) {\n dataURL = options.imagePlaceholder || '';\n let msg = `Failed to fetch resource: ${resourceUrl}`;\n if (error) {\n msg = typeof error === 'string' ? error : error.message;\n }\n if (msg) {\n console.warn(msg);\n }\n }\n cache[cacheKey] = dataURL;\n return dataURL;\n}\n//# sourceMappingURL=dataurl.js.map","import { clonePseudoElements } from './clone-pseudos';\nimport { createImage, toArray, isInstanceOfElement, getStyleProperties, } from './util';\nimport { getMimeType } from './mimes';\nimport { resourceToDataURL } from './dataurl';\nasync function cloneCanvasElement(canvas) {\n const dataURL = canvas.toDataURL();\n if (dataURL === 'data:,') {\n return canvas.cloneNode(false);\n }\n return createImage(dataURL);\n}\nasync function cloneVideoElement(video, options) {\n if (video.currentSrc) {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n canvas.width = video.clientWidth;\n canvas.height = video.clientHeight;\n ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(video, 0, 0, canvas.width, canvas.height);\n const dataURL = canvas.toDataURL();\n return createImage(dataURL);\n }\n const poster = video.poster;\n const contentType = getMimeType(poster);\n const dataURL = await resourceToDataURL(poster, contentType, options);\n return createImage(dataURL);\n}\nasync function cloneIFrameElement(iframe, options) {\n var _a;\n try {\n if ((_a = iframe === null || iframe === void 0 ? void 0 : iframe.contentDocument) === null || _a === void 0 ? void 0 : _a.body) {\n return (await cloneNode(iframe.contentDocument.body, options, true));\n }\n }\n catch (_b) {\n // Failed to clone iframe\n }\n return iframe.cloneNode(false);\n}\nasync function cloneSingleNode(node, options) {\n if (isInstanceOfElement(node, HTMLCanvasElement)) {\n return cloneCanvasElement(node);\n }\n if (isInstanceOfElement(node, HTMLVideoElement)) {\n return cloneVideoElement(node, options);\n }\n if (isInstanceOfElement(node, HTMLIFrameElement)) {\n return cloneIFrameElement(node, options);\n }\n return node.cloneNode(isSVGElement(node));\n}\nconst isSlotElement = (node) => node.tagName != null && node.tagName.toUpperCase() === 'SLOT';\nconst isSVGElement = (node) => node.tagName != null && node.tagName.toUpperCase() === 'SVG';\nasync function cloneChildren(nativeNode, clonedNode, options) {\n var _a, _b;\n if (isSVGElement(clonedNode)) {\n return clonedNode;\n }\n let children = [];\n if (isSlotElement(nativeNode) && nativeNode.assignedNodes) {\n children = toArray(nativeNode.assignedNodes());\n }\n else if (isInstanceOfElement(nativeNode, HTMLIFrameElement) &&\n ((_a = nativeNode.contentDocument) === null || _a === void 0 ? void 0 : _a.body)) {\n children = toArray(nativeNode.contentDocument.body.childNodes);\n }\n else {\n children = toArray(((_b = nativeNode.shadowRoot) !== null && _b !== void 0 ? _b : nativeNode).childNodes);\n }\n if (children.length === 0 ||\n isInstanceOfElement(nativeNode, HTMLVideoElement)) {\n return clonedNode;\n }\n await children.reduce((deferred, child) => deferred\n .then(() => cloneNode(child, options))\n .then((clonedChild) => {\n if (clonedChild) {\n clonedNode.appendChild(clonedChild);\n }\n }), Promise.resolve());\n return clonedNode;\n}\nfunction cloneCSSStyle(nativeNode, clonedNode, options) {\n const targetStyle = clonedNode.style;\n if (!targetStyle) {\n return;\n }\n const sourceStyle = window.getComputedStyle(nativeNode);\n if (sourceStyle.cssText) {\n targetStyle.cssText = sourceStyle.cssText;\n targetStyle.transformOrigin = sourceStyle.transformOrigin;\n }\n else {\n getStyleProperties(options).forEach((name) => {\n let value = sourceStyle.getPropertyValue(name);\n if (name === 'font-size' && value.endsWith('px')) {\n const reducedFont = Math.floor(parseFloat(value.substring(0, value.length - 2))) - 0.1;\n value = `${reducedFont}px`;\n }\n if (isInstanceOfElement(nativeNode, HTMLIFrameElement) &&\n name === 'display' &&\n value === 'inline') {\n value = 'block';\n }\n if (name === 'd' && clonedNode.getAttribute('d')) {\n value = `path(${clonedNode.getAttribute('d')})`;\n }\n targetStyle.setProperty(name, value, sourceStyle.getPropertyPriority(name));\n });\n }\n}\nfunction cloneInputValue(nativeNode, clonedNode) {\n if (isInstanceOfElement(nativeNode, HTMLTextAreaElement)) {\n clonedNode.innerHTML = nativeNode.value;\n }\n if (isInstanceOfElement(nativeNode, HTMLInputElement)) {\n clonedNode.setAttribute('value', nativeNode.value);\n }\n}\nfunction cloneSelectValue(nativeNode, clonedNode) {\n if (isInstanceOfElement(nativeNode, HTMLSelectElement)) {\n const clonedSelect = clonedNode;\n const selectedOption = Array.from(clonedSelect.children).find((child) => nativeNode.value === child.getAttribute('value'));\n if (selectedOption) {\n selectedOption.setAttribute('selected', '');\n }\n }\n}\nfunction decorate(nativeNode, clonedNode, options) {\n if (isInstanceOfElement(clonedNode, Element)) {\n cloneCSSStyle(nativeNode, clonedNode, options);\n clonePseudoElements(nativeNode, clonedNode, options);\n cloneInputValue(nativeNode, clonedNode);\n cloneSelectValue(nativeNode, clonedNode);\n }\n return clonedNode;\n}\nasync function ensureSVGSymbols(clone, options) {\n const uses = clone.querySelectorAll ? clone.querySelectorAll('use') : [];\n if (uses.length === 0) {\n return clone;\n }\n const processedDefs = {};\n for (let i = 0; i < uses.length; i++) {\n const use = uses[i];\n const id = use.getAttribute('xlink:href');\n if (id) {\n const exist = clone.querySelector(id);\n const definition = document.querySelector(id);\n if (!exist && definition && !processedDefs[id]) {\n // eslint-disable-next-line no-await-in-loop\n processedDefs[id] = (await cloneNode(definition, options, true));\n }\n }\n }\n const nodes = Object.values(processedDefs);\n if (nodes.length) {\n const ns = 'http://www.w3.org/1999/xhtml';\n const svg = document.createElementNS(ns, 'svg');\n svg.setAttribute('xmlns', ns);\n svg.style.position = 'absolute';\n svg.style.width = '0';\n svg.style.height = '0';\n svg.style.overflow = 'hidden';\n svg.style.display = 'none';\n const defs = document.createElementNS(ns, 'defs');\n svg.appendChild(defs);\n for (let i = 0; i < nodes.length; i++) {\n defs.appendChild(nodes[i]);\n }\n clone.appendChild(svg);\n }\n return clone;\n}\nexport async function cloneNode(node, options, isRoot) {\n if (!isRoot && options.filter && !options.filter(node)) {\n return null;\n }\n return Promise.resolve(node)\n .then((clonedNode) => cloneSingleNode(clonedNode, options))\n .then((clonedNode) => cloneChildren(node, clonedNode, options))\n .then((clonedNode) => decorate(node, clonedNode, options))\n .then((clonedNode) => ensureSVGSymbols(clonedNode, options));\n}\n//# sourceMappingURL=clone-node.js.map","import { resolveUrl } from './util';\nimport { getMimeType } from './mimes';\nimport { isDataUrl, makeDataUrl, resourceToDataURL } from './dataurl';\nconst URL_REGEX = /url\\((['\"]?)([^'\"]+?)\\1\\)/g;\nconst URL_WITH_FORMAT_REGEX = /url\\([^)]+\\)\\s*format\\(([\"']?)([^\"']+)\\1\\)/g;\nconst FONT_SRC_REGEX = /src:\\s*(?:url\\([^)]+\\)\\s*format\\([^)]+\\)[,;]\\s*)+/g;\nfunction toRegex(url) {\n // eslint-disable-next-line no-useless-escape\n const escaped = url.replace(/([.*+?^${}()|\\[\\]\\/\\\\])/g, '\\\\$1');\n return new RegExp(`(url\\\\(['\"]?)(${escaped})(['\"]?\\\\))`, 'g');\n}\nexport function parseURLs(cssText) {\n const urls = [];\n cssText.replace(URL_REGEX, (raw, quotation, url) => {\n urls.push(url);\n return raw;\n });\n return urls.filter((url) => !isDataUrl(url));\n}\nexport async function embed(cssText, resourceURL, baseURL, options, getContentFromUrl) {\n try {\n const resolvedURL = baseURL ? resolveUrl(resourceURL, baseURL) : resourceURL;\n const contentType = getMimeType(resourceURL);\n let dataURL;\n if (getContentFromUrl) {\n const content = await getContentFromUrl(resolvedURL);\n dataURL = makeDataUrl(content, contentType);\n }\n else {\n dataURL = await resourceToDataURL(resolvedURL, contentType, options);\n }\n return cssText.replace(toRegex(resourceURL), `$1${dataURL}$3`);\n }\n catch (error) {\n // pass\n }\n return cssText;\n}\nfunction filterPreferredFontFormat(str, { preferredFontFormat }) {\n return !preferredFontFormat\n ? str\n : str.replace(FONT_SRC_REGEX, (match) => {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const [src, , format] = URL_WITH_FORMAT_REGEX.exec(match) || [];\n if (!format) {\n return '';\n }\n if (format === preferredFontFormat) {\n return `src: ${src};`;\n }\n }\n });\n}\nexport function shouldEmbed(url) {\n return url.search(URL_REGEX) !== -1;\n}\nexport async function embedResources(cssText, baseUrl, options) {\n if (!shouldEmbed(cssText)) {\n return cssText;\n }\n const filteredCSSText = filterPreferredFontFormat(cssText, options);\n const urls = parseURLs(filteredCSSText);\n return urls.reduce((deferred, url) => deferred.then((css) => embed(css, url, baseUrl, options)), Promise.resolve(filteredCSSText));\n}\n//# sourceMappingURL=embed-resources.js.map","import { embedResources } from './embed-resources';\nimport { toArray, isInstanceOfElement } from './util';\nimport { isDataUrl, resourceToDataURL } from './dataurl';\nimport { getMimeType } from './mimes';\nasync function embedProp(propName, node, options) {\n var _a;\n const propValue = (_a = node.style) === null || _a === void 0 ? void 0 : _a.getPropertyValue(propName);\n if (propValue) {\n const cssString = await embedResources(propValue, null, options);\n node.style.setProperty(propName, cssString, node.style.getPropertyPriority(propName));\n return true;\n }\n return false;\n}\nasync function embedBackground(clonedNode, options) {\n ;\n (await embedProp('background', clonedNode, options)) ||\n (await embedProp('background-image', clonedNode, options));\n (await embedProp('mask', clonedNode, options)) ||\n (await embedProp('-webkit-mask', clonedNode, options)) ||\n (await embedProp('mask-image', clonedNode, options)) ||\n (await embedProp('-webkit-mask-image', clonedNode, options));\n}\nasync function embedImageNode(clonedNode, options) {\n const isImageElement = isInstanceOfElement(clonedNode, HTMLImageElement);\n if (!(isImageElement && !isDataUrl(clonedNode.src)) &&\n !(isInstanceOfElement(clonedNode, SVGImageElement) &&\n !isDataUrl(clonedNode.href.baseVal))) {\n return;\n }\n const url = isImageElement ? clonedNode.src : clonedNode.href.baseVal;\n const dataURL = await resourceToDataURL(url, getMimeType(url), options);\n await new Promise((resolve, reject) => {\n clonedNode.onload = resolve;\n clonedNode.onerror = options.onImageErrorHandler\n ? (...attributes) => {\n try {\n resolve(options.onImageErrorHandler(...attributes));\n }\n catch (error) {\n reject(error);\n }\n }\n : reject;\n const image = clonedNode;\n if (image.decode) {\n image.decode = resolve;\n }\n if (image.loading === 'lazy') {\n image.loading = 'eager';\n }\n if (isImageElement) {\n clonedNode.srcset = '';\n clonedNode.src = dataURL;\n }\n else {\n clonedNode.href.baseVal = dataURL;\n }\n });\n}\nasync function embedChildren(clonedNode, options) {\n const children = toArray(clonedNode.childNodes);\n const deferreds = children.map((child) => embedImages(child, options));\n await Promise.all(deferreds).then(() => clonedNode);\n}\nexport async function embedImages(clonedNode, options) {\n if (isInstanceOfElement(clonedNode, Element)) {\n await embedBackground(clonedNode, options);\n await embedImageNode(clonedNode, options);\n await embedChildren(clonedNode, options);\n }\n}\n//# sourceMappingURL=embed-images.js.map","export function applyStyle(node, options) {\n const { style } = node;\n if (options.backgroundColor) {\n style.backgroundColor = options.backgroundColor;\n }\n if (options.width) {\n style.width = `${options.width}px`;\n }\n if (options.height) {\n style.height = `${options.height}px`;\n }\n const manual = options.style;\n if (manual != null) {\n Object.keys(manual).forEach((key) => {\n style[key] = manual[key];\n });\n }\n return node;\n}\n//# sourceMappingURL=apply-style.js.map","import { toArray } from './util';\nimport { fetchAsDataURL } from './dataurl';\nimport { shouldEmbed, embedResources } from './embed-resources';\nconst cssFetchCache = {};\nasync function fetchCSS(url) {\n let cache = cssFetchCache[url];\n if (cache != null) {\n return cache;\n }\n const res = await fetch(url);\n const cssText = await res.text();\n cache = { url, cssText };\n cssFetchCache[url] = cache;\n return cache;\n}\nasync function embedFonts(data, options) {\n let cssText = data.cssText;\n const regexUrl = /url\\([\"']?([^\"')]+)[\"']?\\)/g;\n const fontLocs = cssText.match(/url\\([^)]+\\)/g) || [];\n const loadFonts = fontLocs.map(async (loc) => {\n let url = loc.replace(regexUrl, '$1');\n if (!url.startsWith('https://')) {\n url = new URL(url, data.url).href;\n }\n return fetchAsDataURL(url, options.fetchRequestInit, ({ result }) => {\n cssText = cssText.replace(loc, `url(${result})`);\n return [loc, result];\n });\n });\n return Promise.all(loadFonts).then(() => cssText);\n}\nfunction parseCSS(source) {\n if (source == null) {\n return [];\n }\n const result = [];\n const commentsRegex = /(\\/\\*[\\s\\S]*?\\*\\/)/gi;\n // strip out comments\n let cssText = source.replace(commentsRegex, '');\n // eslint-disable-next-line prefer-regex-literals\n const keyframesRegex = new RegExp('((@.*?keyframes [\\\\s\\\\S]*?){([\\\\s\\\\S]*?}\\\\s*?)})', 'gi');\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const matches = keyframesRegex.exec(cssText);\n if (matches === null) {\n break;\n }\n result.push(matches[0]);\n }\n cssText = cssText.replace(keyframesRegex, '');\n const importRegex = /@import[\\s\\S]*?url\\([^)]*\\)[\\s\\S]*?;/gi;\n // to match css & media queries together\n const combinedCSSRegex = '((\\\\s*?(?:\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)?\\\\s*?@media[\\\\s\\\\S]' +\n '*?){([\\\\s\\\\S]*?)}\\\\s*?})|(([\\\\s\\\\S]*?){([\\\\s\\\\S]*?)})';\n // unified regex\n const unifiedRegex = new RegExp(combinedCSSRegex, 'gi');\n // eslint-disable-next-line no-constant-condition\n while (true) {\n let matches = importRegex.exec(cssText);\n if (matches === null) {\n matches = unifiedRegex.exec(cssText);\n if (matches === null) {\n break;\n }\n else {\n importRegex.lastIndex = unifiedRegex.lastIndex;\n }\n }\n else {\n unifiedRegex.lastIndex = importRegex.lastIndex;\n }\n result.push(matches[0]);\n }\n return result;\n}\nasync function getCSSRules(styleSheets, options) {\n const ret = [];\n const deferreds = [];\n // First loop inlines imports\n styleSheets.forEach((sheet) => {\n if ('cssRules' in sheet) {\n try {\n toArray(sheet.cssRules || []).forEach((item, index) => {\n if (item.type === CSSRule.IMPORT_RULE) {\n let importIndex = index + 1;\n const url = item.href;\n const deferred = fetchCSS(url)\n .then((metadata) => embedFonts(metadata, options))\n .then((cssText) => parseCSS(cssText).forEach((rule) => {\n try {\n sheet.insertRule(rule, rule.startsWith('@import')\n ? (importIndex += 1)\n : sheet.cssRules.length);\n }\n catch (error) {\n console.error('Error inserting rule from remote css', {\n rule,\n error,\n });\n }\n }))\n .catch((e) => {\n console.error('Error loading remote css', e.toString());\n });\n deferreds.push(deferred);\n }\n });\n }\n catch (e) {\n const inline = styleSheets.find((a) => a.href == null) || document.styleSheets[0];\n if (sheet.href != null) {\n deferreds.push(fetchCSS(sheet.href)\n .then((metadata) => embedFonts(metadata, options))\n .then((cssText) => parseCSS(cssText).forEach((rule) => {\n inline.insertRule(rule, inline.cssRules.length);\n }))\n .catch((err) => {\n console.error('Error loading remote stylesheet', err);\n }));\n }\n console.error('Error inlining remote css file', e);\n }\n }\n });\n return Promise.all(deferreds).then(() => {\n // Second loop parses rules\n styleSheets.forEach((sheet) => {\n if ('cssRules' in sheet) {\n try {\n toArray(sheet.cssRules || []).forEach((item) => {\n ret.push(item);\n });\n }\n catch (e) {\n console.error(`Error while reading CSS rules from ${sheet.href}`, e);\n }\n }\n });\n return ret;\n });\n}\nfunction getWebFontRules(cssRules) {\n return cssRules\n .filter((rule) => rule.type === CSSRule.FONT_FACE_RULE)\n .filter((rule) => shouldEmbed(rule.style.getPropertyValue('src')));\n}\nasync function parseWebFontRules(node, options) {\n if (node.ownerDocument == null) {\n throw new Error('Provided element is not within a Document');\n }\n const styleSheets = toArray(node.ownerDocument.styleSheets);\n const cssRules = await getCSSRules(styleSheets, options);\n return getWebFontRules(cssRules);\n}\nfunction normalizeFontFamily(font) {\n return font.trim().replace(/[\"']/g, '');\n}\nfunction getUsedFonts(node) {\n const fonts = new Set();\n function traverse(node) {\n const fontFamily = node.style.fontFamily || getComputedStyle(node).fontFamily;\n fontFamily.split(',').forEach((font) => {\n fonts.add(normalizeFontFamily(font));\n });\n Array.from(node.children).forEach((child) => {\n if (child instanceof HTMLElement) {\n traverse(child);\n }\n });\n }\n traverse(node);\n return fonts;\n}\nexport async function getWebFontCSS(node, options) {\n const rules = await parseWebFontRules(node, options);\n const usedFonts = getUsedFonts(node);\n const cssTexts = await Promise.all(rules\n .filter((rule) => usedFonts.has(normalizeFontFamily(rule.style.fontFamily)))\n .map((rule) => {\n const baseUrl = rule.parentStyleSheet\n ? rule.parentStyleSheet.href\n : null;\n return embedResources(rule.cssText, baseUrl, options);\n }));\n return cssTexts.join('\\n');\n}\nexport async function embedWebFonts(clonedNode, options) {\n const cssText = options.fontEmbedCSS != null\n ? options.fontEmbedCSS\n : options.skipFonts\n ? null\n : await getWebFontCSS(clonedNode, options);\n if (cssText) {\n const styleNode = document.createElement('style');\n const sytleContent = document.createTextNode(cssText);\n styleNode.appendChild(sytleContent);\n if (clonedNode.firstChild) {\n clonedNode.insertBefore(styleNode, clonedNode.firstChild);\n }\n else {\n clonedNode.appendChild(styleNode);\n }\n }\n}\n//# sourceMappingURL=embed-webfonts.js.map","import { cloneNode } from './clone-node';\nimport { embedImages } from './embed-images';\nimport { applyStyle } from './apply-style';\nimport { embedWebFonts, getWebFontCSS } from './embed-webfonts';\nimport { getImageSize, getPixelRatio, createImage, canvasToBlob, nodeToDataURL, checkCanvasDimensions, } from './util';\nexport async function toSvg(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const clonedNode = (await cloneNode(node, options, true));\n await embedWebFonts(clonedNode, options);\n await embedImages(clonedNode, options);\n applyStyle(clonedNode, options);\n const datauri = await nodeToDataURL(clonedNode, width, height);\n return datauri;\n}\nexport async function toCanvas(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const svg = await toSvg(node, options);\n const img = await createImage(svg);\n const canvas = document.createElement('canvas');\n const context = canvas.getContext('2d');\n const ratio = options.pixelRatio || getPixelRatio();\n const canvasWidth = options.canvasWidth || width;\n const canvasHeight = options.canvasHeight || height;\n canvas.width = canvasWidth * ratio;\n canvas.height = canvasHeight * ratio;\n if (!options.skipAutoScale) {\n checkCanvasDimensions(canvas);\n }\n canvas.style.width = `${canvasWidth}`;\n canvas.style.height = `${canvasHeight}`;\n if (options.backgroundColor) {\n context.fillStyle = options.backgroundColor;\n context.fillRect(0, 0, canvas.width, canvas.height);\n }\n context.drawImage(img, 0, 0, canvas.width, canvas.height);\n return canvas;\n}\nexport async function toPixelData(node, options = {}) {\n const { width, height } = getImageSize(node, options);\n const canvas = await toCanvas(node, options);\n const ctx = canvas.getContext('2d');\n return ctx.getImageData(0, 0, width, height).data;\n}\nexport async function toPng(node, options = {}) {\n const canvas = await toCanvas(node, options);\n return canvas.toDataURL();\n}\nexport async function toJpeg(node, options = {}) {\n const canvas = await toCanvas(node, options);\n return canvas.toDataURL('image/jpeg', options.quality || 1);\n}\nexport async function toBlob(node, options = {}) {\n const canvas = await toCanvas(node, options);\n const blob = await canvasToBlob(canvas);\n return blob;\n}\nexport async function getFontEmbedCSS(node, options = {}) {\n return getWebFontCSS(node, options);\n}\n//# sourceMappingURL=index.js.map","import { toPng } from 'html-to-image'\nimport type { Annotation } from '../types'\n\nexport async function captureScreenshot(annotations: Annotation[] = []): Promise<Blob | null> {\n const annotationLayer = mountCaptureAnnotations(annotations)\n\n try {\n const dataUrl = await toPng(document.body, {\n cacheBust: true,\n skipAutoScale: false,\n filter: (node) => {\n if (node instanceof HTMLElement && node.id === 'mtb-widget-host') return false\n return true\n },\n })\n return dataUrlToBlob(dataUrl)\n } catch {\n return null\n } finally {\n annotationLayer?.remove()\n }\n}\n\nfunction mountCaptureAnnotations(annotations: Annotation[]): HTMLDivElement | null {\n if (annotations.length === 0) return null\n\n const layer = document.createElement('div')\n layer.setAttribute('data-mtb-capture-annotations', 'true')\n layer.setAttribute('aria-hidden', 'true')\n layer.style.cssText = 'position:fixed;inset:0;pointer-events:none;z-index:2147483645;'\n\n for (const [index, annotation] of annotations.entries()) {\n if (annotation.type === 'pin') {\n layer.appendChild(buildCapturePin(annotation, index + 1))\n } else if (annotation.type === 'draw' && annotation.drawPath) {\n layer.appendChild(buildCaptureDraw(annotation.drawPath))\n }\n }\n\n document.body.appendChild(layer)\n return layer\n}\n\nfunction buildCapturePin(annotation: Annotation, index: number): HTMLDivElement {\n const pin = document.createElement('div')\n pin.textContent = String(index)\n pin.style.cssText = [\n 'position:fixed',\n `left:${annotation.x}px`,\n `top:${annotation.y}px`,\n 'width:22px',\n 'height:22px',\n 'border-radius:50% 50% 50% 2px',\n 'background:#059669',\n 'border:2px solid #fff',\n 'display:flex',\n 'align-items:center',\n 'justify-content:center',\n 'font:700 10px -apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif',\n 'color:#fff',\n 'box-shadow:0 2px 8px rgba(5,150,105,0.45)',\n 'transform:translate(-50%,-50%)',\n ].join(';')\n return pin\n}\n\nfunction buildCaptureDraw(drawPath: string): SVGSVGElement {\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('width', '100%')\n svg.setAttribute('height', '100%')\n svg.setAttribute('viewBox', `0 0 ${window.innerWidth} ${window.innerHeight}`)\n svg.style.cssText = 'position:fixed;inset:0;width:100%;height:100%;overflow:visible;'\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('d', drawPath)\n path.setAttribute('fill', 'none')\n path.setAttribute('stroke', '#059669')\n path.setAttribute('stroke-width', '3.5')\n path.setAttribute('stroke-linecap', 'round')\n path.setAttribute('stroke-linejoin', 'round')\n path.setAttribute('filter', 'drop-shadow(0 1px 2px rgba(5,150,105,0.35))')\n svg.appendChild(path)\n\n return svg\n}\n\nfunction dataUrlToBlob(dataUrl: string): Blob {\n const [header, data] = dataUrl.split(',')\n const mime = header.match(/:(.*?);/)?.[1] ?? 'image/png'\n const binary = atob(data)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return new Blob([bytes], { type: mime })\n}\n","export interface ErrorSourceEvent {\n message: string\n source?: string\n line?: number\n col?: number\n error?: unknown\n}\n\ntype ErrorListener = (event: ErrorSourceEvent) => void\n\nclass ErrorSource {\n private listeners = new Set<ErrorListener>()\n private originalOnError: OnErrorEventHandler | null = null\n private installedOnError: OnErrorEventHandler | null = null\n private rejectionHandler: ((e: PromiseRejectionEvent) => void) | null = null\n private hooked = false\n\n subscribe(listener: ErrorListener): () => void {\n this.listeners.add(listener)\n this.hook()\n return () => {\n this.listeners.delete(listener)\n if (this.listeners.size === 0) this.unhook()\n }\n }\n\n private hook(): void {\n if (this.hooked) return\n this.hooked = true\n\n this.originalOnError = window.onerror\n this.installedOnError = (msg, source, line, col, error) => {\n this.emit({ message: String(msg), source, line, col, error })\n if (this.originalOnError) {\n return this.originalOnError.call(window, msg, source, line, col, error)\n }\n return false\n }\n window.onerror = this.installedOnError\n\n this.rejectionHandler = (e: PromiseRejectionEvent) => {\n const reason = e.reason instanceof Error ? e.reason.message : String(e.reason)\n this.emit({ message: `Unhandled rejection: ${reason}` })\n }\n window.addEventListener('unhandledrejection', this.rejectionHandler)\n }\n\n private unhook(): void {\n if (!this.hooked) return\n this.hooked = false\n // Only restore if nothing replaced our handler meanwhile — restoring\n // the stale snapshot would clobber a handler the page installed later.\n if (window.onerror === this.installedOnError) {\n window.onerror = this.originalOnError\n }\n this.installedOnError = null\n this.originalOnError = null\n if (this.rejectionHandler) {\n window.removeEventListener('unhandledrejection', this.rejectionHandler)\n this.rejectionHandler = null\n }\n }\n\n private emit(event: ErrorSourceEvent): void {\n for (const listener of this.listeners) listener(event)\n }\n}\n\nexport const errorSource = new ErrorSource()\n","import { errorSource, type ErrorSourceEvent } from './error-source'\n\nconst MAX_CONSOLE_ERRORS = 20\n\nexport class ConsoleErrorCollector {\n private errors: string[] = []\n private unsubscribe: (() => void) | null = null\n\n start(): void {\n if (this.unsubscribe) return\n this.unsubscribe = errorSource.subscribe((e) => this.record(e))\n }\n\n private record(e: ErrorSourceEvent): void {\n const location = e.line != null ? ` (${e.line}:${e.col ?? 0})` : ''\n this.addError(`${e.message}${location}`)\n }\n\n private addError(msg: string): void {\n if (this.errors.length >= MAX_CONSOLE_ERRORS) return\n if (!this.errors.includes(msg)) {\n this.errors.push(msg)\n }\n }\n\n getErrors(): string[] {\n return [...this.errors]\n }\n\n stop(): void {\n this.unsubscribe?.()\n this.unsubscribe = null\n }\n}\n","import { errorSource } from './error-source'\n\nexport type FrustrationSignal =\n | 'rage_click'\n | 'dead_click'\n | 'rapid_navigation'\n | 'form_failure'\n | 'error_page'\n | 'dead_click_dom'\n\nexport interface FrustrationEvent {\n signal: FrustrationSignal\n target?: string\n detail?: string\n timestamp: number\n}\n\ninterface ClickRecord {\n target: EventTarget | null\n time: number\n}\n\nconst RAGE_CLICK_THRESHOLD = 3\nconst RAGE_CLICK_WINDOW_MS = 1000\nconst RAPID_NAV_THRESHOLD = 3\nconst RAPID_NAV_WINDOW_MS = 5000\nconst FORM_CHECK_DELAY_MS = 500\nconst DEAD_CLICK_DOM_DELAY_MS = 500\nconst ERROR_PAGE_CHECK_DELAY_MS = 300\n\nconst INTERACTIVE_TAGS = new Set([\n 'A', 'BUTTON', 'INPUT', 'SELECT', 'TEXTAREA', 'LABEL', 'SUMMARY', 'DETAILS',\n])\n\nconst INTERACTIVE_ROLES = new Set([\n 'button', 'link', 'checkbox', 'radio', 'tab', 'menuitem', 'option',\n 'switch', 'textbox', 'combobox', 'listbox', 'slider', 'spinbutton',\n])\n\nconst ERROR_PAGE_PATTERNS = [\n '404', '500', 'not found', 'page not found',\n 'server error', 'internal server error',\n]\n\nexport class FrustrationDetector {\n private clickHistory: ClickRecord[] = []\n private onFrustration: (event: FrustrationEvent) => void\n private boundClickHandler: (e: MouseEvent) => void\n private unsubscribeErrors: (() => void) | null = null\n private active = false\n private errorCount = 0\n private deadClickCount = 0\n private cooldownUntil = 0\n private static readonly COOLDOWN_MS = 60_000\n\n private navTimestamps: number[] = []\n private boundPopstateHandler: (() => void) | null = null\n private originalPushState: History['pushState'] | null = null\n private originalReplaceState: History['replaceState'] | null = null\n private installedPushState: History['pushState'] | null = null\n private installedReplaceState: History['replaceState'] | null = null\n private boundSubmitHandler: ((e: Event) => void) | null = null\n private boundInvalidHandler: ((e: Event) => void) | null = null\n private errorPageUrls = new Set<string>()\n private domObserver: MutationObserver | null = null\n private pendingDomChecks = 0\n private lastMutationAt = -1\n\n constructor(onFrustration: (event: FrustrationEvent) => void) {\n this.onFrustration = onFrustration\n this.boundClickHandler = (e: MouseEvent) => this.handleClick(e)\n }\n\n start(): void {\n if (this.active) return\n this.active = true\n document.addEventListener('click', this.boundClickHandler, true)\n this.unsubscribeErrors = errorSource.subscribe((_e) => {\n this.errorCount++\n })\n\n this.startNavigationTracking()\n this.startFormTracking()\n this.checkErrorPage()\n }\n\n stop(): void {\n if (!this.active) return\n this.active = false\n document.removeEventListener('click', this.boundClickHandler, true)\n this.unsubscribeErrors?.()\n this.unsubscribeErrors = null\n this.clickHistory = []\n\n this.stopNavigationTracking()\n this.stopFormTracking()\n this.errorPageUrls.clear()\n\n this.disconnectDomObserver()\n }\n\n private startNavigationTracking(): void {\n this.boundPopstateHandler = () => this.handleNavigation()\n window.addEventListener('popstate', this.boundPopstateHandler)\n\n this.originalPushState = history.pushState.bind(history)\n this.originalReplaceState = history.replaceState.bind(history)\n const pushOrig = this.originalPushState\n const replaceOrig = this.originalReplaceState\n const onNav = () => this.handleNavigation()\n\n this.installedPushState = function (data: unknown, unused: string, url?: string | URL | null) {\n pushOrig(data, unused, url)\n onNav()\n }\n this.installedReplaceState = function (data: unknown, unused: string, url?: string | URL | null) {\n replaceOrig(data, unused, url)\n onNav()\n }\n history.pushState = this.installedPushState\n history.replaceState = this.installedReplaceState\n }\n\n private stopNavigationTracking(): void {\n if (this.boundPopstateHandler) {\n window.removeEventListener('popstate', this.boundPopstateHandler)\n this.boundPopstateHandler = null\n }\n // Only restore if nothing (e.g. an SPA router) re-wrapped the functions\n // after us — restoring the stale snapshot would discard their wrapper.\n if (this.originalPushState && history.pushState === this.installedPushState) {\n history.pushState = this.originalPushState\n }\n if (this.originalReplaceState && history.replaceState === this.installedReplaceState) {\n history.replaceState = this.originalReplaceState\n }\n this.originalPushState = null\n this.originalReplaceState = null\n this.installedPushState = null\n this.installedReplaceState = null\n this.navTimestamps = []\n }\n\n private startFormTracking(): void {\n this.boundSubmitHandler = (e: Event) => this.handleFormSubmit(e)\n this.boundInvalidHandler = (e: Event) => this.handleFormInvalid(e)\n document.addEventListener('submit', this.boundSubmitHandler, true)\n document.addEventListener('invalid', this.boundInvalidHandler, true)\n }\n\n private stopFormTracking(): void {\n if (this.boundSubmitHandler) {\n document.removeEventListener('submit', this.boundSubmitHandler, true)\n this.boundSubmitHandler = null\n }\n if (this.boundInvalidHandler) {\n document.removeEventListener('invalid', this.boundInvalidHandler, true)\n this.boundInvalidHandler = null\n }\n }\n\n private handleClick(e: MouseEvent): void {\n const target = e.target as Element | null\n if (!target) return\n\n if (this.isWidgetElement(target)) return\n\n const now = Date.now()\n this.clickHistory.push({ target, time: now })\n\n const cutoff = now - RAGE_CLICK_WINDOW_MS\n this.clickHistory = this.clickHistory.filter(r => r.time > cutoff)\n\n const sameTargetClicks = this.clickHistory.filter(r => r.target === target)\n if (sameTargetClicks.length >= RAGE_CLICK_THRESHOLD) {\n this.clickHistory = []\n this.emitHighPriority({\n signal: 'rage_click',\n target: describeElement(target),\n timestamp: now,\n })\n return\n }\n\n if (!this.isInteractive(target)) {\n this.deadClickCount++\n if (this.deadClickCount >= 3 && this.errorCount > 0) {\n this.deadClickCount = 0\n this.errorCount = 0\n this.emitIfReady({\n signal: 'dead_click',\n target: describeElement(target),\n timestamp: now,\n })\n }\n }\n\n this.checkDeadClickDom(target, now)\n }\n\n private handleNavigation(): void {\n const now = Date.now()\n this.navTimestamps.push(now)\n const cutoff = now - RAPID_NAV_WINDOW_MS\n this.navTimestamps = this.navTimestamps.filter(t => t > cutoff)\n if (this.navTimestamps.length >= RAPID_NAV_THRESHOLD) {\n this.navTimestamps = []\n this.emitIfReady({\n signal: 'rapid_navigation',\n timestamp: now,\n })\n }\n setTimeout(() => {\n if (this.active) this.checkErrorPage()\n }, ERROR_PAGE_CHECK_DELAY_MS)\n }\n\n private handleFormSubmit(e: Event): void {\n const form = e.target\n if (!(form instanceof HTMLFormElement)) return\n if (this.isWidgetElement(form)) return\n\n setTimeout(() => {\n if (!this.active) return\n if (form.querySelector('[aria-invalid=\"true\"], .is-invalid')) {\n this.emitIfReady({\n signal: 'form_failure',\n target: describeElement(form),\n timestamp: Date.now(),\n })\n }\n }, FORM_CHECK_DELAY_MS)\n }\n\n private handleFormInvalid(e: Event): void {\n const el = e.target as Element | null\n if (!el) return\n if (this.isWidgetElement(el)) return\n const form = el.closest('form')\n this.emitIfReady({\n signal: 'form_failure',\n target: form ? describeElement(form) : describeElement(el),\n timestamp: Date.now(),\n })\n }\n\n private checkErrorPage(): void {\n const url = location.href\n if (this.errorPageUrls.has(url)) return\n\n const title = document.title.toLowerCase()\n if (ERROR_PAGE_PATTERNS.some(p => title.includes(p))) {\n this.errorPageUrls.add(url)\n this.emitHighPriority({\n signal: 'error_page',\n detail: document.title,\n timestamp: Date.now(),\n })\n return\n }\n\n const candidates = document.querySelectorAll(\n 'h1, h2, [class*=\"error\"], [class*=\"not-found\"], [id*=\"error\"], [id*=\"not-found\"]'\n )\n for (const el of candidates) {\n const text = el.textContent ?? ''\n if (text.length < 200 && ERROR_PAGE_PATTERNS.some(p => text.toLowerCase().includes(p))) {\n this.errorPageUrls.add(url)\n this.emitHighPriority({\n signal: 'error_page',\n detail: text.trim().slice(0, 60),\n timestamp: Date.now(),\n })\n return\n }\n }\n }\n\n // One shared observer for all in-flight dead-click checks, connected only\n // while at least one check is pending — a full-page observer per click was\n // too heavy on mutation-busy pages.\n private checkDeadClickDom(target: Element, clickTime: number): void {\n if (!this.looksInteractive(target)) return\n\n this.pendingDomChecks++\n this.ensureDomObserver()\n\n setTimeout(() => {\n this.pendingDomChecks--\n const mutated = this.lastMutationAt >= clickTime\n if (this.pendingDomChecks === 0) this.disconnectDomObserver()\n\n if (!mutated && this.active) {\n this.emitIfReady({\n signal: 'dead_click_dom',\n target: describeElement(target),\n timestamp: clickTime,\n })\n }\n }, DEAD_CLICK_DOM_DELAY_MS)\n }\n\n private ensureDomObserver(): void {\n if (this.domObserver) return\n this.domObserver = new MutationObserver(() => {\n this.lastMutationAt = Date.now()\n })\n this.domObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n })\n }\n\n private disconnectDomObserver(): void {\n this.domObserver?.disconnect()\n this.domObserver = null\n }\n\n private looksInteractive(el: Element): boolean {\n const style = window.getComputedStyle(el)\n if (style.cursor === 'pointer') return true\n\n if (el.classList) {\n for (const cls of el.classList) {\n const lower = cls.toLowerCase()\n if (lower.includes('btn') || lower.includes('button')) return true\n }\n }\n\n return false\n }\n\n private isInteractive(el: Element): boolean {\n if (INTERACTIVE_TAGS.has(el.tagName)) return true\n\n const role = el.getAttribute('role')\n if (role && INTERACTIVE_ROLES.has(role)) return true\n\n if (el.hasAttribute('onclick') || el.hasAttribute('tabindex')) return true\n if ((el as HTMLElement).contentEditable === 'true') return true\n\n const style = window.getComputedStyle(el)\n if (style.cursor === 'pointer') return true\n\n const parent = el.closest('a, button, [role=\"button\"], [role=\"link\"], label')\n if (parent) return true\n\n return false\n }\n\n private isWidgetElement(el: Element): boolean {\n const host = document.getElementById('mtb-widget-host')\n if (!host) return false\n return host === el || host.contains(el)\n }\n\n private emitIfReady(event: FrustrationEvent): void {\n const now = Date.now()\n if (now < this.cooldownUntil) return\n this.cooldownUntil = now + FrustrationDetector.COOLDOWN_MS\n this.onFrustration(event)\n }\n\n private emitHighPriority(event: FrustrationEvent): void {\n this.cooldownUntil = Date.now() + FrustrationDetector.COOLDOWN_MS\n this.onFrustration(event)\n }\n}\n\nfunction describeElement(el: Element): string {\n const tag = el.tagName.toLowerCase()\n const id = el.id ? `#${el.id}` : ''\n const cls = el.className && typeof el.className === 'string'\n ? '.' + el.className.trim().split(/\\s+/).slice(0, 2).join('.')\n : ''\n const text = el.textContent?.trim().slice(0, 30) ?? ''\n return `<${tag}${id}${cls}>${text ? ` \"${text}\"` : ''}`\n}\n","export interface PageContext {\n page_url: string\n user_agent: string\n browser: string\n os: string\n screen_width: number\n screen_height: number\n}\n\nexport function collectPageContext(): PageContext {\n return {\n page_url: window.location.href,\n user_agent: navigator.userAgent,\n browser: detectBrowser(),\n os: detectOS(),\n screen_width: window.screen.width,\n screen_height: window.screen.height,\n }\n}\n\nfunction detectBrowser(): string {\n const ua = navigator.userAgent\n if (/Edg\\//.test(ua)) return `Edge ${ua.match(/Edg\\/(\\S+)/)?.[1] ?? ''}`\n if (/OPR\\//.test(ua)) return `Opera ${ua.match(/OPR\\/(\\S+)/)?.[1] ?? ''}`\n if (/Chrome\\//.test(ua)) return `Chrome ${ua.match(/Chrome\\/(\\S+)/)?.[1] ?? ''}`\n if (/Safari\\//.test(ua) && /Version\\//.test(ua)) return `Safari ${ua.match(/Version\\/(\\S+)/)?.[1] ?? ''}`\n if (/Firefox\\//.test(ua)) return `Firefox ${ua.match(/Firefox\\/(\\S+)/)?.[1] ?? ''}`\n return 'Unknown'\n}\n\nfunction detectOS(): string {\n const ua = navigator.userAgent\n if (/Windows NT 10/.test(ua)) return 'Windows 10/11'\n if (/Windows NT/.test(ua)) return 'Windows'\n if (/Mac OS X 10_15|macOS 1[56789]/.test(ua)) return 'macOS'\n if (/Mac OS X/.test(ua)) return 'macOS'\n if (/Android/.test(ua)) return `Android ${ua.match(/Android (\\d+)/)?.[1] ?? ''}`\n if (/iPhone|iPad|iPod/.test(ua)) return 'iOS'\n if (/Linux/.test(ua)) return 'Linux'\n return 'Unknown'\n}\n","import type { FeedbackPayload, FeedbackResponse, ClarifyResponse } from '../types'\n\nconst DEFAULT_API_URL = 'https://makethisbetter.dev/api/v1'\n\nexport class ApiClient {\n private apiUrl: string\n private projectKey: string\n private retryDelayMs: number\n private userToken?: string\n private userTokenFn?: () => Promise<string>\n\n constructor(projectKey: string, apiUrl?: string, retryDelayMs = 1000, userToken?: string, userTokenFn?: () => Promise<string>) {\n this.projectKey = projectKey\n this.apiUrl = (apiUrl ?? DEFAULT_API_URL).replace(/\\/$/, '')\n this.retryDelayMs = retryDelayMs\n this.userToken = userToken\n this.userTokenFn = userTokenFn\n }\n\n async resolveUserToken(): Promise<string | undefined> {\n if (this.userTokenFn) return this.userTokenFn()\n return this.userToken\n }\n\n private async authHeaders(contentType?: string): Promise<Record<string, string>> {\n const headers: Record<string, string> = { 'X-Project-Key': this.projectKey }\n const token = await this.resolveUserToken()\n if (token) headers['X-User-Token'] = token\n if (contentType) headers['Content-Type'] = contentType\n return headers\n }\n\n async submitFeedback(payload: FeedbackPayload, screenshot: Blob | null): Promise<FeedbackResponse> {\n const form = new FormData()\n form.append('feedback[description]', payload.description)\n form.append('feedback[page_url]', payload.page_url)\n form.append('feedback[user_agent]', payload.user_agent)\n form.append('feedback[browser]', payload.browser)\n form.append('feedback[os]', payload.os)\n form.append('feedback[screen_width]', String(payload.screen_width))\n form.append('feedback[screen_height]', String(payload.screen_height))\n form.append('feedback[console_errors]', JSON.stringify(payload.console_errors))\n form.append('feedback[annotations]', JSON.stringify(payload.annotations))\n\n if (payload.target_element) {\n form.append('feedback[target_element]', JSON.stringify(payload.target_element))\n }\n if (payload.user_id) form.append('feedback[user_id]', payload.user_id)\n if (payload.user_email) form.append('feedback[user_email]', payload.user_email)\n if (payload.user_name) form.append('feedback[user_name]', payload.user_name)\n\n if (payload.recording_events && payload.recording_events.length > 0) {\n const json = JSON.stringify(payload.recording_events)\n const blob = new Blob([json], { type: 'application/json' })\n form.append('feedback[recording]', blob, 'recording.json')\n form.append('feedback[recording_duration]', String(payload.recording_duration ?? 0))\n }\n\n if (screenshot) {\n form.append('feedback[screenshot]', screenshot, 'screenshot.png')\n }\n\n const headers = await this.authHeaders()\n // One key per submission, reused across retries: if the first POST\n // reached the server but the response was lost, the retry must not\n // create a second feedback.\n headers['X-Idempotency-Key'] = generateIdempotencyKey()\n const res = await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks`, {\n method: 'POST',\n headers,\n body: form,\n })\n return res.json() as Promise<FeedbackResponse>\n }\n\n async startClarification(feedbackId: string, message?: string): Promise<ClarifyResponse> {\n const body: Record<string, string> = {}\n if (message) body.message = message\n const headers = await this.authHeaders('application/json')\n const res = await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks/${feedbackId}/clarify`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n return res.json() as Promise<ClarifyResponse>\n }\n\n async getClarification(feedbackId: string): Promise<ClarifyResponse> {\n const headers = await this.authHeaders()\n const res = await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks/${feedbackId}/clarify`, {\n method: 'GET',\n headers,\n })\n return res.json() as Promise<ClarifyResponse>\n }\n\n private async fetchWithRetry(url: string, init: RequestInit, retries = 1): Promise<Response> {\n let res: Response\n try {\n res = await fetch(url, init)\n } catch (err) {\n if (retries > 0) {\n await delay(this.retryDelayMs)\n return this.fetchWithRetry(url, init, retries - 1)\n }\n throw err\n }\n\n if (res.ok) return res\n if (res.status >= 500 && retries > 0) {\n await delay(this.retryDelayMs)\n return this.fetchWithRetry(url, init, retries - 1)\n }\n throw new Error(`HTTP ${res.status}`)\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n if (ms <= 0) return Promise.resolve()\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nfunction generateIdempotencyKey(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`\n}\n","import type { PageContext } from '../context/collector'\nimport type { Annotation, FeedbackPayload, MakeThisBetterConfig } from '../types'\nimport type { RecordingResult } from '../record/session'\n\nexport function buildPayload(\n description: string,\n pageContext: PageContext,\n consoleErrors: string[],\n annotation: Annotation | null,\n user: MakeThisBetterConfig['user'],\n recording?: RecordingResult,\n): FeedbackPayload {\n return {\n description,\n ...pageContext,\n console_errors: consoleErrors,\n annotations: annotation ? [annotation] : [],\n target_element: annotation?.targetSelector\n ? {\n selector: annotation.targetSelector,\n text: annotation.targetText ?? '',\n name: annotation.targetName ?? '',\n }\n : undefined,\n user_id: user?.id,\n user_email: user?.email,\n user_name: user?.name,\n recording_events: recording?.events,\n recording_duration: recording?.duration,\n }\n}\n","export default {\n tab: 'Feedback',\n toolbar: {\n markup: 'Mark up',\n record: 'Record',\n hint: 'Click any element to annotate · drag to draw',\n hintRecord: 'Recording your screen',\n exit: 'Exit',\n },\n popup: {\n about: 'About',\n placeholder: 'Describe the issue or suggestion...',\n submit: 'Submit',\n cancel: 'Cancel',\n quickOptions: [\n { emoji: '🐛', label: 'Something is broken' },\n { emoji: '💡', label: 'I wish this worked differently' },\n { emoji: '🤔', label: \"I don't understand this\" },\n { emoji: '✨', label: 'I have an idea' },\n ],\n },\n success: {\n title: 'Thanks!',\n message: 'Your feedback has been received.',\n title_no_ai: 'Sent — thanks!',\n message_no_ai: \"We'll take it from here. You'll hear back when it's resolved.\",\n view_feedback: 'View my feedback',\n close: 'Close',\n },\n error: {\n submit: 'Failed to submit. Please try again.',\n },\n pet: {\n bubble: 'Need help?',\n },\n frustration: {\n prompt: 'Something not working? Tell us.',\n action: 'Annotate',\n dismiss: 'Dismiss',\n },\n annotation: {\n drawing: 'Drawing',\n element: 'element',\n },\n record: {\n stop: 'Stop',\n timer_label: 'Recording',\n max_reached: 'Maximum recording time reached',\n },\n clarify: {\n thinking: 'Thinking...',\n placeholder: 'Type your response...',\n send: 'Send',\n skip: 'Skip',\n },\n}\n","export default {\n tab: '反馈',\n toolbar: {\n markup: '标注',\n record: '录屏',\n hint: '点击任意元素进行标注 · 拖拽可自由绘制',\n hintRecord: '正在录制屏幕',\n exit: '退出',\n },\n popup: {\n about: '关于',\n placeholder: '描述问题或建议...',\n submit: '提交',\n cancel: '取消',\n quickOptions: [\n { emoji: '🐛', label: '这里有问题' },\n { emoji: '💡', label: '我希望它能更好用' },\n { emoji: '🤔', label: '我看不懂这里' },\n { emoji: '✨', label: '我有个想法' },\n ],\n },\n success: {\n title: '感谢!',\n message: '您的反馈已收到。',\n title_no_ai: '已发送,感谢!',\n message_no_ai: '我们会跟进处理,解决后会通知您。',\n view_feedback: '查看我的反馈',\n close: '关闭',\n },\n error: {\n submit: '提交失败,请重试。',\n },\n pet: {\n bubble: '需要帮助吗?',\n },\n frustration: {\n prompt: '遇到问题了?告诉我们。',\n action: '标注',\n dismiss: '关闭',\n },\n annotation: {\n drawing: '绘制',\n element: '元素',\n },\n record: {\n stop: '停止',\n timer_label: '录制中',\n max_reached: '已达到最大录制时长',\n },\n clarify: {\n thinking: '思考中...',\n placeholder: '输入你的回复...',\n send: '发送',\n skip: '跳过',\n },\n}\n","export default {\n tab: 'フィードバック',\n toolbar: {\n markup: 'マークアップ',\n record: '録画',\n hint: '要素をクリックして注釈 · ドラッグで描画',\n hintRecord: '画面を録画中',\n exit: '終了',\n },\n popup: {\n about: '概要',\n placeholder: '問題や提案を入力してください...',\n submit: '送信',\n cancel: 'キャンセル',\n quickOptions: [\n { emoji: '🐛', label: '不具合があります' },\n { emoji: '💡', label: 'もっと使いやすくしてほしい' },\n { emoji: '🤔', label: 'ここがわかりにくい' },\n { emoji: '✨', label: 'アイデアがあります' },\n ],\n },\n success: {\n title: 'ありがとうございます!',\n message: 'フィードバックを受け付けました。',\n title_no_ai: '送信しました!',\n message_no_ai: 'チームが対応します。解決次第お知らせします。',\n view_feedback: 'フィードバックを確認',\n close: '閉じる',\n },\n error: {\n submit: '送信に失敗しました。もう一度お試しください。',\n },\n pet: {\n bubble: 'お困りですか?',\n },\n frustration: {\n prompt: 'うまくいかないことがありますか?お知らせください。',\n action: '注釈',\n dismiss: '閉じる',\n },\n annotation: {\n drawing: '描画',\n element: '要素',\n },\n record: {\n stop: '停止',\n timer_label: '録画中',\n max_reached: '最大録画時間に達しました',\n },\n clarify: {\n thinking: '考え中...',\n placeholder: '回答を入力...',\n send: '送信',\n skip: 'スキップ',\n },\n}\n","export default {\n tab: '피드백',\n toolbar: {\n markup: '마크업',\n record: '녹화',\n hint: '요소를 클릭하여 주석 · 드래그하여 그리기',\n hintRecord: '화면을 녹화 중입니다',\n exit: '나가기',\n },\n popup: {\n about: '정보',\n placeholder: '문제 또는 제안 사항을 설명해 주세요...',\n submit: '제출',\n cancel: '취소',\n quickOptions: [\n { emoji: '🐛', label: '오류가 있어요' },\n { emoji: '💡', label: '이 기능을 개선해 주세요' },\n { emoji: '🤔', label: '이 부분을 모르겠어요' },\n { emoji: '✨', label: '아이디어가 있어요' },\n ],\n },\n success: {\n title: '감사합니다!',\n message: '피드백이 접수되었습니다.',\n title_no_ai: '전송 완료!',\n message_no_ai: '팀에서 처리 후 알려드리겠습니다.',\n view_feedback: '내 피드백 보기',\n close: '닫기',\n },\n error: {\n submit: '제출에 실패했습니다. 다시 시도해 주세요.',\n },\n pet: {\n bubble: '도움이 필요하신가요?',\n },\n frustration: {\n prompt: '문제가 있으신가요? 알려 주세요.',\n action: '주석',\n dismiss: '닫기',\n },\n annotation: {\n drawing: '그리기',\n element: '요소',\n },\n record: {\n stop: '중지',\n timer_label: '녹화 중',\n max_reached: '최대 녹화 시간에 도달했습니다',\n },\n clarify: {\n thinking: '생각 중...',\n placeholder: '답변을 입력하세요...',\n send: '보내기',\n skip: '건너뛰기',\n },\n}\n","export default {\n tab: 'Comentarios',\n toolbar: {\n markup: 'Anotar',\n record: 'Grabar',\n hint: 'Haz clic en cualquier elemento para anotar · arrastra para dibujar',\n hintRecord: 'Grabando tu pantalla',\n exit: 'Salir',\n },\n popup: {\n about: 'Acerca de',\n placeholder: 'Describe el problema o sugerencia...',\n submit: 'Enviar',\n cancel: 'Cancelar',\n quickOptions: [\n { emoji: '🐛', label: 'Algo no funciona' },\n { emoji: '💡', label: 'Me gustaría que funcionara diferente' },\n { emoji: '🤔', label: 'No entiendo esto' },\n { emoji: '✨', label: 'Tengo una idea' },\n ],\n },\n success: {\n title: '¡Gracias!',\n message: 'Tu comentario ha sido recibido.',\n title_no_ai: '¡Enviado!',\n message_no_ai: 'Nos encargamos. Te avisaremos cuando se resuelva.',\n view_feedback: 'Ver mis comentarios',\n close: 'Cerrar',\n },\n error: {\n submit: 'Error al enviar. Por favor, inténtalo de nuevo.',\n },\n pet: {\n bubble: '¿Necesitas ayuda?',\n },\n frustration: {\n prompt: '¿Algo no funciona? Cuéntanos.',\n action: 'Anotar',\n dismiss: 'Cerrar',\n },\n annotation: {\n drawing: 'Dibujo',\n element: 'elemento',\n },\n record: {\n stop: 'Detener',\n timer_label: 'Grabando',\n max_reached: 'Se alcanzó el tiempo máximo de grabación',\n },\n clarify: {\n thinking: 'Pensando...',\n placeholder: 'Escribe tu respuesta...',\n send: 'Enviar',\n skip: 'Omitir',\n },\n}\n","export default {\n tab: 'Avis',\n toolbar: {\n markup: 'Annoter',\n record: 'Enregistrer',\n hint: \"Cliquez sur un élément pour l'annoter · glissez pour dessiner\",\n hintRecord: \"Enregistrement de l'écran en cours\",\n exit: 'Quitter',\n },\n popup: {\n about: 'À propos',\n placeholder: 'Décrivez le problème ou votre suggestion...',\n submit: 'Envoyer',\n cancel: 'Annuler',\n quickOptions: [\n { emoji: '🐛', label: 'Quelque chose ne fonctionne pas' },\n { emoji: '💡', label: \"J'aimerais que cela fonctionne autrement\" },\n { emoji: '🤔', label: 'Je ne comprends pas ceci' },\n { emoji: '✨', label: \"J'ai une idée\" },\n ],\n },\n success: {\n title: 'Merci !',\n message: 'Votre avis a bien été reçu.',\n title_no_ai: 'Envoyé !',\n message_no_ai: \"On s'en occupe. Vous serez informé(e) dès que ce sera résolu.\",\n view_feedback: 'Voir mes avis',\n close: 'Fermer',\n },\n error: {\n submit: \"Échec de l'envoi. Veuillez réessayer.\",\n },\n pet: {\n bubble: \"Besoin d'aide ?\",\n },\n frustration: {\n prompt: 'Un problème ? Dites-le-nous.',\n action: 'Annoter',\n dismiss: 'Fermer',\n },\n annotation: {\n drawing: 'Dessin',\n element: 'élément',\n },\n record: {\n stop: 'Arrêter',\n timer_label: 'Enregistrement',\n max_reached: \"Durée maximale d'enregistrement atteinte\",\n },\n clarify: {\n thinking: 'Réflexion...',\n placeholder: 'Tapez votre réponse...',\n send: 'Envoyer',\n skip: 'Passer',\n },\n}\n","export default {\n tab: 'Feedback',\n toolbar: {\n markup: 'Markieren',\n record: 'Aufnehmen',\n hint: 'Klicken Sie auf ein Element zum Kommentieren · ziehen Sie zum Zeichnen',\n hintRecord: 'Bildschirmaufnahme läuft',\n exit: 'Beenden',\n },\n popup: {\n about: 'Info',\n placeholder: 'Beschreiben Sie das Problem oder Ihren Vorschlag...',\n submit: 'Absenden',\n cancel: 'Abbrechen',\n quickOptions: [\n { emoji: '🐛', label: 'Etwas funktioniert nicht' },\n { emoji: '💡', label: 'Ich wünsche mir das anders' },\n { emoji: '🤔', label: 'Das verstehe ich nicht' },\n { emoji: '✨', label: 'Ich habe eine Idee' },\n ],\n },\n success: {\n title: 'Vielen Dank!',\n message: 'Ihr Feedback wurde empfangen.',\n title_no_ai: 'Gesendet!',\n message_no_ai: 'Wir kümmern uns darum. Sie werden benachrichtigt, sobald es gelöst ist.',\n view_feedback: 'Mein Feedback ansehen',\n close: 'Schließen',\n },\n error: {\n submit: 'Senden fehlgeschlagen. Bitte versuchen Sie es erneut.',\n },\n pet: {\n bubble: 'Brauchen Sie Hilfe?',\n },\n frustration: {\n prompt: 'Etwas funktioniert nicht? Sagen Sie es uns.',\n action: 'Kommentieren',\n dismiss: 'Schließen',\n },\n annotation: {\n drawing: 'Zeichnung',\n element: 'Element',\n },\n record: {\n stop: 'Stopp',\n timer_label: 'Aufnahme',\n max_reached: 'Maximale Aufnahmezeit erreicht',\n },\n clarify: {\n thinking: 'Einen Moment...',\n placeholder: 'Antwort eingeben...',\n send: 'Senden',\n skip: 'Überspringen',\n },\n}\n","import en from './en'\nimport zhCN from './zh-CN'\nimport ja from './ja'\nimport ko from './ko'\nimport es from './es'\nimport fr from './fr'\nimport de from './de'\n\nexport type I18nMessages = typeof en\n\nconst locales: Record<string, I18nMessages> = {\n en,\n 'zh-CN': zhCN,\n ja,\n ko,\n es,\n fr,\n de,\n}\n\nexport function getMessages(locale: string): I18nMessages {\n if (locales[locale]) return locales[locale]\n const lang = locale.split('-')[0]\n if (locales[lang]) return locales[lang]\n return locales['en']\n}\n","import type { ShadowContainer } from '../widget/shadow'\n\ntype RRWebEvent = Record<string, unknown>\ntype StopFn = () => void\n\ninterface RRWebRecordFn {\n (options: { emit: (event: RRWebEvent) => void }): StopFn\n addCustomEvent: (tag: string, payload: Record<string, unknown>) => void\n}\n\nexport interface RecordingResult {\n events: RRWebEvent[]\n duration: number\n}\n\nconst MAX_DURATION_S = 60\n// Pinned version + SRI: this script executes on customers' pages, so a\n// floating tag or unverified content would be a supply-chain hole. Bumping\n// the version requires recomputing the hash from the exact CDN file:\n// curl -sL <url> | openssl dgst -sha384 -binary | openssl base64 -A\n// Must stay on @rrweb/record's static /umd/ build: the `rrweb` package ships\n// no UMD in 2.x (its dist files are ESM and throw \"Unexpected token 'export'\"\n// in a classic script tag), and jsDelivr's auto-minified files are unsafe for\n// SRI because their hash changes when jsDelivr upgrades its minifier.\nconst RRWEB_CDN = 'https://cdn.jsdelivr.net/npm/@rrweb/record@2.1.0/umd/record.min.js'\nconst RRWEB_SRI = 'sha384-MrD66HBNSykaP2N95+6hQCFlF5oH2tvL3TD/zyvHNkP/sAFWZx98DX9MEDy8MdVT'\n\nlet rrwebLoaded: Promise<RRWebRecordFn> | null = null\n\nfunction loadRrweb(): Promise<RRWebRecordFn> {\n if (rrwebLoaded) return rrwebLoaded\n rrwebLoaded = loadViaImport().catch(() => loadViaCdn())\n return rrwebLoaded\n}\n\nasync function loadViaImport(): Promise<RRWebRecordFn> {\n const mod = await import('@rrweb/record')\n return mod.record as unknown as RRWebRecordFn\n}\n\ninterface RRWebGlobals {\n rrwebRecord?: { record: RRWebRecordFn }\n rrweb?: { record: RRWebRecordFn }\n}\n\nfunction findGlobalRecord(): RRWebRecordFn | undefined {\n const win = globalThis as unknown as Window & RRWebGlobals\n return win.rrwebRecord?.record ?? win.rrweb?.record\n}\n\nfunction loadViaCdn(): Promise<RRWebRecordFn> {\n return new Promise((resolve, reject) => {\n const existing = findGlobalRecord()\n if (existing) { resolve(existing); return }\n const script = document.createElement('script')\n script.src = RRWEB_CDN\n script.integrity = RRWEB_SRI\n script.crossOrigin = 'anonymous'\n script.onload = () => {\n const record = findGlobalRecord()\n if (record) resolve(record)\n else reject(new Error('rrweb record global not found after script load'))\n }\n script.onerror = () => reject(new Error('Failed to load rrweb from CDN'))\n document.head.appendChild(script)\n })\n}\n\nexport class RecordSession {\n private events: RRWebEvent[] = []\n private stopFn: StopFn | null = null\n private startedAt = 0\n private timer: ReturnType<typeof setTimeout> | null = null\n private clickHandler: ((e: MouseEvent) => void) | null = null\n private shadow: ShadowContainer\n private onMaxReached?: () => void\n private stopped = false\n\n constructor(shadow: ShadowContainer, onMaxReached?: () => void) {\n this.shadow = shadow\n this.onMaxReached = onMaxReached\n }\n\n async start(): Promise<void> {\n const record = await loadRrweb()\n\n this.startedAt = Date.now()\n this.stopped = false\n\n this.stopFn = record({\n emit: (event: RRWebEvent) => {\n if (!this.stopped) this.events.push(event)\n },\n })\n\n this.clickHandler = (e: MouseEvent) => {\n this.showClickRipple(e.clientX, e.clientY)\n record.addCustomEvent?.('mtb-click', {\n x: e.clientX,\n y: e.clientY,\n target: e.target instanceof HTMLElement ? e.target.tagName : '',\n })\n }\n document.addEventListener('click', this.clickHandler, true)\n\n this.timer = setTimeout(() => {\n this.onMaxReached?.()\n }, MAX_DURATION_S * 1000)\n }\n\n stop(): RecordingResult {\n this.stopped = true\n this.stopFn?.()\n this.stopFn = null\n this.cleanupTimer()\n this.cleanupClickHandler()\n\n return {\n events: this.events,\n duration: this.getDuration(),\n }\n }\n\n getDuration(): number {\n if (this.startedAt === 0) return 0\n return Math.round((Date.now() - this.startedAt) / 1000)\n }\n\n destroy(): void {\n this.stopped = true\n this.stopFn?.()\n this.stopFn = null\n this.cleanupTimer()\n this.cleanupClickHandler()\n this.events = []\n this.startedAt = 0\n }\n\n private cleanupTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer)\n this.timer = null\n }\n }\n\n private cleanupClickHandler(): void {\n if (this.clickHandler) {\n document.removeEventListener('click', this.clickHandler, true)\n this.clickHandler = null\n }\n }\n\n private showClickRipple(x: number, y: number): void {\n const ripple = this.shadow.el<HTMLDivElement>('div', 'mtb-click-ripple')\n ripple.style.left = `${x}px`\n ripple.style.top = `${y}px`\n this.shadow.append(ripple)\n ripple.addEventListener('animationend', () => ripple.remove())\n }\n}\n","import type { ShadowContainer } from '../widget/shadow'\nimport type { I18nMessages } from '../i18n'\n\nexport class RecordControlBar {\n private el: HTMLDivElement\n private timerEl!: HTMLSpanElement\n private intervalId: ReturnType<typeof setInterval> | null = null\n private getDuration: () => number\n\n constructor(\n shadow: ShadowContainer,\n messages: I18nMessages,\n getDuration: () => number,\n onStop: () => void,\n ) {\n this.getDuration = getDuration\n\n this.el = shadow.el<HTMLDivElement>('div', 'mtb-record-bar')\n this.el.innerHTML = `\n <span class=\"mtb-record-dot\"></span>\n <span class=\"mtb-record-timer\">00:00</span>\n <button class=\"mtb-record-stop\" type=\"button\">${messages.record.stop}</button>\n `\n shadow.append(this.el)\n\n this.timerEl = this.el.querySelector('.mtb-record-timer')!\n this.el.querySelector('.mtb-record-stop')!.addEventListener('click', onStop)\n\n this.intervalId = setInterval(() => this.updateTimer(), 1000)\n }\n\n private updateTimer(): void {\n const secs = this.getDuration()\n const mm = String(Math.floor(secs / 60)).padStart(2, '0')\n const ss = String(secs % 60).padStart(2, '0')\n this.timerEl.textContent = `${mm}:${ss}`\n }\n\n destroy(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId)\n this.intervalId = null\n }\n this.el.remove()\n }\n}\n","import { RecordSession } from '../record/session'\nimport type { RecordingResult } from '../record/session'\nimport { RecordControlBar } from '../record/control-bar'\nimport type { ShadowContainer } from './shadow'\nimport type { I18nMessages } from '../i18n'\n\nexport type { RecordingResult }\n\nexport class RecordingManager {\n private session: RecordSession | null = null\n private bar: RecordControlBar | null = null\n private result: RecordingResult | null = null\n\n async start(\n shadow: ShadowContainer,\n messages: I18nMessages,\n onStop: () => void,\n ): Promise<void> {\n this.session = new RecordSession(shadow, onStop)\n this.bar = new RecordControlBar(\n shadow,\n messages,\n () => this.session?.getDuration() ?? 0,\n onStop,\n )\n await this.session.start()\n }\n\n stop(): RecordingResult | null {\n if (!this.session) return null\n this.result = this.session.stop()\n this.teardownUI()\n return this.result\n }\n\n getRecording(): RecordingResult | null {\n return this.result\n }\n\n destroy(): void {\n this.teardownUI()\n this.result = null\n }\n\n private teardownUI(): void {\n this.session?.destroy()\n this.session = null\n this.bar?.destroy()\n this.bar = null\n }\n}\n","import { ShadowContainer } from './shadow'\nimport { FeedbackTab } from './tab'\nimport { FrustrationPromptCard } from './frustration-prompt'\nimport { AnnotationToolbar } from '../annotate/toolbar'\nimport type { ToolbarMode } from '../annotate/toolbar'\nimport { AnnotationSession } from '../annotate/session'\nimport { CommentPopup } from '../popup/comment'\nimport { ClarifyCard } from '../popup/clarify'\nimport { SuccessCard } from '../popup/success'\nimport type { SuccessCardOptions } from '../popup/success'\nimport { captureScreenshot } from '../screenshot/capture'\nimport { ConsoleErrorCollector } from '../context/console'\nimport { FrustrationDetector } from '../context/frustration'\nimport { collectPageContext } from '../context/collector'\nimport { ApiClient } from '../api/client'\nimport { buildPayload } from './payload'\nimport { getMessages } from '../i18n'\nimport { RecordingManager } from './recording-manager'\nimport type { MakeThisBetterConfig, Annotation } from '../types'\n\ntype Mode = 'idle' | 'annotating' | 'recording' | 'popup'\n\nexport class WidgetController {\n private config: MakeThisBetterConfig\n private shadow!: ShadowContainer\n private tab: FeedbackTab | null = null\n private toolbar: AnnotationToolbar | null = null\n private session: AnnotationSession | null = null\n private popup: CommentPopup | null = null\n private clarify: ClarifyCard | null = null\n private success: SuccessCard | null = null\n private frustrationPrompt: FrustrationPromptCard | null = null\n private apiClient: ApiClient\n private consoleCollector: ConsoleErrorCollector\n private frustrationDetector: FrustrationDetector | null = null\n private messages: ReturnType<typeof getMessages>\n private mode: Mode = 'idle'\n private currentAnnotation: Annotation | null = null\n private recordingManager: RecordingManager | null = null\n\n constructor(config: MakeThisBetterConfig) {\n this.config = config\n this.messages = getMessages(config.locale ?? 'en')\n this.apiClient = new ApiClient(config.projectKey, config.apiUrl, undefined, config.userToken, config.userTokenFn)\n this.consoleCollector = new ConsoleErrorCollector()\n this.consoleCollector.start()\n this.buildUI()\n\n if (config.frustrationDetection !== false) {\n this.frustrationDetector = new FrustrationDetector(() => this.handleFrustration())\n this.frustrationDetector.start()\n }\n }\n\n private buildUI(): void {\n this.shadow = new ShadowContainer(this.config.theme ?? 'auto')\n\n this.tab = new FeedbackTab(\n this.shadow,\n this.messages,\n this.config.position ?? 'right',\n () => this.handleTabClick(),\n this.config.tabText,\n )\n }\n\n private handleTabClick(): void {\n if (this.mode === 'idle') {\n this.dismissFrustrationPrompt()\n this.enterAnnotationMode()\n } else {\n this.exitAll()\n }\n }\n\n private handleFrustration(): void {\n if (this.mode !== 'idle' || this.frustrationPrompt) return\n\n this.frustrationPrompt = new FrustrationPromptCard(this.shadow, this.messages, {\n onTell: () => {\n this.dismissFrustrationPrompt()\n this.enterAnnotationMode()\n },\n onDismiss: () => this.dismissFrustrationPrompt(),\n })\n }\n\n private dismissFrustrationPrompt(): void {\n this.frustrationPrompt?.destroy()\n this.frustrationPrompt = null\n }\n\n private enterAnnotationMode(): void {\n this.mode = 'annotating'\n this.tab?.setActive(true)\n\n this.toolbar = new AnnotationToolbar(\n this.shadow,\n this.messages,\n () => this.exitAll(),\n (mode: ToolbarMode) => this.handleToolbarModeChange(mode),\n )\n this.session = new AnnotationSession(this.shadow, this.messages, (annotation, targetName) => {\n this.currentAnnotation = annotation\n this.showPopup(annotation.x, annotation.y, targetName)\n })\n }\n\n private handleToolbarModeChange(mode: ToolbarMode): void {\n if (mode === 'record') {\n this.mode = 'recording'\n this.session?.destroy()\n this.session = null\n this.recordingManager = new RecordingManager()\n this.recordingManager.start(this.shadow, this.messages, () => {\n if (!this.recordingManager) return\n this.recordingManager.stop()\n this.showPopup(window.innerWidth / 2, window.innerHeight / 2, this.messages.record.timer_label)\n }).catch((error) => {\n // rrweb failed to load (network / SRI mismatch) — fall back to markup\n console.warn('[MakeThisBetter] Screen recording unavailable, falling back to markup:', error)\n if (this.mode !== 'recording') return\n this.toolbar?.setMode('markup')\n this.handleToolbarModeChange('markup')\n })\n } else {\n this.recordingManager?.destroy()\n this.recordingManager = null\n if (!this.session) {\n this.session = new AnnotationSession(this.shadow, this.messages, (annotation, targetName) => {\n this.currentAnnotation = annotation\n this.showPopup(annotation.x, annotation.y, targetName)\n })\n }\n this.mode = 'annotating'\n }\n }\n\n private showPopup(x: number, y: number, targetName: string): void {\n this.mode = 'popup'\n this.session?.dismissInteraction()\n\n this.popup = new CommentPopup(this.shadow, {\n targetName,\n x,\n y,\n messages: this.messages,\n onSubmit: (description) => this.handleSubmit(description),\n onClose: () => this.exitAll(),\n })\n }\n\n private async handleSubmit(description: string): Promise<void> {\n if (!this.popup) return\n this.popup.setLoading(true)\n const annotation = this.currentAnnotation\n const recording = this.recordingManager?.getRecording() ?? undefined\n\n const [screenshot, pageContext] = await Promise.all([\n captureScreenshot(annotation ? [annotation] : []),\n Promise.resolve(collectPageContext()),\n ])\n\n const payload = buildPayload(\n description,\n pageContext,\n this.consoleCollector.getErrors(),\n annotation,\n this.config.user,\n recording,\n )\n\n try {\n const feedback = await this.apiClient.submitFeedback(payload, screenshot)\n this.popup?.destroy()\n this.popup = null\n this.session?.destroy()\n this.session = null\n this.toolbar?.destroy()\n this.toolbar = null\n this.recordingManager?.destroy()\n this.recordingManager = null\n const skipFollowup = feedback.skip_followup === true || feedback.ai_clarify_available === false\n if (skipFollowup) {\n this.showSuccess(feedback.project_id, { skipFollowup: true })\n } else {\n this.showClarify(feedback.id, feedback.project_id)\n }\n } catch {\n this.popup?.setLoading(false)\n this.popup?.setError(this.messages.error.submit)\n }\n }\n\n private showClarify(feedbackId: string, projectId: string): void {\n this.mode = 'idle'\n this.tab?.setActive(false)\n this.clarify = new ClarifyCard(this.shadow, {\n feedbackId,\n apiClient: this.apiClient,\n messages: this.messages,\n onDone: () => {\n this.clarify?.destroy()\n this.clarify = null\n this.showSuccess(projectId)\n },\n })\n }\n\n private showSuccess(projectId: string, options?: SuccessCardOptions): void {\n this.mode = 'idle'\n this.tab?.setActive(false)\n const baseUrl = this.config.apiUrl\n ? this.config.apiUrl.replace(/\\/api\\/v1\\/?$/, '')\n : 'https://makethisbetter.dev'\n const boardUrl = `${baseUrl}/board/projects/${projectId}/feedbacks`\n const hasIdentity = !!(this.config.userToken || this.config.userTokenFn)\n this.success = new SuccessCard(this.shadow, this.messages, () => {\n this.success?.destroy()\n this.success = null\n }, hasIdentity ? async () => {\n const token = await this.apiClient.resolveUserToken()\n if (token) window.open(`${boardUrl}?identity=${encodeURIComponent(token)}`, '_blank')\n } : undefined, options)\n }\n\n private exitAll(): void {\n this.mode = 'idle'\n this.tab?.setActive(false)\n this.toolbar?.destroy()\n this.toolbar = null\n this.session?.destroy()\n this.session = null\n this.popup?.destroy()\n this.popup = null\n this.clarify?.destroy()\n this.clarify = null\n this.currentAnnotation = null\n this.recordingManager?.destroy()\n this.recordingManager = null\n }\n\n destroy(): void {\n this.exitAll()\n this.consoleCollector.stop()\n this.frustrationDetector?.stop()\n this.dismissFrustrationPrompt()\n this.clarify?.destroy()\n this.success?.destroy()\n this.tab?.destroy()\n this.recordingManager?.destroy()\n this.shadow.destroy()\n }\n}\n","import { WidgetController } from './widget/controller'\nimport type { MakeThisBetterConfig } from './types'\n\nlet instance: WidgetController | null = null\n\nconst MakeThisBetter = {\n init(config: MakeThisBetterConfig): void {\n if (instance) {\n instance.destroy()\n instance = null\n }\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n instance = new WidgetController(config)\n })\n } else {\n instance = new WidgetController(config)\n }\n },\n\n destroy(): void {\n instance?.destroy()\n instance = null\n },\n}\n\nexport { MakeThisBetter }\nexport type { MakeThisBetterConfig }\n\nif (typeof window !== 'undefined') {\n (window as Window & { MakeThisBetter?: typeof MakeThisBetter }).MakeThisBetter = MakeThisBetter\n}\n"],"names":["ShadowContainer","theme","style","cssText","tag","className","el","nodes","n","FeedbackTab","shadow","messages","position","onClick","customText","label","active","FRUSTRATION_DISMISS_MS","FrustrationPromptCard","handlers","AnnotationToolbar","onExit","onModeChange","m","mode","AnnotationOverlay","ElementHighlighter","rect","getElementName","title","text","placeholder","alt","dataMark","getCssSelector","parts","current","selector","classNames","c","parent","siblings","idx","PinMarker","x","y","index","pin","BRAND_COLOR","DRAW_STROKE","DrawLayer","onDrawComplete","center","pathD","annotation","fx","fy","d","i","xs","p","ys","cx","cy","DRAW_MIN_POINTS","AnnotationSession","onReady","e","underEl","getElementUnder","targetName","CommentPopup","opts","quickOpts","o","escapeHtml","vw","vh","margin","left","top","btn","hasText","loading","message","POLL_INTERVAL_MS","DONE_DELAY_MS","ClarifyCard","res","done","last","msg","bubble","dots","SUCCESS_AUTO_CLOSE_MS","SuccessCard","onClose","onViewFeedback","options","viewLink","resolveUrl","url","baseUrl","doc","base","a","uuid","counter","random","toArray","arrayLike","arr","l","styleProps","getStyleProperties","px","node","styleProperty","val","getNodeWidth","leftBorder","rightBorder","getNodeHeight","topBorder","bottomBorder","getImageSize","targetNode","width","height","getPixelRatio","ratio","FINAL_PROCESS","canvasDimensionLimit","checkCanvasDimensions","canvas","createImage","resolve","reject","img","svgToDataURL","svg","html","nodeToDataURL","xmlns","foreignObject","isInstanceOfElement","instance","nodePrototype","formatCSSText","content","formatCSSProperties","name","value","priority","getPseudoElementStyle","pseudo","clonePseudoElement","nativeNode","clonedNode","styleElement","clonePseudoElements","WOFF","JPEG","mimes","getExtension","match","getMimeType","extension","getContentFromDataUrl","dataURL","isDataUrl","makeDataUrl","mimeType","fetchAsDataURL","init","process","blob","reader","error","cache","getCacheKey","contentType","includeQueryParams","key","resourceToDataURL","resourceUrl","cacheKey","result","cloneCanvasElement","cloneVideoElement","video","ctx","poster","cloneIFrameElement","iframe","_a","cloneNode","cloneSingleNode","isSVGElement","isSlotElement","cloneChildren","_b","children","deferred","child","clonedChild","cloneCSSStyle","targetStyle","sourceStyle","cloneInputValue","cloneSelectValue","clonedSelect","selectedOption","decorate","ensureSVGSymbols","clone","uses","processedDefs","id","exist","definition","ns","defs","isRoot","URL_REGEX","URL_WITH_FORMAT_REGEX","FONT_SRC_REGEX","toRegex","escaped","parseURLs","urls","raw","quotation","embed","resourceURL","baseURL","getContentFromUrl","resolvedURL","filterPreferredFontFormat","str","preferredFontFormat","src","format","shouldEmbed","embedResources","filteredCSSText","css","embedProp","propName","propValue","cssString","embedBackground","embedImageNode","isImageElement","attributes","image","embedChildren","deferreds","embedImages","applyStyle","manual","cssFetchCache","fetchCSS","embedFonts","data","regexUrl","loadFonts","loc","parseCSS","source","commentsRegex","keyframesRegex","matches","importRegex","combinedCSSRegex","unifiedRegex","getCSSRules","styleSheets","ret","sheet","item","importIndex","metadata","rule","inline","err","getWebFontRules","cssRules","parseWebFontRules","normalizeFontFamily","font","getUsedFonts","fonts","traverse","getWebFontCSS","rules","usedFonts","embedWebFonts","styleNode","sytleContent","toSvg","toCanvas","context","canvasWidth","canvasHeight","toPng","captureScreenshot","annotations","annotationLayer","mountCaptureAnnotations","dataUrl","dataUrlToBlob","layer","buildCapturePin","buildCaptureDraw","drawPath","path","header","mime","binary","bytes","ErrorSource","listener","line","col","reason","event","errorSource","MAX_CONSOLE_ERRORS","ConsoleErrorCollector","location","RAGE_CLICK_THRESHOLD","RAGE_CLICK_WINDOW_MS","RAPID_NAV_THRESHOLD","RAPID_NAV_WINDOW_MS","FORM_CHECK_DELAY_MS","DEAD_CLICK_DOM_DELAY_MS","ERROR_PAGE_CHECK_DELAY_MS","INTERACTIVE_TAGS","INTERACTIVE_ROLES","ERROR_PAGE_PATTERNS","_FrustrationDetector","onFrustration","_e","pushOrig","replaceOrig","onNav","unused","target","now","cutoff","r","describeElement","t","form","candidates","clickTime","mutated","cls","lower","role","host","FrustrationDetector","collectPageContext","detectBrowser","detectOS","ua","DEFAULT_API_URL","ApiClient","projectKey","apiUrl","retryDelayMs","userToken","userTokenFn","headers","token","payload","screenshot","json","generateIdempotencyKey","feedbackId","body","retries","delay","ms","buildPayload","description","pageContext","consoleErrors","user","recording","en","zhCN","ja","ko","es","fr","de","locales","getMessages","locale","lang","MAX_DURATION_S","RRWEB_CDN","RRWEB_SRI","rrwebLoaded","loadRrweb","loadViaImport","loadViaCdn","findGlobalRecord","win","existing","script","record","RecordSession","onMaxReached","ripple","RecordControlBar","getDuration","onStop","secs","mm","ss","RecordingManager","WidgetController","config","feedback","projectId","boardUrl","hasIdentity","MakeThisBetter"],"mappings":"+hhBAGO,MAAMA,EAAgB,CAI3B,YAAYC,EAAuC,OAAQ,CACzD,KAAK,KAAO,SAAS,cAAc,KAAK,EACxC,KAAK,KAAK,GAAK,kBACf,KAAK,KAAK,MAAM,QAAU,oFAC1B,KAAK,KAAK,aAAa,iBAAkBA,CAAK,EAC9C,SAAS,KAAK,YAAY,KAAK,IAAI,EAEnC,KAAK,KAAO,KAAK,KAAK,aAAa,CAAE,KAAM,OAAQ,EAEnD,MAAMC,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,YAAcC,GACpB,KAAK,KAAK,YAAYD,CAAK,CAC7B,CAEA,GAAwCE,EAAaC,EAAuB,CAC1E,MAAMC,EAAK,SAAS,cAAcF,CAAG,EACrC,OAAIC,MAAc,UAAYA,GACvBC,CACT,CAEA,UAAUC,EAAqB,CAC7B,UAAWC,KAAKD,EAAO,KAAK,KAAK,YAAYC,CAAC,CAChD,CAEA,UAAUD,EAAqB,CAC7B,UAAWC,KAAKD,EACVC,EAAE,aAAe,KAAK,MAAM,KAAK,KAAK,YAAYA,CAAC,CAE3D,CAEA,SAAgB,CACd,SAAS,KAAK,YAAY,KAAK,IAAI,CACrC,CACF,CCrCO,MAAMC,EAAY,CAIvB,YACEC,EACAC,EACAC,EACAC,EACAC,EACA,CACA,KAAK,QAAUD,EACf,KAAK,GAAKH,EAAO,GAAsB,SAAU,SAAS,EACtDE,IAAa,QAAQ,KAAK,GAAG,UAAU,IAAI,MAAM,EACrD,MAAMG,EAAQD,GAAcH,EAAS,IACrC,KAAK,GAAG,YAAcI,EACtB,KAAK,GAAG,aAAa,aAAcA,CAAK,EACxC,KAAK,GAAG,iBAAiB,QAASF,CAAO,EACzCH,EAAO,OAAO,KAAK,EAAE,CACvB,CAEA,UAAUM,EAAuB,CAC/B,KAAK,GAAG,UAAU,OAAO,SAAUA,CAAM,CAC3C,CAEA,SAAgB,CACd,KAAK,GAAG,oBAAoB,QAAS,KAAK,OAAO,EACjD,KAAK,GAAG,OAAA,CACV,CACF,CC7BA,MAAMC,GAAyB,IAExB,MAAMC,EAAsB,CAGjC,YACER,EACAC,EACAQ,EACA,CACA,KAAK,GAAKT,EAAO,GAAmB,MAAO,wBAAwB,EACnE,KAAK,GAAG,UAAY;AAAA;AAAA,2CAEmBC,EAAS,YAAY,MAAM;AAAA;AAAA,+CAEvBA,EAAS,YAAY,MAAM;AAAA,kDACxBA,EAAS,YAAY,OAAO;AAAA;AAAA,MAI1E,KAAK,GAAG,cAAc,uBAAuB,EAAG,iBAAiB,QAASQ,EAAS,MAAM,EACzF,KAAK,GAAG,cAAc,0BAA0B,EAAG,iBAAiB,QAASA,EAAS,SAAS,EAE/FT,EAAO,OAAO,KAAK,EAAE,EACrB,WAAWS,EAAS,UAAWF,EAAsB,CACvD,CAEA,SAAgB,CACd,KAAK,GAAG,OAAA,CACV,CACF,CC5BO,MAAMG,EAAkB,CAQ7B,YACEV,EACAC,EACAU,EACAC,EACA,CAPF,KAAQ,YAA2B,SAQjC,KAAK,SAAWX,EAEhB,KAAK,GAAKD,EAAO,GAAmB,MAAO,aAAa,EACxD,KAAK,GAAG,UAAY,KAAK,UAAUC,CAAQ,EAC3CD,EAAO,OAAO,KAAK,EAAE,EAErB,KAAK,OAAS,KAAK,GAAG,cAAc,mBAAmB,EACvD,KAAK,UAAY,KAAK,GAAG,cAAc,0BAA0B,EACjE,KAAK,UAAY,KAAK,GAAG,cAAc,0BAA0B,EAEjE,KAAK,UAAU,iBAAiB,QAAS,IAAM,CAC7C,KAAK,QAAQ,QAAQ,EACrBY,IAAe,QAAQ,CACzB,CAAC,EACD,KAAK,UAAU,iBAAiB,QAAS,IAAM,CAC7C,KAAK,QAAQ,QAAQ,EACrBA,IAAe,QAAQ,CACzB,CAAC,EACD,KAAK,GAAG,cAAc,eAAe,EAAG,iBAAiB,QAASD,CAAM,CAC1E,CAEQ,UAAUE,EAAyB,CACzC,MAAO;AAAA;AAAA;AAAA,2VAGgVA,EAAE,QAAQ,MAAM;AAAA;AAAA;AAAA,qNAGtJA,EAAE,QAAQ,MAAM;AAAA;AAAA;AAAA,uCAG9LA,EAAE,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,gBAKrCA,EAAE,QAAQ,IAAI;AAAA;AAAA,KAG5B,CAEA,QAAQC,EAAyB,CAC/B,KAAK,YAAcA,EACfA,IAAS,UACX,KAAK,UAAU,UAAU,IAAI,QAAQ,EACrC,KAAK,UAAU,UAAU,OAAO,QAAQ,EACxC,KAAK,OAAO,YAAc,KAAK,SAAS,QAAQ,OAEhD,KAAK,UAAU,UAAU,OAAO,QAAQ,EACxC,KAAK,UAAU,UAAU,IAAI,QAAQ,EACrC,KAAK,OAAO,YAAc,KAAK,SAAS,QAAQ,WAEpD,CAEA,SAAuB,CACrB,OAAO,KAAK,WACd,CAEA,SAAgB,CACd,KAAK,GAAG,OAAA,CACV,CACF,CC9EO,MAAMC,EAAkB,CAQ7B,YACEf,EACAS,EAMA,CACA,KAAK,YAAcA,EAAS,YAC5B,KAAK,YAAcA,EAAS,YAC5B,KAAK,UAAYA,EAAS,UAC1B,KAAK,aAAeA,EAAS,aAE7B,KAAK,UAAYT,EAAO,GAAmB,MAAO,aAAa,EAC/D,KAAK,UAAU,iBAAiB,YAAa,KAAK,WAAW,EAC7D,KAAK,UAAU,iBAAiB,YAAa,KAAK,WAAW,EAC7D,KAAK,UAAU,iBAAiB,UAAW,KAAK,SAAS,EACzD,KAAK,UAAU,iBAAiB,aAAc,KAAK,YAAY,EAC/DA,EAAO,OAAO,KAAK,SAAS,EAE5B,KAAK,MAAQA,EAAO,GAAmB,MAAO,SAAS,EACvDA,EAAO,OAAO,KAAK,KAAK,CAC1B,CAEA,SAAgB,CACd,KAAK,UAAU,oBAAoB,YAAa,KAAK,WAAW,EAChE,KAAK,UAAU,oBAAoB,YAAa,KAAK,WAAW,EAChE,KAAK,UAAU,oBAAoB,UAAW,KAAK,SAAS,EAC5D,KAAK,UAAU,oBAAoB,aAAc,KAAK,YAAY,EAClE,KAAK,UAAU,OAAA,EACf,KAAK,MAAM,OAAA,CACb,CACF,CCzCO,MAAMgB,EAAmB,CAG9B,YAAYhB,EAAyB,CACnC,KAAK,YAAcA,EAAO,GAAmB,MAAO,eAAe,EACnE,KAAK,KAAA,EACLA,EAAO,OAAO,KAAK,WAAW,CAChC,CAEA,UAAUJ,EAAmB,CAC3B,MAAMqB,EAAOrB,EAAG,sBAAA,EAChB,KAAK,YAAY,MAAM,IAAM,GAAGqB,EAAK,IAAM,CAAC,KAC5C,KAAK,YAAY,MAAM,KAAO,GAAGA,EAAK,KAAO,CAAC,KAC9C,KAAK,YAAY,MAAM,MAAQ,GAAGA,EAAK,MAAQ,CAAC,KAChD,KAAK,YAAY,MAAM,OAAS,GAAGA,EAAK,OAAS,CAAC,KAClD,KAAK,YAAY,MAAM,QAAU,OACnC,CAEA,MAAa,CACX,KAAK,YAAY,MAAM,QAAU,MACnC,CAEA,SAAgB,CACd,KAAK,YAAY,OAAA,CACnB,CACF,CAEO,SAASC,GAAetB,EAAqB,CAClD,GAAIA,aAAc,YAAa,CAC7B,MAAMS,EAAQT,EAAG,aAAa,YAAY,EAC1C,GAAIS,EAAO,OAAOA,EAElB,MAAMc,EAAQvB,EAAG,aAAa,OAAO,EACrC,GAAIuB,EAAO,OAAOA,EAElB,MAAMC,EAAOxB,EAAG,aAAa,OAAO,MAAM,EAAG,EAAE,EAC/C,GAAIwB,EAAM,OAAOA,EAEjB,MAAMC,EAAezB,EAAwB,YAC7C,GAAIyB,EAAa,OAAOA,EAExB,MAAMC,EAAO1B,EAAwB,IACrC,GAAI0B,EAAK,OAAOA,EAEhB,MAAMC,EAAW3B,EAAG,aAAa,WAAW,EAC5C,GAAI2B,EAAU,OAAOA,CACvB,CACA,OAAO3B,EAAG,QAAQ,YAAA,CACpB,CAEO,SAAS4B,GAAe5B,EAAqB,CAClD,MAAM6B,EAAkB,CAAA,EACxB,IAAIC,EAA0B9B,EAC9B,KAAO8B,GAAWA,IAAY,SAAS,MAAQD,EAAM,OAAS,GAAG,CAC/D,IAAIE,EAAWD,EAAQ,QAAQ,YAAA,EAC/B,GAAIA,EAAQ,GAAI,CACdC,EAAW,IAAID,EAAQ,EAAE,GACzBD,EAAM,QAAQE,CAAQ,EACtB,KACF,CACA,MAAMC,EAAa,MAAM,KAAKF,EAAQ,SAAS,EAC5C,OAAOG,GAAK,CAACA,EAAE,WAAW,MAAM,CAAC,EACjC,MAAM,EAAG,CAAC,EACV,KAAK,GAAG,EACPD,IAAYD,GAAY,IAAIC,CAAU,IAE1C,MAAME,EAASJ,EAAQ,cACvB,GAAII,EAAQ,CACV,MAAMC,EAAW,MAAM,KAAKD,EAAO,QAAQ,EAAE,OAC3CD,GAAKA,EAAE,UAAYH,EAAS,OAAA,EAE9B,GAAIK,EAAS,OAAS,EAAG,CACvB,MAAMC,EAAMD,EAAS,QAAQL,CAAO,EAAI,EACxCC,GAAY,cAAcK,CAAG,GAC/B,CACF,CAEAP,EAAM,QAAQE,CAAQ,EACtBD,EAAUA,EAAQ,aACpB,CACA,OAAOD,EAAM,KAAK,KAAK,CACzB,CCjFO,MAAMQ,EAAU,CAIrB,YAAYjC,EAAyB,CAHrC,KAAQ,KAAyB,CAAA,EAI/B,KAAK,OAASA,CAChB,CAEA,OAAOkC,EAAWC,EAAWC,EAAqB,CAChD,MAAMC,EAAM,KAAK,OAAO,GAAmB,MAAO,SAAS,EAC3DA,EAAI,YAAc,OAAOD,CAAK,EAC9BC,EAAI,MAAM,IAAM,GAAGF,CAAC,KACpBE,EAAI,MAAM,KAAO,GAAGH,CAAC,KACrB,KAAK,OAAO,OAAOG,CAAG,EACtB,KAAK,KAAK,KAAKA,CAAG,CACpB,CAEA,UAAiB,CACf,UAAWA,KAAO,KAAK,KAAMA,EAAI,OAAA,EACjC,KAAK,KAAO,CAAA,CACd,CAEA,SAAgB,CACd,KAAK,SAAA,CACP,CACF,CC3BO,MAAMC,EAAc,UAEdC,EAAc,CACzB,MAAOD,EACP,MAAO,MACP,QAAS,QACT,SAAU,QACV,OAAQ,6CACV,ECJO,MAAME,EAAU,CAOrB,YAAYxC,EAAyByC,EAAkD,CALvF,KAAQ,KAA8B,KACtC,KAAQ,OAA6B,CAAA,EACrC,KAAQ,UAAY,GAIlB,KAAK,eAAiBA,EAEtB,KAAK,IAAM,SAAS,gBAAgB,6BAA8B,KAAK,EACvE,KAAK,IAAI,aAAa,QAAS,cAAc,EAC7CzC,EAAO,OAAO,KAAK,GAAG,CACxB,CAEA,UAAUkC,EAAWC,EAAiB,CACpC,KAAK,UAAY,GACjB,KAAK,OAAS,CAAC,CAACD,EAAGC,CAAC,CAAC,EAErB,KAAK,KAAO,SAAS,gBAAgB,6BAA8B,MAAM,EACzE,KAAK,KAAK,aAAa,OAAQ,MAAM,EACrC,KAAK,KAAK,aAAa,SAAUI,EAAY,KAAK,EAClD,KAAK,KAAK,aAAa,eAAgBA,EAAY,KAAK,EACxD,KAAK,KAAK,aAAa,iBAAkBA,EAAY,OAAO,EAC5D,KAAK,KAAK,aAAa,kBAAmBA,EAAY,QAAQ,EAC9D,KAAK,KAAK,aAAa,QAAS,UAAUA,EAAY,MAAM,EAAE,EAC9D,KAAK,IAAI,YAAY,KAAK,IAAI,CAChC,CAEA,aAAaL,EAAWC,EAAiB,CACnC,CAAC,KAAK,WAAa,CAAC,KAAK,OAC7B,KAAK,OAAO,KAAK,CAACD,EAAGC,CAAC,CAAC,EACvB,KAAK,KAAK,aAAa,IAAK,KAAK,YAAY,EAC/C,CAEA,SAAgB,CACd,GAAI,CAAC,KAAK,WAAa,KAAK,OAAO,OAAS,EAAG,CAC7C,KAAK,UAAY,GACb,KAAK,OACP,KAAK,KAAK,OAAA,EACV,KAAK,KAAO,MAEd,MACF,CACA,KAAK,UAAY,GAEjB,MAAMO,EAAS,KAAK,UAAA,EACdC,EAAQ,KAAK,WAAA,EAEbC,EAAyB,CAC7B,KAAM,OACN,EAAGF,EAAO,CAAC,EACX,EAAGA,EAAO,CAAC,EACX,SAAUC,CAAA,EAGZ,KAAK,eAAeC,CAAU,CAChC,CAEQ,YAAqB,CAC3B,GAAI,KAAK,OAAO,SAAW,EAAG,MAAO,GACrC,KAAM,CAACC,EAAIC,CAAE,EAAI,KAAK,OAAO,CAAC,EAC9B,IAAIC,EAAI,KAAKF,CAAE,IAAIC,CAAE,GACrB,QAASE,EAAI,EAAGA,EAAI,KAAK,OAAO,OAAQA,IAAK,CAC3C,KAAM,CAACd,EAAGC,CAAC,EAAI,KAAK,OAAOa,CAAC,EAC5BD,GAAK,MAAMb,CAAC,IAAIC,CAAC,EACnB,CACA,OAAOY,CACT,CAEQ,WAA8B,CACpC,MAAME,EAAK,KAAK,OAAO,IAAIC,GAAKA,EAAE,CAAC,CAAC,EAC9BC,EAAK,KAAK,OAAO,IAAID,GAAKA,EAAE,CAAC,CAAC,EAC9BE,GAAM,KAAK,IAAI,GAAGH,CAAE,EAAI,KAAK,IAAI,GAAGA,CAAE,GAAK,EAC3CI,GAAM,KAAK,IAAI,GAAGF,CAAE,EAAI,KAAK,IAAI,GAAGA,CAAE,GAAK,EACjD,MAAO,CAACC,EAAIC,CAAE,CAChB,CAEA,UAAiB,CACf,KAAO,KAAK,IAAI,YAAY,KAAK,IAAI,YAAY,KAAK,IAAI,UAAU,EACpE,KAAK,KAAO,KACZ,KAAK,UAAY,GACjB,KAAK,OAAS,CAAA,CAChB,CAEA,mBAA0B,CACxB,KAAK,MAAM,OAAA,EACX,KAAK,KAAO,KACZ,KAAK,UAAY,GACjB,KAAK,OAAS,CAAA,CAChB,CAEA,oBAA8B,CAC5B,OAAO,KAAK,SACd,CAEA,eAAwB,CACtB,OAAO,KAAK,OAAO,MACrB,CAEA,SAAgB,CACd,KAAK,IAAI,OAAA,CACX,CACF,CCnGA,MAAMC,GAAkB,EAEjB,MAAMC,CAAkB,CAW7B,YACEvD,EACQC,EACAuD,EACR,CAFQ,KAAA,SAAAvD,EACA,KAAA,QAAAuD,EATV,KAAQ,SAAW,EACnB,KAAQ,kBAAoB,GAC5B,KAAQ,sBAAuC,KAC/C,KAAQ,UAAY,EACpB,KAAQ,UAAY,EAOlB,KAAK,YAAc,IAAIxC,GAAmBhB,CAAM,EAChD,KAAK,UAAY,IAAIiC,GAAUjC,CAAM,EACrC,KAAK,UAAY,IAAIwC,GAAUxC,EAAS4C,GAAe,CACrD,KAAK,QAAQA,EAAY,KAAK,SAAS,WAAW,OAAO,CAC3D,CAAC,EACD,KAAK,QAAU,IAAI7B,GAAkBf,EAAQ,CAC3C,YAAcyD,GAAM,KAAK,gBAAgBA,CAAC,EAC1C,YAAcA,GAAM,KAAK,gBAAgBA,CAAC,EAC1C,UAAYA,GAAM,KAAK,cAAcA,CAAC,EACtC,aAAc,IAAM,CACd,KAAK,UAAU,mBAAA,GAAsB,KAAK,UAAU,QAAA,EACxD,KAAK,uBAAA,EACL,KAAK,YAAY,KAAA,CACnB,CAAA,CACD,CACH,CAEQ,gBAAgBA,EAAqB,CAC3CA,EAAE,eAAA,EACF,KAAK,UAAU,UAAUA,EAAE,QAASA,EAAE,OAAO,CAC/C,CAEQ,gBAAgBA,EAAqB,CAC3C,GAAI,KAAK,UAAU,qBAAsB,CACvC,KAAK,uBAAA,EACL,KAAK,UAAU,aAAaA,EAAE,QAASA,EAAE,OAAO,EAChD,KAAK,YAAY,KAAA,EACjB,MACF,CAEA,KAAK,UAAYA,EAAE,QACnB,KAAK,UAAYA,EAAE,QACf,KAAK,wBAA0B,OACnC,KAAK,sBAAwB,sBAAsB,IAAM,CACvD,KAAK,sBAAwB,KAC7B,KAAK,gBAAA,CACP,CAAC,EACH,CAEQ,iBAAwB,CAC9B,GAAI,CAAC,KAAK,mBAAqB,KAAK,UAAU,qBAAsB,OACpE,MAAMC,EAAUC,EAAgB,KAAK,UAAW,KAAK,SAAS,EAC1DD,EAAS,KAAK,YAAY,UAAUA,CAAO,EAC1C,KAAK,YAAY,KAAA,CACxB,CAEQ,wBAA+B,CACjC,KAAK,wBAA0B,OACnC,qBAAqB,KAAK,qBAAqB,EAC/C,KAAK,sBAAwB,KAC/B,CAEQ,cAAcD,EAAqB,CACzC,GAAI,CAAC,KAAK,UAAU,qBAAsB,OAE1C,GAAI,KAAK,UAAU,cAAA,GAAmBH,GAAiB,CACrD,KAAK,UAAU,QAAA,EACf,MACF,CAEA,KAAK,UAAU,kBAAA,EACf,MAAMI,EAAUC,EAAgBF,EAAE,QAASA,EAAE,OAAO,EAC9CG,EAAaF,EAAUxC,GAAewC,CAAO,EAAI,KAAK,SAAS,WAAW,QAC1Ed,EAAyB,CAC7B,KAAM,MACN,EAAGa,EAAE,QACL,EAAGA,EAAE,QACL,eAAgBC,EAAUlC,GAAekC,CAAO,EAAI,OACpD,WAAYA,GAAS,aAAa,KAAA,EAAO,MAAM,EAAG,GAAG,GAAK,GAC1D,WAAAE,CAAA,EAEF,KAAK,UAAU,OAAOH,EAAE,QAASA,EAAE,QAAS,EAAE,KAAK,QAAQ,EAC3D,KAAK,UAAU,SAAA,EACf,KAAK,YAAY,KAAA,EACjB,KAAK,QAAQb,EAAYgB,CAAU,CACrC,CAEA,oBAA2B,CACpB,KAAK,oBACV,KAAK,kBAAoB,GACzB,KAAK,uBAAA,EACL,KAAK,QAAQ,QAAA,EACb,KAAK,YAAY,QAAA,EACnB,CAEA,SAAgB,CACd,KAAK,mBAAA,EACL,KAAK,UAAU,QAAA,EACf,KAAK,UAAU,QAAA,CACjB,CACF,CAIA,SAASD,EAAgBzB,EAAWC,EAA2B,CAC7D,OAAO,SAAS,kBAAkBD,EAAGC,CAAC,EAAE,KAAKvC,GAAMA,EAAG,KAAO,iBAAiB,GAAK,IACrF,CC9GO,MAAMiE,EAAa,CAUxB,YAAY7D,EAAyB8D,EAAoB,CAFzD,KAAQ,QAAU,GAGhB,KAAK,SAAWA,EAAK,SACrB,KAAK,QAAUA,EAAK,QACpB,KAAK,YAAcA,EAAK,SAAS,MAAM,OAEvC,KAAK,GAAK9D,EAAO,GAAmB,MAAO,WAAW,EACtD,KAAK,GAAG,UAAY,KAAK,UAAU8D,CAAI,EACvC9D,EAAO,OAAO,KAAK,EAAE,EAErB,KAAK,SAAW,KAAK,GAAG,cAAc,eAAe,EACrD,KAAK,UAAY,KAAK,GAAG,cAAc,iBAAiB,EAExD,KAAK,cAAc8D,EAAK,EAAGA,EAAK,CAAC,EACjC,KAAK,WAAWA,EAAK,QAAQ,EAC7B,KAAK,SAAS,MAAA,CAChB,CAEQ,UAAUA,EAA4B,CAC5C,MAAMjD,EAAIiD,EAAK,SACTC,EAAYlD,EAAE,MAAM,aACvB,IACCmD,GAAK;AAAA,uDAC0CC,EAAWD,EAAE,KAAK,CAAC;AAAA,iDACzBA,EAAE,KAAK;AAAA,kBACtCC,EAAWD,EAAE,KAAK,CAAC;AAAA,kBAAA,EAG9B,KAAK,EAAE,EAEV,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wCAO6BnD,EAAE,MAAM,KAAK,KAAKoD,EAAWH,EAAK,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YASzEC,CAAS;AAAA;AAAA;AAAA,wDAGmCE,EAAWpD,EAAE,MAAM,WAAW,CAAC;AAAA;AAAA;AAAA;AAAA,yDAI9BoD,EAAWpD,EAAE,MAAM,MAAM,CAAC;AAAA,kEACjBoD,EAAWpD,EAAE,MAAM,MAAM,CAAC;AAAA;AAAA;AAAA,KAI1F,CAEQ,cAAcqB,EAAWC,EAAiB,CAGhD,MAAM+B,EAAK,OAAO,WACZC,EAAK,OAAO,YACZC,EAAS,GAEf,IAAIC,EAAOnC,EAAI,GACXoC,EAAMnC,EAAI,GAEVkC,EAAO,IAASH,EAAKE,IACvBC,EAAOnC,EAAI,IAAS,IAElBmC,EAAOD,IAAQC,EAAOD,GAEtBE,EAAM,IAASH,EAAKC,IACtBE,EAAMH,EAAK,IAASC,GAElBE,EAAMF,IAAQE,EAAMF,GAExB,KAAK,GAAG,MAAM,KAAO,GAAGC,CAAI,KAC5B,KAAK,GAAG,MAAM,IAAM,GAAGC,CAAG,IAC5B,CAEQ,WAAWrE,EAA8B,CAC/C,KAAK,GAAG,cAAc,kBAAkB,EAAG,iBAAiB,QAAS,IAAM,KAAK,SAAS,EACzF,KAAK,GAAG,cAAc,iBAAiB,EAAG,iBAAiB,QAAS,IAAM,KAAK,SAAS,EACxF,KAAK,QAAU,KAAK,GAAG,cAAc,kBAAkB,EAEvD,KAAK,GAAG,iBAAiB,mBAAmB,EAAE,QAAQsE,GAAO,CAC3DA,EAAI,iBAAiB,QAAS,IAAM,CAClC,MAAMlE,EAASkE,EAAoB,QAAQ,OAAY,GACvD,KAAK,SAAS,MAAQlE,EACtB,KAAK,kBAAA,EACL,KAAK,SAAS,MAAA,CAChB,CAAC,CACH,CAAC,EAED,KAAK,SAAS,iBAAiB,QAAS,IAAM,KAAK,mBAAmB,EAEtE,KAAK,SAAS,iBAAiB,UAAY,GAAqB,CAC1D,EAAE,MAAQ,UAAY,EAAE,SAAW,EAAE,WACvC,EAAE,eAAA,EACF,KAAK,OAAA,EAET,CAAC,EAED,KAAK,UAAU,iBAAiB,QAAS,IAAM,KAAK,QAAQ,CAC9D,CAEQ,mBAA0B,CAChC,MAAMmE,EAAU,KAAK,SAAS,MAAM,KAAA,EAAO,OAAS,EACpD,KAAK,UAAU,UAAU,OAAO,QAASA,GAAW,CAAC,KAAK,OAAO,EACjE,KAAK,UAAU,SAAW,CAACA,GAAW,KAAK,QAC3C,KAAK,QAAQ,OAAS,GACtB,KAAK,QAAQ,YAAc,EAC7B,CAEQ,QAAe,CACrB,MAAMpD,EAAO,KAAK,SAAS,MAAM,KAAA,EAC7B,CAACA,GAAQ,KAAK,SAClB,KAAK,SAASA,CAAI,CACpB,CAEA,WAAWqD,EAAwB,CACjC,KAAK,QAAUA,EACXA,GACF,KAAK,UAAU,UAAU,IAAI,SAAS,EACtC,KAAK,UAAU,UAAY,0FAC3B,KAAK,SAAS,SAAW,KAEzB,KAAK,UAAU,UAAU,OAAO,SAAS,EACzC,KAAK,UAAU,YAAc,KAAK,YAClC,KAAK,SAAS,SAAW,IAE3B,KAAK,kBAAA,CACP,CAEA,SAASC,EAAuB,CAC9B,KAAK,QAAQ,YAAcA,EAC3B,KAAK,QAAQ,OAAS,EACxB,CAEA,SAAgB,CACd,KAAK,GAAG,OAAA,CACV,CACF,CAEA,SAAST,EAAW7C,EAAsB,CACxC,OAAOA,EACJ,QAAQ,KAAM,OAAO,EACrB,QAAQ,KAAM,MAAM,EACpB,QAAQ,KAAM,MAAM,EACpB,QAAQ,KAAM,QAAQ,EACtB,QAAQ,KAAM,QAAQ,CAC3B,CC1KA,MAAMuD,GAAmB,IACnBC,GAAgB,IASf,MAAMC,EAAY,CAavB,YAAY7E,EAAyB8D,EAA0B,CAR/D,KAAQ,UAAmD,KAC3D,KAAQ,UAAkD,KAI1D,KAAQ,QAAU,GAClB,KAAQ,UAAY,GAGlB,KAAK,WAAaA,EAAK,WACvB,KAAK,UAAYA,EAAK,UACtB,KAAK,OAASA,EAAK,OAEnB,KAAK,GAAK9D,EAAO,GAAmB,MAAO,aAAa,EACxD,KAAK,GAAG,MAAM,MAAQ,OACtB,KAAK,GAAG,MAAM,OAAS,OACvB,KAAK,GAAG,UAAY,KAAK,UAAU8D,EAAK,QAAQ,EAChD9D,EAAO,OAAO,KAAK,EAAE,EAErB,KAAK,WAAa,KAAK,GAAG,cAAc,uBAAuB,EAC/D,KAAK,QAAU,KAAK,GAAG,cAAc,oBAAoB,EACzD,KAAK,QAAU,KAAK,GAAG,cAAc,mBAAmB,EAExD,KAAK,WAAW8D,EAAK,QAAQ,EAC7B,KAAK,kBAAA,CACP,CAEQ,UAAUjD,EAAyB,CACzC,MAAO;AAAA;AAAA;AAAA,gFAGqEyB,CAAW;AAAA;AAAA;AAAA;AAAA,2CAIhD2B,EAAWpD,EAAE,QAAQ,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,oEAIDoD,EAAWpD,EAAE,QAAQ,WAAW,CAAC;AAAA,oDACjDoD,EAAWpD,EAAE,QAAQ,IAAI,CAAC;AAAA;AAAA,KAG5E,CAEQ,WAAWA,EAAuB,CACxC,KAAK,GAAG,cAAc,mBAAmB,EAAG,iBAAiB,QAAS,IAAM,CAC1E,KAAK,YAAA,EACL,KAAK,OAAA,CACP,CAAC,EAED,KAAK,QAAQ,iBAAiB,QAAS,IAAM,CAC3C,MAAM2D,EAAU,KAAK,QAAQ,MAAM,KAAA,EAAO,OAAS,EACnD,KAAK,QAAQ,SAAW,CAACA,GAAW,KAAK,OAC3C,CAAC,EAED,KAAK,QAAQ,iBAAiB,UAAY,GAAqB,CAEzD,EAAE,aAAe,EAAE,UAAY,KAC/B,EAAE,MAAQ,UACZ,EAAE,eAAA,EACF,KAAK,YAAY3D,CAAC,EAEtB,CAAC,EAED,KAAK,QAAQ,iBAAiB,QAAS,IAAM,KAAK,YAAYA,CAAC,CAAC,CAClE,CAEA,MAAc,mBAAmC,CAC/C,KAAK,aAAA,EACL,GAAI,CACF,MAAMiE,EAAM,MAAM,KAAK,UAAU,mBAAmB,KAAK,UAAU,EACnE,GAAI,KAAK,UAAW,OACpB,KAAK,mBAAmBA,EAAI,SAAUA,EAAI,IAAI,EAC1CA,EAAI,KACN,KAAK,WAAA,EAEL,KAAK,aAAA,CAET,MAAQ,CACN,GAAI,KAAK,UAAW,OACpB,KAAK,OAAA,CACP,CACF,CAEA,MAAc,YAAYjE,EAAgC,CACxD,MAAMO,EAAO,KAAK,QAAQ,MAAM,KAAA,EAChC,GAAI,GAACA,GAAQ,KAAK,SAElB,MAAK,QAAU,GACf,KAAK,QAAQ,SAAW,GACxB,KAAK,QAAQ,SAAW,GACxB,KAAK,YAAA,EAEL,KAAK,cAAc,CAAE,KAAM,OAAQ,QAASA,EAAM,EAClD,KAAK,QAAQ,MAAQ,GACrB,KAAK,aAAA,EAEL,GAAI,CACF,MAAM0D,EAAM,MAAM,KAAK,UAAU,mBAAmB,KAAK,WAAY1D,CAAI,EACzE,GAAI,KAAK,UAAW,OACpB,KAAK,mBAAmB0D,EAAI,SAAUA,EAAI,IAAI,EAC1CA,EAAI,KACN,KAAK,WAAA,EAEL,KAAK,aAAA,CAET,MAAQ,CACN,GAAI,KAAK,UAAW,OACpB,KAAK,OAAA,CACP,QAAA,CACE,KAAK,QAAU,GACf,KAAK,QAAQ,SAAW,GACxB,KAAK,QAAQ,SAAW,KAAK,QAAQ,MAAM,OAAO,SAAW,EAC7D,KAAK,QAAQ,MAAA,CACf,EACF,CAEQ,cAAqB,CAC3B,KAAK,YAAA,EACL,KAAK,UAAY,YAAY,IAAM,KAAK,KAAA,EAAQH,EAAgB,CAClE,CAEQ,aAAoB,CACtB,KAAK,YAAc,OACrB,cAAc,KAAK,SAAS,EAC5B,KAAK,UAAY,KAErB,CAEA,MAAc,MAAsB,CAClC,GAAI,CACF,MAAMG,EAAM,MAAM,KAAK,UAAU,iBAAiB,KAAK,UAAU,EACjE,GAAI,KAAK,UAAW,OACpB,KAAK,mBAAmBA,EAAI,SAAUA,EAAI,IAAI,EAC1CA,EAAI,OACN,KAAK,YAAA,EACL,KAAK,WAAA,EAET,MAAQ,CACN,GAAI,KAAK,UAAW,OACpB,KAAK,YAAA,CACP,CACF,CAEQ,YAAmB,CACzB,KAAK,QAAQ,SAAW,GACxB,KAAK,QAAQ,SAAW,GACxB,KAAK,UAAY,WAAW,IAAM,CAC3B,KAAK,WAAW,KAAK,OAAA,CAC5B,EAAGF,EAAa,CAClB,CAEQ,mBAAmB3E,EAA4B8E,EAAqB,CAC1E,KAAK,eAAe9E,CAAQ,EAC5B,MAAM+E,EAAO/E,EAASA,EAAS,OAAS,CAAC,EACrC,CAAC8E,IAAS,CAACC,GAAQA,EAAK,OAAS,cAAc,aAAA,CACrD,CAEQ,eAAe/E,EAAkC,CACvD,KAAK,WAAW,UAAY,GAC5B,UAAWgF,KAAOhF,EAChB,KAAK,cAAcgF,CAAG,EAExB,KAAK,WAAW,UAAY,KAAK,WAAW,YAC9C,CAEQ,cAAcA,EAA2B,CAC/C,MAAMC,EAAS,SAAS,cAAc,KAAK,EAC3CA,EAAO,UAAYD,EAAI,OAAS,OAAS,sCAAwC,oCACjFC,EAAO,YAAcD,EAAI,QACzB,KAAK,WAAW,YAAYC,CAAM,EAClC,KAAK,WAAW,UAAY,KAAK,WAAW,YAC9C,CAEQ,cAAqB,CAC3B,MAAMC,EAAO,SAAS,cAAc,KAAK,EACzCA,EAAK,UAAY,yDACjBA,EAAK,UAAY,0FACjB,KAAK,WAAW,YAAYA,CAAI,EAChC,KAAK,WAAW,UAAY,KAAK,WAAW,YAC9C,CAEA,SAAgB,CACd,KAAK,UAAY,GACjB,KAAK,YAAA,EACD,KAAK,YAAc,OACrB,aAAa,KAAK,SAAS,EAC3B,KAAK,UAAY,MAEnB,KAAK,GAAG,OAAA,CACV,CACF,CAEA,SAASlB,EAAW7C,EAAsB,CACxC,OAAOA,EACJ,QAAQ,KAAM,OAAO,EACrB,QAAQ,KAAM,MAAM,EACpB,QAAQ,KAAM,MAAM,EACpB,QAAQ,KAAM,QAAQ,EACtB,QAAQ,KAAM,QAAQ,CAC3B,CC1NA,MAAMgE,GAAwB,IAMvB,MAAMC,EAAY,CAGvB,YAAYrF,EAAyBC,EAAwBqF,EAAqBC,EAA6BC,EAA8B,CAC3I,KAAK,GAAKxF,EAAO,GAAmB,MAAO,aAAa,EACxD,KAAK,GAAG,MAAM,MAAQ,OACtB,KAAK,GAAG,MAAM,OAAS,OAEvB,MAAMmB,EAAQqE,GAAS,aAAevF,EAAS,QAAQ,YAAcA,EAAS,QAAQ,MAChFgF,EAAMO,GAAS,aAAevF,EAAS,QAAQ,cAAgBA,EAAS,QAAQ,QAEhFwF,EAAWF,EACb,0CAA0CtF,EAAS,QAAQ,aAAa,YACxE,GAEJ,KAAK,GAAG,UAAY;AAAA;AAAA,8EAEsDqC,CAAW;AAAA;AAAA;AAAA;AAAA,uCAIlDnB,CAAK;AAAA,qCACP8D,CAAG;AAAA,QAChCQ,CAAQ;AAAA,uCACuBxF,EAAS,QAAQ,KAAK;AAAA,MAEzDD,EAAO,OAAO,KAAK,EAAE,EACrB,KAAK,GAAG,cAAc,iBAAiB,EAAG,iBAAiB,QAASsF,CAAO,EAEvEC,GACF,KAAK,GAAG,cAAc,yBAAyB,EAAG,iBAAiB,QAASA,CAAc,EAG5F,WAAW,IAAMD,EAAA,EAAWF,EAAqB,CACnD,CAEA,SAAgB,CACd,KAAK,GAAG,OAAA,CACV,CACF,CCjDO,SAASM,GAAWC,EAAKC,EAAS,CAErC,GAAID,EAAI,MAAM,eAAe,EACzB,OAAOA,EAGX,GAAIA,EAAI,MAAM,OAAO,EACjB,OAAO,OAAO,SAAS,SAAWA,EAGtC,GAAIA,EAAI,MAAM,WAAW,EACrB,OAAOA,EAEX,MAAME,EAAM,SAAS,eAAe,mBAAkB,EAChDC,EAAOD,EAAI,cAAc,MAAM,EAC/BE,EAAIF,EAAI,cAAc,GAAG,EAC/B,OAAAA,EAAI,KAAK,YAAYC,CAAI,EACzBD,EAAI,KAAK,YAAYE,CAAC,EAClBH,IACAE,EAAK,KAAOF,GAEhBG,EAAE,KAAOJ,EACFI,EAAE,IACb,CACO,MAAMC,IAAQ,IAAM,CAGvB,IAAIC,EAAU,EAEd,MAAMC,EAAS,IAEf,QAAS,KAAK,OAAM,EAAK,IAAM,GAAM,GAAG,SAAS,EAAE,CAAC,GAAG,MAAM,EAAE,EAC/D,MAAO,KACHD,GAAW,EACJ,IAAIC,GAAQ,GAAGD,CAAO,GAErC,GAAC,EAMM,SAASE,EAAQC,EAAW,CAC/B,MAAMC,EAAM,CAAA,EACZ,QAASrD,EAAI,EAAGsD,EAAIF,EAAU,OAAQpD,EAAIsD,EAAGtD,IACzCqD,EAAI,KAAKD,EAAUpD,CAAC,CAAC,EAEzB,OAAOqD,CACX,CACA,IAAIE,EAAa,KACV,SAASC,EAAmBhB,EAAU,GAAI,CAC7C,OAAIe,IAGAf,EAAQ,wBACRe,EAAaf,EAAQ,uBACde,IAEXA,EAAaJ,EAAQ,OAAO,iBAAiB,SAAS,eAAe,CAAC,EAC/DI,GACX,CACA,SAASE,EAAGC,EAAMC,EAAe,CAE7B,MAAMC,GADMF,EAAK,cAAc,aAAe,QAC9B,iBAAiBA,CAAI,EAAE,iBAAiBC,CAAa,EACrE,OAAOC,EAAM,WAAWA,EAAI,QAAQ,KAAM,EAAE,CAAC,EAAI,CACrD,CACA,SAASC,GAAaH,EAAM,CACxB,MAAMI,EAAaL,EAAGC,EAAM,mBAAmB,EACzCK,EAAcN,EAAGC,EAAM,oBAAoB,EACjD,OAAOA,EAAK,YAAcI,EAAaC,CAC3C,CACA,SAASC,GAAcN,EAAM,CACzB,MAAMO,EAAYR,EAAGC,EAAM,kBAAkB,EACvCQ,EAAeT,EAAGC,EAAM,qBAAqB,EACnD,OAAOA,EAAK,aAAeO,EAAYC,CAC3C,CACO,SAASC,EAAaC,EAAY5B,EAAU,GAAI,CACnD,MAAM6B,EAAQ7B,EAAQ,OAASqB,GAAaO,CAAU,EAChDE,EAAS9B,EAAQ,QAAUwB,GAAcI,CAAU,EACzD,MAAO,CAAE,MAAAC,EAAO,OAAAC,CAAM,CAC1B,CACO,SAASC,IAAgB,CAC5B,IAAIC,EACAC,EACJ,GAAI,CACAA,EAAgB,OACpB,MACU,CAEV,CACA,MAAMb,EAAMa,GAAiBA,EAAc,IACrCA,EAAc,IAAI,iBAClB,KACN,OAAIb,IACAY,EAAQ,SAASZ,EAAK,EAAE,EACpB,OAAO,MAAMY,CAAK,IAClBA,EAAQ,IAGTA,GAAS,OAAO,kBAAoB,CAC/C,CAEA,MAAME,EAAuB,MACtB,SAASC,GAAsBC,EAAQ,EACtCA,EAAO,MAAQF,GACfE,EAAO,OAASF,KACZE,EAAO,MAAQF,GACfE,EAAO,OAASF,EACZE,EAAO,MAAQA,EAAO,QACtBA,EAAO,QAAUF,EAAuBE,EAAO,MAC/CA,EAAO,MAAQF,IAGfE,EAAO,OAASF,EAAuBE,EAAO,OAC9CA,EAAO,OAASF,GAGfE,EAAO,MAAQF,GACpBE,EAAO,QAAUF,EAAuBE,EAAO,MAC/CA,EAAO,MAAQF,IAGfE,EAAO,OAASF,EAAuBE,EAAO,OAC9CA,EAAO,OAASF,GAG5B,CAqBO,SAASG,EAAYlC,EAAK,CAC7B,OAAO,IAAI,QAAQ,CAACmC,EAASC,IAAW,CACpC,MAAMC,EAAM,IAAI,MAChBA,EAAI,OAAS,IAAM,CACfA,EAAI,SAAS,KAAK,IAAM,CACpB,sBAAsB,IAAMF,EAAQE,CAAG,CAAC,CAC5C,CAAC,CACL,EACAA,EAAI,QAAUD,EACdC,EAAI,YAAc,YAClBA,EAAI,SAAW,QACfA,EAAI,IAAMrC,CACd,CAAC,CACL,CACO,eAAesC,GAAaC,EAAK,CACpC,OAAO,QAAQ,QAAO,EACjB,KAAK,IAAM,IAAI,gBAAgB,kBAAkBA,CAAG,CAAC,EACrD,KAAK,kBAAkB,EACvB,KAAMC,GAAS,oCAAoCA,CAAI,EAAE,CAClE,CACO,eAAeC,GAAc1B,EAAMW,EAAOC,EAAQ,CACrD,MAAMe,EAAQ,6BACRH,EAAM,SAAS,gBAAgBG,EAAO,KAAK,EAC3CC,EAAgB,SAAS,gBAAgBD,EAAO,eAAe,EACrE,OAAAH,EAAI,aAAa,QAAS,GAAGb,CAAK,EAAE,EACpCa,EAAI,aAAa,SAAU,GAAGZ,CAAM,EAAE,EACtCY,EAAI,aAAa,UAAW,OAAOb,CAAK,IAAIC,CAAM,EAAE,EACpDgB,EAAc,aAAa,QAAS,MAAM,EAC1CA,EAAc,aAAa,SAAU,MAAM,EAC3CA,EAAc,aAAa,IAAK,GAAG,EACnCA,EAAc,aAAa,IAAK,GAAG,EACnCA,EAAc,aAAa,4BAA6B,MAAM,EAC9DJ,EAAI,YAAYI,CAAa,EAC7BA,EAAc,YAAY5B,CAAI,EACvBuB,GAAaC,CAAG,CAC3B,CACO,MAAMK,EAAsB,CAAC7B,EAAM8B,IAAa,CACnD,GAAI9B,aAAgB8B,EAChB,MAAO,GACX,MAAMC,EAAgB,OAAO,eAAe/B,CAAI,EAChD,OAAI+B,IAAkB,KACX,GACHA,EAAc,YAAY,OAASD,EAAS,MAChDD,EAAoBE,EAAeD,CAAQ,CACnD,EC9LA,SAASE,GAAclJ,EAAO,CAC1B,MAAMmJ,EAAUnJ,EAAM,iBAAiB,SAAS,EAChD,MAAO,GAAGA,EAAM,OAAO,cAAcmJ,EAAQ,QAAQ,OAAQ,EAAE,CAAC,IACpE,CACA,SAASC,GAAoBpJ,EAAOgG,EAAS,CACzC,OAAOgB,EAAmBhB,CAAO,EAC5B,IAAKqD,GAAS,CACf,MAAMC,EAAQtJ,EAAM,iBAAiBqJ,CAAI,EACnCE,EAAWvJ,EAAM,oBAAoBqJ,CAAI,EAC/C,MAAO,GAAGA,CAAI,KAAKC,CAAK,GAAGC,EAAW,cAAgB,EAAE,GAC5D,CAAC,EACI,KAAK,GAAG,CACjB,CACA,SAASC,GAAsBrJ,EAAWsJ,EAAQzJ,EAAOgG,EAAS,CAC9D,MAAM7D,EAAW,IAAIhC,CAAS,IAAIsJ,CAAM,GAClCxJ,EAAUD,EAAM,QAChBkJ,GAAclJ,CAAK,EACnBoJ,GAAoBpJ,EAAOgG,CAAO,EACxC,OAAO,SAAS,eAAe,GAAG7D,CAAQ,IAAIlC,CAAO,GAAG,CAC5D,CACA,SAASyJ,EAAmBC,EAAYC,EAAYH,EAAQzD,EAAS,CACjE,MAAMhG,EAAQ,OAAO,iBAAiB2J,EAAYF,CAAM,EAClDN,EAAUnJ,EAAM,iBAAiB,SAAS,EAChD,GAAImJ,IAAY,IAAMA,IAAY,OAC9B,OAEJ,MAAMhJ,EAAYqG,GAAI,EACtB,GAAI,CACAoD,EAAW,UAAY,GAAGA,EAAW,SAAS,IAAIzJ,CAAS,EAC/D,MACY,CACR,MACJ,CACA,MAAM0J,EAAe,SAAS,cAAc,OAAO,EACnDA,EAAa,YAAYL,GAAsBrJ,EAAWsJ,EAAQzJ,EAAOgG,CAAO,CAAC,EACjF4D,EAAW,YAAYC,CAAY,CACvC,CACO,SAASC,GAAoBH,EAAYC,EAAY5D,EAAS,CACjE0D,EAAmBC,EAAYC,EAAY,UAAW5D,CAAO,EAC7D0D,EAAmBC,EAAYC,EAAY,SAAU5D,CAAO,CAChE,CCzCA,MAAM+D,EAAO,wBACPC,EAAO,aACPC,GAAQ,CACV,KAAMF,EACN,MAAOA,EACP,IAAK,4BACL,IAAK,gCACL,IAAK,YACL,IAAKC,EACL,KAAMA,EACN,IAAK,YACL,KAAM,aACN,IAAK,gBACL,KAAM,YACV,EACA,SAASE,GAAa/D,EAAK,CACvB,MAAMgE,EAAQ,gBAAgB,KAAKhE,CAAG,EACtC,OAAOgE,EAAQA,EAAM,CAAC,EAAI,EAC9B,CACO,SAASC,EAAYjE,EAAK,CAC7B,MAAMkE,EAAYH,GAAa/D,CAAG,EAAE,YAAW,EAC/C,OAAO8D,GAAMI,CAAS,GAAK,EAC/B,CCtBA,SAASC,GAAsBC,EAAS,CACpC,OAAOA,EAAQ,MAAM,GAAG,EAAE,CAAC,CAC/B,CACO,SAASC,EAAUrE,EAAK,CAC3B,OAAOA,EAAI,OAAO,UAAU,IAAM,EACtC,CACO,SAASsE,GAAYtB,EAASuB,EAAU,CAC3C,MAAO,QAAQA,CAAQ,WAAWvB,CAAO,EAC7C,CACO,eAAewB,EAAexE,EAAKyE,EAAMC,EAAS,CACrD,MAAMvF,EAAM,MAAM,MAAMa,EAAKyE,CAAI,EACjC,GAAItF,EAAI,SAAW,IACf,MAAM,IAAI,MAAM,aAAaA,EAAI,GAAG,aAAa,EAErD,MAAMwF,EAAO,MAAMxF,EAAI,KAAI,EAC3B,OAAO,IAAI,QAAQ,CAACgD,EAASC,IAAW,CACpC,MAAMwC,EAAS,IAAI,WACnBA,EAAO,QAAUxC,EACjBwC,EAAO,UAAY,IAAM,CACrB,GAAI,CACAzC,EAAQuC,EAAQ,CAAE,IAAAvF,EAAK,OAAQyF,EAAO,MAAM,CAAE,CAAC,CACnD,OACOC,EAAO,CACVzC,EAAOyC,CAAK,CAChB,CACJ,EACAD,EAAO,cAAcD,CAAI,CAC7B,CAAC,CACL,CACA,MAAMG,EAAQ,CAAA,EACd,SAASC,GAAY/E,EAAKgF,EAAaC,EAAoB,CACvD,IAAIC,EAAMlF,EAAI,QAAQ,OAAQ,EAAE,EAChC,OAAIiF,IACAC,EAAMlF,GAGN,sBAAsB,KAAKkF,CAAG,IAC9BA,EAAMA,EAAI,QAAQ,OAAQ,EAAE,GAEzBF,EAAc,IAAIA,CAAW,IAAIE,CAAG,GAAKA,CACpD,CACO,eAAeC,EAAkBC,EAAaJ,EAAanF,EAAS,CACvE,MAAMwF,EAAWN,GAAYK,EAAaJ,EAAanF,EAAQ,kBAAkB,EACjF,GAAIiF,EAAMO,CAAQ,GAAK,KACnB,OAAOP,EAAMO,CAAQ,EAGrBxF,EAAQ,YAERuF,IAAgB,KAAK,KAAKA,CAAW,EAAI,IAAM,KAAO,IAAI,KAAI,EAAG,QAAO,GAE5E,IAAIhB,EACJ,GAAI,CACA,MAAMpB,EAAU,MAAMwB,EAAeY,EAAavF,EAAQ,iBAAkB,CAAC,CAAE,IAAAV,EAAK,OAAAmG,MAC3EN,IAEDA,EAAc7F,EAAI,QAAQ,IAAI,cAAc,GAAK,IAE9CgF,GAAsBmB,CAAM,EACtC,EACDlB,EAAUE,GAAYtB,EAASgC,CAAW,CAC9C,OACOH,EAAO,CACVT,EAAUvE,EAAQ,kBAAoB,GACtC,IAAIP,EAAM,6BAA6B8F,CAAW,GAC9CP,IACAvF,EAAM,OAAOuF,GAAU,SAAWA,EAAQA,EAAM,SAEhDvF,GACA,QAAQ,KAAKA,CAAG,CAExB,CACA,OAAAwF,EAAMO,CAAQ,EAAIjB,EACXA,CACX,CCtEA,eAAemB,GAAmBtD,EAAQ,CACtC,MAAMmC,EAAUnC,EAAO,UAAS,EAChC,OAAImC,IAAY,SACLnC,EAAO,UAAU,EAAK,EAE1BC,EAAYkC,CAAO,CAC9B,CACA,eAAeoB,GAAkBC,EAAO5F,EAAS,CAC7C,GAAI4F,EAAM,WAAY,CAClB,MAAMxD,EAAS,SAAS,cAAc,QAAQ,EACxCyD,EAAMzD,EAAO,WAAW,IAAI,EAClCA,EAAO,MAAQwD,EAAM,YACrBxD,EAAO,OAASwD,EAAM,aACoBC,GAAI,UAAUD,EAAO,EAAG,EAAGxD,EAAO,MAAOA,EAAO,MAAM,EAChG,MAAMmC,EAAUnC,EAAO,UAAS,EAChC,OAAOC,EAAYkC,CAAO,CAC9B,CACA,MAAMuB,EAASF,EAAM,OACfT,EAAcf,EAAY0B,CAAM,EAChCvB,EAAU,MAAMe,EAAkBQ,EAAQX,EAAanF,CAAO,EACpE,OAAOqC,EAAYkC,CAAO,CAC9B,CACA,eAAewB,GAAmBC,EAAQhG,EAAS,CAC/C,IAAIiG,EACJ,GAAI,CACA,GAAK,GAAAA,EAAqDD,GAAO,mBAAqB,MAAQC,IAAO,SAAkBA,EAAG,KACtH,OAAQ,MAAMC,EAAUF,EAAO,gBAAgB,KAAMhG,EAAS,EAAI,CAE1E,MACW,CAEX,CACA,OAAOgG,EAAO,UAAU,EAAK,CACjC,CACA,eAAeG,GAAgBjF,EAAMlB,EAAS,CAC1C,OAAI+C,EAAoB7B,EAAM,iBAAiB,EACpCwE,GAAmBxE,CAAI,EAE9B6B,EAAoB7B,EAAM,gBAAgB,EACnCyE,GAAkBzE,EAAMlB,CAAO,EAEtC+C,EAAoB7B,EAAM,iBAAiB,EACpC6E,GAAmB7E,EAAMlB,CAAO,EAEpCkB,EAAK,UAAUkF,EAAalF,CAAI,CAAC,CAC5C,CACA,MAAMmF,GAAiBnF,GAASA,EAAK,SAAW,MAAQA,EAAK,QAAQ,YAAW,IAAO,OACjFkF,EAAgBlF,GAASA,EAAK,SAAW,MAAQA,EAAK,QAAQ,YAAW,IAAO,MACtF,eAAeoF,GAAc3C,EAAYC,EAAY5D,EAAS,CAC1D,IAAIiG,EAAIM,EACR,GAAIH,EAAaxC,CAAU,EACvB,OAAOA,EAEX,IAAI4C,EAAW,CAAA,EAWf,OAVIH,GAAc1C,CAAU,GAAKA,EAAW,cACxC6C,EAAW7F,EAAQgD,EAAW,eAAe,EAExCZ,EAAoBY,EAAY,iBAAiB,IACpD,GAAAsC,EAAKtC,EAAW,mBAAqB,MAAQsC,IAAO,SAAkBA,EAAG,MAC3EO,EAAW7F,EAAQgD,EAAW,gBAAgB,KAAK,UAAU,EAG7D6C,EAAW7F,IAAU4F,EAAK5C,EAAW,cAAgB,MAAQ4C,IAAO,OAASA,EAAK5C,GAAY,UAAU,EAExG6C,EAAS,SAAW,GACpBzD,EAAoBY,EAAY,gBAAgB,GAGpD,MAAM6C,EAAS,OAAO,CAACC,EAAUC,IAAUD,EACtC,KAAK,IAAMP,EAAUQ,EAAO1G,CAAO,CAAC,EACpC,KAAM2G,GAAgB,CACnBA,GACA/C,EAAW,YAAY+C,CAAW,CAE1C,CAAC,EAAG,QAAQ,SAAS,EACd/C,CACX,CACA,SAASgD,GAAcjD,EAAYC,EAAY5D,EAAS,CACpD,MAAM6G,EAAcjD,EAAW,MAC/B,GAAI,CAACiD,EACD,OAEJ,MAAMC,EAAc,OAAO,iBAAiBnD,CAAU,EAClDmD,EAAY,SACZD,EAAY,QAAUC,EAAY,QAClCD,EAAY,gBAAkBC,EAAY,iBAG1C9F,EAAmBhB,CAAO,EAAE,QAASqD,GAAS,CAC1C,IAAIC,EAAQwD,EAAY,iBAAiBzD,CAAI,EACzCA,IAAS,aAAeC,EAAM,SAAS,IAAI,IAE3CA,EAAQ,GADY,KAAK,MAAM,WAAWA,EAAM,UAAU,EAAGA,EAAM,OAAS,CAAC,CAAC,CAAC,EAAI,EAC7D,MAEtBP,EAAoBY,EAAY,iBAAiB,GACjDN,IAAS,WACTC,IAAU,WACVA,EAAQ,SAERD,IAAS,KAAOO,EAAW,aAAa,GAAG,IAC3CN,EAAQ,QAAQM,EAAW,aAAa,GAAG,CAAC,KAEhDiD,EAAY,YAAYxD,EAAMC,EAAOwD,EAAY,oBAAoBzD,CAAI,CAAC,CAC9E,CAAC,CAET,CACA,SAAS0D,GAAgBpD,EAAYC,EAAY,CACzCb,EAAoBY,EAAY,mBAAmB,IACnDC,EAAW,UAAYD,EAAW,OAElCZ,EAAoBY,EAAY,gBAAgB,GAChDC,EAAW,aAAa,QAASD,EAAW,KAAK,CAEzD,CACA,SAASqD,GAAiBrD,EAAYC,EAAY,CAC9C,GAAIb,EAAoBY,EAAY,iBAAiB,EAAG,CACpD,MAAMsD,EAAerD,EACfsD,EAAiB,MAAM,KAAKD,EAAa,QAAQ,EAAE,KAAMP,GAAU/C,EAAW,QAAU+C,EAAM,aAAa,OAAO,CAAC,EACrHQ,GACAA,EAAe,aAAa,WAAY,EAAE,CAElD,CACJ,CACA,SAASC,GAASxD,EAAYC,EAAY5D,EAAS,CAC/C,OAAI+C,EAAoBa,EAAY,OAAO,IACvCgD,GAAcjD,EAAYC,EAAY5D,CAAO,EAC7C8D,GAAoBH,EAAYC,EAAY5D,CAAO,EACnD+G,GAAgBpD,EAAYC,CAAU,EACtCoD,GAAiBrD,EAAYC,CAAU,GAEpCA,CACX,CACA,eAAewD,GAAiBC,EAAOrH,EAAS,CAC5C,MAAMsH,EAAOD,EAAM,iBAAmBA,EAAM,iBAAiB,KAAK,EAAI,CAAA,EACtE,GAAIC,EAAK,SAAW,EAChB,OAAOD,EAEX,MAAME,EAAgB,CAAA,EACtB,QAAS/J,EAAI,EAAGA,EAAI8J,EAAK,OAAQ9J,IAAK,CAElC,MAAMgK,EADMF,EAAK9J,CAAC,EACH,aAAa,YAAY,EACxC,GAAIgK,EAAI,CACJ,MAAMC,EAAQJ,EAAM,cAAcG,CAAE,EAC9BE,EAAa,SAAS,cAAcF,CAAE,EACxC,CAACC,GAASC,GAAc,CAACH,EAAcC,CAAE,IAEzCD,EAAcC,CAAE,EAAK,MAAMtB,EAAUwB,EAAY1H,EAAS,EAAI,EAEtE,CACJ,CACA,MAAM3F,EAAQ,OAAO,OAAOkN,CAAa,EACzC,GAAIlN,EAAM,OAAQ,CACd,MAAMsN,EAAK,+BACLjF,EAAM,SAAS,gBAAgBiF,EAAI,KAAK,EAC9CjF,EAAI,aAAa,QAASiF,CAAE,EAC5BjF,EAAI,MAAM,SAAW,WACrBA,EAAI,MAAM,MAAQ,IAClBA,EAAI,MAAM,OAAS,IACnBA,EAAI,MAAM,SAAW,SACrBA,EAAI,MAAM,QAAU,OACpB,MAAMkF,EAAO,SAAS,gBAAgBD,EAAI,MAAM,EAChDjF,EAAI,YAAYkF,CAAI,EACpB,QAASpK,EAAI,EAAGA,EAAInD,EAAM,OAAQmD,IAC9BoK,EAAK,YAAYvN,EAAMmD,CAAC,CAAC,EAE7B6J,EAAM,YAAY3E,CAAG,CACzB,CACA,OAAO2E,CACX,CACO,eAAenB,EAAUhF,EAAMlB,EAAS6H,EAAQ,CACnD,MAAI,CAACA,GAAU7H,EAAQ,QAAU,CAACA,EAAQ,OAAOkB,CAAI,EAC1C,KAEJ,QAAQ,QAAQA,CAAI,EACtB,KAAM0C,GAAeuC,GAAgBvC,EAAY5D,CAAO,CAAC,EACzD,KAAM4D,GAAe0C,GAAcpF,EAAM0C,EAAY5D,CAAO,CAAC,EAC7D,KAAM4D,GAAeuD,GAASjG,EAAM0C,EAAY5D,CAAO,CAAC,EACxD,KAAM4D,GAAewD,GAAiBxD,EAAY5D,CAAO,CAAC,CACnE,CCnLA,MAAM8H,EAAY,6BACZC,GAAwB,8CACxBC,GAAiB,qDACvB,SAASC,GAAQ9H,EAAK,CAElB,MAAM+H,EAAU/H,EAAI,QAAQ,2BAA4B,MAAM,EAC9D,OAAO,IAAI,OAAO,iBAAiB+H,CAAO,cAAe,GAAG,CAChE,CACO,SAASC,GAAUlO,EAAS,CAC/B,MAAMmO,EAAO,CAAA,EACb,OAAAnO,EAAQ,QAAQ6N,EAAW,CAACO,EAAKC,EAAWnI,KACxCiI,EAAK,KAAKjI,CAAG,EACNkI,EACV,EACMD,EAAK,OAAQjI,GAAQ,CAACqE,EAAUrE,CAAG,CAAC,CAC/C,CACO,eAAeoI,GAAMtO,EAASuO,EAAaC,EAASzI,EAAS0I,EAAmB,CACnF,GAAI,CACA,MAAMC,EAAcF,EAAUvI,GAAWsI,EAAaC,CAAO,EAAID,EAC3DrD,EAAcf,EAAYoE,CAAW,EAC3C,IAAIjE,EACJ,OAAImE,IAKAnE,EAAU,MAAMe,EAAkBqD,EAAaxD,EAAanF,CAAO,GAEhE/F,EAAQ,QAAQgO,GAAQO,CAAW,EAAG,KAAKjE,CAAO,IAAI,CACjE,MACc,CAEd,CACA,OAAOtK,CACX,CACA,SAAS2O,GAA0BC,EAAK,CAAE,oBAAAC,GAAuB,CAC7D,OAAQA,EAEFD,EAAI,QAAQb,GAAiB7D,GAAU,CAErC,OAAa,CACT,KAAM,CAAC4E,EAAG,CAAIC,CAAM,EAAIjB,GAAsB,KAAK5D,CAAK,GAAK,CAAA,EAC7D,GAAI,CAAC6E,EACD,MAAO,GAEX,GAAIA,IAAWF,EACX,MAAO,QAAQC,CAAG,GAE1B,CACJ,CAAC,EAZCF,CAaV,CACO,SAASI,EAAY9I,EAAK,CAC7B,OAAOA,EAAI,OAAO2H,CAAS,IAAM,EACrC,CACO,eAAeoB,GAAejP,EAASmG,EAASJ,EAAS,CAC5D,GAAI,CAACiJ,EAAYhP,CAAO,EACpB,OAAOA,EAEX,MAAMkP,EAAkBP,GAA0B3O,EAAS+F,CAAO,EAElE,OADamI,GAAUgB,CAAe,EAC1B,OAAO,CAAC1C,EAAUtG,IAAQsG,EAAS,KAAM2C,GAAQb,GAAMa,EAAKjJ,EAAKC,EAASJ,CAAO,CAAC,EAAG,QAAQ,QAAQmJ,CAAe,CAAC,CACrI,CC5DA,eAAeE,EAAUC,EAAUpI,EAAMlB,EAAS,CAC9C,IAAIiG,EACJ,MAAMsD,GAAatD,EAAK/E,EAAK,SAAW,MAAQ+E,IAAO,OAAS,OAASA,EAAG,iBAAiBqD,CAAQ,EACrG,GAAIC,EAAW,CACX,MAAMC,EAAY,MAAMN,GAAeK,EAAW,KAAMvJ,CAAO,EAC/D,OAAAkB,EAAK,MAAM,YAAYoI,EAAUE,EAAWtI,EAAK,MAAM,oBAAoBoI,CAAQ,CAAC,EAC7E,EACX,CACA,MAAO,EACX,CACA,eAAeG,GAAgB7F,EAAY5D,EAAS,CAE/C,MAAMqJ,EAAU,aAAczF,EAAY5D,CAAO,GAC7C,MAAMqJ,EAAU,mBAAoBzF,EAAY5D,CAAO,EAC3D,MAAMqJ,EAAU,OAAQzF,EAAY5D,CAAO,GACvC,MAAMqJ,EAAU,eAAgBzF,EAAY5D,CAAO,GACnD,MAAMqJ,EAAU,aAAczF,EAAY5D,CAAO,GACjD,MAAMqJ,EAAU,qBAAsBzF,EAAY5D,CAAO,CAClE,CACA,eAAe0J,GAAe9F,EAAY5D,EAAS,CAC/C,MAAM2J,EAAiB5G,EAAoBa,EAAY,gBAAgB,EACvE,GAAI,EAAE+F,GAAkB,CAACnF,EAAUZ,EAAW,GAAG,IAC7C,EAAEb,EAAoBa,EAAY,eAAe,GAC7C,CAACY,EAAUZ,EAAW,KAAK,OAAO,GACtC,OAEJ,MAAMzD,EAAMwJ,EAAiB/F,EAAW,IAAMA,EAAW,KAAK,QACxDW,EAAU,MAAMe,EAAkBnF,EAAKiE,EAAYjE,CAAG,EAAGH,CAAO,EACtE,MAAM,IAAI,QAAQ,CAACsC,EAASC,IAAW,CACnCqB,EAAW,OAAStB,EACpBsB,EAAW,QAAU5D,EAAQ,oBACvB,IAAI4J,IAAe,CACjB,GAAI,CACAtH,EAAQtC,EAAQ,oBAAoB,GAAG4J,CAAU,CAAC,CACtD,OACO5E,EAAO,CACVzC,EAAOyC,CAAK,CAChB,CACJ,EACEzC,EACN,MAAMsH,EAAQjG,EACViG,EAAM,SACNA,EAAM,OAASvH,GAEfuH,EAAM,UAAY,SAClBA,EAAM,QAAU,SAEhBF,GACA/F,EAAW,OAAS,GACpBA,EAAW,IAAMW,GAGjBX,EAAW,KAAK,QAAUW,CAElC,CAAC,CACL,CACA,eAAeuF,GAAclG,EAAY5D,EAAS,CAE9C,MAAM+J,EADWpJ,EAAQiD,EAAW,UAAU,EACnB,IAAK8C,GAAUsD,GAAYtD,EAAO1G,CAAO,CAAC,EACrE,MAAM,QAAQ,IAAI+J,CAAS,EAAE,KAAK,IAAMnG,CAAU,CACtD,CACO,eAAeoG,GAAYpG,EAAY5D,EAAS,CAC/C+C,EAAoBa,EAAY,OAAO,IACvC,MAAM6F,GAAgB7F,EAAY5D,CAAO,EACzC,MAAM0J,GAAe9F,EAAY5D,CAAO,EACxC,MAAM8J,GAAclG,EAAY5D,CAAO,EAE/C,CCvEO,SAASiK,GAAW/I,EAAMlB,EAAS,CACtC,KAAM,CAAE,MAAAhG,CAAK,EAAKkH,EACdlB,EAAQ,kBACRhG,EAAM,gBAAkBgG,EAAQ,iBAEhCA,EAAQ,QACRhG,EAAM,MAAQ,GAAGgG,EAAQ,KAAK,MAE9BA,EAAQ,SACRhG,EAAM,OAAS,GAAGgG,EAAQ,MAAM,MAEpC,MAAMkK,EAASlK,EAAQ,MACvB,OAAIkK,GAAU,MACV,OAAO,KAAKA,CAAM,EAAE,QAAS7E,GAAQ,CACjCrL,EAAMqL,CAAG,EAAI6E,EAAO7E,CAAG,CAC3B,CAAC,EAEEnE,CACX,CCfA,MAAMiJ,EAAgB,CAAA,EACtB,eAAeC,EAASjK,EAAK,CACzB,IAAI8E,EAAQkF,EAAchK,CAAG,EAC7B,GAAI8E,GAAS,KACT,OAAOA,EAGX,MAAMhL,EAAU,MADJ,MAAM,MAAMkG,CAAG,GACD,KAAI,EAC9B,OAAA8E,EAAQ,CAAE,IAAA9E,EAAK,QAAAlG,CAAO,EACtBkQ,EAAchK,CAAG,EAAI8E,EACdA,CACX,CACA,eAAeoF,EAAWC,EAAMtK,EAAS,CACrC,IAAI/F,EAAUqQ,EAAK,QACnB,MAAMC,EAAW,8BAEXC,GADWvQ,EAAQ,MAAM,eAAe,GAAK,CAAA,GACxB,IAAI,MAAOwQ,GAAQ,CAC1C,IAAItK,EAAMsK,EAAI,QAAQF,EAAU,IAAI,EACpC,OAAKpK,EAAI,WAAW,UAAU,IAC1BA,EAAM,IAAI,IAAIA,EAAKmK,EAAK,GAAG,EAAE,MAE1B3F,EAAexE,EAAKH,EAAQ,iBAAkB,CAAC,CAAE,OAAAyF,MACpDxL,EAAUA,EAAQ,QAAQwQ,EAAK,OAAOhF,CAAM,GAAG,EACxC,CAACgF,EAAKhF,CAAM,EACtB,CACL,CAAC,EACD,OAAO,QAAQ,IAAI+E,CAAS,EAAE,KAAK,IAAMvQ,CAAO,CACpD,CACA,SAASyQ,EAASC,EAAQ,CACtB,GAAIA,GAAU,KACV,MAAO,CAAA,EAEX,MAAMlF,EAAS,CAAA,EACTmF,EAAgB,uBAEtB,IAAI3Q,EAAU0Q,EAAO,QAAQC,EAAe,EAAE,EAE9C,MAAMC,EAAiB,IAAI,OAAO,mDAAoD,IAAI,EAE1F,OAAa,CACT,MAAMC,EAAUD,EAAe,KAAK5Q,CAAO,EAC3C,GAAI6Q,IAAY,KACZ,MAEJrF,EAAO,KAAKqF,EAAQ,CAAC,CAAC,CAC1B,CACA7Q,EAAUA,EAAQ,QAAQ4Q,EAAgB,EAAE,EAC5C,MAAME,EAAc,yCAEdC,EAAmB,6GAGnBC,EAAe,IAAI,OAAOD,EAAkB,IAAI,EAEtD,OAAa,CACT,IAAIF,EAAUC,EAAY,KAAK9Q,CAAO,EACtC,GAAI6Q,IAAY,KAAM,CAElB,GADAA,EAAUG,EAAa,KAAKhR,CAAO,EAC/B6Q,IAAY,KACZ,MAGAC,EAAY,UAAYE,EAAa,SAE7C,MAEIA,EAAa,UAAYF,EAAY,UAEzCtF,EAAO,KAAKqF,EAAQ,CAAC,CAAC,CAC1B,CACA,OAAOrF,CACX,CACA,eAAeyF,GAAYC,EAAanL,EAAS,CAC7C,MAAMoL,EAAM,CAAA,EACNrB,EAAY,CAAA,EAElB,OAAAoB,EAAY,QAASE,GAAU,CAC3B,GAAI,aAAcA,EACd,GAAI,CACA1K,EAAQ0K,EAAM,UAAY,CAAA,CAAE,EAAE,QAAQ,CAACC,EAAM1O,IAAU,CACnD,GAAI0O,EAAK,OAAS,QAAQ,YAAa,CACnC,IAAIC,EAAc3O,EAAQ,EAC1B,MAAMuD,EAAMmL,EAAK,KACX7E,EAAW2D,EAASjK,CAAG,EACxB,KAAMqL,GAAanB,EAAWmB,EAAUxL,CAAO,CAAC,EAChD,KAAM/F,GAAYyQ,EAASzQ,CAAO,EAAE,QAASwR,GAAS,CACvD,GAAI,CACAJ,EAAM,WAAWI,EAAMA,EAAK,WAAW,SAAS,EACzCF,GAAe,EAChBF,EAAM,SAAS,MAAM,CAC/B,OACOrG,GAAO,CACV,QAAQ,MAAM,uCAAwC,CAClD,KAAAyG,EACA,MAAAzG,EACpC,CAAiC,CACL,CACJ,CAAC,CAAC,EACG,MAAO/G,GAAM,CACd,QAAQ,MAAM,2BAA4BA,EAAE,SAAQ,CAAE,CAC1D,CAAC,EACD8L,EAAU,KAAKtD,CAAQ,CAC3B,CACJ,CAAC,CACL,OACOxI,EAAG,CACN,MAAMyN,EAASP,EAAY,KAAM,GAAM,EAAE,MAAQ,IAAI,GAAK,SAAS,YAAY,CAAC,EAC5EE,EAAM,MAAQ,MACdtB,EAAU,KAAKK,EAASiB,EAAM,IAAI,EAC7B,KAAMG,GAAanB,EAAWmB,EAAUxL,CAAO,CAAC,EAChD,KAAM/F,GAAYyQ,EAASzQ,CAAO,EAAE,QAASwR,GAAS,CACvDC,EAAO,WAAWD,EAAMC,EAAO,SAAS,MAAM,CAClD,CAAC,CAAC,EACG,MAAOC,GAAQ,CAChB,QAAQ,MAAM,kCAAmCA,CAAG,CACxD,CAAC,CAAC,EAEN,QAAQ,MAAM,iCAAkC1N,CAAC,CACrD,CAER,CAAC,EACM,QAAQ,IAAI8L,CAAS,EAAE,KAAK,KAE/BoB,EAAY,QAASE,GAAU,CAC3B,GAAI,aAAcA,EACd,GAAI,CACA1K,EAAQ0K,EAAM,UAAY,CAAA,CAAE,EAAE,QAASC,GAAS,CAC5CF,EAAI,KAAKE,CAAI,CACjB,CAAC,CACL,OACOrN,EAAG,CACN,QAAQ,MAAM,sCAAsCoN,EAAM,IAAI,GAAIpN,CAAC,CACvE,CAER,CAAC,EACMmN,EACV,CACL,CACA,SAASQ,GAAgBC,EAAU,CAC/B,OAAOA,EACF,OAAQJ,GAASA,EAAK,OAAS,QAAQ,cAAc,EACrD,OAAQA,GAASxC,EAAYwC,EAAK,MAAM,iBAAiB,KAAK,CAAC,CAAC,CACzE,CACA,eAAeK,GAAkB5K,EAAMlB,EAAS,CAC5C,GAAIkB,EAAK,eAAiB,KACtB,MAAM,IAAI,MAAM,2CAA2C,EAE/D,MAAMiK,EAAcxK,EAAQO,EAAK,cAAc,WAAW,EACpD2K,EAAW,MAAMX,GAAYC,EAAanL,CAAO,EACvD,OAAO4L,GAAgBC,CAAQ,CACnC,CACA,SAASE,GAAoBC,EAAM,CAC/B,OAAOA,EAAK,KAAI,EAAG,QAAQ,QAAS,EAAE,CAC1C,CACA,SAASC,GAAa/K,EAAM,CACxB,MAAMgL,EAAQ,IAAI,IAClB,SAASC,EAASjL,EAAM,EACDA,EAAK,MAAM,YAAc,iBAAiBA,CAAI,EAAE,YACxD,MAAM,GAAG,EAAE,QAAS8K,GAAS,CACpCE,EAAM,IAAIH,GAAoBC,CAAI,CAAC,CACvC,CAAC,EACD,MAAM,KAAK9K,EAAK,QAAQ,EAAE,QAASwF,GAAU,CACrCA,aAAiB,aACjByF,EAASzF,CAAK,CAEtB,CAAC,CACL,CACA,OAAAyF,EAASjL,CAAI,EACNgL,CACX,CACO,eAAeE,GAAclL,EAAMlB,EAAS,CAC/C,MAAMqM,EAAQ,MAAMP,GAAkB5K,EAAMlB,CAAO,EAC7CsM,EAAYL,GAAa/K,CAAI,EASnC,OARiB,MAAM,QAAQ,IAAImL,EAC9B,OAAQZ,GAASa,EAAU,IAAIP,GAAoBN,EAAK,MAAM,UAAU,CAAC,CAAC,EAC1E,IAAKA,GAAS,CACf,MAAMrL,EAAUqL,EAAK,iBACfA,EAAK,iBAAiB,KACtB,KACN,OAAOvC,GAAeuC,EAAK,QAASrL,EAASJ,CAAO,CACxD,CAAC,CAAC,GACc,KAAK;AAAA,CAAI,CAC7B,CACO,eAAeuM,GAAc3I,EAAY5D,EAAS,CACrD,MAAM/F,EAAU+F,EAAQ,cAAgB,KAClCA,EAAQ,aACRA,EAAQ,UACJ,KACA,MAAMoM,GAAcxI,EAAY5D,CAAO,EACjD,GAAI/F,EAAS,CACT,MAAMuS,EAAY,SAAS,cAAc,OAAO,EAC1CC,EAAe,SAAS,eAAexS,CAAO,EACpDuS,EAAU,YAAYC,CAAY,EAC9B7I,EAAW,WACXA,EAAW,aAAa4I,EAAW5I,EAAW,UAAU,EAGxDA,EAAW,YAAY4I,CAAS,CAExC,CACJ,CCtMO,eAAeE,GAAMxL,EAAMlB,EAAU,GAAI,CAC5C,KAAM,CAAE,MAAA6B,EAAO,OAAAC,CAAM,EAAKH,EAAaT,EAAMlB,CAAO,EAC9C4D,EAAc,MAAMsC,EAAUhF,EAAMlB,EAAS,EAAI,EACvD,aAAMuM,GAAc3I,EAAY5D,CAAO,EACvC,MAAMgK,GAAYpG,EAAY5D,CAAO,EACrCiK,GAAWrG,EAAY5D,CAAO,EACd,MAAM4C,GAAcgB,EAAY/B,EAAOC,CAAM,CAEjE,CACO,eAAe6K,GAASzL,EAAMlB,EAAU,GAAI,CAC/C,KAAM,CAAE,MAAA6B,EAAO,OAAAC,CAAM,EAAKH,EAAaT,EAAMlB,CAAO,EAC9C0C,EAAM,MAAMgK,GAAMxL,EAAMlB,CAAO,EAC/BwC,EAAM,MAAMH,EAAYK,CAAG,EAC3BN,EAAS,SAAS,cAAc,QAAQ,EACxCwK,EAAUxK,EAAO,WAAW,IAAI,EAChCJ,EAAQhC,EAAQ,YAAc+B,GAAa,EAC3C8K,EAAc7M,EAAQ,aAAe6B,EACrCiL,EAAe9M,EAAQ,cAAgB8B,EAC7C,OAAAM,EAAO,MAAQyK,EAAc7K,EAC7BI,EAAO,OAAS0K,EAAe9K,EAC1BhC,EAAQ,eACTmC,GAAsBC,CAAM,EAEhCA,EAAO,MAAM,MAAQ,GAAGyK,CAAW,GACnCzK,EAAO,MAAM,OAAS,GAAG0K,CAAY,GACjC9M,EAAQ,kBACR4M,EAAQ,UAAY5M,EAAQ,gBAC5B4M,EAAQ,SAAS,EAAG,EAAGxK,EAAO,MAAOA,EAAO,MAAM,GAEtDwK,EAAQ,UAAUpK,EAAK,EAAG,EAAGJ,EAAO,MAAOA,EAAO,MAAM,EACjDA,CACX,CAOO,eAAe2K,GAAM7L,EAAMlB,EAAU,GAAI,CAE5C,OADe,MAAM2M,GAASzL,EAAMlB,CAAO,GAC7B,UAAS,CAC3B,CC3CA,eAAsBgN,GAAkBC,EAA4B,GAA0B,CAC5F,MAAMC,EAAkBC,GAAwBF,CAAW,EAE3D,GAAI,CACF,MAAMG,EAAU,MAAML,GAAM,SAAS,KAAM,CACzC,UAAW,GACX,cAAe,GACf,OAAS7L,GACH,EAAAA,aAAgB,aAAeA,EAAK,KAAO,kBAEjD,CACD,EACD,OAAOmM,GAAcD,CAAO,CAC9B,MAAQ,CACN,OAAO,IACT,QAAA,CACEF,GAAiB,OAAA,CACnB,CACF,CAEA,SAASC,GAAwBF,EAAkD,CACjF,GAAIA,EAAY,SAAW,EAAG,OAAO,KAErC,MAAMK,EAAQ,SAAS,cAAc,KAAK,EAC1CA,EAAM,aAAa,+BAAgC,MAAM,EACzDA,EAAM,aAAa,cAAe,MAAM,EACxCA,EAAM,MAAM,QAAU,iEAEtB,SAAW,CAAC1Q,EAAOQ,CAAU,IAAK6P,EAAY,UACxC7P,EAAW,OAAS,MACtBkQ,EAAM,YAAYC,GAAgBnQ,EAAYR,EAAQ,CAAC,CAAC,EAC/CQ,EAAW,OAAS,QAAUA,EAAW,UAClDkQ,EAAM,YAAYE,GAAiBpQ,EAAW,QAAQ,CAAC,EAI3D,gBAAS,KAAK,YAAYkQ,CAAK,EACxBA,CACT,CAEA,SAASC,GAAgBnQ,EAAwBR,EAA+B,CAC9E,MAAMC,EAAM,SAAS,cAAc,KAAK,EACxC,OAAAA,EAAI,YAAc,OAAOD,CAAK,EAC9BC,EAAI,MAAM,QAAU,CAClB,iBACA,QAAQO,EAAW,CAAC,KACpB,OAAOA,EAAW,CAAC,KACnB,aACA,cACA,gCACA,qBACA,wBACA,eACA,qBACA,yBACA,8EACA,aACA,4CACA,gCAAA,EACA,KAAK,GAAG,EACHP,CACT,CAEA,SAAS2Q,GAAiBC,EAAiC,CACzD,MAAM/K,EAAM,SAAS,gBAAgB,6BAA8B,KAAK,EACxEA,EAAI,aAAa,QAAS,MAAM,EAChCA,EAAI,aAAa,SAAU,MAAM,EACjCA,EAAI,aAAa,UAAW,OAAO,OAAO,UAAU,IAAI,OAAO,WAAW,EAAE,EAC5EA,EAAI,MAAM,QAAU,kEAEpB,MAAMgL,EAAO,SAAS,gBAAgB,6BAA8B,MAAM,EAC1E,OAAAA,EAAK,aAAa,IAAKD,CAAQ,EAC/BC,EAAK,aAAa,OAAQ,MAAM,EAChCA,EAAK,aAAa,SAAU,SAAS,EACrCA,EAAK,aAAa,eAAgB,KAAK,EACvCA,EAAK,aAAa,iBAAkB,OAAO,EAC3CA,EAAK,aAAa,kBAAmB,OAAO,EAC5CA,EAAK,aAAa,SAAU,6CAA6C,EACzEhL,EAAI,YAAYgL,CAAI,EAEbhL,CACT,CAEA,SAAS2K,GAAcD,EAAuB,CAC5C,KAAM,CAACO,EAAQrD,CAAI,EAAI8C,EAAQ,MAAM,GAAG,EAClCQ,EAAOD,EAAO,MAAM,SAAS,IAAI,CAAC,GAAK,YACvCE,EAAS,KAAKvD,CAAI,EAClBwD,EAAQ,IAAI,WAAWD,EAAO,MAAM,EAC1C,QAASrQ,EAAI,EAAGA,EAAIqQ,EAAO,OAAQrQ,IACjCsQ,EAAMtQ,CAAC,EAAIqQ,EAAO,WAAWrQ,CAAC,EAEhC,OAAO,IAAI,KAAK,CAACsQ,CAAK,EAAG,CAAE,KAAMF,EAAM,CACzC,CCrFA,MAAMG,EAAY,CAAlB,aAAA,CACE,KAAQ,cAAgB,IACxB,KAAQ,gBAA8C,KACtD,KAAQ,iBAA+C,KACvD,KAAQ,iBAAgE,KACxE,KAAQ,OAAS,EAAA,CAEjB,UAAUC,EAAqC,CAC7C,YAAK,UAAU,IAAIA,CAAQ,EAC3B,KAAK,KAAA,EACE,IAAM,CACX,KAAK,UAAU,OAAOA,CAAQ,EAC1B,KAAK,UAAU,OAAS,QAAQ,OAAA,CACtC,CACF,CAEQ,MAAa,CACf,KAAK,SACT,KAAK,OAAS,GAEd,KAAK,gBAAkB,OAAO,QAC9B,KAAK,iBAAmB,CAACvO,EAAKkL,EAAQsD,EAAMC,EAAKlJ,KAC/C,KAAK,KAAK,CAAE,QAAS,OAAOvF,CAAG,EAAG,OAAAkL,EAAQ,KAAAsD,EAAM,IAAAC,EAAK,MAAAlJ,EAAO,EACxD,KAAK,gBACA,KAAK,gBAAgB,KAAK,OAAQvF,EAAKkL,EAAQsD,EAAMC,EAAKlJ,CAAK,EAEjE,IAET,OAAO,QAAU,KAAK,iBAEtB,KAAK,iBAAoB/G,GAA6B,CACpD,MAAMkQ,EAASlQ,EAAE,kBAAkB,MAAQA,EAAE,OAAO,QAAU,OAAOA,EAAE,MAAM,EAC7E,KAAK,KAAK,CAAE,QAAS,wBAAwBkQ,CAAM,GAAI,CACzD,EACA,OAAO,iBAAiB,qBAAsB,KAAK,gBAAgB,EACrE,CAEQ,QAAe,CAChB,KAAK,SACV,KAAK,OAAS,GAGV,OAAO,UAAY,KAAK,mBAC1B,OAAO,QAAU,KAAK,iBAExB,KAAK,iBAAmB,KACxB,KAAK,gBAAkB,KACnB,KAAK,mBACP,OAAO,oBAAoB,qBAAsB,KAAK,gBAAgB,EACtE,KAAK,iBAAmB,MAE5B,CAEQ,KAAKC,EAA+B,CAC1C,UAAWJ,KAAY,KAAK,UAAWA,EAASI,CAAK,CACvD,CACF,CAEO,MAAMC,GAAc,IAAIN,GClEzBO,GAAqB,GAEpB,MAAMC,EAAsB,CAA5B,aAAA,CACL,KAAQ,OAAmB,CAAA,EAC3B,KAAQ,YAAmC,IAAA,CAE3C,OAAc,CACR,KAAK,cACT,KAAK,YAAcF,GAAY,UAAWpQ,GAAM,KAAK,OAAOA,CAAC,CAAC,EAChE,CAEQ,OAAOA,EAA2B,CACxC,MAAMuQ,EAAWvQ,EAAE,MAAQ,KAAO,KAAKA,EAAE,IAAI,IAAIA,EAAE,KAAO,CAAC,IAAM,GACjE,KAAK,SAAS,GAAGA,EAAE,OAAO,GAAGuQ,CAAQ,EAAE,CACzC,CAEQ,SAAS/O,EAAmB,CAC9B,KAAK,OAAO,QAAU6O,IACrB,KAAK,OAAO,SAAS7O,CAAG,GAC3B,KAAK,OAAO,KAAKA,CAAG,CAExB,CAEA,WAAsB,CACpB,MAAO,CAAC,GAAG,KAAK,MAAM,CACxB,CAEA,MAAa,CACX,KAAK,cAAA,EACL,KAAK,YAAc,IACrB,CACF,CCXA,MAAMgP,GAAuB,EACvBC,GAAuB,IACvBC,GAAsB,EACtBC,GAAsB,IACtBC,GAAsB,IACtBC,GAA0B,IAC1BC,GAA4B,IAE5BC,OAAuB,IAAI,CAC/B,IAAK,SAAU,QAAS,SAAU,WAAY,QAAS,UAAW,SACpE,CAAC,EAEKC,OAAwB,IAAI,CAChC,SAAU,OAAQ,WAAY,QAAS,MAAO,WAAY,SAC1D,SAAU,UAAW,WAAY,UAAW,SAAU,YACxD,CAAC,EAEKC,EAAsB,CAC1B,MAAO,MAAO,YAAa,iBAC3B,eAAgB,uBAClB,EAEaC,EAAN,MAAMA,CAAoB,CAwB/B,YAAYC,EAAkD,CAvB9D,KAAQ,aAA8B,CAAA,EAGtC,KAAQ,kBAAyC,KACjD,KAAQ,OAAS,GACjB,KAAQ,WAAa,EACrB,KAAQ,eAAiB,EACzB,KAAQ,cAAgB,EAGxB,KAAQ,cAA0B,CAAA,EAClC,KAAQ,qBAA4C,KACpD,KAAQ,kBAAiD,KACzD,KAAQ,qBAAuD,KAC/D,KAAQ,mBAAkD,KAC1D,KAAQ,sBAAwD,KAChE,KAAQ,mBAAkD,KAC1D,KAAQ,oBAAmD,KAC3D,KAAQ,kBAAoB,IAC5B,KAAQ,YAAuC,KAC/C,KAAQ,iBAAmB,EAC3B,KAAQ,eAAiB,GAGvB,KAAK,cAAgBA,EACrB,KAAK,kBAAqB,GAAkB,KAAK,YAAY,CAAC,CAChE,CAEA,OAAc,CACR,KAAK,SACT,KAAK,OAAS,GACd,SAAS,iBAAiB,QAAS,KAAK,kBAAmB,EAAI,EAC/D,KAAK,kBAAoBf,GAAY,UAAWgB,GAAO,CACrD,KAAK,YACP,CAAC,EAED,KAAK,wBAAA,EACL,KAAK,kBAAA,EACL,KAAK,eAAA,EACP,CAEA,MAAa,CACN,KAAK,SACV,KAAK,OAAS,GACd,SAAS,oBAAoB,QAAS,KAAK,kBAAmB,EAAI,EAClE,KAAK,oBAAA,EACL,KAAK,kBAAoB,KACzB,KAAK,aAAe,CAAA,EAEpB,KAAK,uBAAA,EACL,KAAK,iBAAA,EACL,KAAK,cAAc,MAAA,EAEnB,KAAK,sBAAA,EACP,CAEQ,yBAAgC,CACtC,KAAK,qBAAuB,IAAM,KAAK,iBAAA,EACvC,OAAO,iBAAiB,WAAY,KAAK,oBAAoB,EAE7D,KAAK,kBAAoB,QAAQ,UAAU,KAAK,OAAO,EACvD,KAAK,qBAAuB,QAAQ,aAAa,KAAK,OAAO,EAC7D,MAAMC,EAAW,KAAK,kBAChBC,EAAc,KAAK,qBACnBC,EAAQ,IAAM,KAAK,iBAAA,EAEzB,KAAK,mBAAqB,SAAUlF,EAAemF,EAAgBtP,EAA2B,CAC5FmP,EAAShF,EAAMmF,EAAQtP,CAAG,EAC1BqP,EAAA,CACF,EACA,KAAK,sBAAwB,SAAUlF,EAAemF,EAAgBtP,EAA2B,CAC/FoP,EAAYjF,EAAMmF,EAAQtP,CAAG,EAC7BqP,EAAA,CACF,EACA,QAAQ,UAAY,KAAK,mBACzB,QAAQ,aAAe,KAAK,qBAC9B,CAEQ,wBAA+B,CACjC,KAAK,uBACP,OAAO,oBAAoB,WAAY,KAAK,oBAAoB,EAChE,KAAK,qBAAuB,MAI1B,KAAK,mBAAqB,QAAQ,YAAc,KAAK,qBACvD,QAAQ,UAAY,KAAK,mBAEvB,KAAK,sBAAwB,QAAQ,eAAiB,KAAK,wBAC7D,QAAQ,aAAe,KAAK,sBAE9B,KAAK,kBAAoB,KACzB,KAAK,qBAAuB,KAC5B,KAAK,mBAAqB,KAC1B,KAAK,sBAAwB,KAC7B,KAAK,cAAgB,CAAA,CACvB,CAEQ,mBAA0B,CAChC,KAAK,mBAAsBvR,GAAa,KAAK,iBAAiBA,CAAC,EAC/D,KAAK,oBAAuBA,GAAa,KAAK,kBAAkBA,CAAC,EACjE,SAAS,iBAAiB,SAAU,KAAK,mBAAoB,EAAI,EACjE,SAAS,iBAAiB,UAAW,KAAK,oBAAqB,EAAI,CACrE,CAEQ,kBAAyB,CAC3B,KAAK,qBACP,SAAS,oBAAoB,SAAU,KAAK,mBAAoB,EAAI,EACpE,KAAK,mBAAqB,MAExB,KAAK,sBACP,SAAS,oBAAoB,UAAW,KAAK,oBAAqB,EAAI,EACtE,KAAK,oBAAsB,KAE/B,CAEQ,YAAYA,EAAqB,CACvC,MAAMyR,EAASzR,EAAE,OAGjB,GAFI,CAACyR,GAED,KAAK,gBAAgBA,CAAM,EAAG,OAElC,MAAMC,EAAM,KAAK,IAAA,EACjB,KAAK,aAAa,KAAK,CAAE,OAAAD,EAAQ,KAAMC,EAAK,EAE5C,MAAMC,EAASD,EAAMjB,GAIrB,GAHA,KAAK,aAAe,KAAK,aAAa,OAAOmB,GAAKA,EAAE,KAAOD,CAAM,EAExC,KAAK,aAAa,OAAOC,GAAKA,EAAE,SAAWH,CAAM,EACrD,QAAUjB,GAAsB,CACnD,KAAK,aAAe,CAAA,EACpB,KAAK,iBAAiB,CACpB,OAAQ,aACR,OAAQqB,EAAgBJ,CAAM,EAC9B,UAAWC,CAAA,CACZ,EACD,MACF,CAEK,KAAK,cAAcD,CAAM,IAC5B,KAAK,iBACD,KAAK,gBAAkB,GAAK,KAAK,WAAa,IAChD,KAAK,eAAiB,EACtB,KAAK,WAAa,EAClB,KAAK,YAAY,CACf,OAAQ,aACR,OAAQI,EAAgBJ,CAAM,EAC9B,UAAWC,CAAA,CACZ,IAIL,KAAK,kBAAkBD,EAAQC,CAAG,CACpC,CAEQ,kBAAyB,CAC/B,MAAMA,EAAM,KAAK,IAAA,EACjB,KAAK,cAAc,KAAKA,CAAG,EAC3B,MAAMC,EAASD,EAAMf,GACrB,KAAK,cAAgB,KAAK,cAAc,OAAOmB,GAAKA,EAAIH,CAAM,EAC1D,KAAK,cAAc,QAAUjB,KAC/B,KAAK,cAAgB,CAAA,EACrB,KAAK,YAAY,CACf,OAAQ,mBACR,UAAWgB,CAAA,CACZ,GAEH,WAAW,IAAM,CACX,KAAK,QAAQ,KAAK,eAAA,CACxB,EAAGZ,EAAyB,CAC9B,CAEQ,iBAAiB9Q,EAAgB,CACvC,MAAM+R,EAAO/R,EAAE,OACT+R,aAAgB,kBAClB,KAAK,gBAAgBA,CAAI,GAE7B,WAAW,IAAM,CACV,KAAK,QACNA,EAAK,cAAc,oCAAoC,GACzD,KAAK,YAAY,CACf,OAAQ,eACR,OAAQF,EAAgBE,CAAI,EAC5B,UAAW,KAAK,IAAA,CAAI,CACrB,CAEL,EAAGnB,EAAmB,EACxB,CAEQ,kBAAkB5Q,EAAgB,CACxC,MAAM7D,EAAK6D,EAAE,OAEb,GADI,CAAC7D,GACD,KAAK,gBAAgBA,CAAE,EAAG,OAC9B,MAAM4V,EAAO5V,EAAG,QAAQ,MAAM,EAC9B,KAAK,YAAY,CACf,OAAQ,eACR,OAAe0V,EAAPE,GAA+C5V,CAApB,EACnC,UAAW,KAAK,IAAA,CAAI,CACrB,CACH,CAEQ,gBAAuB,CAC7B,MAAM+F,EAAM,SAAS,KACrB,GAAI,KAAK,cAAc,IAAIA,CAAG,EAAG,OAEjC,MAAMxE,EAAQ,SAAS,MAAM,YAAA,EAC7B,GAAIuT,EAAoB,KAAKxR,GAAK/B,EAAM,SAAS+B,CAAC,CAAC,EAAG,CACpD,KAAK,cAAc,IAAIyC,CAAG,EAC1B,KAAK,iBAAiB,CACpB,OAAQ,aACR,OAAQ,SAAS,MACjB,UAAW,KAAK,IAAA,CAAI,CACrB,EACD,MACF,CAEA,MAAM8P,EAAa,SAAS,iBAC1B,kFAAA,EAEF,UAAW7V,KAAM6V,EAAY,CAC3B,MAAMrU,EAAOxB,EAAG,aAAe,GAC/B,GAAIwB,EAAK,OAAS,KAAOsT,EAAoB,KAAKxR,GAAK9B,EAAK,YAAA,EAAc,SAAS8B,CAAC,CAAC,EAAG,CACtF,KAAK,cAAc,IAAIyC,CAAG,EAC1B,KAAK,iBAAiB,CACpB,OAAQ,aACR,OAAQvE,EAAK,KAAA,EAAO,MAAM,EAAG,EAAE,EAC/B,UAAW,KAAK,IAAA,CAAI,CACrB,EACD,MACF,CACF,CACF,CAKQ,kBAAkB8T,EAAiBQ,EAAyB,CAC7D,KAAK,iBAAiBR,CAAM,IAEjC,KAAK,mBACL,KAAK,kBAAA,EAEL,WAAW,IAAM,CACf,KAAK,mBACL,MAAMS,EAAU,KAAK,gBAAkBD,EACnC,KAAK,mBAAqB,GAAG,KAAK,sBAAA,EAElC,CAACC,GAAW,KAAK,QACnB,KAAK,YAAY,CACf,OAAQ,iBACR,OAAQL,EAAgBJ,CAAM,EAC9B,UAAWQ,CAAA,CACZ,CAEL,EAAGpB,EAAuB,EAC5B,CAEQ,mBAA0B,CAC5B,KAAK,cACT,KAAK,YAAc,IAAI,iBAAiB,IAAM,CAC5C,KAAK,eAAiB,KAAK,IAAA,CAC7B,CAAC,EACD,KAAK,YAAY,QAAQ,SAAS,KAAM,CACtC,UAAW,GACX,QAAS,GACT,WAAY,GACZ,cAAe,EAAA,CAChB,EACH,CAEQ,uBAA8B,CACpC,KAAK,aAAa,WAAA,EAClB,KAAK,YAAc,IACrB,CAEQ,iBAAiB1U,EAAsB,CAE7C,GADc,OAAO,iBAAiBA,CAAE,EAC9B,SAAW,UAAW,MAAO,GAEvC,GAAIA,EAAG,UACL,UAAWgW,KAAOhW,EAAG,UAAW,CAC9B,MAAMiW,EAAQD,EAAI,YAAA,EAClB,GAAIC,EAAM,SAAS,KAAK,GAAKA,EAAM,SAAS,QAAQ,EAAG,MAAO,EAChE,CAGF,MAAO,EACT,CAEQ,cAAcjW,EAAsB,CAC1C,GAAI4U,GAAiB,IAAI5U,EAAG,OAAO,EAAG,MAAO,GAE7C,MAAMkW,EAAOlW,EAAG,aAAa,MAAM,EAUnC,MATI,GAAAkW,GAAQrB,GAAkB,IAAIqB,CAAI,GAElClW,EAAG,aAAa,SAAS,GAAKA,EAAG,aAAa,UAAU,GACvDA,EAAmB,kBAAoB,QAE9B,OAAO,iBAAiBA,CAAE,EAC9B,SAAW,WAENA,EAAG,QAAQ,kDAAkD,EAI9E,CAEQ,gBAAgBA,EAAsB,CAC5C,MAAMmW,EAAO,SAAS,eAAe,iBAAiB,EACtD,OAAKA,EACEA,IAASnW,GAAMmW,EAAK,SAASnW,CAAE,EADpB,EAEpB,CAEQ,YAAYgU,EAA+B,CACjD,MAAMuB,EAAM,KAAK,IAAA,EACbA,EAAM,KAAK,gBACf,KAAK,cAAgBA,EAAMR,EAAoB,YAC/C,KAAK,cAAcf,CAAK,EAC1B,CAEQ,iBAAiBA,EAA+B,CACtD,KAAK,cAAgB,KAAK,IAAA,EAAQe,EAAoB,YACtD,KAAK,cAAcf,CAAK,CAC1B,CACF,EA5TEe,EAAwB,YAAc,IATjC,IAAMqB,EAANrB,EAuUP,SAASW,EAAgB1V,EAAqB,CAC5C,MAAMF,EAAME,EAAG,QAAQ,YAAA,EACjBoN,EAAKpN,EAAG,GAAK,IAAIA,EAAG,EAAE,GAAK,GAC3BgW,EAAMhW,EAAG,WAAa,OAAOA,EAAG,WAAc,SAChD,IAAMA,EAAG,UAAU,OAAO,MAAM,KAAK,EAAE,MAAM,EAAG,CAAC,EAAE,KAAK,GAAG,EAC3D,GACEwB,EAAOxB,EAAG,aAAa,KAAA,EAAO,MAAM,EAAG,EAAE,GAAK,GACpD,MAAO,IAAIF,CAAG,GAAGsN,CAAE,GAAG4I,CAAG,IAAIxU,EAAO,KAAKA,CAAI,IAAM,EAAE,EACvD,CClXO,SAAS6U,IAAkC,CAChD,MAAO,CACL,SAAU,OAAO,SAAS,KAC1B,WAAY,UAAU,UACtB,QAASC,GAAA,EACT,GAAIC,GAAA,EACJ,aAAc,OAAO,OAAO,MAC5B,cAAe,OAAO,OAAO,MAAA,CAEjC,CAEA,SAASD,IAAwB,CAC/B,MAAME,EAAK,UAAU,UACrB,MAAI,QAAQ,KAAKA,CAAE,EAAU,QAAQA,EAAG,MAAM,YAAY,IAAI,CAAC,GAAK,EAAE,GAClE,QAAQ,KAAKA,CAAE,EAAU,SAASA,EAAG,MAAM,YAAY,IAAI,CAAC,GAAK,EAAE,GACnE,WAAW,KAAKA,CAAE,EAAU,UAAUA,EAAG,MAAM,eAAe,IAAI,CAAC,GAAK,EAAE,GAC1E,WAAW,KAAKA,CAAE,GAAK,YAAY,KAAKA,CAAE,EAAU,UAAUA,EAAG,MAAM,gBAAgB,IAAI,CAAC,GAAK,EAAE,GACnG,YAAY,KAAKA,CAAE,EAAU,WAAWA,EAAG,MAAM,gBAAgB,IAAI,CAAC,GAAK,EAAE,GAC1E,SACT,CAEA,SAASD,IAAmB,CAC1B,MAAMC,EAAK,UAAU,UACrB,MAAI,gBAAgB,KAAKA,CAAE,EAAU,gBACjC,aAAa,KAAKA,CAAE,EAAU,UAC9B,gCAAgC,KAAKA,CAAE,GACvC,WAAW,KAAKA,CAAE,EAAU,QAC5B,UAAU,KAAKA,CAAE,EAAU,WAAWA,EAAG,MAAM,eAAe,IAAI,CAAC,GAAK,EAAE,GAC1E,mBAAmB,KAAKA,CAAE,EAAU,MACpC,QAAQ,KAAKA,CAAE,EAAU,QACtB,SACT,CCtCA,MAAMC,GAAkB,oCAEjB,MAAMC,EAAU,CAOrB,YAAYC,EAAoBC,EAAiBC,EAAe,IAAMC,EAAoBC,EAAqC,CAC7H,KAAK,WAAaJ,EAClB,KAAK,QAAUC,GAAUH,IAAiB,QAAQ,MAAO,EAAE,EAC3D,KAAK,aAAeI,EACpB,KAAK,UAAYC,EACjB,KAAK,YAAcC,CACrB,CAEA,MAAM,kBAAgD,CACpD,OAAI,KAAK,YAAoB,KAAK,YAAA,EAC3B,KAAK,SACd,CAEA,MAAc,YAAYhM,EAAuD,CAC/E,MAAMiM,EAAkC,CAAE,gBAAiB,KAAK,UAAA,EAC1DC,EAAQ,MAAM,KAAK,iBAAA,EACzB,OAAIA,IAAOD,EAAQ,cAAc,EAAIC,GACjClM,IAAaiM,EAAQ,cAAc,EAAIjM,GACpCiM,CACT,CAEA,MAAM,eAAeE,EAA0BC,EAAoD,CACjG,MAAMvB,EAAO,IAAI,SAkBjB,GAjBAA,EAAK,OAAO,wBAAyBsB,EAAQ,WAAW,EACxDtB,EAAK,OAAO,qBAAsBsB,EAAQ,QAAQ,EAClDtB,EAAK,OAAO,uBAAwBsB,EAAQ,UAAU,EACtDtB,EAAK,OAAO,oBAAqBsB,EAAQ,OAAO,EAChDtB,EAAK,OAAO,eAAgBsB,EAAQ,EAAE,EACtCtB,EAAK,OAAO,yBAA0B,OAAOsB,EAAQ,YAAY,CAAC,EAClEtB,EAAK,OAAO,0BAA2B,OAAOsB,EAAQ,aAAa,CAAC,EACpEtB,EAAK,OAAO,2BAA4B,KAAK,UAAUsB,EAAQ,cAAc,CAAC,EAC9EtB,EAAK,OAAO,wBAAyB,KAAK,UAAUsB,EAAQ,WAAW,CAAC,EAEpEA,EAAQ,gBACVtB,EAAK,OAAO,2BAA4B,KAAK,UAAUsB,EAAQ,cAAc,CAAC,EAE5EA,EAAQ,SAAStB,EAAK,OAAO,oBAAqBsB,EAAQ,OAAO,EACjEA,EAAQ,YAAYtB,EAAK,OAAO,uBAAwBsB,EAAQ,UAAU,EAC1EA,EAAQ,WAAWtB,EAAK,OAAO,sBAAuBsB,EAAQ,SAAS,EAEvEA,EAAQ,kBAAoBA,EAAQ,iBAAiB,OAAS,EAAG,CACnE,MAAME,EAAO,KAAK,UAAUF,EAAQ,gBAAgB,EAC9CxM,EAAO,IAAI,KAAK,CAAC0M,CAAI,EAAG,CAAE,KAAM,mBAAoB,EAC1DxB,EAAK,OAAO,sBAAuBlL,EAAM,gBAAgB,EACzDkL,EAAK,OAAO,+BAAgC,OAAOsB,EAAQ,oBAAsB,CAAC,CAAC,CACrF,CAEIC,GACFvB,EAAK,OAAO,uBAAwBuB,EAAY,gBAAgB,EAGlE,MAAMH,EAAU,MAAM,KAAK,YAAA,EAI3B,OAAAA,EAAQ,mBAAmB,EAAIK,GAAA,GACnB,MAAM,KAAK,eAAe,GAAG,KAAK,MAAM,oBAAqB,CACvE,OAAQ,OACR,QAAAL,EACA,KAAMpB,CAAA,CACP,GACU,KAAA,CACb,CAEA,MAAM,mBAAmB0B,EAAoBxS,EAA4C,CACvF,MAAMyS,EAA+B,CAAA,EACjCzS,MAAc,QAAUA,GAC5B,MAAMkS,EAAU,MAAM,KAAK,YAAY,kBAAkB,EAMzD,OALY,MAAM,KAAK,eAAe,GAAG,KAAK,MAAM,qBAAqBM,CAAU,WAAY,CAC7F,OAAQ,OACR,QAAAN,EACA,KAAM,KAAK,UAAUO,CAAI,CAAA,CAC1B,GACU,KAAA,CACb,CAEA,MAAM,iBAAiBD,EAA8C,CACnE,MAAMN,EAAU,MAAM,KAAK,YAAA,EAK3B,OAJY,MAAM,KAAK,eAAe,GAAG,KAAK,MAAM,qBAAqBM,CAAU,WAAY,CAC7F,OAAQ,MACR,QAAAN,CAAA,CACD,GACU,KAAA,CACb,CAEA,MAAc,eAAejR,EAAayE,EAAmBgN,EAAU,EAAsB,CAC3F,IAAItS,EACJ,GAAI,CACFA,EAAM,MAAM,MAAMa,EAAKyE,CAAI,CAC7B,OAAS+G,EAAK,CACZ,GAAIiG,EAAU,EACZ,aAAMC,EAAM,KAAK,YAAY,EACtB,KAAK,eAAe1R,EAAKyE,EAAMgN,EAAU,CAAC,EAEnD,MAAMjG,CACR,CAEA,GAAIrM,EAAI,GAAI,OAAOA,EACnB,GAAIA,EAAI,QAAU,KAAOsS,EAAU,EACjC,aAAMC,EAAM,KAAK,YAAY,EACtB,KAAK,eAAe1R,EAAKyE,EAAMgN,EAAU,CAAC,EAEnD,MAAM,IAAI,MAAM,QAAQtS,EAAI,MAAM,EAAE,CACtC,CACF,CAEA,SAASuS,EAAMC,EAA2B,CACxC,OAAIA,GAAM,EAAU,QAAQ,QAAA,EACrB,IAAI,QAAQxP,GAAW,WAAWA,EAASwP,CAAE,CAAC,CACvD,CAEA,SAASL,IAAiC,CACxC,OAAI,OAAO,OAAW,KAAe,OAAO,OAAO,YAAe,WACzD,OAAO,WAAA,EAET,GAAG,KAAK,IAAA,EAAM,SAAS,EAAE,CAAC,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,EAAG,EAAE,CAAC,EAC9E,CC3HO,SAASM,GACdC,EACAC,EACAC,EACA9U,EACA+U,EACAC,EACiB,CACjB,MAAO,CACL,YAAAJ,EACA,GAAGC,EACH,eAAgBC,EAChB,YAAa9U,EAAa,CAACA,CAAU,EAAI,CAAA,EACzC,eAAgBA,GAAY,eACxB,CACE,SAAUA,EAAW,eACrB,KAAMA,EAAW,YAAc,GAC/B,KAAMA,EAAW,YAAc,EAAA,EAEjC,OACJ,QAAS+U,GAAM,GACf,WAAYA,GAAM,MAClB,UAAWA,GAAM,KACjB,iBAAkBC,GAAW,OAC7B,mBAAoBA,GAAW,QAAA,CAEnC,CC9BA,MAAAC,GAAe,CACb,IAAK,WACL,QAAS,CACP,OAAQ,UACR,OAAQ,SACR,KAAM,+CACN,WAAY,wBACZ,KAAM,MAAA,EAER,MAAO,CACL,MAAO,QACP,YAAa,sCACb,OAAQ,SACR,OAAQ,SACR,aAAc,CACZ,CAAE,MAAO,KAAM,MAAO,qBAAA,EACtB,CAAE,MAAO,KAAM,MAAO,gCAAA,EACtB,CAAE,MAAO,KAAM,MAAO,yBAAA,EACtB,CAAE,MAAO,IAAK,MAAO,gBAAA,CAAiB,CACxC,EAEF,QAAS,CACP,MAAO,UACP,QAAS,mCACT,YAAa,iBACb,cAAe,gEACf,cAAe,mBACf,MAAO,OAAA,EAET,MAAO,CACL,OAAQ,qCAAA,EAEV,IAAK,CACH,OAAQ,YAAA,EAEV,YAAa,CACX,OAAQ,kCACR,OAAQ,WACR,QAAS,SAAA,EAEX,WAAY,CACV,QAAS,UACT,QAAS,SAAA,EAEX,OAAQ,CACN,KAAM,OACN,YAAa,YACb,YAAa,gCAAA,EAEf,QAAS,CACP,SAAU,cACV,YAAa,wBACb,KAAM,OACN,KAAM,MAAA,CAEV,ECvDAC,GAAe,CACb,IAAK,KACL,QAAS,CACP,OAAQ,KACR,OAAQ,KACR,KAAM,uBACN,WAAY,SACZ,KAAM,IAAA,EAER,MAAO,CACL,MAAO,KACP,YAAa,aACb,OAAQ,KACR,OAAQ,KACR,aAAc,CACZ,CAAE,MAAO,KAAM,MAAO,OAAA,EACtB,CAAE,MAAO,KAAM,MAAO,UAAA,EACtB,CAAE,MAAO,KAAM,MAAO,QAAA,EACtB,CAAE,MAAO,IAAK,MAAO,OAAA,CAAQ,CAC/B,EAEF,QAAS,CACP,MAAO,MACP,QAAS,WACT,YAAa,UACb,cAAe,mBACf,cAAe,SACf,MAAO,IAAA,EAET,MAAO,CACL,OAAQ,WAAA,EAEV,IAAK,CACH,OAAQ,QAAA,EAEV,YAAa,CACX,OAAQ,cACR,OAAQ,KACR,QAAS,IAAA,EAEX,WAAY,CACV,QAAS,KACT,QAAS,IAAA,EAEX,OAAQ,CACN,KAAM,KACN,YAAa,MACb,YAAa,WAAA,EAEf,QAAS,CACP,SAAU,SACV,YAAa,YACb,KAAM,KACN,KAAM,IAAA,CAEV,ECvDAC,GAAe,CACb,IAAK,UACL,QAAS,CACP,OAAQ,SACR,OAAQ,KACR,KAAM,wBACN,WAAY,SACZ,KAAM,IAAA,EAER,MAAO,CACL,MAAO,KACP,YAAa,oBACb,OAAQ,KACR,OAAQ,QACR,aAAc,CACZ,CAAE,MAAO,KAAM,MAAO,UAAA,EACtB,CAAE,MAAO,KAAM,MAAO,eAAA,EACtB,CAAE,MAAO,KAAM,MAAO,WAAA,EACtB,CAAE,MAAO,IAAK,MAAO,WAAA,CAAY,CACnC,EAEF,QAAS,CACP,MAAO,cACP,QAAS,mBACT,YAAa,UACb,cAAe,yBACf,cAAe,aACf,MAAO,KAAA,EAET,MAAO,CACL,OAAQ,wBAAA,EAEV,IAAK,CACH,OAAQ,SAAA,EAEV,YAAa,CACX,OAAQ,4BACR,OAAQ,KACR,QAAS,KAAA,EAEX,WAAY,CACV,QAAS,KACT,QAAS,IAAA,EAEX,OAAQ,CACN,KAAM,KACN,YAAa,MACb,YAAa,cAAA,EAEf,QAAS,CACP,SAAU,SACV,YAAa,WACb,KAAM,KACN,KAAM,MAAA,CAEV,ECvDAC,GAAe,CACb,IAAK,MACL,QAAS,CACP,OAAQ,MACR,OAAQ,KACR,KAAM,0BACN,WAAY,cACZ,KAAM,KAAA,EAER,MAAO,CACL,MAAO,KACP,YAAa,0BACb,OAAQ,KACR,OAAQ,KACR,aAAc,CACZ,CAAE,MAAO,KAAM,MAAO,SAAA,EACtB,CAAE,MAAO,KAAM,MAAO,eAAA,EACtB,CAAE,MAAO,KAAM,MAAO,aAAA,EACtB,CAAE,MAAO,IAAK,MAAO,WAAA,CAAY,CACnC,EAEF,QAAS,CACP,MAAO,SACP,QAAS,gBACT,YAAa,SACb,cAAe,qBACf,cAAe,WACf,MAAO,IAAA,EAET,MAAO,CACL,OAAQ,yBAAA,EAEV,IAAK,CACH,OAAQ,aAAA,EAEV,YAAa,CACX,OAAQ,qBACR,OAAQ,KACR,QAAS,IAAA,EAEX,WAAY,CACV,QAAS,MACT,QAAS,IAAA,EAEX,OAAQ,CACN,KAAM,KACN,YAAa,OACb,YAAa,kBAAA,EAEf,QAAS,CACP,SAAU,UACV,YAAa,eACb,KAAM,MACN,KAAM,MAAA,CAEV,ECvDAC,GAAe,CACb,IAAK,cACL,QAAS,CACP,OAAQ,SACR,OAAQ,SACR,KAAM,qEACN,WAAY,uBACZ,KAAM,OAAA,EAER,MAAO,CACL,MAAO,YACP,YAAa,uCACb,OAAQ,SACR,OAAQ,WACR,aAAc,CACZ,CAAE,MAAO,KAAM,MAAO,kBAAA,EACtB,CAAE,MAAO,KAAM,MAAO,sCAAA,EACtB,CAAE,MAAO,KAAM,MAAO,kBAAA,EACtB,CAAE,MAAO,IAAK,MAAO,gBAAA,CAAiB,CACxC,EAEF,QAAS,CACP,MAAO,YACP,QAAS,kCACT,YAAa,YACb,cAAe,oDACf,cAAe,sBACf,MAAO,QAAA,EAET,MAAO,CACL,OAAQ,iDAAA,EAEV,IAAK,CACH,OAAQ,mBAAA,EAEV,YAAa,CACX,OAAQ,gCACR,OAAQ,SACR,QAAS,QAAA,EAEX,WAAY,CACV,QAAS,SACT,QAAS,UAAA,EAEX,OAAQ,CACN,KAAM,UACN,YAAa,WACb,YAAa,0CAAA,EAEf,QAAS,CACP,SAAU,cACV,YAAa,0BACb,KAAM,SACN,KAAM,QAAA,CAEV,ECvDAC,GAAe,CACb,IAAK,OACL,QAAS,CACP,OAAQ,UACR,OAAQ,cACR,KAAM,gEACN,WAAY,qCACZ,KAAM,SAAA,EAER,MAAO,CACL,MAAO,WACP,YAAa,8CACb,OAAQ,UACR,OAAQ,UACR,aAAc,CACZ,CAAE,MAAO,KAAM,MAAO,iCAAA,EACtB,CAAE,MAAO,KAAM,MAAO,0CAAA,EACtB,CAAE,MAAO,KAAM,MAAO,0BAAA,EACtB,CAAE,MAAO,IAAK,MAAO,eAAA,CAAgB,CACvC,EAEF,QAAS,CACP,MAAO,UACP,QAAS,8BACT,YAAa,WACb,cAAe,gEACf,cAAe,gBACf,MAAO,QAAA,EAET,MAAO,CACL,OAAQ,uCAAA,EAEV,IAAK,CACH,OAAQ,iBAAA,EAEV,YAAa,CACX,OAAQ,+BACR,OAAQ,UACR,QAAS,QAAA,EAEX,WAAY,CACV,QAAS,SACT,QAAS,SAAA,EAEX,OAAQ,CACN,KAAM,UACN,YAAa,iBACb,YAAa,0CAAA,EAEf,QAAS,CACP,SAAU,eACV,YAAa,yBACb,KAAM,UACN,KAAM,QAAA,CAEV,ECvDAC,GAAe,CACb,IAAK,WACL,QAAS,CACP,OAAQ,YACR,OAAQ,YACR,KAAM,yEACN,WAAY,2BACZ,KAAM,SAAA,EAER,MAAO,CACL,MAAO,OACP,YAAa,sDACb,OAAQ,WACR,OAAQ,YACR,aAAc,CACZ,CAAE,MAAO,KAAM,MAAO,0BAAA,EACtB,CAAE,MAAO,KAAM,MAAO,4BAAA,EACtB,CAAE,MAAO,KAAM,MAAO,wBAAA,EACtB,CAAE,MAAO,IAAK,MAAO,oBAAA,CAAqB,CAC5C,EAEF,QAAS,CACP,MAAO,eACP,QAAS,gCACT,YAAa,YACb,cAAe,0EACf,cAAe,wBACf,MAAO,WAAA,EAET,MAAO,CACL,OAAQ,uDAAA,EAEV,IAAK,CACH,OAAQ,qBAAA,EAEV,YAAa,CACX,OAAQ,8CACR,OAAQ,eACR,QAAS,WAAA,EAEX,WAAY,CACV,QAAS,YACT,QAAS,SAAA,EAEX,OAAQ,CACN,KAAM,QACN,YAAa,WACb,YAAa,gCAAA,EAEf,QAAS,CACP,SAAU,kBACV,YAAa,sBACb,KAAM,SACN,KAAM,cAAA,CAEV,EC7CMC,EAAwC,CAC5C,GAAAP,GACA,QAASC,GACT,GAAAC,GACA,GAAAC,GACA,GAAAC,GACA,GAAAC,GACA,GAAAC,EACF,EAEO,SAASE,GAAYC,EAA8B,CACxD,GAAIF,EAAQE,CAAM,EAAG,OAAOF,EAAQE,CAAM,EAC1C,MAAMC,EAAOD,EAAO,MAAM,GAAG,EAAE,CAAC,EAChC,OAAIF,EAAQG,CAAI,EAAUH,EAAQG,CAAI,EAC/BH,EAAQ,EACjB,CCVA,MAAMI,GAAiB,GASjBC,GAAY,qEACZC,GAAY,0EAElB,IAAIC,EAA6C,KAEjD,SAASC,IAAoC,CAC3C,OAAID,IACJA,EAAcE,GAAA,EAAgB,MAAM,IAAMC,IAAY,EAC/CH,EACT,CAEA,eAAeE,IAAwC,CAErD,OADY,KAAM,QAAO,eAAe,GAC7B,MACb,CAOA,SAASE,GAA8C,CACrD,MAAMC,EAAM,WACZ,OAAOA,EAAI,aAAa,QAAUA,EAAI,OAAO,MAC/C,CAEA,SAASF,IAAqC,CAC5C,OAAO,IAAI,QAAQ,CAAChR,EAASC,IAAW,CACtC,MAAMkR,EAAWF,EAAA,EACjB,GAAIE,EAAU,CAAEnR,EAAQmR,CAAQ,EAAG,MAAO,CAC1C,MAAMC,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,IAAMT,GACbS,EAAO,UAAYR,GACnBQ,EAAO,YAAc,YACrBA,EAAO,OAAS,IAAM,CACpB,MAAMC,EAASJ,EAAA,EACXI,IAAgBA,CAAM,EACrBpR,EAAO,IAAI,MAAM,iDAAiD,CAAC,CAC1E,EACAmR,EAAO,QAAU,IAAMnR,EAAO,IAAI,MAAM,+BAA+B,CAAC,EACxE,SAAS,KAAK,YAAYmR,CAAM,CAClC,CAAC,CACH,CAEO,MAAME,EAAc,CAUzB,YAAYpZ,EAAyBqZ,EAA2B,CAThE,KAAQ,OAAuB,CAAA,EAC/B,KAAQ,OAAwB,KAChC,KAAQ,UAAY,EACpB,KAAQ,MAA8C,KACtD,KAAQ,aAAiD,KAGzD,KAAQ,QAAU,GAGhB,KAAK,OAASrZ,EACd,KAAK,aAAeqZ,CACtB,CAEA,MAAM,OAAuB,CAC3B,MAAMF,EAAS,MAAMP,GAAA,EAErB,KAAK,UAAY,KAAK,IAAA,EACtB,KAAK,QAAU,GAEf,KAAK,OAASO,EAAO,CACnB,KAAOvF,GAAsB,CACtB,KAAK,SAAS,KAAK,OAAO,KAAKA,CAAK,CAC3C,CAAA,CACD,EAED,KAAK,aAAgB,GAAkB,CACrC,KAAK,gBAAgB,EAAE,QAAS,EAAE,OAAO,EACzCuF,EAAO,iBAAiB,YAAa,CACnC,EAAG,EAAE,QACL,EAAG,EAAE,QACL,OAAQ,EAAE,kBAAkB,YAAc,EAAE,OAAO,QAAU,EAAA,CAC9D,CACH,EACA,SAAS,iBAAiB,QAAS,KAAK,aAAc,EAAI,EAE1D,KAAK,MAAQ,WAAW,IAAM,CAC5B,KAAK,eAAA,CACP,EAAGX,GAAiB,GAAI,CAC1B,CAEA,MAAwB,CACtB,YAAK,QAAU,GACf,KAAK,SAAA,EACL,KAAK,OAAS,KACd,KAAK,aAAA,EACL,KAAK,oBAAA,EAEE,CACL,OAAQ,KAAK,OACb,SAAU,KAAK,YAAA,CAAY,CAE/B,CAEA,aAAsB,CACpB,OAAI,KAAK,YAAc,EAAU,EAC1B,KAAK,OAAO,KAAK,MAAQ,KAAK,WAAa,GAAI,CACxD,CAEA,SAAgB,CACd,KAAK,QAAU,GACf,KAAK,SAAA,EACL,KAAK,OAAS,KACd,KAAK,aAAA,EACL,KAAK,oBAAA,EACL,KAAK,OAAS,CAAA,EACd,KAAK,UAAY,CACnB,CAEQ,cAAqB,CACvB,KAAK,QACP,aAAa,KAAK,KAAK,EACvB,KAAK,MAAQ,KAEjB,CAEQ,qBAA4B,CAC9B,KAAK,eACP,SAAS,oBAAoB,QAAS,KAAK,aAAc,EAAI,EAC7D,KAAK,aAAe,KAExB,CAEQ,gBAAgBtW,EAAWC,EAAiB,CAClD,MAAMmX,EAAS,KAAK,OAAO,GAAmB,MAAO,kBAAkB,EACvEA,EAAO,MAAM,KAAO,GAAGpX,CAAC,KACxBoX,EAAO,MAAM,IAAM,GAAGnX,CAAC,KACvB,KAAK,OAAO,OAAOmX,CAAM,EACzBA,EAAO,iBAAiB,eAAgB,IAAMA,EAAO,QAAQ,CAC/D,CACF,CC5JO,MAAMC,EAAiB,CAM5B,YACEvZ,EACAC,EACAuZ,EACAC,EACA,CARF,KAAQ,WAAoD,KAS1D,KAAK,YAAcD,EAEnB,KAAK,GAAKxZ,EAAO,GAAmB,MAAO,gBAAgB,EAC3D,KAAK,GAAG,UAAY;AAAA;AAAA;AAAA,sDAG8BC,EAAS,OAAO,IAAI;AAAA,MAEtED,EAAO,OAAO,KAAK,EAAE,EAErB,KAAK,QAAU,KAAK,GAAG,cAAc,mBAAmB,EACxD,KAAK,GAAG,cAAc,kBAAkB,EAAG,iBAAiB,QAASyZ,CAAM,EAE3E,KAAK,WAAa,YAAY,IAAM,KAAK,YAAA,EAAe,GAAI,CAC9D,CAEQ,aAAoB,CAC1B,MAAMC,EAAO,KAAK,YAAA,EACZC,EAAK,OAAO,KAAK,MAAMD,EAAO,EAAE,CAAC,EAAE,SAAS,EAAG,GAAG,EAClDE,EAAK,OAAOF,EAAO,EAAE,EAAE,SAAS,EAAG,GAAG,EAC5C,KAAK,QAAQ,YAAc,GAAGC,CAAE,IAAIC,CAAE,EACxC,CAEA,SAAgB,CACV,KAAK,aACP,cAAc,KAAK,UAAU,EAC7B,KAAK,WAAa,MAEpB,KAAK,GAAG,OAAA,CACV,CACF,CCrCO,MAAMC,EAAiB,CAAvB,aAAA,CACL,KAAQ,QAAgC,KACxC,KAAQ,IAA+B,KACvC,KAAQ,OAAiC,IAAA,CAEzC,MAAM,MACJ7Z,EACAC,EACAwZ,EACe,CACf,KAAK,QAAU,IAAIL,GAAcpZ,EAAQyZ,CAAM,EAC/C,KAAK,IAAM,IAAIF,GACbvZ,EACAC,EACA,IAAM,KAAK,SAAS,YAAA,GAAiB,EACrCwZ,CAAA,EAEF,MAAM,KAAK,QAAQ,MAAA,CACrB,CAEA,MAA+B,CAC7B,OAAK,KAAK,SACV,KAAK,OAAS,KAAK,QAAQ,KAAA,EAC3B,KAAK,WAAA,EACE,KAAK,QAHc,IAI5B,CAEA,cAAuC,CACrC,OAAO,KAAK,MACd,CAEA,SAAgB,CACd,KAAK,WAAA,EACL,KAAK,OAAS,IAChB,CAEQ,YAAmB,CACzB,KAAK,SAAS,QAAA,EACd,KAAK,QAAU,KACf,KAAK,KAAK,QAAA,EACV,KAAK,IAAM,IACb,CACF,CC5BO,MAAMK,CAAiB,CAkB5B,YAAYC,EAA8B,CAf1C,KAAQ,IAA0B,KAClC,KAAQ,QAAoC,KAC5C,KAAQ,QAAoC,KAC5C,KAAQ,MAA6B,KACrC,KAAQ,QAA8B,KACtC,KAAQ,QAA8B,KACtC,KAAQ,kBAAkD,KAG1D,KAAQ,oBAAkD,KAE1D,KAAQ,KAAa,OACrB,KAAQ,kBAAuC,KAC/C,KAAQ,iBAA4C,KAGlD,KAAK,OAASA,EACd,KAAK,SAAW1B,GAAY0B,EAAO,QAAU,IAAI,EACjD,KAAK,UAAY,IAAIzD,GAAUyD,EAAO,WAAYA,EAAO,OAAQ,OAAWA,EAAO,UAAWA,EAAO,WAAW,EAChH,KAAK,iBAAmB,IAAIhG,GAC5B,KAAK,iBAAiB,MAAA,EACtB,KAAK,QAAA,EAEDgG,EAAO,uBAAyB,KAClC,KAAK,oBAAsB,IAAI/D,EAAoB,IAAM,KAAK,mBAAmB,EACjF,KAAK,oBAAoB,MAAA,EAE7B,CAEQ,SAAgB,CACtB,KAAK,OAAS,IAAI1W,GAAgB,KAAK,OAAO,OAAS,MAAM,EAE7D,KAAK,IAAM,IAAIS,GACb,KAAK,OACL,KAAK,SACL,KAAK,OAAO,UAAY,QACxB,IAAM,KAAK,eAAA,EACX,KAAK,OAAO,OAAA,CAEhB,CAEQ,gBAAuB,CACzB,KAAK,OAAS,QAChB,KAAK,yBAAA,EACL,KAAK,oBAAA,GAEL,KAAK,QAAA,CAET,CAEQ,mBAA0B,CAC5B,KAAK,OAAS,QAAU,KAAK,oBAEjC,KAAK,kBAAoB,IAAIS,GAAsB,KAAK,OAAQ,KAAK,SAAU,CAC7E,OAAQ,IAAM,CACZ,KAAK,yBAAA,EACL,KAAK,oBAAA,CACP,EACA,UAAW,IAAM,KAAK,yBAAA,CAAyB,CAChD,EACH,CAEQ,0BAAiC,CACvC,KAAK,mBAAmB,QAAA,EACxB,KAAK,kBAAoB,IAC3B,CAEQ,qBAA4B,CAClC,KAAK,KAAO,aACZ,KAAK,KAAK,UAAU,EAAI,EAExB,KAAK,QAAU,IAAIE,GACjB,KAAK,OACL,KAAK,SACL,IAAM,KAAK,QAAA,EACVI,GAAsB,KAAK,wBAAwBA,CAAI,CAAA,EAE1D,KAAK,QAAU,IAAIyC,EAAkB,KAAK,OAAQ,KAAK,SAAU,CAACX,EAAYgB,IAAe,CAC3F,KAAK,kBAAoBhB,EACzB,KAAK,UAAUA,EAAW,EAAGA,EAAW,EAAGgB,CAAU,CACvD,CAAC,CACH,CAEQ,wBAAwB9C,EAAyB,CACnDA,IAAS,UACX,KAAK,KAAO,YACZ,KAAK,SAAS,QAAA,EACd,KAAK,QAAU,KACf,KAAK,iBAAmB,IAAI+Y,GAC5B,KAAK,iBAAiB,MAAM,KAAK,OAAQ,KAAK,SAAU,IAAM,CACvD,KAAK,mBACV,KAAK,iBAAiB,KAAA,EACtB,KAAK,UAAU,OAAO,WAAa,EAAG,OAAO,YAAc,EAAG,KAAK,SAAS,OAAO,WAAW,EAChG,CAAC,EAAE,MAAOrP,GAAU,CAElB,QAAQ,KAAK,yEAA0EA,CAAK,EACxF,KAAK,OAAS,cAClB,KAAK,SAAS,QAAQ,QAAQ,EAC9B,KAAK,wBAAwB,QAAQ,EACvC,CAAC,IAED,KAAK,kBAAkB,QAAA,EACvB,KAAK,iBAAmB,KACnB,KAAK,UACR,KAAK,QAAU,IAAIjH,EAAkB,KAAK,OAAQ,KAAK,SAAU,CAACX,EAAYgB,IAAe,CAC3F,KAAK,kBAAoBhB,EACzB,KAAK,UAAUA,EAAW,EAAGA,EAAW,EAAGgB,CAAU,CACvD,CAAC,GAEH,KAAK,KAAO,aAEhB,CAEQ,UAAU1B,EAAWC,EAAWyB,EAA0B,CAChE,KAAK,KAAO,QACZ,KAAK,SAAS,mBAAA,EAEd,KAAK,MAAQ,IAAIC,GAAa,KAAK,OAAQ,CACzC,WAAAD,EACA,EAAA1B,EACA,EAAAC,EACA,SAAU,KAAK,SACf,SAAWqV,GAAgB,KAAK,aAAaA,CAAW,EACxD,QAAS,IAAM,KAAK,QAAA,CAAQ,CAC7B,CACH,CAEA,MAAc,aAAaA,EAAoC,CAC7D,GAAI,CAAC,KAAK,MAAO,OACjB,KAAK,MAAM,WAAW,EAAI,EAC1B,MAAM5U,EAAa,KAAK,kBAClBgV,EAAY,KAAK,kBAAkB,aAAA,GAAkB,OAErD,CAACb,EAAYU,CAAW,EAAI,MAAM,QAAQ,IAAI,CAClDjF,GAAkB5P,EAAa,CAACA,CAAU,EAAI,CAAA,CAAE,EAChD,QAAQ,QAAQqT,GAAA,CAAoB,CAAA,CACrC,EAEKa,EAAUS,GACdC,EACAC,EACA,KAAK,iBAAiB,UAAA,EACtB7U,EACA,KAAK,OAAO,KACZgV,CAAA,EAGF,GAAI,CACF,MAAMoC,EAAW,MAAM,KAAK,UAAU,eAAelD,EAASC,CAAU,EACxE,KAAK,OAAO,QAAA,EACZ,KAAK,MAAQ,KACb,KAAK,SAAS,QAAA,EACd,KAAK,QAAU,KACf,KAAK,SAAS,QAAA,EACd,KAAK,QAAU,KACf,KAAK,kBAAkB,QAAA,EACvB,KAAK,iBAAmB,KACHiD,EAAS,gBAAkB,IAAQA,EAAS,uBAAyB,GAExF,KAAK,YAAYA,EAAS,WAAY,CAAE,aAAc,GAAM,EAE5D,KAAK,YAAYA,EAAS,GAAIA,EAAS,UAAU,CAErD,MAAQ,CACN,KAAK,OAAO,WAAW,EAAK,EAC5B,KAAK,OAAO,SAAS,KAAK,SAAS,MAAM,MAAM,CACjD,CACF,CAEQ,YAAY9C,EAAoB+C,EAAyB,CAC/D,KAAK,KAAO,OACZ,KAAK,KAAK,UAAU,EAAK,EACzB,KAAK,QAAU,IAAIpV,GAAY,KAAK,OAAQ,CAC1C,WAAAqS,EACA,UAAW,KAAK,UAChB,SAAU,KAAK,SACf,OAAQ,IAAM,CACZ,KAAK,SAAS,QAAA,EACd,KAAK,QAAU,KACf,KAAK,YAAY+C,CAAS,CAC5B,CAAA,CACD,CACH,CAEQ,YAAYA,EAAmBzU,EAAoC,CACzE,KAAK,KAAO,OACZ,KAAK,KAAK,UAAU,EAAK,EAIzB,MAAM0U,EAAW,GAHD,KAAK,OAAO,OACxB,KAAK,OAAO,OAAO,QAAQ,gBAAiB,EAAE,EAC9C,4BACuB,mBAAmBD,CAAS,aACjDE,EAAc,CAAC,EAAE,KAAK,OAAO,WAAa,KAAK,OAAO,aAC5D,KAAK,QAAU,IAAI9U,GAAY,KAAK,OAAQ,KAAK,SAAU,IAAM,CAC/D,KAAK,SAAS,QAAA,EACd,KAAK,QAAU,IACjB,EAAG8U,EAAc,SAAY,CAC3B,MAAMtD,EAAQ,MAAM,KAAK,UAAU,iBAAA,EAC/BA,GAAO,OAAO,KAAK,GAAGqD,CAAQ,aAAa,mBAAmBrD,CAAK,CAAC,GAAI,QAAQ,CACtF,EAAI,OAAWrR,CAAO,CACxB,CAEQ,SAAgB,CACtB,KAAK,KAAO,OACZ,KAAK,KAAK,UAAU,EAAK,EACzB,KAAK,SAAS,QAAA,EACd,KAAK,QAAU,KACf,KAAK,SAAS,QAAA,EACd,KAAK,QAAU,KACf,KAAK,OAAO,QAAA,EACZ,KAAK,MAAQ,KACb,KAAK,SAAS,QAAA,EACd,KAAK,QAAU,KACf,KAAK,kBAAoB,KACzB,KAAK,kBAAkB,QAAA,EACvB,KAAK,iBAAmB,IAC1B,CAEA,SAAgB,CACd,KAAK,QAAA,EACL,KAAK,iBAAiB,KAAA,EACtB,KAAK,qBAAqB,KAAA,EAC1B,KAAK,yBAAA,EACL,KAAK,SAAS,QAAA,EACd,KAAK,SAAS,QAAA,EACd,KAAK,KAAK,QAAA,EACV,KAAK,kBAAkB,QAAA,EACvB,KAAK,OAAO,QAAA,CACd,CACF,CC1PA,IAAIgD,EAAoC,KAExC,MAAM4R,GAAiB,CACrB,KAAKL,EAAoC,CACnCvR,IACFA,EAAS,QAAA,EACTA,EAAW,MAET,SAAS,aAAe,UAC1B,SAAS,iBAAiB,mBAAoB,IAAM,CAClDA,EAAW,IAAIsR,EAAiBC,CAAM,CACxC,CAAC,EAEDvR,EAAW,IAAIsR,EAAiBC,CAAM,CAE1C,EAEA,SAAgB,CACdvR,GAAU,QAAA,EACVA,EAAW,IACb,CACF,EAKI,OAAO,OAAW,MACnB,OAA+D,eAAiB4R","x_google_ignoreList":[13,14,15,16,17,18,19,20,21,22]}
|