feedbackkit-web 1.0.37
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/LICENSE +73 -0
- package/README.md +125 -0
- package/dist/feedbackkit.iife.js +283 -0
- package/dist/feedbackkit.iife.js.map +1 -0
- package/dist/feedbackkit.js +2075 -0
- package/dist/feedbackkit.js.map +1 -0
- package/dist/types/capture.d.ts +34 -0
- package/dist/types/environment.d.ts +23 -0
- package/dist/types/global.d.ts +25 -0
- package/dist/types/index.d.ts +90 -0
- package/dist/types/logs.d.ts +36 -0
- package/dist/types/renderer.d.ts +64 -0
- package/dist/types/submit.d.ts +42 -0
- package/dist/types/types.d.ts +149 -0
- package/dist/types/ui/editor.d.ts +60 -0
- package/dist/types/ui/icons.d.ts +15 -0
- package/dist/types/ui/styles.d.ts +6 -0
- package/dist/types/ui/widget.d.ts +48 -0
- package/package.json +63 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
var FeedbackKit=(function(){"use strict";async function At(t={}){const e=Math.min(window.devicePixelRatio||1,t.maxPixelRatio??2);if(t.mode==="display")try{const n=await De(e);if(n)return n}catch{}return Ne(e,t.exclude)}const G="data-feedbackkit-pin";async function Ne(t,e){const n=window.innerWidth,r=window.innerHeight,o=Le(e),s=document.documentElement,i=getComputedStyle(document.body).backgroundColor,a=getComputedStyle(s).backgroundColor,c=Pt(a)?Pt(i)?"#ffffff":i:a;try{const{domToCanvas:d}=await Promise.resolve().then(()=>Tr);return{canvas:await d(s,{width:n,height:r,scale:t,backgroundColor:c,filter:e?h=>!e(h):null,features:{restoreScrollPosition:!0},timeout:8e3,onCloneEachNode:h=>{if(!(h instanceof HTMLElement))return;h.tagName==="BODY"&&!h.style.transform&&(h.style.transform="translate(0px, 0px)");const f=h.getAttribute(G);if(f===null)return;h.removeAttribute(G);const u=o.info.get(f);if(!u)return;const m=h.style;u.kind==="sticky"?(m.setProperty("position","relative","important"),m.setProperty("inset","auto","important"),m.setProperty("top",`${u.top}px`,"important"),m.setProperty("left",`${u.left}px`,"important")):(m.setProperty("position","fixed","important"),m.setProperty("inset","auto","important"),m.setProperty("top",`${u.top}px`,"important"),m.setProperty("left",`${u.left}px`,"important"),m.setProperty("width",`${u.width}px`,"important"),m.setProperty("height",`${u.height}px`,"important"),m.setProperty("margin","0","important"),m.setProperty("box-sizing","border-box","important"),m.setProperty("transform","none","important"),m.setProperty("translate","none","important"))}}),width:n,height:r,pixelRatio:t}}finally{o.cleanup()}}function Le(t){const e=new Map,n=[],r=document.body;if(!r)return{info:e,cleanup:()=>{}};const o=document.createTreeWalker(r,NodeFilter.SHOW_ELEMENT,{acceptNode:i=>t?.(i)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT});let s=0;for(let i=o.nextNode();i;i=o.nextNode()){const a=i,c=getComputedStyle(a);if(c.position!=="fixed"&&c.position!=="sticky"||c.display==="none")continue;const d=a.getBoundingClientRect(),l=String(s++);if(c.position==="sticky"){const h=a.style.getPropertyValue("position"),f=a.style.getPropertyPriority("position");a.style.setProperty("position","static","important");const u=a.getBoundingClientRect();a.style.setProperty("position",h,f),h||a.style.removeProperty("position");const m=d.top-u.top,p=d.left-u.left;if(Math.abs(p)<.5&&Math.abs(m)<.5)continue;e.set(l,{kind:"sticky",top:m,left:p,width:d.width,height:d.height})}else{const h=Ie(a),f=h.getBoundingClientRect();e.set(l,{kind:"fixed",top:d.top-(f.top+h.clientTop),left:d.left-(f.left+h.clientLeft),width:d.width,height:d.height})}a.setAttribute(G,l),n.push(a)}return{info:e,cleanup:()=>{for(const i of n)i.removeAttribute(G)}}}function Ie(t){for(let e=t.parentElement;e&&e!==document.body;e=e.parentElement){const n=getComputedStyle(e);if(n.transform!=="none"||n.filter!=="none"||n.perspective!=="none"||n.backdropFilter!==void 0&&n.backdropFilter!=="none"||/paint|layout|strict|content/.test(n.contain)||/transform|filter|perspective/.test(n.willChange))return e;const r=e.parentElement;if(r&&(r.scrollTop!==0||r.scrollLeft!==0))return e}return document.body}function Pt(t){return!t||t==="transparent"||/rgba\(\s*0,\s*0,\s*0,\s*0\s*\)/.test(t)}async function De(t){if(!navigator.mediaDevices?.getDisplayMedia)return null;const e={video:{displaySurface:"browser"},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include"},n=await navigator.mediaDevices.getDisplayMedia(e);try{const r=document.createElement("video");r.muted=!0,r.playsInline=!0,r.srcObject=n,await r.play(),await new Promise(c=>setTimeout(c,250));const o=window.innerWidth,s=window.innerHeight,i=document.createElement("canvas");i.width=Math.round(o*t),i.height=Math.round(s*t);const a=i.getContext("2d");return a?(a.drawImage(r,0,0,i.width,i.height),{canvas:i,width:o,height:s,pixelRatio:t}):null}finally{for(const r of n.getTracks())r.stop()}}function lt(t){return new Promise((e,n)=>{t.toBlob(r=>r?e(r):n(new Error("Failed to encode screenshot")),"image/png")})}function Fe(t){let e="Unknown",n="",r;(r=t.match(/(?:iPhone|iPad|iPod).*?OS (\d+[_.\d]*)/))?(e=/iPad/.test(t)?"iPadOS":"iOS",n=r[1].replace(/_/g,".")):(r=t.match(/Android (\d+(?:\.\d+)*)/))?(e="Android",n=r[1]):(r=t.match(/Windows NT (\d+\.\d+)/))?(e="Windows",n={"10.0":"10","6.3":"8.1","6.2":"8","6.1":"7"}[r[1]]??r[1]):(r=t.match(/Mac OS X (\d+[_.\d]*)/))?(e="macOS",n=r[1].replace(/_/g,".")):/CrOS/.test(t)?e="ChromeOS":/Linux/.test(t)&&(e="Linux");let o="Unknown",s="";const i=[["Edge",/Edg(?:e|A|iOS)?\/([\d.]+)/],["Opera",/(?:OPR|Opera)\/([\d.]+)/],["Samsung Internet",/SamsungBrowser\/([\d.]+)/],["Firefox",/(?:Firefox|FxiOS)\/([\d.]+)/],["Chrome",/(?:Chrome|CriOS)\/([\d.]+)/],["Safari",/Version\/([\d.]+).*Safari/]];for(const[a,c]of i){const d=t.match(c);if(d){o=a,s=d[1];break}}return{osName:e,osVersion:n,browserName:o,browserVersion:s}}const Mt=/token|secret|password|passwd|pwd|auth|session|key|code|signature|sig|jwt|otp|email/i;function Nt(t){try{const e=new URL(t);for(const n of[...e.searchParams.keys()])Mt.test(n)&&e.searchParams.set(n,"[redacted]");return e.hash&&Mt.test(e.hash)&&(e.hash="#[redacted]"),e.toString()}catch{return t}}async function Re(){const t=navigator.userAgentData;if(!t?.getHighEntropyValues)return null;try{return await Promise.race([t.getHighEntropyValues(["platform","platformVersion","fullVersionList"]),new Promise(e=>setTimeout(()=>e(null),300))])}catch{return null}}function $e(t,e){const n=t.platform,r=t.platformVersion??"";if(!n)return e;if(n==="macOS")return{osName:"macOS",osVersion:X(r)};if(n==="Windows"){const o=parseInt(r,10);return{osName:"Windows",osVersion:o>=13?"11":o>0?"10":e.osVersion}}return n==="Android"?{osName:"Android",osVersion:X(r)||e.osVersion}:n==="Chrome OS"||n==="ChromeOS"?{osName:"ChromeOS",osVersion:X(r)}:{osName:n,osVersion:X(r)||e.osVersion}}function X(t){return t.replace(/(\.0)+$/,"")}function _e(t){const e=t.fullVersionList??[],n=["Microsoft Edge","Opera","Google Chrome","Chromium"];for(const r of n){const o=e.find(s=>s.brand===r);if(o)return{name:r==="Microsoft Edge"?"Edge":r==="Google Chrome"?"Chrome":r,version:o.version}}return null}async function Be(t={}){const e=navigator.userAgent,n=Fe(e),r=await Re(),o=r?$e(r,n):n,s=r&&_e(r)||{name:n.browserName,version:n.browserVersion},i=s.version.split(".")[0];return{osName:o.osName,osVersion:o.osVersion,deviceModel:i?`${s.name} ${i}`:s.name,appVersion:t.appVersion??"",appBuild:t.appBuild??"",bundleIdentifier:location.host,screenName:t.screenName||location.pathname||null,locale:navigator.language||"en",screenWidthPoints:window.innerWidth,screenHeightPoints:window.innerHeight,screenScale:window.devicePixelRatio||1,platform:"web",pageUrl:Nt(location.href),userAgent:e,browserName:s.name,browserVersion:s.version}}const Lt=1e3;function Oe(t){return t.replace(/\b(Bearer|Basic)\s+[A-Za-z0-9._~+/=-]+/gi,"$1 [redacted]").replace(/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g,"[redacted-jwt]").replace(/https?:\/\/[^\s"'<>)]+/g,e=>Nt(e)).replace(/("?(?:password|passwd|secret|token|api[_-]?key|access[_-]?token|refresh[_-]?token)"?\s*[:=]\s*)("[^"]*"|'[^']*'|[^\s,}&]+)/gi,"$1[redacted]")}function Y(t){if(typeof t=="string")return t;if(t instanceof Error)return t.stack||`${t.name}: ${t.message}`;if(t===void 0)return"undefined";if(typeof t=="function")return`[function ${t.name||"anonymous"}]`;if(typeof Element<"u"&&t instanceof Element)return`<${t.tagName.toLowerCase()}>`;try{const e=new WeakSet;return JSON.stringify(t,(n,r)=>{if(typeof r=="object"&&r!==null){if(e.has(r))return"[circular]";e.add(r)}return typeof r=="bigint"?r.toString():r})}catch{return String(t)}}class Ue{constructor(e=50){this.maxEntries=e,this.entries=[]}push(e,n){let r=Oe(n);r.length>Lt&&(r=`${r.slice(0,Lt)}… [truncated]`),this.entries.push({level:e,message:r,timestamp:new Date().toISOString()}),this.entries.length>this.maxEntries&&this.entries.splice(0,this.entries.length-this.maxEntries)}snapshot(){return this.entries.slice()}clear(){this.entries=[]}}function je(t={}){const e=new Ue(t.maxEntries??50),n=[],r=t.includeVerbose?["log","info","warn","error","debug"]:["warn","error"];for(const i of r){const a=console[i];console[i]=function(...c){try{e.push(i,c.map(Y).join(" "))}catch{}return a.apply(this,c)},n.push(()=>{console[i]=a})}const o=i=>{const a=i.filename?` (${i.filename}:${i.lineno}:${i.colno})`:"";e.push("error",`Uncaught ${i.error?Y(i.error):i.message}${a}`)},s=i=>{e.push("error",`Unhandled promise rejection: ${Y(i.reason)}`)};return window.addEventListener("error",o),window.addEventListener("unhandledrejection",s),n.push(()=>{window.removeEventListener("error",o),window.removeEventListener("unhandledrejection",s)}),t.network!==!1&&n.push(ze(e),Ve(e)),{buffer:e,uninstall:()=>{for(const i of n.reverse())i()}}}let dt=null;function He(t){dt=t}function ht(t){return!!dt&&t.startsWith(dt)}function ze(t){if(typeof window.fetch!="function")return()=>{};const e=window.fetch;return window.fetch=async function(n,r){const o=(r?.method||(n instanceof Request?n.method:"GET")).toUpperCase(),s=n instanceof Request?n.url:String(n);try{const i=await e.call(window,n,r);return i.status>=400&&!ht(s)&&t.push("network",`${o} ${s} → ${i.status} ${i.statusText}`.trim()),i}catch(i){throw!ht(s)&&!(i instanceof DOMException&&i.name==="AbortError")&&t.push("network",`${o} ${s} → failed: ${Y(i)}`),i}},()=>{window.fetch=e}}function Ve(t){if(typeof XMLHttpRequest>"u")return()=>{};const e=XMLHttpRequest.prototype,n=e.open,r=e.send,o=new WeakMap;return e.open=function(s,i,...a){return o.set(this,{method:String(s).toUpperCase(),url:String(i)}),n.call(this,s,i,...a)},e.send=function(s){return this.addEventListener("loadend",()=>{const i=o.get(this);!i||ht(i.url)||(this.status===0?t.push("network",`${i.method} ${i.url} → failed (network error)`):this.status>=400&&t.push("network",`${i.method} ${i.url} → ${this.status} ${this.statusText}`.trim()))}),r.call(this,s)},()=>{e.open=n,e.send=r}}const J="https://gpucoladcyvijefdjudf.supabase.co/functions/v1/ingest-feedback";class Z extends Error{constructor(e,n,r){super(e),this.kind=n,this.status=r,this.name="FeedbackSubmissionError"}}async function ut(t){const e=new Uint8Array(await t.arrayBuffer());let n="";const r=32768;for(let o=0;o<e.length;o+=r)n+=String.fromCharCode(...e.subarray(o,o+r));return btoa(n)}async function We(t,e){const n={project_key:e,id:t.id,created_at:t.createdAt.toISOString(),text:t.text,annotations:t.annotations,environment:t.environment};if(t.screenshotRaw&&t.screenshotAnnotated){const[r,o]=await Promise.all([ut(t.screenshotRaw),ut(t.screenshotAnnotated)]);n.screenshot_raw_png_base64=r,n.screenshot_annotated_png_base64=o}return t.attachment&&(n.attachment_filename=t.attachment.filename,n.attachment_mime_type=t.attachment.mimeType,n.attachment_data_base64=await ut(t.attachment.data)),t.products.length>0&&(n.product_keys=t.products.map(r=>r.key),n.products=t.products.map(r=>({key:r.key,name:r.name,description:r.description??"",is_default:r.isDefault??!1}))),t.logs.length>0&&(n.logs=t.logs),n}async function It(t,e){if(!e.projectKey)throw new Z("FeedbackKit is not configured with a project key.","not_configured");const n=JSON.stringify(await We(t,e.projectKey));let r;try{r=await fetch(e.endpoint??J,{method:"POST",headers:{"Content-Type":"application/json"},body:n})}catch(o){throw new Z(`Network error: ${o instanceof Error?o.message:String(o)}`,"network")}if(!r.ok){let o="";try{o=(await r.json()).error??""}catch{}const s=o?` (${o})`:"",i=o==="origin_not_allowed"?`This site (${location.origin}) isn't in the project's allowed origins.`:r.status===401||r.status===403?`Server rejected the project key or origin (HTTP ${r.status})${s}.`:r.status===429?"Too many reports right now — please try again in a minute.":`Server returned HTTP ${r.status}${s}.`;throw new Z(i,"server",r.status)}}async function Ke(t){const e=new URL(t.endpoint??J);e.searchParams.set("project_key",t.projectKey);const n=await fetch(e.toString());if(!n.ok)throw new Z(`HTTP ${n.status}`,"server",n.status);return((await n.json()).products??[]).map(o=>({key:o.key,name:o.name,description:o.description??"",isDefault:o.is_default??!1}))}const Q=4,B=16,tt=18,et=Math.PI/7,ft=16,pt=8,Dt=1.19,Ft="#FF0000";function mt(t=1){return`bold ${ft*t}px -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif`}function Rt(t){if(Array.isArray(t))return{x:Number(t[0])||0,y:Number(t[1])||0};if(t&&typeof t=="object"){const e=t;return{x:Number(e.x)||0,y:Number(e.y)||0}}return{x:0,y:0}}function gt(t,e){return(t.points??[]).map(n=>{const{x:r,y:o}=Rt(n);return{x:r*e.width,y:o*e.height}})}function $t(t){if(!t)return Ft;const e=t.trim().replace(/^#/,"");return/^[0-9a-fA-F]{6}$/.test(e)||/^[0-9a-fA-F]{8}$/.test(e)?`#${e}`:Ft}function yt(t,e,n){for(const r of e)wt(t,r,n)}function wt(t,e,n){const r=$t(e.colorHex),o=gt(e,n),s=e.scale??1,i=e.rotation??0;switch(e.kind){case"freehand":qe(t,o,r);break;case"rectangle":o.length===2&&Ge(t,o[0],o[1],r,s,i);break;case"arrow":o.length===2&&Xe(t,o[0],o[1],r,s,i);break;case"text":o.length>=1&&e.label&&Ye(t,e.label,o[0],r,s);break}}function qe(t,e,n){if(e.length!==0){t.save(),t.lineWidth=Q,t.lineJoin="round",t.lineCap="round",t.strokeStyle=n,t.beginPath(),t.moveTo(e[0].x,e[0].y),e.length===1&&t.lineTo(e[0].x+.01,e[0].y);for(const r of e.slice(1))t.lineTo(r.x,r.y);t.stroke(),t.restore()}}function Ge(t,e,n,r,o,s){const i=O(e,n),a=Bt(i,Math.abs(n.x-e.x)/2*o,Math.abs(n.y-e.y)/2*o,s);t.save(),t.lineWidth=Q,t.lineJoin="miter",t.strokeStyle=r,t.beginPath(),t.moveTo(a[0].x,a[0].y);for(const c of a.slice(1))t.lineTo(c.x,c.y);t.closePath(),t.stroke(),t.restore()}function Xe(t,e,n,r,o,s){const{start:i,end:a,left:c,right:d}=_t(e,n,o,s);t.save(),t.lineWidth=Q,t.lineJoin="round",t.lineCap="round",t.strokeStyle=r,t.beginPath(),t.moveTo(i.x,i.y),t.lineTo(a.x,a.y),t.lineTo(c.x,c.y),t.moveTo(a.x,a.y),t.lineTo(d.x,d.y),t.stroke(),t.restore()}function _t(t,e,n=1,r=0){const o=O(t,e),s=nt(U(t,n,o),r,o),i=nt(U(e,n,o),r,o),a=Math.atan2(i.y-s.y,i.x-s.x),c={x:i.x-tt*Math.cos(a-et),y:i.y-tt*Math.sin(a-et)},d={x:i.x-tt*Math.cos(a+et),y:i.y-tt*Math.sin(a+et)};return{start:s,end:i,left:c,right:d}}function Ye(t,e,n,r,o){const s=bt(t,e,n,o);t.save(),t.fillStyle=r,t.beginPath(),Je(t,s.x,s.y,s.width,s.height,8),t.fill(),t.font=mt(o),t.fillStyle="#FFFFFF",t.textBaseline="top",t.fillText(e,s.x+pt,s.y+pt+ft*o*(Dt-1)/2),t.restore()}function Je(t,e,n,r,o,s){const i=Math.min(s,r/2,o/2);t.moveTo(e+i,n),t.arcTo(e+r,n,e+r,n+o,i),t.arcTo(e+r,n+o,e,n+o,i),t.arcTo(e,n+o,e,n,i),t.arcTo(e,n,e+r,n,i),t.closePath()}function bt(t,e,n,r=1){const o=t.font;t.font=mt(r);const s=t.measureText(e).width;t.font=o;const i=ft*r*Dt,a=pt*r;return{x:n.x,y:n.y,width:s+a*2,height:i+a*2}}function Bt(t,e,n,r){return[{x:t.x-e,y:t.y-n},{x:t.x+e,y:t.y-n},{x:t.x+e,y:t.y+n},{x:t.x-e,y:t.y+n}].map(o=>nt(o,r,t))}function Ot(t,e,n,r){const o=gt(t,n),s=t.scale??1;switch(t.kind){case"rectangle":{if(o.length!==2)return!1;const i=O(o[0],o[1]),a=Math.abs(o[1].x-o[0].x)/2*s+B,c=Math.abs(o[1].y-o[0].y)/2*s+B;return Math.abs(e.x-i.x)<=a&&Math.abs(e.y-i.y)<=c}case"arrow":{if(o.length!==2)return!1;const i=O(o[0],o[1]);return Ut(e,U(o[0],s,i),U(o[1],s,i))<=B}case"text":{if(o.length<1||!t.label)return!1;const i=bt(r,t.label,o[0],s),a=B/2;return e.x>=i.x-a&&e.x<=i.x+i.width+a&&e.y>=i.y-a&&e.y<=i.y+i.height+a}case"freehand":return!1}}function O(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}function nt(t,e,n){const r=t.x-n.x,o=t.y-n.y;return{x:n.x+r*Math.cos(e)-o*Math.sin(e),y:n.y+r*Math.sin(e)+o*Math.cos(e)}}function U(t,e,n){return{x:n.x+(t.x-n.x)*e,y:n.y+(t.y-n.y)*e}}function Ut(t,e,n){const r=n.x-e.x,o=n.y-e.y,s=r*r+o*o;if(s===0)return Math.hypot(t.x-e.x,t.y-e.y);const i=Math.max(0,Math.min(1,((t.x-e.x)*r+(t.y-e.y)*o)/s));return Math.hypot(t.x-(e.x+i*r),t.y-(e.y+i*o))}const Ze=Object.freeze(Object.defineProperty({__proto__:null,HIT_TEST_TOLERANCE:B,STROKE_WIDTH:Q,arrowGeometry:_t,denormalize:gt,distanceToSegment:Ut,drawAnnotation:wt,drawAnnotations:yt,hitTest:Ot,midpoint:O,normalizeColor:$t,readPoint:Rt,rectangleCorners:Bt,rotate:nt,scaled:U,textBubbleRect:bt,textFont:mt},Symbol.toStringTag,{value:"Module"})),jt=["#FF3B30","#FFCC00","#34C759","#007AFF","#000000"],Ht=.3,zt=5;class Qe{constructor(e){this.shot=e,this.annotations=[],this.tool="pen",this.color=jt[0],this.onChange=()=>{},this.history=[],this.draft=null,this.draftStart=null,this.pointers=new Map,this.drag=null,this.gesture=null,this.selected=null,this.textInput=null,this.displayScale=1,this.element=document.createElement("div"),this.element.className="fk-canvas-box",this.base=document.createElement("canvas"),this.ink=document.createElement("canvas"),this.ink.className="fk-ink",this.ink.setAttribute("role","img"),this.ink.setAttribute("aria-label","Screenshot — draw on it to highlight the problem"),this.element.append(this.base,this.ink);const n=this.ink.getContext("2d");if(!n)throw new Error("Canvas 2D is unavailable");this.inkCtx=n,this.ink.addEventListener("pointerdown",r=>this.onPointerDown(r)),this.ink.addEventListener("pointermove",r=>this.onPointerMove(r)),this.ink.addEventListener("pointerup",r=>this.onPointerUp(r)),this.ink.addEventListener("pointercancel",r=>this.onPointerUp(r)),this.ink.addEventListener("wheel",r=>this.onWheel(r),{passive:!1})}layout(e,n){const r=Math.max(.05,Math.min(e/this.shot.width,n/this.shot.height,1));this.displayScale=r;const o=Math.round(this.shot.width*r),s=Math.round(this.shot.height*r),i=window.devicePixelRatio||1;for(const c of[this.base,this.ink])c.style.width=`${o}px`,c.style.height=`${s}px`,c.width=Math.round(o*i),c.height=Math.round(s*i);const a=this.base.getContext("2d");a&&(a.imageSmoothingQuality="high",a.drawImage(this.shot.canvas,0,0,this.base.width,this.base.height)),this.cancelTextInput(),this.render()}setTool(e){this.commitTextInput(),this.tool=e,this.selected=null,this.ink.style.cursor=e==="move"?"grab":e==="text"?"text":"crosshair",this.render()}undo(){this.commitTextInput();const e=this.history.pop();e&&(this.annotations=e,this.selected=null,this.changed())}clear(){this.annotations.length!==0&&(this.snapshot(),this.annotations=[],this.selected=null,this.changed())}get canUndo(){return this.history.length>0}deleteSelected(){return this.selected===null||!this.annotations[this.selected]?!1:(this.snapshot(),this.annotations.splice(this.selected,1),this.selected=null,this.changed(),!0)}flatten(){this.commitTextInput();const e=document.createElement("canvas");e.width=this.shot.canvas.width,e.height=this.shot.canvas.height;const n=e.getContext("2d");if(!n)throw new Error("Canvas 2D is unavailable");return n.drawImage(this.shot.canvas,0,0),n.scale(e.width/this.shot.width,e.height/this.shot.height),yt(n,this.annotations,{width:this.shot.width,height:this.shot.height}),e}commitTextInput(){const e=this.textInput;if(!e)return;this.textInput=null;const n=e.value.trim(),r=JSON.parse(e.dataset.origin??"[0,0]");e.remove(),n&&(this.snapshot(),this.annotations.push({kind:"text",points:[r],colorHex:this.color,label:n,scale:1,rotation:0}),this.changed())}cancelTextInput(){this.textInput?.remove(),this.textInput=null}render(){const e=this.inkCtx;e.setTransform(1,0,0,1,0,0),e.clearRect(0,0,this.ink.width,this.ink.height);const n=this.ink.width/this.shot.width;e.setTransform(n,0,0,n,0,0);const r={width:this.shot.width,height:this.shot.height};yt(e,this.annotations,r),this.draft&&wt(e,this.draft,r)}changed(){this.render(),this.onChange()}snapshot(){this.history.push(this.annotations.map(e=>({...e,points:e.points.map(n=>[n[0],n[1]])}))),this.history.length>100&&this.history.shift()}toCapture(e){const n=this.ink.getBoundingClientRect();return{x:Math.max(0,Math.min(this.shot.width,(e.clientX-n.left)/this.displayScale)),y:Math.max(0,Math.min(this.shot.height,(e.clientY-n.top)/this.displayScale))}}normalize(e){return[M(e.x/this.shot.width),M(e.y/this.shot.height)]}hitIndex(e){const n={width:this.shot.width,height:this.shot.height};for(let r=this.annotations.length-1;r>=0;r--)if(Ot(this.annotations[r],e,n,this.inkCtx))return r;return null}onPointerDown(e){if(e.button!==0&&e.pointerType==="mouse")return;e.preventDefault();const n=this.toCapture(e);if(this.ink.setPointerCapture(e.pointerId),this.pointers.set(e.pointerId,n),this.tool==="move"){if(this.pointers.size===2&&this.selected!==null){this.drag=null,this.startGesture();return}const o=this.hitIndex(n);this.selected=o,o!==null&&(this.snapshot(),this.drag={index:o,last:n,moved:!1},this.ink.style.cursor="grabbing");return}if(this.pointers.size>1)return;if(this.tool==="text"){this.commitTextInput(),this.openTextInput(n);return}this.draftStart=n;const r=this.normalize(n);this.draft={kind:this.tool==="pen"?"freehand":this.tool,points:this.tool==="pen"?[r]:[r,r],colorHex:this.color,scale:1,rotation:0},this.render()}onPointerMove(e){if(!this.pointers.has(e.pointerId)){this.tool==="move"&&e.pointerType==="mouse"&&(this.ink.style.cursor=this.hitIndex(this.toCapture(e))!==null?"grab":"default");return}const n=this.toCapture(e);if(this.pointers.set(e.pointerId,n),this.gesture){this.updateGesture();return}if(this.drag){const o=(n.x-this.drag.last.x)/this.shot.width,s=(n.y-this.drag.last.y)/this.shot.height;this.drag.last=n,this.drag.moved=!0;const i=this.annotations[this.drag.index];i.points=i.points.map(([a,c])=>[M(a+o),M(c+s)]),this.render();return}if(!this.draft||!this.draftStart)return;const r=this.normalize(n);if(this.draft.kind==="freehand"){const o=this.draft.points[this.draft.points.length-1];Math.hypot((r[0]-o[0])*this.shot.width,(r[1]-o[1])*this.shot.height)>=1.5&&this.draft.points.push(r)}else this.draft.points=[this.draft.points[0],r];this.render()}onPointerUp(e){if(!this.pointers.has(e.pointerId))return;if(this.pointers.delete(e.pointerId),this.ink.hasPointerCapture(e.pointerId)&&this.ink.releasePointerCapture(e.pointerId),this.gesture){this.pointers.size<2&&(this.gesture=null,this.onChange());return}if(this.drag){this.drag.moved||this.history.pop(),this.drag=null,this.ink.style.cursor="grab",this.onChange();return}const n=this.draft;this.draft=null;const r=this.draftStart;if(this.draftStart=null,!(!n||!r)){if(n.kind!=="freehand"){const[o,s]=n.points;if(Math.hypot((s[0]-o[0])*this.shot.width,(s[1]-o[1])*this.shot.height)<6){this.render();return}}this.snapshot(),this.annotations.push(n),this.changed()}}onWheel(e){if(this.tool!=="move")return;const n=this.toCapture(e),r=this.hitIndex(n)??this.selected;if(r===null||!this.annotations[r])return;e.preventDefault();const o=this.annotations[r];if(o.kind!=="freehand"){if(this.selected=r,e.shiftKey||e.altKey){if(o.kind==="text")return;const s=e.deltaY!==0?e.deltaY:e.deltaX;o.rotation=M(o.rotation+s*.004)}else o.scale=M(Vt(o.scale*Math.exp(-e.deltaY*(e.ctrlKey?.01:.0015)),Ht,zt));this.render(),this.onChange()}}startGesture(){if(this.selected===null)return;const[e,n]=[...this.pointers.values()],r=this.annotations[this.selected];this.snapshot(),this.gesture={index:this.selected,startDistance:Math.max(1,Math.hypot(n.x-e.x,n.y-e.y)),startAngle:Math.atan2(n.y-e.y,n.x-e.x),startScale:r.scale,startRotation:r.rotation}}updateGesture(){const e=this.gesture;if(!e||this.pointers.size<2)return;const[n,r]=[...this.pointers.values()],o=this.annotations[e.index];if(!o||o.kind==="freehand")return;const s=Math.hypot(r.x-n.x,r.y-n.y);o.scale=M(Vt(e.startScale*(s/e.startDistance),Ht,zt)),o.kind!=="text"&&(o.rotation=M(e.startRotation+(Math.atan2(r.y-n.y,r.x-n.x)-e.startAngle))),this.render()}openTextInput(e){const n=document.createElement("input");n.type="text",n.className="fk-text-input",n.placeholder="Add a note…",n.setAttribute("aria-label","Annotation text"),n.dataset.origin=JSON.stringify(this.normalize(e)),n.style.left=`${Math.min(e.x*this.displayScale,this.shot.width*this.displayScale-130)}px`,n.style.top=`${Math.min(e.y*this.displayScale,this.shot.height*this.displayScale-36)}px`,n.style.borderColor=this.color,n.addEventListener("keydown",r=>{r.stopPropagation(),r.key==="Enter"?this.commitTextInput():r.key==="Escape"&&this.cancelTextInput()}),n.addEventListener("blur",()=>this.commitTextInput()),this.element.append(n),this.textInput=n,requestAnimationFrame(()=>n.focus())}}function Vt(t,e,n){return Math.max(e,Math.min(n,t))}function M(t){return Math.round(t*1e4)/1e4}const E=t=>`<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${t}</svg>`,v={feedback:E('<path d="M21 12a8 8 0 0 1-11.6 7.1L4 20l1-4.6A8 8 0 1 1 21 12Z"/><path d="M8.5 10.5h7M8.5 14h4.5"/>'),pen:E('<path d="M4 20l4-1L19 8a2.1 2.1 0 0 0-3-3L5 16l-1 4Z"/><path d="M14.5 6.5l3 3"/>'),rectangle:E('<rect x="4" y="6" width="16" height="12" rx="1.5"/>'),arrow:E('<path d="M6 18L18 6"/><path d="M9 6h9v9"/>'),text:E('<path d="M5 6V5h14v1"/><path d="M12 5v14"/><path d="M9 19h6"/>'),move:E('<path d="M12 3v18M3 12h18"/><path d="M9 6l3-3 3 3M9 18l3 3 3-3M6 9l-3 3 3 3M18 9l3 3-3 3"/>'),undo:E('<path d="M9 14L4 9l5-5"/><path d="M4 9h10.5a5.5 5.5 0 0 1 0 11H11"/>'),trash:E('<path d="M4 7h16"/><path d="M10 11v6M14 11v6"/><path d="M6 7l1 13h10l1-13"/><path d="M9 7V4h6v3"/>'),close:E('<path d="M6 6l12 12M18 6L6 18"/>'),paperclip:E('<path d="M21 11.5l-8.6 8.6a5.5 5.5 0 0 1-7.8-7.8l8.6-8.6a3.7 3.7 0 0 1 5.2 5.2l-8.6 8.6a1.8 1.8 0 0 1-2.6-2.6l7.9-7.9"/>'),send:E('<path d="M4 12l16-8-6 16-3-7-7-1Z"/>'),check:E('<path d="M5 12.5l4.5 4.5L19 7.5"/>')},tn=`
|
|
2
|
+
:host {
|
|
3
|
+
all: initial;
|
|
4
|
+
--fk-primary: #007aff;
|
|
5
|
+
--fk-secondary: #6b7280;
|
|
6
|
+
--fk-bg: #ffffff;
|
|
7
|
+
--fk-surface: #f5f5f7;
|
|
8
|
+
--fk-border: rgba(0, 0, 0, 0.1);
|
|
9
|
+
--fk-text: #111114;
|
|
10
|
+
--fk-muted: #6b6b73;
|
|
11
|
+
--fk-danger: #d92d20;
|
|
12
|
+
--fk-backdrop: rgba(10, 10, 14, 0.55);
|
|
13
|
+
--fk-shadow: 0 24px 64px rgba(0, 0, 0, 0.28), 0 2px 8px rgba(0, 0, 0, 0.12);
|
|
14
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
|
|
15
|
+
font-size: 14px;
|
|
16
|
+
line-height: 1.4;
|
|
17
|
+
color: var(--fk-text);
|
|
18
|
+
}
|
|
19
|
+
@media (prefers-color-scheme: dark) {
|
|
20
|
+
:host(:not([data-color-scheme="light"])) {
|
|
21
|
+
--fk-bg: #1c1c1f;
|
|
22
|
+
--fk-surface: #26262a;
|
|
23
|
+
--fk-border: rgba(255, 255, 255, 0.12);
|
|
24
|
+
--fk-text: #f2f2f5;
|
|
25
|
+
--fk-muted: #a0a0a8;
|
|
26
|
+
--fk-backdrop: rgba(0, 0, 0, 0.65);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
:host([data-color-scheme="dark"]) {
|
|
30
|
+
--fk-bg: #1c1c1f;
|
|
31
|
+
--fk-surface: #26262a;
|
|
32
|
+
--fk-border: rgba(255, 255, 255, 0.12);
|
|
33
|
+
--fk-text: #f2f2f5;
|
|
34
|
+
--fk-muted: #a0a0a8;
|
|
35
|
+
--fk-backdrop: rgba(0, 0, 0, 0.65);
|
|
36
|
+
}
|
|
37
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
38
|
+
button { font: inherit; color: inherit; cursor: pointer; }
|
|
39
|
+
button:disabled { cursor: not-allowed; opacity: 0.45; }
|
|
40
|
+
:focus-visible { outline: 2px solid var(--fk-primary); outline-offset: 2px; }
|
|
41
|
+
|
|
42
|
+
/* ---------- floating trigger ---------- */
|
|
43
|
+
.fk-trigger {
|
|
44
|
+
position: fixed;
|
|
45
|
+
z-index: 2147483000;
|
|
46
|
+
bottom: 20px;
|
|
47
|
+
right: 20px;
|
|
48
|
+
display: inline-flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
gap: 8px;
|
|
51
|
+
height: 44px;
|
|
52
|
+
padding: 0 16px 0 14px;
|
|
53
|
+
border: 0;
|
|
54
|
+
border-radius: 22px;
|
|
55
|
+
background: var(--fk-primary);
|
|
56
|
+
color: #fff;
|
|
57
|
+
font-weight: 600;
|
|
58
|
+
font-size: 14px;
|
|
59
|
+
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22);
|
|
60
|
+
transition: transform 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
|
|
61
|
+
}
|
|
62
|
+
.fk-trigger[data-position="bottom-left"] { right: auto; left: 20px; }
|
|
63
|
+
.fk-trigger:hover { transform: translateY(-1px); box-shadow: 0 10px 26px rgba(0, 0, 0, 0.26); }
|
|
64
|
+
.fk-trigger[data-compact="true"] { width: 48px; height: 48px; padding: 0; justify-content: center; border-radius: 24px; }
|
|
65
|
+
.fk-trigger[data-compact="true"] .fk-trigger-label { display: none; }
|
|
66
|
+
.fk-trigger[aria-busy="true"] { opacity: 0.6; pointer-events: none; }
|
|
67
|
+
|
|
68
|
+
/* ---------- overlay ---------- */
|
|
69
|
+
.fk-overlay {
|
|
70
|
+
position: fixed;
|
|
71
|
+
inset: 0;
|
|
72
|
+
z-index: 2147483001;
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
padding: 24px;
|
|
77
|
+
background: var(--fk-backdrop);
|
|
78
|
+
animation: fk-fade 0.16s ease-out;
|
|
79
|
+
}
|
|
80
|
+
@keyframes fk-fade { from { opacity: 0; } to { opacity: 1; } }
|
|
81
|
+
@keyframes fk-rise { from { opacity: 0; transform: translateY(8px) scale(0.99); } to { opacity: 1; transform: none; } }
|
|
82
|
+
.fk-dialog {
|
|
83
|
+
display: grid;
|
|
84
|
+
grid-template-columns: minmax(0, 1fr) 340px;
|
|
85
|
+
width: min(1180px, 100%);
|
|
86
|
+
height: min(780px, 100%);
|
|
87
|
+
overflow: hidden;
|
|
88
|
+
border-radius: 16px;
|
|
89
|
+
background: var(--fk-bg);
|
|
90
|
+
box-shadow: var(--fk-shadow);
|
|
91
|
+
animation: fk-rise 0.2s ease-out;
|
|
92
|
+
}
|
|
93
|
+
.fk-stage {
|
|
94
|
+
display: flex;
|
|
95
|
+
flex-direction: column;
|
|
96
|
+
min-width: 0;
|
|
97
|
+
min-height: 0;
|
|
98
|
+
background: var(--fk-surface);
|
|
99
|
+
border-right: 1px solid var(--fk-border);
|
|
100
|
+
}
|
|
101
|
+
.fk-toolbar {
|
|
102
|
+
display: flex;
|
|
103
|
+
align-items: center;
|
|
104
|
+
gap: 4px;
|
|
105
|
+
flex-wrap: wrap;
|
|
106
|
+
padding: 10px 12px;
|
|
107
|
+
border-bottom: 1px solid var(--fk-border);
|
|
108
|
+
}
|
|
109
|
+
.fk-toolbar-sep { width: 1px; height: 22px; margin: 0 6px; background: var(--fk-border); }
|
|
110
|
+
.fk-tool {
|
|
111
|
+
display: inline-flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
justify-content: center;
|
|
114
|
+
width: 34px;
|
|
115
|
+
height: 34px;
|
|
116
|
+
border: 0;
|
|
117
|
+
border-radius: 8px;
|
|
118
|
+
background: transparent;
|
|
119
|
+
color: var(--fk-muted);
|
|
120
|
+
}
|
|
121
|
+
.fk-tool:hover:not(:disabled) { background: var(--fk-border); color: var(--fk-text); }
|
|
122
|
+
.fk-tool[aria-pressed="true"] { background: var(--fk-primary); color: #fff; }
|
|
123
|
+
.fk-swatch {
|
|
124
|
+
width: 22px;
|
|
125
|
+
height: 22px;
|
|
126
|
+
margin: 0 2px;
|
|
127
|
+
padding: 0;
|
|
128
|
+
border-radius: 11px;
|
|
129
|
+
border: 2px solid var(--fk-bg);
|
|
130
|
+
box-shadow: 0 0 0 1px var(--fk-border);
|
|
131
|
+
}
|
|
132
|
+
.fk-swatch[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--fk-text); }
|
|
133
|
+
.fk-hint { margin-left: auto; font-size: 12px; color: var(--fk-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
134
|
+
.fk-canvas-wrap {
|
|
135
|
+
position: relative;
|
|
136
|
+
flex: 1;
|
|
137
|
+
min-height: 0;
|
|
138
|
+
display: flex;
|
|
139
|
+
align-items: center;
|
|
140
|
+
justify-content: center;
|
|
141
|
+
padding: 16px;
|
|
142
|
+
overflow: hidden;
|
|
143
|
+
}
|
|
144
|
+
.fk-canvas-box { position: relative; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.18); border-radius: 6px; overflow: hidden; }
|
|
145
|
+
.fk-canvas-box canvas { display: block; }
|
|
146
|
+
.fk-canvas-box .fk-ink { position: absolute; inset: 0; touch-action: none; }
|
|
147
|
+
.fk-stage[data-screenshot="off"] .fk-canvas-box { opacity: 0.25; filter: grayscale(1); }
|
|
148
|
+
.fk-stage[data-screenshot="off"] .fk-toolbar button { pointer-events: none; opacity: 0.35; }
|
|
149
|
+
.fk-off-note {
|
|
150
|
+
position: absolute;
|
|
151
|
+
inset: 0;
|
|
152
|
+
display: none;
|
|
153
|
+
align-items: center;
|
|
154
|
+
justify-content: center;
|
|
155
|
+
font-weight: 600;
|
|
156
|
+
color: var(--fk-muted);
|
|
157
|
+
pointer-events: none;
|
|
158
|
+
}
|
|
159
|
+
.fk-stage[data-screenshot="off"] .fk-off-note { display: flex; }
|
|
160
|
+
.fk-text-input {
|
|
161
|
+
position: absolute;
|
|
162
|
+
z-index: 2;
|
|
163
|
+
min-width: 120px;
|
|
164
|
+
padding: 6px 8px;
|
|
165
|
+
border: 2px solid var(--fk-primary);
|
|
166
|
+
border-radius: 8px;
|
|
167
|
+
background: var(--fk-bg);
|
|
168
|
+
color: var(--fk-text);
|
|
169
|
+
font: bold 14px -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
|
|
170
|
+
outline: none;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* ---------- composer ---------- */
|
|
174
|
+
.fk-composer { display: flex; flex-direction: column; min-height: 0; padding: 18px; gap: 14px; overflow-y: auto; }
|
|
175
|
+
.fk-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
|
|
176
|
+
.fk-title { margin: 0; font-size: 17px; font-weight: 650; letter-spacing: -0.01em; }
|
|
177
|
+
.fk-close { display: inline-flex; width: 30px; height: 30px; align-items: center; justify-content: center; border: 0; border-radius: 15px; background: var(--fk-surface); color: var(--fk-muted); }
|
|
178
|
+
.fk-close:hover { color: var(--fk-text); }
|
|
179
|
+
.fk-label { display: block; margin-bottom: 6px; font-size: 12px; font-weight: 600; color: var(--fk-muted); text-transform: uppercase; letter-spacing: 0.04em; }
|
|
180
|
+
.fk-textarea {
|
|
181
|
+
width: 100%;
|
|
182
|
+
min-height: 140px;
|
|
183
|
+
resize: vertical;
|
|
184
|
+
padding: 10px 12px;
|
|
185
|
+
border: 1px solid var(--fk-border);
|
|
186
|
+
border-radius: 10px;
|
|
187
|
+
background: var(--fk-bg);
|
|
188
|
+
color: var(--fk-text);
|
|
189
|
+
font: inherit;
|
|
190
|
+
line-height: 1.45;
|
|
191
|
+
}
|
|
192
|
+
.fk-textarea:focus { outline: none; border-color: var(--fk-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--fk-primary) 22%, transparent); }
|
|
193
|
+
.fk-chips { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
194
|
+
.fk-chip {
|
|
195
|
+
display: inline-flex;
|
|
196
|
+
align-items: center;
|
|
197
|
+
gap: 5px;
|
|
198
|
+
height: 28px;
|
|
199
|
+
padding: 0 11px;
|
|
200
|
+
border: 1px solid var(--fk-border);
|
|
201
|
+
border-radius: 14px;
|
|
202
|
+
background: var(--fk-bg);
|
|
203
|
+
font-size: 13px;
|
|
204
|
+
}
|
|
205
|
+
.fk-chip[aria-pressed="true"] { border-color: var(--fk-primary); background: color-mix(in srgb, var(--fk-primary) 12%, transparent); color: var(--fk-primary); font-weight: 600; }
|
|
206
|
+
.fk-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
|
207
|
+
.fk-switch { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; user-select: none; }
|
|
208
|
+
.fk-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
|
|
209
|
+
.fk-switch-track { position: relative; width: 36px; height: 22px; border-radius: 11px; background: var(--fk-border); transition: background 0.15s; }
|
|
210
|
+
.fk-switch-track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 9px; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); transition: transform 0.15s; }
|
|
211
|
+
.fk-switch input:checked + .fk-switch-track { background: var(--fk-primary); }
|
|
212
|
+
.fk-switch input:checked + .fk-switch-track::after { transform: translateX(14px); }
|
|
213
|
+
.fk-switch input:focus-visible + .fk-switch-track { outline: 2px solid var(--fk-primary); outline-offset: 2px; }
|
|
214
|
+
.fk-attach {
|
|
215
|
+
display: inline-flex;
|
|
216
|
+
align-items: center;
|
|
217
|
+
gap: 6px;
|
|
218
|
+
height: 32px;
|
|
219
|
+
padding: 0 12px;
|
|
220
|
+
border: 1px dashed var(--fk-secondary);
|
|
221
|
+
border-radius: 8px;
|
|
222
|
+
background: transparent;
|
|
223
|
+
color: var(--fk-secondary);
|
|
224
|
+
font-size: 13px;
|
|
225
|
+
}
|
|
226
|
+
.fk-file { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 4px 6px 4px 10px; border-radius: 8px; background: var(--fk-surface); font-size: 12px; }
|
|
227
|
+
.fk-file span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
228
|
+
.fk-file button { display: inline-flex; border: 0; background: transparent; color: var(--fk-muted); padding: 2px; }
|
|
229
|
+
.fk-meta { font-size: 12px; color: var(--fk-muted); }
|
|
230
|
+
.fk-meta details summary { cursor: pointer; }
|
|
231
|
+
.fk-meta pre { max-height: 140px; overflow: auto; margin: 6px 0 0; padding: 8px; border-radius: 8px; background: var(--fk-surface); font-size: 11px; white-space: pre-wrap; word-break: break-word; }
|
|
232
|
+
.fk-spacer { flex: 1; }
|
|
233
|
+
.fk-actions { display: flex; gap: 8px; }
|
|
234
|
+
.fk-btn {
|
|
235
|
+
display: inline-flex;
|
|
236
|
+
flex: 1;
|
|
237
|
+
align-items: center;
|
|
238
|
+
justify-content: center;
|
|
239
|
+
gap: 7px;
|
|
240
|
+
height: 40px;
|
|
241
|
+
border-radius: 10px;
|
|
242
|
+
font-weight: 600;
|
|
243
|
+
}
|
|
244
|
+
.fk-btn-secondary { border: 1px solid var(--fk-border); background: transparent; color: var(--fk-secondary); }
|
|
245
|
+
.fk-btn-primary { border: 0; background: var(--fk-primary); color: #fff; }
|
|
246
|
+
.fk-btn-primary:hover:not(:disabled) { filter: brightness(1.06); }
|
|
247
|
+
.fk-error { margin: 0; padding: 8px 10px; border-radius: 8px; background: color-mix(in srgb, var(--fk-danger) 12%, transparent); color: var(--fk-danger); font-size: 13px; }
|
|
248
|
+
.fk-spinner { width: 16px; height: 16px; border: 2px solid rgba(255, 255, 255, 0.45); border-top-color: #fff; border-radius: 50%; animation: fk-spin 0.7s linear infinite; }
|
|
249
|
+
@keyframes fk-spin { to { transform: rotate(360deg); } }
|
|
250
|
+
.fk-done { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; flex: 1; text-align: center; }
|
|
251
|
+
.fk-done-icon { display: inline-flex; width: 48px; height: 48px; align-items: center; justify-content: center; border-radius: 24px; background: var(--fk-primary); color: #fff; }
|
|
252
|
+
.fk-done-icon svg { width: 26px; height: 26px; }
|
|
253
|
+
.fk-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
|
|
254
|
+
|
|
255
|
+
/* ---------- narrow screens: stack stage over composer ---------- */
|
|
256
|
+
@media (max-width: 760px) {
|
|
257
|
+
.fk-overlay { padding: 0; }
|
|
258
|
+
.fk-dialog { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr) auto; width: 100%; height: 100%; border-radius: 0; }
|
|
259
|
+
.fk-stage { border-right: 0; border-bottom: 1px solid var(--fk-border); }
|
|
260
|
+
.fk-hint { display: none; }
|
|
261
|
+
.fk-canvas-wrap { padding: 10px; }
|
|
262
|
+
.fk-composer { max-height: 55vh; padding: 14px; gap: 10px; }
|
|
263
|
+
.fk-textarea { min-height: 84px; }
|
|
264
|
+
}
|
|
265
|
+
@media (prefers-reduced-motion: reduce) {
|
|
266
|
+
.fk-overlay, .fk-dialog { animation: none; }
|
|
267
|
+
}
|
|
268
|
+
`,en=10*1024*1024,nn=[{tool:"pen",label:"Draw",icon:v.pen},{tool:"rectangle",label:"Rectangle",icon:v.rectangle},{tool:"arrow",label:"Arrow",icon:v.arrow},{tool:"text",label:"Text",icon:v.text},{tool:"move",label:"Move / resize",icon:v.move}],Wt={pen:"Draw on the screenshot to highlight the problem",rectangle:"Drag to box an area",arrow:"Drag to point at something",text:"Click to add a note",move:"Drag to move · scroll to resize · Shift+scroll to rotate · Delete to remove"};class rn{constructor(e){this.deps=e,this.host=null,this.shadow=null,this.trigger=null,this.pending=null,this.isOwnNode=n=>n===this.host}get isOpen(){return this.pending!==null}showTrigger(e,n){const r=this.mount();this.trigger?.remove();const o=document.createElement("button");o.type="button",o.className="fk-trigger",o.dataset.position=e.position??"bottom-right",o.dataset.compact=String(!!e.compact);const s=e.label??"Feedback";o.setAttribute("aria-label",s),o.innerHTML=`${v.feedback}<span class="fk-trigger-label"></span>`,o.querySelector(".fk-trigger-label").textContent=s,o.addEventListener("click",n),r.append(o),this.trigger=o,this.applyTheme()}hideTrigger(){this.trigger?.remove(),this.trigger=null}destroy(){this.hideTrigger(),this.host?.remove(),this.host=null,this.shadow=null}open(e){return this.pending?this.pending:(this.pending=this.run(e).finally(()=>{this.pending=null}),this.pending)}mount(){if(this.shadow&&this.host?.isConnected)return this.shadow;const e=document.createElement("div");e.setAttribute("data-feedbackkit-root",""),e.style.cssText="position:static!important;display:contents!important;";const n=e.attachShadow({mode:"open"}),r=document.createElement("style");return r.textContent=tn,n.append(r),document.body.append(e),this.host=e,this.shadow=n,this.applyTheme(),n}applyTheme(){const e=this.deps.theme(),n=this.host;if(!n)return;const r=qt(e?.primaryColorHex),o=qt(e?.secondaryColorHex);r?n.style.setProperty("--fk-primary",r):n.style.removeProperty("--fk-primary"),o?n.style.setProperty("--fk-secondary",o):n.style.removeProperty("--fk-secondary")}async run(e){const n=this.mount();this.applyTheme(),this.trigger?.setAttribute("aria-busy","true");const r=this.deps.captureOptions(),[o,s]=await Promise.all([At({...r,exclude:this.isOwnNode}).catch(a=>(console.warn("[FeedbackKit] Screenshot capture failed; continuing without one.",a),null)),Be({screenName:this.deps.currentScreen(),appVersion:this.deps.configuration()?.appVersion,appBuild:this.deps.configuration()?.appBuild})]),i=this.deps.logs();return this.trigger?.removeAttribute("aria-busy"),new Promise(a=>{new on(n,o,s,i,this.deps,e,d=>{a(d)}).show()})}}class on{constructor(e,n,r,o,s,i,a){this.shadow=e,this.shot=n,this.environment=r,this.logs=o,this.deps=s,this.options=i,this.done=a,this.editor=null,this.includeLogs=!0,this.attachment=null,this.selectedProducts=new Set,this.products=[],this.sending=!1,this.finished=!1,this.resizeObserver=null,this.previousFocus=null,this.previousOverflow="",this.toolButtons=new Map,this.swatches=[],this.onKeyDown=c=>this.handleKey(c),this.includeScreenshot=n!==null}show(){this.previousFocus=document.activeElement,this.previousOverflow=document.documentElement.style.overflow,document.documentElement.style.overflow="hidden";const e=w("div","fk-overlay"),n=w("div","fk-dialog");n.setAttribute("role","dialog"),n.setAttribute("aria-modal","true"),n.setAttribute("aria-labelledby","fk-title"),n.append(this.buildStage(),this.buildComposer()),e.append(n),e.addEventListener("mousedown",r=>{r.target===e&&this.cancel()}),this.overlay=e,this.shadow.append(e),document.addEventListener("keydown",this.onKeyDown,!0),this.layoutEditor(),requestAnimationFrame(()=>this.textarea.focus()),this.loadProducts()}buildStage(){const e=w("div","fk-stage");this.stage=e,e.dataset.screenshot=this.includeScreenshot?"on":"off";const n=w("div","fk-toolbar");n.setAttribute("role","toolbar"),n.setAttribute("aria-label","Annotation tools");for(const{tool:s,label:i,icon:a}of nn){const c=j("fk-tool",a,i);c.setAttribute("aria-pressed",String(s==="pen")),c.addEventListener("click",()=>this.selectTool(s)),this.toolButtons.set(s,c),n.append(c)}n.append(w("span","fk-toolbar-sep")),jt.forEach((s,i)=>{const a=document.createElement("button");a.type="button",a.className="fk-swatch",a.style.background=s,a.setAttribute("aria-label",`Color ${["red","yellow","green","blue","black"][i]}`),a.setAttribute("aria-pressed",String(i===0)),a.addEventListener("click",()=>{this.editor&&(this.editor.color=s),this.swatches.forEach(c=>c.setAttribute("aria-pressed",String(c===a)))}),this.swatches.push(a),n.append(a)}),n.append(w("span","fk-toolbar-sep")),this.undoButton=j("fk-tool",v.undo,"Undo"),this.undoButton.addEventListener("click",()=>this.editor?.undo()),this.clearButton=j("fk-tool",v.trash,"Clear all annotations"),this.clearButton.addEventListener("click",()=>this.editor?.clear()),n.append(this.undoButton,this.clearButton),this.hint=w("span","fk-hint"),this.hint.textContent=Wt.pen,n.append(this.hint);const r=w("div","fk-canvas-wrap");if(this.shot){const s=new Qe(this.shot);s.onChange=()=>this.refreshState(),s.setTool("pen"),this.editor=s,r.append(s.element),this.resizeObserver=new ResizeObserver(()=>this.layoutEditor()),this.resizeObserver.observe(r)}const o=w("div","fk-off-note");return o.textContent=this.shot?"Screenshot won't be included":"Screenshot unavailable on this page",r.append(o),e.append(n,r),e}layoutEditor(){if(!this.editor)return;const e=this.editor.element.parentElement;if(!e)return;const n=getComputedStyle(e),r=parseFloat(n.paddingLeft)+parseFloat(n.paddingRight),o=parseFloat(n.paddingTop)+parseFloat(n.paddingBottom);this.editor.layout(Math.max(40,e.clientWidth-r),Math.max(40,e.clientHeight-o))}selectTool(e){this.editor?.setTool(e),this.toolButtons.forEach((n,r)=>n.setAttribute("aria-pressed",String(r===e))),this.hint.textContent=Wt[e]}buildComposer(){const e=w("div","fk-composer"),n=w("div","fk-header"),r=w("h2","fk-title");r.id="fk-title",r.textContent="Send feedback";const o=j("fk-close",v.close,"Close");o.addEventListener("click",()=>this.cancel()),n.append(r,o);const s=w("label","fk-label");s.textContent="What's the problem?",s.setAttribute("for","fk-text"),this.textarea=document.createElement("textarea"),this.textarea.id="fk-text",this.textarea.className="fk-textarea",this.textarea.placeholder="Describe what happened and what you expected instead…",this.textarea.addEventListener("input",()=>this.refreshState());const i=w("div");i.append(s,this.textarea);const a=w("div");a.dataset.role="products",a.hidden=!0;const c=w("div","fk-row"),d=Kt("Screenshot",this.includeScreenshot,y=>{this.includeScreenshot=y,this.stage.dataset.screenshot=y?"on":"off",this.refreshState()});this.shot||(d.querySelector("input").disabled=!0);const l=w("div"),h=document.createElement("input");h.type="file",h.hidden=!0;const f=document.createElement("button");f.type="button",f.className="fk-attach",f.innerHTML=`${v.paperclip}<span>Attach file</span>`,f.addEventListener("click",()=>h.click()),h.addEventListener("change",()=>{const y=h.files?.[0];if(h.value="",!!y){if(y.size>en){this.showError(`"${y.name}" is larger than 10 MB.`);return}this.attachment={filename:y.name,mimeType:y.type||"application/octet-stream",data:y},u()}});const u=()=>{if(l.replaceChildren(h),this.attachment){const y=w("span","fk-file"),k=w("span");k.textContent=this.attachment.filename;const b=j("",v.close,`Remove ${this.attachment.filename}`);b.addEventListener("click",()=>{this.attachment=null,u()}),y.append(k,b),l.append(y)}else l.append(f)};u(),c.append(l,d);const m=this.buildDiagnostics();this.errorBox=w("p","fk-error"),this.errorBox.setAttribute("role","alert"),this.errorBox.hidden=!0;const p=w("div","fk-actions"),g=document.createElement("button");return g.type="button",g.className="fk-btn fk-btn-secondary",g.textContent="Cancel",g.addEventListener("click",()=>this.cancel()),this.sendButton=document.createElement("button"),this.sendButton.type="button",this.sendButton.className="fk-btn fk-btn-primary",this.sendButton.innerHTML=`${v.send}<span>Send</span>`,this.sendButton.title="Send (⌘/Ctrl + Enter)",this.sendButton.addEventListener("click",()=>{this.send()}),p.append(g,this.sendButton),e.append(n,i,a,c),m&&e.append(m),e.append(w("div","fk-spacer"),this.errorBox,p),this.refreshState(),e}buildDiagnostics(){const e=w("div","fk-meta"),n=this.environment,r=`${n.deviceModel} · ${n.osName} ${n.osVersion}`.trim(),o=document.createElement("details"),s=document.createElement("summary");s.textContent=`Included: page URL, ${r}${this.logs.length?`, ${this.logs.length} log entr${this.logs.length===1?"y":"ies"}`:""}`;const i=document.createElement("pre"),a=[`URL: ${n.pageUrl??""}`,`Viewport: ${n.screenWidthPoints}×${n.screenHeightPoints} @${n.screenScale}x`];if(this.logs.length&&a.push("",...this.logs.map(c=>`[${c.level}] ${c.message}`)),i.textContent=a.join(`
|
|
269
|
+
`),o.append(s,i),e.append(o),this.logs.length){const c=Kt("Include console & network logs",!0,d=>{this.includeLogs=d});c.style.marginTop="8px",e.append(c)}return e}async loadProducts(){let e=[];try{e=await this.deps.products()}catch{return}if(this.finished||e.length===0)return;this.products=e;const n=this.deps.defaultProductKey(),r=n&&e.find(a=>a.key===n)||e.find(a=>a.isDefault)||null;r&&this.selectedProducts.add(r.key);const o=this.overlay.querySelector('[data-role="products"]');if(!o)return;const s=w("span","fk-label");s.textContent="Affected product";const i=w("div","fk-chips");i.setAttribute("role","group"),i.setAttribute("aria-label","Affected products");for(const a of e){const c=document.createElement("button");c.type="button",c.className="fk-chip",c.textContent=a.name||a.key,a.description&&(c.title=a.description),c.setAttribute("aria-pressed",String(this.selectedProducts.has(a.key))),c.addEventListener("click",()=>{this.selectedProducts.has(a.key)?this.selectedProducts.delete(a.key):this.selectedProducts.add(a.key),c.setAttribute("aria-pressed",String(this.selectedProducts.has(a.key)))}),i.append(c)}o.replaceChildren(s,i),o.hidden=!1}refreshState(){const e=this.textarea?.value.trim().length>0,n=this.includeScreenshot&&(this.editor?.annotations.length??0)>0;this.sendButton&&(this.sendButton.disabled=this.sending||!e&&!n),this.undoButton&&(this.undoButton.disabled=!this.editor?.canUndo),this.clearButton&&(this.clearButton.disabled=!(this.editor&&this.editor.annotations.length>0))}handleKey(e){if(this.finished)return;const n=e.metaKey||e.ctrlKey,r=this.shadow.activeElement,o=r instanceof HTMLTextAreaElement||r instanceof HTMLInputElement;r instanceof HTMLInputElement&&r.classList.contains("fk-text-input")||(e.key==="Escape"?(e.preventDefault(),e.stopPropagation(),this.cancel()):n&&e.key==="Enter"?(e.preventDefault(),e.stopPropagation(),this.send()):n&&!e.shiftKey&&e.key.toLowerCase()==="z"&&!o?(e.preventDefault(),e.stopPropagation(),this.editor?.undo()):(e.key==="Backspace"||e.key==="Delete")&&!o?this.editor?.deleteSelected()&&(e.preventDefault(),e.stopPropagation()):e.key==="Tab"&&this.trapFocus(e))}trapFocus(e){const n=[...this.overlay.querySelectorAll("button:not(:disabled), textarea, input:not([type=file]):not(:disabled), summary")].filter(i=>i.offsetParent!==null||i.tagName==="INPUT");if(n.length===0)return;const r=n[0],o=n[n.length-1],s=this.shadow.activeElement;e.shiftKey&&(s===r||!s)?(e.preventDefault(),o.focus()):!e.shiftKey&&s===o&&(e.preventDefault(),r.focus())}showError(e){this.errorBox.hidden=!e,this.errorBox.textContent=e??""}async buildReport(){let e=null,n=null,r=[];if(this.includeScreenshot&&this.shot&&this.editor){const o=this.editor.flatten();[e,n]=await Promise.all([lt(this.shot.canvas),lt(o)]),r=this.editor.annotations.map(s=>({...s}))}return{id:sn(),createdAt:new Date,text:this.textarea.value.trim(),screenshotRaw:e,screenshotAnnotated:n,annotations:r,environment:this.environment,attachment:this.attachment,products:this.products.filter(o=>this.selectedProducts.has(o.key)),logs:this.includeLogs?this.logs:[]}}async send(){if(!(this.sending||this.sendButton.disabled)){this.sending=!0,this.showError(null),this.refreshState(),this.sendButton.innerHTML='<span class="fk-spinner" aria-hidden="true"></span><span>Sending…</span>';try{const e=await this.buildReport();if(this.options.submit){const n=this.deps.configuration();if(!n)throw new Error("FeedbackKit.configure() hasn't been called.");await It(e,n)}await this.options.onReport?.(e),this.showThanks(),setTimeout(()=>this.finish(e),this.options.submit?1300:0)}catch(e){this.sending=!1,this.sendButton.innerHTML=`${v.send}<span>Retry</span>`,this.showError(e instanceof Error?e.message:"Something went wrong sending your feedback."),this.refreshState(),this.options.onError?.(e)}}}showThanks(){if(!this.options.submit)return;const e=this.overlay.querySelector(".fk-composer");if(!e)return;const n=w("div","fk-done");n.setAttribute("role","status");const r=w("span","fk-done-icon");r.innerHTML=v.check;const o=w("h2","fk-title");o.textContent="Thanks for the feedback!";const s=w("p","fk-meta");s.textContent="It's on its way to the team.",n.append(r,o,s),e.replaceChildren(n)}cancel(){this.sending||this.finish(null)}finish(e){this.finished||(this.finished=!0,this.resizeObserver?.disconnect(),document.removeEventListener("keydown",this.onKeyDown,!0),this.overlay.remove(),document.documentElement.style.overflow=this.previousOverflow,this.previousFocus instanceof HTMLElement&&this.previousFocus.focus({preventScroll:!0}),this.done(e))}}function w(t,e){const n=document.createElement(t);return e&&(n.className=e),n}function j(t,e,n){const r=document.createElement("button");return r.type="button",t&&(r.className=t),r.innerHTML=e,r.setAttribute("aria-label",n),r.title=n,r}function Kt(t,e,n){const r=w("label","fk-switch"),o=document.createElement("input");o.type="checkbox",o.checked=e,o.setAttribute("role","switch"),o.addEventListener("change",()=>n(o.checked));const s=w("span","fk-switch-track"),i=w("span");return i.textContent=t,r.append(o,s,i),r}function qt(t){if(!t)return null;const e=t.trim().replace(/^#/,"");return/^[0-9a-fA-F]{6}$/.test(e)?`#${e}`:null}function sn(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();const t=new Uint8Array(16);crypto.getRandomValues(t),t[6]=t[6]&15|64,t[8]=t[8]&63|128;const e=[...t].map(n=>n.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}let x=null,H=[],z=null,F=null,V=null;const I=new rn({configuration:()=>x,theme:()=>C.theme,products:()=>kt(),defaultProductKey:()=>x?.defaultProductKey,logs:()=>F?.buffer.snapshot()??[],captureOptions:()=>C.captureOptions,currentScreen:()=>C.currentScreen});function kt(){if(H.length>0||!x)return Promise.resolve(H);if(!z){const t=x;z=Ke(t).then(e=>(x===t&&(H=e),e)).catch(()=>(z=null,[]))}return z}function an(t){document.body?t():document.addEventListener("DOMContentLoaded",t,{once:!0})}const C={currentScreen:null,theme:null,captureOptions:{},DEFAULT_ENDPOINT:J,configure(t){x=t?{...t,endpoint:t.endpoint??J}:null,H=t?.products??[],z=null,He(x?.endpoint??null),x&&H.length===0&&kt(),t&&t.captureLogs!==!1&&!F&&C.enableLogCapture(typeof t.captureLogs=="object"?t.captureLogs:{})},get isConfigured(){return x!==null},get configuration(){return x},fetchProducts(){return kt()},present(t={}){return I.open({submit:!1,onReport:t.onReport})},presentAndSubmit(t={}){return x?I.open({submit:!0,onReport:t.onSubmitted,onError:t.onError}):Promise.reject(new Error("FeedbackKit.configure({ projectKey }) must be called before presentAndSubmit()."))},submit(t){return x?It(t,x):Promise.reject(new Error("FeedbackKit.configure({ projectKey }) must be called before submit()."))},get isPresenting(){return I.isOpen},showFloatingTriggerButton(t={}){an(()=>I.showTrigger(t,()=>{x?C.presentAndSubmit():C.present({onReport:e=>console.info("[FeedbackKit] report",e)})}))},hideFloatingTriggerButton(){I.hideTrigger()},enableKeyboardShortcut(t={}){C.disableKeyboardShortcut();const e=(t.key??"F").toLowerCase();V=n=>{!(n.metaKey||n.ctrlKey)||!n.shiftKey||n.altKey||n.key.toLowerCase()!==e||(n.preventDefault(),x?C.presentAndSubmit():C.present({onReport:r=>console.info("[FeedbackKit] report",r)}))},window.addEventListener("keydown",V)},disableKeyboardShortcut(){V&&window.removeEventListener("keydown",V),V=null},enableLogCapture(t={}){F?.uninstall(),F=t===!1?null:je(t)},async captureScreenshot(t={}){const e=await At({...C.captureOptions,...t,exclude:I.isOwnNode});return lt(e.canvas)},destroy(){C.disableKeyboardShortcut(),F?.uninstall(),F=null,I.destroy()}},cn=Object.assign(C,{renderer:Ze});function Gt(t,e){return t[13]=1,t[14]=e>>8,t[15]=e&255,t[16]=e>>8,t[17]=e&255,t}const Xt=112,Yt=72,Jt=89,Zt=115;let xt;function ln(){const t=new Int32Array(256);for(let e=0;e<256;e++){let n=e;for(let r=0;r<8;r++)n=n&1?3988292384^n>>>1:n>>>1;t[e]=n}return t}function dn(t){let e=-1;xt||(xt=ln());for(let n=0;n<t.length;n++)e=xt[(e^t[n])&255]^e>>>8;return e^-1}function hn(t){const e=t.length-1;for(let n=e;n>=4;n--)if(t[n-4]===9&&t[n-3]===Xt&&t[n-2]===Yt&&t[n-1]===Jt&&t[n]===Zt)return n-3;return 0}function Qt(t,e,n=!1){const r=new Uint8Array(13);e*=39.3701,r[0]=Xt,r[1]=Yt,r[2]=Jt,r[3]=Zt,r[4]=e>>>24,r[5]=e>>>16,r[6]=e>>>8,r[7]=e&255,r[8]=r[4],r[9]=r[5],r[10]=r[6],r[11]=r[7],r[12]=1;const o=dn(r),s=new Uint8Array(4);if(s[0]=o>>>24,s[1]=o>>>16,s[2]=o>>>8,s[3]=o&255,n){const i=hn(t);return t.set(r,i),t.set(s,i+13),t}else{const i=new Uint8Array(4);i[0]=0,i[1]=0,i[2]=0,i[3]=9;const a=new Uint8Array(54);return a.set(t,0),a.set(i,33),a.set(r,37),a.set(s,50),a}}const un="AAlwSFlz",fn="AAAJcEhZ",pn="AAAACXBI";function mn(t){let e=t.indexOf(un);return e===-1&&(e=t.indexOf(fn)),e===-1&&(e=t.indexOf(pn)),e}const te="[modern-screenshot]",N=typeof window<"u",gn=N&&"Worker"in window,ee=N&&"atob"in window,yn=N&&"btoa"in window,vt=N?window.navigator?.userAgent:"",ne=vt.includes("Chrome"),rt=vt.includes("AppleWebKit")&&!ne,St=vt.includes("Firefox"),wn=t=>t&&"__CONTEXT__"in t,bn=t=>t.constructor.name==="CSSFontFaceRule",kn=t=>t.constructor.name==="CSSImportRule",xn=t=>t.constructor.name==="CSSLayerBlockRule",T=t=>t.nodeType===1,W=t=>typeof t.className=="object",re=t=>t.tagName==="image",vn=t=>t.tagName==="use",K=t=>T(t)&&typeof t.style<"u"&&!W(t),Sn=t=>t.nodeType===8,En=t=>t.nodeType===3,R=t=>t.tagName==="IMG",ot=t=>t.tagName==="VIDEO",Cn=t=>t.tagName==="CANVAS",Tn=t=>t.tagName==="TEXTAREA",An=t=>t.tagName==="INPUT",Pn=t=>t.tagName==="STYLE",Mn=t=>t.tagName==="SCRIPT",Nn=t=>t.tagName==="SELECT",Ln=t=>t.tagName==="SLOT",In=t=>t.tagName==="IFRAME",Dn=(...t)=>console.warn(te,...t);function Fn(t){const e=t?.createElement?.("canvas");return e&&(e.height=e.width=1),!!e&&"toDataURL"in e&&!!e.toDataURL("image/webp").includes("image/webp")}const Et=t=>t.startsWith("data:");function oe(t,e){if(t.match(/^[a-z]+:\/\//i))return t;if(N&&t.match(/^\/\//))return window.location.protocol+t;if(t.match(/^[a-z]+:/i)||!N)return t;const n=st().implementation.createHTMLDocument(),r=n.createElement("base"),o=n.createElement("a");return n.head.appendChild(r),n.body.appendChild(o),e&&(r.href=e),o.href=t,o.href}function st(t){return(t&&T(t)?t?.ownerDocument:t)??window.document}const it="http://www.w3.org/2000/svg";function se(t,e,n){const r=st(n).createElementNS(it,"svg");return r.setAttributeNS(null,"width",t.toString()),r.setAttributeNS(null,"height",e.toString()),r.setAttributeNS(null,"viewBox",`0 0 ${t} ${e}`),r}function ie(t,e){let n=new XMLSerializer().serializeToString(t);return e&&(n=n.replace(/[\u0000-\u0008\v\f\u000E-\u001F\uD800-\uDFFF\uFFFE\uFFFF]/gu,"")),`data:image/svg+xml;charset=utf-8,${encodeURIComponent(n)}`}async function Rn(t,e="image/png",n=1){try{return await new Promise((r,o)=>{t.toBlob(s=>{s?r(s):o(new Error("Blob is null"))},e,n)})}catch(r){if(ee)return $n(t.toDataURL(e,n));throw r}}function $n(t){const[e,n]=t.split(","),r=e.match(/data:(.+);/)?.[1]??void 0,o=window.atob(n),s=o.length,i=new Uint8Array(s);for(let a=0;a<s;a+=1)i[a]=o.charCodeAt(a);return new Blob([i],{type:r})}function ae(t,e){return new Promise((n,r)=>{const o=new FileReader;o.onload=()=>n(o.result),o.onerror=()=>r(o.error),o.onabort=()=>r(new Error(`Failed read blob to ${e}`)),e==="dataUrl"?o.readAsDataURL(t):e==="arrayBuffer"&&o.readAsArrayBuffer(t)})}const _n=t=>ae(t,"dataUrl"),Bn=t=>ae(t,"arrayBuffer");function D(t,e){const n=st(e).createElement("img");return n.decoding="sync",n.loading="eager",n.src=t,n}function $(t,e){return new Promise(n=>{const{timeout:r,ownerDocument:o,onError:s,onWarn:i}=e??{},a=typeof t=="string"?D(t,st(o)):t;let c=null,d=null;function l(){n(a),c&&clearTimeout(c),d?.()}if(r&&(c=setTimeout(l,r)),ot(a)){const h=a.currentSrc||a.src;if(!h)return a.poster?$(a.poster,e).then(n):l();if(a.readyState>=2)return l();const f=l,u=m=>{i?.("Failed video load",h,m),s?.(m),l()};d=()=>{a.removeEventListener("loadeddata",f),a.removeEventListener("error",u)},a.addEventListener("loadeddata",f,{once:!0}),a.addEventListener("error",u,{once:!0})}else{const h=re(a)?a.href.baseVal:a.currentSrc||a.src;if(!h)return l();const f=async()=>{if(R(a)&&"decode"in a)try{await a.decode()}catch(m){i?.("Failed to decode image, trying to render anyway",a.dataset.originalSrc||h,m)}l()},u=m=>{i?.("Failed image load",a.dataset.originalSrc||h,m),l()};if(R(a)&&a.complete)return f();d=()=>{a.removeEventListener("load",f),a.removeEventListener("error",u)},a.addEventListener("load",f,{once:!0}),a.addEventListener("error",u,{once:!0})}})}async function ce(t,e){K(t)&&(R(t)||ot(t)?await $(t,e):await Promise.all(["img","video"].flatMap(n=>Array.from(t.querySelectorAll(n)).map(r=>$(r,e)))))}const le=(function(){let e=0;const n=()=>`0000${(Math.random()*36**4<<0).toString(36)}`.slice(-4);return()=>(e+=1,`u${n()}${e}`)})();function de(t){return t?.split(",").map(e=>e.trim().replace(/"|'/g,"").toLowerCase()).filter(Boolean)}let he=0;function On(t){const e=`${te}[#${he}]`;return he++,{time:n=>t&&console.time(`${e} ${n}`),timeEnd:n=>t&&console.timeEnd(`${e} ${n}`),warn:(...n)=>t&&Dn(...n)}}function Un(t){return{cache:t?"no-cache":"force-cache"}}async function A(t,e){return wn(t)?t:ue(t,{...e,autoDestruct:!0})}async function ue(t,e){const{scale:n=1,workerUrl:r,workerNumber:o=1}=e||{},s=!!e?.debug,i=e?.features??!0,a=t.ownerDocument??(N?window.document:void 0),c=t.ownerDocument?.defaultView??(N?window:void 0),d=new Map,l={width:0,height:0,quality:1,type:"image/png",scale:n,backgroundColor:null,style:null,filter:null,maximumCanvasSize:0,timeout:3e4,progress:null,debug:s,fetch:{requestInit:Un(e?.fetch?.bypassingCache),placeholderImage:"data:image/png;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",bypassingCache:!1,...e?.fetch},fetchFn:null,font:{},drawImageInterval:100,workerUrl:null,workerNumber:o,onCloneEachNode:null,onCloneNode:null,onEmbedNode:null,onCreateForeignObjectSvg:null,includeStyleProperties:null,autoDestruct:!1,...e,__CONTEXT__:!0,log:On(s),node:t,ownerDocument:a,ownerWindow:c,dpi:n===1?null:96*n,svgStyleElement:fe(a),svgDefsElement:a?.createElementNS(it,"defs"),svgStyles:new Map,defaultComputedStyles:new Map,workers:[...Array.from({length:gn&&r&&o?o:0})].map(()=>{try{const u=new Worker(r);return u.onmessage=async m=>{const{url:p,result:g}=m.data;g?d.get(p)?.resolve?.(g):d.get(p)?.reject?.(new Error(`Error receiving message from worker: ${p}`))},u.onmessageerror=m=>{const{url:p}=m.data;d.get(p)?.reject?.(new Error(`Error receiving message from worker: ${p}`))},u}catch(u){return l.log.warn("Failed to new Worker",u),null}}).filter(Boolean),fontFamilies:new Map,fontCssTexts:new Map,acceptOfImage:`${[Fn(a)&&"image/webp","image/svg+xml","image/*","*/*"].filter(Boolean).join(",")};q=0.8`,requests:d,drawImageCount:0,tasks:[],features:i,isEnable:u=>u==="restoreScrollPosition"?typeof i=="boolean"?!1:i[u]??!1:typeof i=="boolean"?i:i[u]??!0,shadowRoots:[]};l.log.time("wait until load"),await ce(t,{timeout:l.timeout,onWarn:l.log.warn}),l.log.timeEnd("wait until load");const{width:h,height:f}=jn(t,l);return l.width=h,l.height=f,l}function fe(t){if(!t)return;const e=t.createElement("style"),n=e.ownerDocument.createTextNode(`
|
|
270
|
+
.______background-clip--text {
|
|
271
|
+
background-clip: text;
|
|
272
|
+
-webkit-background-clip: text;
|
|
273
|
+
}
|
|
274
|
+
`);return e.appendChild(n),e}function jn(t,e){let{width:n,height:r}=e;if(T(t)&&(!n||!r)){const o=t.getBoundingClientRect();n=n||o.width||Number(t.getAttribute("width"))||0,r=r||o.height||Number(t.getAttribute("height"))||0}return{width:n,height:r}}async function Hn(t,e){const{log:n,timeout:r,drawImageCount:o,drawImageInterval:s}=e;n.time("image to canvas");const i=await $(t,{timeout:r,onWarn:e.log.warn}),{canvas:a,context2d:c}=zn(t.ownerDocument,e),d=()=>{try{c?.drawImage(i,0,0,a.width,a.height)}catch(l){e.log.warn("Failed to drawImage",l)}};if(d(),e.isEnable("fixSvgXmlDecode"))for(let l=0;l<o;l++)await new Promise(h=>{setTimeout(()=>{c?.clearRect(0,0,a.width,a.height),d(),h()},l+s)});return e.drawImageCount=0,n.timeEnd("image to canvas"),a}function zn(t,e){const{width:n,height:r,scale:o,backgroundColor:s,maximumCanvasSize:i}=e,a=t.createElement("canvas");a.width=Math.floor(n*o),a.height=Math.floor(r*o),a.style.width=`${n}px`,a.style.height=`${r}px`,i&&(a.width>i||a.height>i)&&(a.width>i&&a.height>i?a.width>a.height?(a.height*=i/a.width,a.width=i):(a.width*=i/a.height,a.height=i):a.width>i?(a.height*=i/a.width,a.width=i):(a.width*=i/a.height,a.height=i));const c=a.getContext("2d");return c&&s&&(c.fillStyle=s,c.fillRect(0,0,a.width,a.height)),{canvas:a,context2d:c}}function pe(t,e){if(t.ownerDocument)try{const s=t.toDataURL();if(s!=="data:,")return D(s,t.ownerDocument)}catch(s){e.log.warn("Failed to clone canvas",s)}const n=t.cloneNode(!1),r=t.getContext("2d"),o=n.getContext("2d");try{return r&&o&&o.putImageData(r.getImageData(0,0,t.width,t.height),0,0),n}catch(s){e.log.warn("Failed to clone canvas",s)}return n}function Vn(t,e){try{if(t?.contentDocument?.documentElement)return Ct(t.contentDocument.documentElement,e)}catch(n){e.log.warn("Failed to clone iframe",n)}return t.cloneNode(!1)}function Wn(t){const e=t.cloneNode(!1);return t.currentSrc&&t.currentSrc!==t.src&&(e.src=t.currentSrc,e.srcset=""),e.loading==="lazy"&&(e.loading="eager"),e}async function Kn(t,e){if(t.ownerDocument&&!t.currentSrc&&t.poster)return D(t.poster,t.ownerDocument);const n=t.cloneNode(!1);n.crossOrigin="anonymous",t.currentSrc&&t.currentSrc!==t.src&&(n.src=t.currentSrc);const r=n.ownerDocument;if(r){let o=!0;if(await $(n,{onError:()=>o=!1,onWarn:e.log.warn}),!o)return t.poster?D(t.poster,t.ownerDocument):n;n.currentTime=t.currentTime,await new Promise(i=>{n.addEventListener("seeked",i,{once:!0})});const s=r.createElement("canvas");s.width=t.offsetWidth,s.height=t.offsetHeight;try{const i=s.getContext("2d");i&&i.drawImage(n,0,0,s.width,s.height)}catch(i){return e.log.warn("Failed to clone video",i),t.poster?D(t.poster,t.ownerDocument):n}return pe(s,e)}return n}function qn(t,e){return Cn(t)?pe(t,e):In(t)?Vn(t,e):R(t)?Wn(t):ot(t)?Kn(t,e):t.cloneNode(!1)}function Gn(t){let e=t.sandbox;if(!e){const{ownerDocument:n}=t;try{n&&(e=n.createElement("iframe"),e.id=`__SANDBOX__${le()}`,e.width="0",e.height="0",e.style.visibility="hidden",e.style.position="fixed",n.body.appendChild(e),e.srcdoc='<!DOCTYPE html><meta charset="UTF-8"><title></title><body>',t.sandbox=e)}catch(r){t.log.warn("Failed to getSandBox",r)}}return e}const Xn=["width","height","-webkit-text-fill-color"],Yn=["stroke","fill"];function me(t,e,n){const{defaultComputedStyles:r}=n,o=t.nodeName.toLowerCase(),s=W(t)&&o!=="svg",i=s?Yn.map(p=>[p,t.getAttribute(p)]).filter(([,p])=>p!==null):[],a=[s&&"svg",o,i.map((p,g)=>`${p}=${g}`).join(","),e].filter(Boolean).join(":");if(r.has(a))return r.get(a);const d=Gn(n)?.contentWindow;if(!d)return new Map;const l=d?.document;let h,f;s?(h=l.createElementNS(it,"svg"),f=h.ownerDocument.createElementNS(h.namespaceURI,o),i.forEach(([p,g])=>{f.setAttributeNS(null,p,g)}),h.appendChild(f)):h=f=l.createElement(o),f.textContent=" ",l.body.appendChild(h);const u=d.getComputedStyle(f,e),m=new Map;for(let p=u.length,g=0;g<p;g++){const y=u.item(g);Xn.includes(y)||m.set(y,u.getPropertyValue(y))}return l.body.removeChild(h),r.set(a,m),m}function ge(t,e,n){const r=new Map,o=[],s=new Map;if(n)for(const a of n)i(a);else for(let a=t.length,c=0;c<a;c++){const d=t.item(c);i(d)}for(let a=o.length,c=0;c<a;c++)s.get(o[c])?.forEach((d,l)=>r.set(l,d));function i(a){const c=t.getPropertyValue(a),d=t.getPropertyPriority(a),l=a.lastIndexOf("-"),h=l>-1?a.substring(0,l):void 0;if(h){let f=s.get(h);f||(f=new Map,s.set(h,f)),f.set(a,[c,d])}e.get(a)===c&&!d||(h?o.push(h):r.set(a,[c,d]))}return r}function Jn(t,e,n,r){const{ownerWindow:o,includeStyleProperties:s,currentParentNodeStyle:i}=r,a=e.style,c=o.getComputedStyle(t),d=me(t,null,r);i?.forEach((h,f)=>{d.delete(f)});const l=ge(c,d,s);l.delete("transition-property"),l.delete("all"),l.delete("d"),l.delete("content"),n&&(l.delete("position"),l.delete("margin-top"),l.delete("margin-right"),l.delete("margin-bottom"),l.delete("margin-left"),l.delete("margin-block-start"),l.delete("margin-block-end"),l.delete("margin-inline-start"),l.delete("margin-inline-end"),l.set("box-sizing",["border-box",""])),l.get("background-clip")?.[0]==="text"&&e.classList.add("______background-clip--text"),ne&&(l.has("font-kerning")||l.set("font-kerning",["normal",""]),(l.get("overflow-x")?.[0]==="hidden"||l.get("overflow-y")?.[0]==="hidden")&&l.get("text-overflow")?.[0]==="ellipsis"&&t.scrollWidth===t.clientWidth&&l.set("text-overflow",["clip",""]));for(let h=a.length,f=0;f<h;f++)a.removeProperty(a.item(f));return l.forEach(([h,f],u)=>{a.setProperty(u,h,f)}),l}function Zn(t,e){(Tn(t)||An(t)||Nn(t))&&e.setAttribute("value",t.value)}const Qn=["::before","::after"],tr=["::-webkit-scrollbar","::-webkit-scrollbar-button","::-webkit-scrollbar-thumb","::-webkit-scrollbar-track","::-webkit-scrollbar-track-piece","::-webkit-scrollbar-corner","::-webkit-resizer"];function er(t,e,n,r,o){const{ownerWindow:s,svgStyleElement:i,svgStyles:a,currentNodeStyle:c}=r;if(!i||!s)return;function d(l){const h=s.getComputedStyle(t,l);let f=h.getPropertyValue("content");if(!f||f==="none")return;o?.(f),f=f.replace(/(')|(")|(counter\(.+\))/g,"");const u=[le()],m=me(t,l,r);c?.forEach((b,S)=>{m.delete(S)});const p=ge(h,m,r.includeStyleProperties);p.delete("content"),p.delete("-webkit-locale"),p.get("background-clip")?.[0]==="text"&&e.classList.add("______background-clip--text");const g=[`content: '${f}';`];if(p.forEach(([b,S],L)=>{g.push(`${L}: ${b}${S?" !important":""};`)}),g.length===1)return;try{e.className=[e.className,...u].join(" ")}catch(b){r.log.warn("Failed to copyPseudoClass",b);return}const y=g.join(`
|
|
275
|
+
`);let k=a.get(y);k||(k=[],a.set(y,k)),k.push(`.${u[0]}${l}`)}Qn.forEach(d),n&&tr.forEach(d)}const ye=new Set(["symbol"]);async function we(t,e,n,r,o){if(T(n)&&(Pn(n)||Mn(n))||r.filter&&!r.filter(n))return;ye.has(e.nodeName)||ye.has(n.nodeName)?r.currentParentNodeStyle=void 0:r.currentParentNodeStyle=r.currentNodeStyle;const s=await Ct(n,r,!1,o);r.isEnable("restoreScrollPosition")&&nr(t,s),e.appendChild(s)}async function be(t,e,n,r){let o=t.firstChild;T(t)&&t.shadowRoot&&(o=t.shadowRoot?.firstChild,n.shadowRoots.push(t.shadowRoot));for(let s=o;s;s=s.nextSibling)if(!Sn(s))if(T(s)&&Ln(s)&&typeof s.assignedNodes=="function"){const i=s.assignedNodes();for(let a=0;a<i.length;a++)await we(t,e,i[a],n,r)}else await we(t,e,s,n,r)}function nr(t,e){if(!K(t)||!K(e))return;const{scrollTop:n,scrollLeft:r}=t;if(!n&&!r)return;const{transform:o}=e.style,s=new DOMMatrix(o),{a:i,b:a,c,d}=s;s.a=1,s.b=0,s.c=0,s.d=1,s.translateSelf(-r,-n),s.a=i,s.b=a,s.c=c,s.d=d,e.style.transform=s.toString()}function rr(t,e){const{backgroundColor:n,width:r,height:o,style:s}=e,i=t.style;if(n&&i.setProperty("background-color",n,"important"),r&&i.setProperty("width",`${r}px`,"important"),o&&i.setProperty("height",`${o}px`,"important"),s)for(const a in s)i[a]=s[a]}const or=/^[\w-:]+$/;async function Ct(t,e,n=!1,r){const{ownerDocument:o,ownerWindow:s,fontFamilies:i,onCloneEachNode:a}=e;if(o&&En(t))return r&&/\S/.test(t.data)&&r(t.data),o.createTextNode(t.data);if(o&&s&&T(t)&&(K(t)||W(t))){const d=await qn(t,e);if(e.isEnable("removeAbnormalAttributes")){const p=d.getAttributeNames();for(let g=p.length,y=0;y<g;y++){const k=p[y];or.test(k)||d.removeAttribute(k)}}const l=e.currentNodeStyle=Jn(t,d,n,e);n&&rr(d,e);let h=!1;if(e.isEnable("copyScrollbar")){const p=[l.get("overflow-x")?.[0],l.get("overflow-y")?.[0]];h=p.includes("scroll")||(p.includes("auto")||p.includes("overlay"))&&(t.scrollHeight>t.clientHeight||t.scrollWidth>t.clientWidth)}const f=l.get("text-transform")?.[0],u=de(l.get("font-family")?.[0]),m=u?p=>{f==="uppercase"?p=p.toUpperCase():f==="lowercase"?p=p.toLowerCase():f==="capitalize"&&(p=p[0].toUpperCase()+p.substring(1)),u.forEach(g=>{let y=i.get(g);y||i.set(g,y=new Set),p.split("").forEach(k=>y.add(k))})}:void 0;return er(t,d,h,e,m),Zn(t,d),ot(t)||await be(t,d,e,m),await a?.(d),d}const c=t.cloneNode(!1);return await be(t,c,e),await a?.(c),c}function ke(t){if(t.ownerDocument=void 0,t.ownerWindow=void 0,t.svgStyleElement=void 0,t.svgDefsElement=void 0,t.svgStyles.clear(),t.defaultComputedStyles.clear(),t.sandbox){try{t.sandbox.remove()}catch(e){t.log.warn("Failed to destroyContext",e)}t.sandbox=void 0}t.workers=[],t.fontFamilies.clear(),t.fontCssTexts.clear(),t.requests.clear(),t.tasks=[],t.shadowRoots=[]}function sr(t){const{url:e,timeout:n,responseType:r,...o}=t,s=new AbortController,i=n?setTimeout(()=>s.abort(),n):void 0;return fetch(e,{signal:s.signal,...o}).then(a=>{if(!a.ok)throw new Error("Failed fetch, not 2xx response",{cause:a});switch(r){case"arrayBuffer":return a.arrayBuffer();case"dataUrl":return a.blob().then(_n);default:return a.text()}}).finally(()=>clearTimeout(i))}function q(t,e){const{url:n,requestType:r="text",responseType:o="text",imageDom:s}=e;let i=n;const{timeout:a,acceptOfImage:c,requests:d,fetchFn:l,fetch:{requestInit:h,bypassingCache:f,placeholderImage:u},font:m,workers:p,fontFamilies:g}=t;r==="image"&&(rt||St)&&t.drawImageCount++;let y=d.get(n);if(!y){f&&f instanceof RegExp&&f.test(i)&&(i+=(/\?/.test(i)?"&":"?")+new Date().getTime());const k=r.startsWith("font")&&m&&m.minify,b=new Set;k&&r.split(";")[1].split(",").forEach(ct=>{g.has(ct)&&g.get(ct).forEach(Me=>b.add(Me))});const S=k&&b.size,L={url:i,timeout:a,responseType:S?"arrayBuffer":o,headers:r==="image"?{accept:c}:void 0,...h};y={type:r,resolve:void 0,reject:void 0,response:null},y.response=(async()=>{if(l&&r==="image"){const P=await l(n);if(P)return P}return!rt&&n.startsWith("http")&&p.length?new Promise((P,ct)=>{p[d.size&p.length-1].postMessage({rawUrl:n,...L}),y.resolve=P,y.reject=ct}):sr(L)})().catch(P=>{if(d.delete(n),r==="image"&&u)return t.log.warn("Failed to fetch image base64, trying to use placeholder image",i),typeof u=="string"?u:u(s);throw P}),d.set(n,y)}return y.response}async function xe(t,e,n,r){if(!ve(t))return t;for(const[o,s]of ir(t,e))try{const i=await q(n,{url:s,requestType:r?"image":"text",responseType:"dataUrl"});t=t.replace(ar(o),`$1${i}$3`)}catch(i){n.log.warn("Failed to fetch css data url",o,i)}return t}function ve(t){return/url\((['"]?)([^'"]+?)\1\)/.test(t)}const Se=/url\((['"]?)([^'"]+?)\1\)/g;function ir(t,e){const n=[];return t.replace(Se,(r,o,s)=>(n.push([s,oe(s,e)]),r)),n.filter(([r])=>!Et(r))}function ar(t){const e=t.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1");return new RegExp(`(url\\(['"]?)(${e})(['"]?\\))`,"g")}const cr=["background-image","border-image-source","-webkit-border-image","-webkit-mask-image","list-style-image"];function lr(t,e){return cr.map(n=>{const r=t.getPropertyValue(n);return!r||r==="none"?null:((rt||St)&&e.drawImageCount++,xe(r,null,e,!0).then(o=>{!o||r===o||t.setProperty(n,o,t.getPropertyPriority(n))}))}).filter(Boolean)}function dr(t,e){if(R(t)){const n=t.currentSrc||t.src;if(!Et(n))return[q(e,{url:n,imageDom:t,requestType:"image",responseType:"dataUrl"}).then(r=>{r&&(t.srcset="",t.dataset.originalSrc=n,t.src=r||"")})];(rt||St)&&e.drawImageCount++}else if(W(t)&&!Et(t.href.baseVal)){const n=t.href.baseVal;return[q(e,{url:n,imageDom:t,requestType:"image",responseType:"dataUrl"}).then(r=>{r&&(t.dataset.originalSrc=n,t.href.baseVal=r||"")})]}return[]}function hr(t,e){const{ownerDocument:n,svgDefsElement:r}=e,o=t.getAttribute("href")??t.getAttribute("xlink:href");if(!o)return[];const[s,i]=o.split("#");if(i){const a=`#${i}`,c=e.shadowRoots.reduce((d,l)=>d??l.querySelector(`svg ${a}`),n?.querySelector(`svg ${a}`));if(s&&t.setAttribute("href",a),r?.querySelector(a))return[];if(c)return r?.appendChild(c.cloneNode(!0)),[];if(s)return[q(e,{url:s,responseType:"text"}).then(d=>{r?.insertAdjacentHTML("beforeend",d)})]}return[]}function Ee(t,e){const{tasks:n}=e;T(t)&&((R(t)||re(t))&&n.push(...dr(t,e)),vn(t)&&n.push(...hr(t,e))),K(t)&&n.push(...lr(t.style,e)),t.childNodes.forEach(r=>{Ee(r,e)})}async function ur(t,e){const{ownerDocument:n,svgStyleElement:r,fontFamilies:o,fontCssTexts:s,tasks:i,font:a}=e;if(!(!n||!r||!o.size))if(a&&a.cssText){const c=Te(a.cssText,e);r.appendChild(n.createTextNode(`${c}
|
|
276
|
+
`))}else{const c=Array.from(n.styleSheets).filter(u=>{try{return"cssRules"in u&&!!u.cssRules.length}catch(m){return e.log.warn(`Error while reading CSS rules from ${u.href}`,m),!1}}),d=n.implementation.createHTMLDocument(""),l=d.createElement("style");d.head.appendChild(l);const h=l.sheet;await Promise.all(c.flatMap(u=>Array.from(u.cssRules).map(async m=>{if(kn(m)){const p=m.href;let g="";try{g=await q(e,{url:p,requestType:"text",responseType:"text"})}catch(k){e.log.warn(`Error fetch remote css import from ${p}`,k)}const y=g.replace(Se,(k,b,S)=>k.replace(S,oe(S,p)));for(const k of pr(y))try{h.insertRule(k,h.cssRules.length)}catch(b){e.log.warn("Error inserting rule from remote css import",{rule:k,error:b})}}}))),h.cssRules.length&&c.push(h);const f=[];c.forEach(u=>{Tt(u.cssRules,f)}),f.filter(u=>bn(u)&&ve(u.style.getPropertyValue("src"))&&de(u.style.getPropertyValue("font-family"))?.some(m=>o.has(m))).forEach(u=>{const m=u,p=s.get(m.cssText);p?r.appendChild(n.createTextNode(`${p}
|
|
277
|
+
`)):i.push(xe(m.cssText,m.parentStyleSheet?m.parentStyleSheet.href:null,e).then(g=>{g=Te(g,e),s.set(m.cssText,g),r.appendChild(n.createTextNode(`${g}
|
|
278
|
+
`))}))})}}const fr=/(\/\*[\s\S]*?\*\/)/g,Ce=/((@.*?keyframes [\s\S]*?){([\s\S]*?}\s*?)})/gi;function pr(t){if(t==null)return[];const e=[];let n=t.replace(fr,"");for(;;){const s=Ce.exec(n);if(!s)break;e.push(s[0])}n=n.replace(Ce,"");const r=/@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi,o=new RegExp("((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})","gi");for(;;){let s=r.exec(n);if(s)o.lastIndex=r.lastIndex;else if(s=o.exec(n),s)r.lastIndex=o.lastIndex;else break;e.push(s[0])}return e}const mr=/url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g,gr=/src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;function Te(t,e){const{font:n}=e,r=n?n?.preferredFormat:void 0;return r?t.replace(gr,o=>{for(;;){const[s,,i]=mr.exec(o)||[];if(!i)return"";if(i===r)return`src: ${s};`}}):t}function Tt(t,e=[]){for(const n of Array.from(t))xn(n)?e.push(...Tt(n.cssRules)):"cssRules"in n?Tt(n.cssRules,e):e.push(n);return e}const yr=/\bx?link:?href\s*=\s*["'](?!data:)[^"']+["']/i;function wr(t){return yr.test(t.innerHTML)}async function Ae(t,e){const n=await A(t,e);if(T(n.node)&&W(n.node)&&!wr(n.node))return n.node;const{ownerDocument:r,log:o,tasks:s,svgStyleElement:i,svgDefsElement:a,svgStyles:c,font:d,progress:l,autoDestruct:h,onCloneNode:f,onEmbedNode:u,onCreateForeignObjectSvg:m}=n;o.time("clone node");const p=await Ct(n.node,n,!0);if(i&&r){let S="";c.forEach((L,P)=>{S+=`${L.join(`,
|
|
279
|
+
`)} {
|
|
280
|
+
${P}
|
|
281
|
+
}
|
|
282
|
+
`}),i.appendChild(r.createTextNode(S))}o.timeEnd("clone node"),await f?.(p),d!==!1&&T(p)&&(o.time("embed web font"),await ur(p,n),o.timeEnd("embed web font")),o.time("embed node"),Ee(p,n);const g=s.length;let y=0;const k=async()=>{for(;;){const S=s.pop();if(!S)break;try{await S}catch(L){n.log.warn("Failed to run task",L)}l?.(++y,g)}};l?.(y,g),await Promise.all([...Array.from({length:4})].map(k)),o.timeEnd("embed node"),await u?.(p);const b=br(p,n);return a&&b.insertBefore(a,b.children[0]),i&&b.insertBefore(i,b.children[0]),h&&ke(n),await m?.(b),b}function br(t,e){const{width:n,height:r}=e,o=se(n,r,t.ownerDocument),s=o.ownerDocument.createElementNS(o.namespaceURI,"foreignObject");return s.setAttributeNS(null,"x","0%"),s.setAttributeNS(null,"y","0%"),s.setAttributeNS(null,"width","100%"),s.setAttributeNS(null,"height","100%"),s.append(t),o.appendChild(s),o}async function at(t,e){const n=await A(t,e),r=await Ae(n),o=ie(r,n.isEnable("removeControlCharacter"));n.autoDestruct||(n.svgStyleElement=fe(n.ownerDocument),n.svgDefsElement=n.ownerDocument?.createElementNS(it,"defs"),n.svgStyles.clear());const s=D(o,r.ownerDocument);return await Hn(s,n)}async function kr(t,e){const n=await A(t,e),{log:r,type:o,quality:s,dpi:i}=n,a=await at(n);r.time("canvas to blob");const c=await Rn(a,o,s);if(["image/png","image/jpeg"].includes(o)&&i){const d=await Bn(c.slice(0,33));let l=new Uint8Array(d);return o==="image/png"?l=Qt(l,i):o==="image/jpeg"&&(l=Gt(l,i)),r.timeEnd("canvas to blob"),new Blob([l,c.slice(33)],{type:o})}return r.timeEnd("canvas to blob"),c}async function _(t,e){const n=await A(t,e),{log:r,quality:o,type:s,dpi:i}=n,a=await at(n);r.time("canvas to data url");let c=a.toDataURL(s,o);if(["image/png","image/jpeg"].includes(s)&&i&&ee&&yn){const[d,l]=c.split(",");let h=0,f=!1;if(s==="image/png"){const b=mn(l);b>=0?(h=Math.ceil((b+28)/3)*4,f=!0):h=44}else s==="image/jpeg"&&(h=24);const u=l.substring(0,h),m=l.substring(h),p=window.atob(u),g=new Uint8Array(p.length);for(let b=0;b<g.length;b++)g[b]=p.charCodeAt(b);const y=s==="image/png"?Qt(g,i,f):Gt(g,i),k=window.btoa(String.fromCharCode(...y));c=[d,",",k,m].join("")}return r.timeEnd("canvas to data url"),c}async function Pe(t,e){const n=await A(t,e),{width:r,height:o,ownerDocument:s}=n,i=await _(n),a=se(r,o,s),c=a.ownerDocument.createElementNS(a.namespaceURI,"image");return c.setAttributeNS(null,"href",i),c.setAttributeNS(null,"height","100%"),c.setAttributeNS(null,"width","100%"),a.appendChild(c),ie(a,n.isEnable("removeControlCharacter"))}async function xr(t,e){const n=await A(t,e),{ownerDocument:r,width:o,height:s,scale:i,type:a}=n,c=a==="image/svg+xml"?await Pe(n):await _(n),d=D(c,r);return d.width=Math.floor(o*i),d.height=Math.floor(s*i),d.style.width=`${o}px`,d.style.height=`${s}px`,d}async function vr(t,e){return _(await A(t,{...e,type:"image/jpeg"}))}async function Sr(t,e){const n=await A(t,e),r=await at(n);return r.getContext("2d").getImageData(0,0,r.width,r.height).data}async function Er(t,e){return _(await A(t,{...e,type:"image/png"}))}async function Cr(t,e){return _(await A(t,{...e,type:"image/webp"}))}const Tr=Object.freeze(Object.defineProperty({__proto__:null,createContext:ue,destroyContext:ke,domToBlob:kr,domToCanvas:at,domToDataUrl:_,domToForeignObjectSvg:Ae,domToImage:xr,domToJpeg:vr,domToPixel:Sr,domToPng:Er,domToSvg:Pe,domToWebp:Cr,loadMedia:$,waitUntilLoad:ce},Symbol.toStringTag,{value:"Module"}));return cn})();
|
|
283
|
+
//# sourceMappingURL=feedbackkit.iife.js.map
|