From 665a9cc9e5e4fa5d584fc03e6e95b248a86f571c Mon Sep 17 00:00:00 2001 From: augushong Date: Sun, 17 May 2026 13:25:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor(typesetting):=20=E6=9B=BF=E6=8D=A2html?= =?UTF-8?q?2canvas=E4=B8=BASnapDOM=20v2.12.0=20-=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E6=B8=B2=E6=9F=93=E4=B8=8D=E4=B8=80=E8=87=B4=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 public/static/lib/snapdom/snapdom.js (IIFE构建) - phone_image.html script引用从html2canvas改为snapdom - phone-image.js 3处截图调用全部替换为snapdom.toCanvas() - capturePageViaHtml2Canvas (分页截图) - 长图生成 (scale:2) - 导出单页 (scale:2) - API映射: html2canvas(elem,{scale,useCORS,width,height,logging}) -> snapdom.toCanvas(elem,{scale,backgroundColor}) - 返回值兼容: Promise 下游toDataURL不受影响 - 保留html2canvas目录不删除(output.html仍引用) --- public/static/js/phone-image.js | 39 +++++++++------------------- public/static/lib/snapdom/snapdom.js | 14 ++++++++++ view/admin/post/phone_image.html | 2 +- 3 files changed, 27 insertions(+), 28 deletions(-) create mode 100644 public/static/lib/snapdom/snapdom.js diff --git a/public/static/js/phone-image.js b/public/static/js/phone-image.js index 7f07701..dd8c48f 100644 --- a/public/static/js/phone-image.js +++ b/public/static/js/phone-image.js @@ -81,9 +81,9 @@ var PhoneImageLogPanel = (function () { * PhoneImageEngine - 手机图片排版引擎 * * 将文章HTML内容自动分页并渲染为手机尺寸图片 - * 依赖: jQuery, html2canvas (项目已有) + * 依赖: jQuery, SnapDOM (项目已有) * - * 渲染宽度540px, html2canvas scale=2 输出1080px + * 渲染宽度540px, SnapDOM scale=2 输出1080px * 小红书: 540x720 (输出1080x1440) * 抖音: 540x960 (输出1080x1920) */ @@ -1111,7 +1111,7 @@ var PhoneImageEngine = (function () { /** * 共享截图核心逻辑 - 将pages渲染到staging并逐页截图 * @param {Object} opts - { scale, outputCanvas, quality, sizeConfig } - * scale: html2canvas缩放 (1=缩略图, 2=保存) + * scale: SnapDOM缩放 (1=缩略图, 2=保存) * outputCanvas: true=输出canvas对象, false=输出dataURL字符串 * quality: JPEG质量 (0-1) * sizeConfig: 尺寸配置(用于纯图片页canvas渲染) @@ -1142,7 +1142,7 @@ var PhoneImageEngine = (function () { // 字体加载失败不影响截图,继续执行 }).then(function () { requestAnimationFrame(function () { - // html2canvas会跳过visibility:hidden的元素,临时切换为可见 + // SnapDOM会跳过visibility:hidden的元素,临时切换为可见 $staging.css({ visibility: 'visible' }); // 表格和代码块已在中间栏中转为图片,无需再次转换 runCaptureLoop($staging, opts, deferred, pageProgressCallback); @@ -1197,7 +1197,7 @@ var PhoneImageEngine = (function () { idx++; captureNext(); }).catch(function () { - // 加载失败,回退到html2canvas + // 加载失败,回退到SnapDOM截图 capturePageViaHtml2Canvas($elem, $staging, opts, results, deferred, function () { if (opts.streaming && opts.onPageReady) opts.onPageReady(results[results.length - 1], idx); if (pageProgressCallback) pageProgressCallback(idx + 1, total); idx++; captureNext(); }); }); return; @@ -1220,16 +1220,12 @@ var PhoneImageEngine = (function () { } /** - * 用html2canvas截图单页 + * 用SnapDOM截图单页 */ function capturePageViaHtml2Canvas($elem, $staging, opts, results, deferred, onDone) { - html2canvas($elem[0], { + snapdom.toCanvas($elem[0], { scale: opts.scale, - useCORS: true, - backgroundColor: '#ffffff', - width: $elem.outerWidth(), - height: $elem.outerHeight(), - logging: false + backgroundColor: '#ffffff' }).then(function (canvas) { if (opts.outputCanvas) { results.push(canvas); @@ -1574,13 +1570,9 @@ var PhoneImageEngine = (function () { $('body').append($container); requestAnimationFrame(function () { - html2canvas($container[0], { + snapdom.toCanvas($container[0], { scale: 2, - useCORS: true, - backgroundColor: '#ffffff', - width: $container.outerWidth(), - height: $container[0].scrollHeight, - logging: false + backgroundColor: '#ffffff' }).then(function (canvas) { $container.remove(); // 使用JPEG压缩减少体积 @@ -1643,16 +1635,9 @@ var PhoneImageEngine = (function () { $('body').append($container); requestAnimationFrame(function () { - var width = $container.outerWidth(); - var height = $container[0].scrollHeight; - - html2canvas($container[0], { + snapdom.toCanvas($container[0], { scale: 2, - useCORS: true, - backgroundColor: '#ffffff', - width: width, - height: height, - logging: false + backgroundColor: '#ffffff' }).then(function (canvas) { $container.remove(); var link = document.createElement('a'); diff --git a/public/static/lib/snapdom/snapdom.js b/public/static/lib/snapdom/snapdom.js new file mode 100644 index 0000000..8db0c3e --- /dev/null +++ b/public/static/lib/snapdom/snapdom.js @@ -0,0 +1,14 @@ +/* +* SnapDOM +* v2.12.0 +* Author: Juan Martin Muda +* License: MIT +*/ +var Tr=Object.defineProperty;var j=(t,e)=>()=>(t&&(e=t(t=0)),e);var Rt=(t,e)=>{for(var n in e)Tr(t,n,{get:e[n],enumerable:!0})};function qe(t){if(t===!0)return"soft";if(t===!1)return"disabled";if(typeof t=="string"){let e=t.toLowerCase().trim();if(e==="auto")return"auto";if(e==="full")return"full";if(e==="soft"||e==="disabled")return e}return"soft"}function jt(t="soft"){switch(C.session.__counterEpoch=(C.session.__counterEpoch||0)+1,t){case"auto":{C.session.styleMap=new Map,C.session.nodeMap=new Map;return}case"soft":{C.session.styleMap=new Map,C.session.nodeMap=new Map,C.session.styleCache=new WeakMap;return}case"full":return;case"disabled":{C.session.styleMap=new Map,C.session.nodeMap=new Map,C.session.styleCache=new WeakMap,C.computedStyle=new WeakMap,C.baseStyle=new D(50),C.defaultStyle=new D(30),C.image=new D(100),C.background=new D(100),C.resource=new D(150),C.font=new Set;return}default:{C.session.styleMap=new Map,C.session.nodeMap=new Map,C.session.styleCache=new WeakMap;return}}}var D,C,G=j(()=>{D=class extends Map{constructor(e=100,...n){super(...n),this._maxSize=e}set(e,n){if(this.size>=this._maxSize&&!this.has(e)){let r=this.keys().next().value;r!==void 0&&this.delete(r)}return super.set(e,n)}},C={image:new D(100),background:new D(100),resource:new D(150),defaultStyle:new D(30),baseStyle:new D(50),computedStyle:new WeakMap,measureHints:new WeakMap,font:new Set,session:{styleMap:new Map,styleCache:new WeakMap,nodeMap:new Map}}});function pt(t){let e=t.match(/url\((['"]?)(.*?)(\1)\)/);if(!e)return null;let n=e[2].trim();return n.startsWith("#")?null:n}function me(t){if(!t||t==="none")return"";let e=t.replace(/translate[XY]?\([^)]*\)/g,"");return e=e.replace(/matrix\(([^)]+)\)/g,(n,r)=>{let i=r.split(",").map(o=>o.trim());return i.length!==6?`matrix(${r})`:(i[4]="0",i[5]="0",`matrix(${i.join(", ")})`)}),e=e.replace(/matrix3d\(([^)]+)\)/g,(n,r)=>{let i=r.split(",").map(o=>o.trim());return i.length!==16?`matrix3d(${r})`:(i[12]="0",i[13]="0",`matrix3d(${i.join(", ")})`)}),e.trim().replace(/\s{2,}/g," ")}function ut(t){if(/%[0-9A-Fa-f]{2}/.test(t))return t;try{return encodeURI(t)}catch{return t}}function pe(t,e){if(!t||/^(data|blob|about|#)/i.test(t.trim()))return t;try{let n=e||typeof document<"u"&&(document.baseURI||document.location?.href)||"http://localhost/";return new URL(t,n).href}catch{return t}}var Lt=j(()=>{});function Ir(t="[snapDOM]",{ttlMs:e=5*6e4,maxEntries:n=12}={}){let r=new Map,i=0;function o(s,c,a){if(i>=n)return;let u=Date.now();(r.get(c)||0)>u||(r.set(c,u+e),i++,s==="warn"&&console&&console.warn?console.warn(`${t} ${a}`):console&&console.error&&console.error(`${t} ${a}`))}return{warnOnce(s,c){o("warn",s,c)},errorOnce(s,c){o("error",s,c)},reset(){r.clear(),i=0}}}function Nr(t){return/^data:|^blob:|^about:blank$/i.test(t)}function _r(t,e){try{let n=typeof location<"u"&&location.href?location.href:"http://localhost/",r=e.includes("{url}")?e.split("{url}")[0]:e,i=new URL(r||".",n),o=new URL(t,n);if(o.origin===i.origin)return!0;let s=o.searchParams;if(s&&(s.has("url")||s.has("target")))return!0}catch{}return!1}function Wr(t,e){if(!e||Nr(t)||_r(t,e))return!1;try{let n=typeof location<"u"&&location.href?location.href:"http://localhost/",r=new URL(t,n);return typeof location<"u"?r.origin!==location.origin:!0}catch{return!!e}}function Ur(t,e){if(!e)return t;if(e.includes("{url}"))return e.replace("{urlRaw}",ut(t)).replace("{url}",encodeURIComponent(t));if(/[?&]url=?$/.test(e))return`${e}${encodeURIComponent(t)}`;if(e.endsWith("?"))return`${e}url=${encodeURIComponent(t)}`;if(e.endsWith("/"))return`${e}${ut(t)}`;let n=e.includes("?")?"&":"?";return`${e}${n}url=${encodeURIComponent(t)}`}function je(t){return new Promise((e,n)=>{let r=new FileReader;r.onload=()=>e(String(r.result||"")),r.onerror=()=>n(new Error("read_failed")),r.readAsDataURL(t)})}function Or(t,e){return[e.as||"blob",e.timeout??3e3,e.useProxy||"",e.errorTTL??8e3,t].join("|")}async function O(t,e={}){let n=e.as??"blob",r=e.timeout??3e3,i=e.useProxy||"",o=e.errorTTL??8e3,s=e.headers||{},c=!!e.silent;if(/^data:/i.test(t))try{if(n==="text")return{ok:!0,data:String(t),status:200,url:t,fromCache:!1};if(n==="dataURL")return{ok:!0,data:String(t),status:200,url:t,fromCache:!1,mime:String(t).slice(5).split(";")[0]||""};let[,h="",g=""]=String(t).match(/^data:([^,]*),(.*)$/)||[],S=/;base64/i.test(h)?atob(g):decodeURIComponent(g),b=new Uint8Array([...S].map(v=>v.charCodeAt(0))),x=new Blob([b],{type:(h||"").split(";")[0]||""});return{ok:!0,data:x,status:200,url:t,fromCache:!1,mime:x.type||""}}catch{return{ok:!1,data:null,status:0,url:t,fromCache:!1,reason:"special_url_error"}}if(/^blob:/i.test(t))try{let h=await fetch(t);if(!h.ok)return{ok:!1,data:null,status:h.status,url:t,fromCache:!1,reason:"http_error"};let g=await h.blob(),w=g.type||h.headers.get("content-type")||"";return n==="dataURL"?{ok:!0,data:await je(g),status:h.status,url:t,fromCache:!1,mime:w}:n==="text"?{ok:!0,data:await g.text(),status:h.status,url:t,fromCache:!1,mime:w}:{ok:!0,data:g,status:h.status,url:t,fromCache:!1,mime:w}}catch{return{ok:!1,data:null,status:0,url:t,fromCache:!1,reason:"network"}}if(/^about:blank$/i.test(t))return n==="dataURL"?{ok:!0,data:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==",status:200,url:t,fromCache:!1,mime:"image/png"}:{ok:!0,data:n==="text"?"":new Blob([]),status:200,url:t,fromCache:!1};let a=Or(t,{as:n,timeout:r,useProxy:i,errorTTL:o}),u=Xt.get(a);if(u&&u.until>Date.now())return{...u.result,fromCache:!0};u&&Xt.delete(a);let l=he.get(a);if(l)return l;let f=Wr(t,i)?Ur(t,i):t,m=e.credentials;if(!m)try{let h=typeof location<"u"&&location.href?location.href:"http://localhost/",g=new URL(t,h);m=typeof location<"u"&&g.origin===location.origin?"include":"omit"}catch{m="omit"}let d=new AbortController,y=setTimeout(()=>d.abort("timeout"),r),p=(async()=>{try{let h=await fetch(f,{signal:d.signal,credentials:m,headers:s});if(!h.ok){let S={ok:!1,data:null,status:h.status,url:f,fromCache:!1,reason:"http_error"};if(o>0&&Xt.set(a,{until:Date.now()+o,result:S}),!c){let b=`${h.status} ${h.statusText||""}`.trim();Ve.warnOnce(`http:${h.status}:${n}:${new URL(t,location?.href??"http://localhost/").origin}`,`HTTP error ${b} while fetching ${n} ${t}`)}return e.onError&&e.onError(S),S}if(n==="text")return{ok:!0,data:await h.text(),status:h.status,url:f,fromCache:!1};let g=await h.blob(),w=g.type||h.headers.get("content-type")||"";return n==="dataURL"?{ok:!0,data:await je(g),status:h.status,url:f,fromCache:!1,mime:w}:{ok:!0,data:g,status:h.status,url:f,fromCache:!1,mime:w}}catch(h){let g=h&&typeof h=="object"&&"name"in h&&h.name==="AbortError"?String(h.message||"").includes("timeout")?"timeout":"abort":"network",w={ok:!1,data:null,status:0,url:f,fromCache:!1,reason:g};if(!/^blob:/i.test(t)&&o>0&&Xt.set(a,{until:Date.now()+o,result:w}),!c){let S=`${g}:${n}:${new URL(t,location?.href??"http://localhost/").origin}`,b=g==="timeout"?`Timeout after ${r}ms. Consider increasing timeout or using a proxy for ${t}`:g==="abort"?`Request aborted while fetching ${n} ${t}`:`Network/CORS issue while fetching ${n} ${t}. A proxy may be required`;Ve.errorOnce(S,b)}return e.onError&&e.onError(w),w}finally{clearTimeout(y),he.delete(a)}})();return he.set(a,p),p}var Ve,he,Xt,ht=j(()=>{Lt();Ve=Ir("[snapDOM]",{ttlMs:3*6e4,maxEntries:10}),he=new Map,Xt=new Map});async function gt(t,e={}){if(/^((repeating-)?(linear|radial|conic)-gradient)\(/i.test(t)||t.trim()==="none")return t;let r=pt(t);if(!r)return t;let i=pe(r),o=ut(i);if(C.background.has(o)){let s=C.background.get(o);return s?`url("${s}")`:"none"}try{let s=await O(o,{as:"dataURL",useProxy:e.useProxy});return s.ok?(C.background.set(o,s.data),`url("${s.data}")`):(C.background.set(o,null),"none")}catch{return C.background.set(o,null),"none"}}var Xe=j(()=>{G();Lt();ht()});function ge(){for(let t of Br){let e=String(t).toLowerCase();Gt.has(e)||Yt.has(e)||ye(e)}}function ye(t){if(t=String(t).toLowerCase(),Yt.has(t)){let o={};return C.defaultStyle.set(t,o),o}if(C.defaultStyle.has(t))return C.defaultStyle.get(t);let e=document.getElementById("snapdom-sandbox");e||(e=document.createElement("div"),e.id="snapdom-sandbox",e.setAttribute("data-snapdom-sandbox","true"),e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.left="-9999px",e.style.top="-9999px",e.style.width="0px",e.style.height="0px",e.style.overflow="hidden",document.body.appendChild(e));let n=document.createElement(t);n.style.all="initial",e.appendChild(n);let r=getComputedStyle(n),i={};for(let o of r){if(Pt(o))continue;let s=r.getPropertyValue(o);i[o]=s}return e.removeChild(n),C.defaultStyle.set(t,i),i}function Pt(t){let e=String(t).toLowerCase();return!!(zr.has(e)||Hr.test(e)||Dr.test(e))}function wt(t,e){if(e=String(e||"").toLowerCase(),Yt.has(e))return"";let n=[],r=ye(e),c=(t.display||"").toLowerCase()==="inline"||new Set(["span","small","em","strong","b","i","u","s","code","cite","mark","sub","sup"]).has(e);for(let[a,u]of Object.entries(t)){if(Pt(a)||c&&(a==="width"||a==="min-width"||a==="max-width"))continue;let l=r[a];u&&u!==l&&n.push(`${a}:${u}`)}return n.sort(),n.join(";")}function be(t){let e=new Set;return t.nodeType!==Node.ELEMENT_NODE&&t.nodeType!==Node.DOCUMENT_FRAGMENT_NODE?[]:(t.tagName&&e.add(t.tagName.toLowerCase()),typeof t.querySelectorAll=="function"&&t.querySelectorAll("*").forEach(n=>e.add(n.tagName.toLowerCase())),Array.from(e))}function we(t){let e=new Map;for(let r of t){let i=C.defaultStyle.get(r);if(!i)continue;let o=Object.entries(i).map(([s,c])=>`${s}:${c};`).sort().join("");o&&(e.has(o)||e.set(o,[]),e.get(o).push(r))}let n="";for(let[r,i]of e.entries())n+=`${i.join(",")} { ${r} } +`;return n}function Se(t){let e=Array.from(new Set(t.values())).filter(Boolean).sort(),n=new Map,r=1;for(let i of e)n.set(i,`c${r++}`);return n}function qr(t){try{let e=t?.ownerDocument;if(!e)return typeof window<"u"?window:null;let n=e.defaultView;if(n&&typeof n.getComputedStyle=="function")return n;if(typeof window<"u"&&window.frames)for(let r=0;r{let o={length:0,getPropertyValue:()=>"",item:()=>""};return o[Symbol.iterator]=function*(){},o};if(!(t instanceof Element)){let o=typeof window<"u"?window:null;if(o&&typeof o.getComputedStyle=="function")try{return o.getComputedStyle(t,e)||n()}catch{return n()}return n()}let r=C.computedStyle.get(t);r||(r=new Map,C.computedStyle.set(t,r));let i=r.get(e);if(!i){let o=qr(t),s=null;try{s=o&&typeof o.getComputedStyle=="function"?o.getComputedStyle(t,e):null}catch{}if(!s&&typeof window<"u"&&typeof window.getComputedStyle=="function")try{t.ownerDocument===document&&(s=window.getComputedStyle(t,e))}catch{}i=s||n(),r.set(e,i)}return i}function Kt(t){let e={};for(let n of t)e[n]=t.getPropertyValue(n);for(let n of Vr){let r=e[`border-${n}-style`],i=e[`border-${n}-width`];(r==="none"||r==="hidden"||i==="0px")&&(delete e[`border-${n}-style`],delete e[`border-${n}-width`],delete e[`border-${n}-color`])}return e}function St(t){let e=[],n=0,r=0;for(let i=0;i{G();Gt=new Set(["meta","script","noscript","title","link","template"]),Yt=new Set(["meta","link","style","title","noscript","script","template","g","defs","use","marker","mask","clipPath","pattern","path","polygon","polyline","line","circle","ellipse","rect","filter","lineargradient","radialgradient","stop"]),Br=["div","span","p","a","img","ul","li","button","input","select","textarea","label","section","article","header","footer","nav","main","aside","h1","h2","h3","h4","h5","h6","table","thead","tbody","tr","td","th"];Dr=/(?:^|-)(animation|transition)(?:-|$)/i,Hr=/^(--.+|view-timeline|scroll-timeline|animation-trigger|offset-|position-try|app-region|interactivity|overlay|view-transition|-webkit-locale|-webkit-user-(?:drag|modify)|-webkit-tap-highlight-color|-webkit-text-security)$/i,zr=new Set(["cursor","pointer-events","touch-action","user-select","print-color-adjust","speak","reading-flow","reading-order","anchor-name","anchor-scope","container-name","container-type","timeline-scope","zoom"]);Vr=["top","right","bottom","left"]});function ot(t,{fast:e=!1}={}){if(e)return t();"requestIdleCallback"in window?requestIdleCallback(t,{timeout:50}):setTimeout(t,1)}function Ce(){if(typeof navigator>"u")return!1;if(navigator.userAgentData)return navigator.userAgentData.platform==="iOS";let t=navigator.userAgent||"",e=/iPhone|iPad|iPod/.test(t),n=navigator.maxTouchPoints>2&&/Macintosh/.test(t);return e||n}function z(){if(typeof navigator>"u")return!1;let t=navigator.userAgent||"",e=t.toLowerCase(),n=e.includes("safari")&&!e.includes("chrome")&&!e.includes("crios")&&!e.includes("fxios")&&!e.includes("android"),r=/applewebkit/i.test(t),i=/mobile/i.test(t),o=!/safari/i.test(t),s=r&&i&&o,c=/(micromessenger|wxwork|wecom|windowswechat|macwechat)/i.test(t),a=/(baiduboxapp|baidubrowser|baidusearch|baiduboxlite)/i.test(e),u=/ipad|iphone|ipod/.test(e)&&r;return n||s||c||a||u}function Ge(){if(typeof navigator>"u")return!1;let t=(navigator.userAgent||"").toLowerCase();return t.includes("firefox")||t.includes("fxios")}var xt=j(()=>{});function $(t,e,n){let r=t&&typeof t=="object"&&(t.options||t);r&&r.debug&&(n!==void 0?console.warn("[snapdom]",e,n):console.warn("[snapdom]",e))}var Ae=j(()=>{});var Q=j(()=>{Xe();xe();xt();Lt();Ae()});var br={};Rt(br,{toCanvas:()=>bt});function fi(t){return typeof t=="string"&&/^data:image\/svg\+xml/i.test(t)}function di(t){let e=t.indexOf(",");return e>=0?decodeURIComponent(t.slice(e+1)):""}function mi(t){return`data:image/svg+xml;charset=utf-8,${encodeURIComponent(t)}`}function pi(t){let e=[],n="",r=0;for(let i=0;ii.trim()).filter(Boolean)}function hi(t){let e=[],n="",r=0;for(let o=0;o`${c}:${a}`).join(";")}function gi(t){return t.replace(/([^{}]+)\{([^}]*)\}/g,(e,n,r)=>`${n}{${yr(r)}}`)}function yi(t){return t=t.replace(/]*>([\s\S]*?)<\/style>/gi,(e,n)=>e.replace(n,gi(n))),t=t.replace(/style=(['"])([\s\S]*?)\1/gi,(e,n,r)=>`style=${n}${yr(r)}${n}`),t}function bi(t){if(!z()||!fi(t))return t;try{let e=di(t),n=yi(e);return mi(n)}catch{return t}}async function bt(t,e){let{width:n,height:r,scale:i=1,dpr:o=1,meta:s={},backgroundColor:c}=e;t=bi(t);let a=new Image;if(a.loading="eager",a.decoding="sync",a.crossOrigin="anonymous",a.src=t,await a.decode(),z()){a.style.cssText="position:fixed;left:-99999px;top:-99999px;pointer-events:none",document.body.appendChild(a);try{await new Promise(S=>requestAnimationFrame(()=>requestAnimationFrame(S)))}finally{try{a.remove()}catch{}}}let u=a.naturalWidth,l=a.naturalHeight,f=Number.isFinite(s.w0)?s.w0:u,m=Number.isFinite(s.h0)?s.h0:l,d,y,p=Number.isFinite(n),h=Number.isFinite(r);if(p&&h)d=Math.max(1,n),y=Math.max(1,r);else if(p){let S=n/Math.max(1,f);d=n,y=m*S}else if(h){let S=r/Math.max(1,m);y=r,d=f*S}else d=u,y=l;d=d*i,y=y*i;let g=document.createElement("canvas");g.width=d*o,g.height=y*o,g.style.width=`${d}px`,g.style.height=`${y}px`;let w=g.getContext("2d");return o!==1&&w.scale(o,o),c&&(w.save(),w.fillStyle=c,w.fillRect(0,0,d,y),w.restore()),w.drawImage(a,0,0,d,y),g}var Ut=j(()=>{xt()});var ce={};Rt(ce,{rasterize:()=>_e});async function _e(t,e){let n=await bt(t,e),r=new Image;return r.src=n.toDataURL(`image/${e.format}`,e.quality),await r.decode(),r.style.width=`${n.width/e.dpr}px`,r.style.height=`${n.height/e.dpr}px`,r}var Ot=j(()=>{Ut()});var We={};Rt(We,{toImg:()=>wi,toSvg:()=>wi});async function wi(t,e){let{scale:n=1,width:r,height:i,meta:o={}}=e,s=Number.isFinite(r),c=Number.isFinite(i),a=Number.isFinite(n)&&n!==1||s||c;if(z()&&a)return await _e(t,{...e,format:"png",quality:1,meta:o});let u=new Image;if(u.decoding="sync",u.loading="eager",u.src=t,await u.decode(),s&&c)u.style.width=`${r}px`,u.style.height=`${i}px`;else if(s){let l=Number.isFinite(o.w0)?o.w0:u.naturalWidth,f=Number.isFinite(o.h0)?o.h0:u.naturalHeight,m=r/Math.max(1,l);u.style.width=`${r}px`,u.style.height=`${Math.round(f*m)}px`}else if(c){let l=Number.isFinite(o.w0)?o.w0:u.naturalWidth,f=Number.isFinite(o.h0)?o.h0:u.naturalHeight,m=i/Math.max(1,f);u.style.height=`${i}px`,u.style.width=`${Math.round(l*m)}px`}else{let l=Math.round(u.naturalWidth*n),f=Math.round(u.naturalHeight*n);if(u.style.width=`${l}px`,u.style.height=`${f}px`,typeof t=="string"&&t.startsWith("data:image/svg+xml"))try{let d=decodeURIComponent(t.split(",")[1]).replace(/width="[^"]*"/,`width="${l}"`).replace(/height="[^"]*"/,`height="${f}"`);t=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(d)}`,u.src=t}catch(m){$(e,"SVG width/height patch in toImg failed",m)}}return u}var Ue=j(()=>{Q();Ot()});var wr={};Rt(wr,{toBlob:()=>Oe});async function Oe(t,e){let n=e.type;if(n==="svg"){let i=decodeURIComponent(t.split(",")[1]);return new Blob([i],{type:"image/svg+xml"})}let r=await bt(t,e);return new Promise(i=>r.toBlob(o=>i(o),`image/${n}`,e.quality))}var Be=j(()=>{Ut()});var xr={};Rt(xr,{download:()=>Si});async function Sr(t,e){let n=new File([t],e,{type:t.type});if(!navigator.canShare?.({files:[n]}))return!1;try{await navigator.share({files:[n],title:e})}catch(r){if(r.name!=="AbortError")return!1}return!0}async function Si(t,e){let n=new Set(["png","jpeg","jpg","webp","svg"]),r=(e?.type||"").toLowerCase(),i=n.has(r)?r:"",o=(e?.format||i||"").toLowerCase(),s=o==="jpg"?"jpeg":o||"png",c=e?.filename||`snapdom.${s}`,a={...e||{},format:s,type:s};a.dpr=1;let u=Ce();if(s==="svg"){let m=await Oe(t,{...a,type:"svg"});if(u&&await Sr(m,c))return;let d=URL.createObjectURL(m),y=document.createElement("a");y.href=d,y.download=c,document.body.appendChild(y),y.click(),URL.revokeObjectURL(d),y.remove();return}let l=await bt(t,a);if(u){let m=`image/${s}`,d=await new Promise(y=>l.toBlob(y,m,e?.quality));if(d&&await Sr(d,c))return}let f=document.createElement("a");f.href=l.toDataURL(`image/${s}`,e?.quality),f.download=c,document.body.appendChild(f),f.click(),f.remove()}var Cr=j(()=>{Be();Ut();xt()});Q();Q();G();var Ye=new WeakMap,It=new Map,jr=2e3,ke=0;function Tt(){ke++,It.size>jr&&It.clear()}var Ke=!1;function Xr(t=document.documentElement){if(!Ke){Ke=!0;try{new MutationObserver(()=>Tt()).observe(t,{subtree:!0,childList:!0,characterData:!0,attributes:!0})}catch{}try{new MutationObserver(()=>Tt()).observe(document.head,{subtree:!0,childList:!0,characterData:!0,attributes:!0})}catch{}try{let e=document.fonts;e&&(e.addEventListener?.("loadingdone",Tt),e.ready?.then(()=>Tt()).catch(()=>{}))}catch{}}}function Gr(t,e={}){let n={},r=t.getPropertyValue("visibility"),i=e.excludeStyleProps;for(let f=0;fr[0]i[0]?1:0).map(([r,i])=>`${r}:${i}`).join(";"),Qe.set(t,e),e)}function Kr(t,e=null,n={}){let r=Ye.get(t);if(r&&r.epoch===ke)return r.snapshot;let i=e||getComputedStyle(t),o=Gr(i,n);return no(t,i,o),Ye.set(t,{epoch:ke,snapshot:o}),o}function Qr(t,e){return t&&t.session&&t.persist?t:t&&(t.styleMap||t.styleCache||t.nodeMap)?{session:t,persist:{snapshotKeyCache:It,defaultStyle:C.defaultStyle,baseStyle:C.baseStyle,image:C.image,resource:C.resource,background:C.background,font:C.font},options:e||{}}:{session:C.session,persist:{snapshotKeyCache:It,defaultStyle:C.defaultStyle,baseStyle:C.baseStyle,image:C.image,resource:C.resource,background:C.background,font:C.font},options:t||e||{}}}function Jr(t,e,n){if(!(!t.style||t.style.length===0))for(let r=0;r0||(parseFloat(t.borderBottomWidth)||0)>0||(parseFloat(t.paddingTop)||0)>0||(parseFloat(t.paddingBottom)||0)>0?!0:(t.overflowBlock||t.overflowY||"visible")!=="visible"}function Je(t){let e=t.parentElement;if(!e)return!1;let n=getComputedStyle(e).display||"";return n.includes("flex")||n.includes("grid")}function eo(t,e){if(t.textContent&&/\S/.test(t.textContent))return!0;let n=t.firstElementChild,r=t.lastElementChild;if(n&&n.tagName==="BR"||r&&r.tagName==="BR")return!0;let i=t.scrollHeight;if(i===0)return!1;let o=parseFloat(e.paddingTop)||0,s=parseFloat(e.paddingBottom)||0;return i>o+s}function no(t,e,n){if(t instanceof HTMLElement&&t.style&&t.style.height)return;let r=t.tagName&&t.tagName.toLowerCase();if(!r||!["div","section","article","main","aside","header","footer","nav"].includes(r))return;let o=parseFloat(e.height);if(Number.isFinite(o)&&t.scrollHeight>0&&Math.abs(o-t.scrollHeight)>2||e.aspectRatio&&e.aspectRatio!=="none"&&e.aspectRatio!=="auto")return;let c=e.display||"";if(c.includes("flex")||c.includes("grid")||Zr(t))return;let a=e.position;if(a==="absolute"||a==="fixed"||a==="sticky"||e.transform!=="none"||to(e)||Je(t))return;let u=e.overflowX||e.overflow||"visible",l=e.overflowY||e.overflow||"visible";if(u!=="visible"||l!=="visible")return;let f=e.clip;f&&f!=="auto"&&f!=="rect(auto, auto, auto, auto)"||e.visibility==="hidden"||e.opacity==="0"||eo(t,e)&&(delete n.height,delete n["block-size"])}xe();var tn=["fill","stroke","color","background-color","stop-color"],ro=new Set(["symbol","defs","pattern","mask","clipPath","marker","linearGradient","radialGradient","filter"]);function Qt(t){let e=t;for(;e&&e.nodeType===1;){if(e.namespaceURI==="http://www.w3.org/2000/svg"&&ro.has(e.localName))return!0;e=e.parentNode}return!1}var Ze=new Map;function oo(t,e){let n=e+"::"+t.toLowerCase(),r=Ze.get(n);if(r)return r;let i=document,o=e==="http://www.w3.org/2000/svg"?i.createElementNS(e,t):i.createElement(t),s=i.createElement("div");s.style.cssText="position:absolute;left:-99999px;top:-99999px;contain:strict;display:block;",s.appendChild(o),i.documentElement.appendChild(s);let c=getComputedStyle(o),a={};for(let u of tn)a[u]=c.getPropertyValue(u)||"";return s.remove(),Ze.set(n,a),a}function en(t,e){if(!(t instanceof Element)||!(e instanceof Element)||Qt(t))return;let n=t.getAttribute?.("style"),r=!!(n&&n.includes("var("));if(!r&&t.attributes?.length){let o=t.attributes;for(let s=0;snew Promise(i=>{function o(){ot(s=>{(s&&typeof s.timeRemaining=="function"?s.timeRemaining()>0:!0)?e(r,i):o()},{fast:n})}o()})))}function io(t){return t=t.trim(),!t||/:not\(\s*\[data-sd-slotted\]\s*\)\s*$/.test(t)?t:`${t}:not([data-sd-slotted])`}function so(t,e,n=!0){return t.split(",").map(r=>r.trim()).filter(Boolean).map(r=>{if(r.startsWith(":where(")||r.startsWith("@"))return r;let i=n?io(r):r;return`:where(${e} ${i})`}).join(", ")}function rn(t,e){return t?(t=t.replace(/:host\(([^)]+)\)/g,(n,r)=>`:where(${e}:is(${r.trim()}))`),t=t.replace(/:host\b/g,`:where(${e})`),t=t.replace(/:host-context\(([^)]+)\)/g,(n,r)=>`:where(:where(${r.trim()}) ${e})`),t=t.replace(/::slotted\(([^)]+)\)/g,(n,r)=>`:where(${e} ${r.trim()})`),t=t.replace(/(^|})(\s*)([^@}{]+){/g,(n,r,i,o)=>{let s=so(o,e,!0);return`${r}${i}${s}{`}),t):""}function on(t){return t.shadowScopeSeq=(t.shadowScopeSeq||0)+1,`s${t.shadowScopeSeq}`}function sn(t){let e="";try{t.querySelectorAll("style").forEach(r=>{e+=(r.textContent||"")+` +`});let n=t.adoptedStyleSheets||[];for(let r of n)try{if(r&&r.cssRules)for(let i of r.cssRules)e+=i.cssText+` +`}catch{}}catch{}return e}function an(t,e,n){if(!e)return;let r=document.createElement("style");r.setAttribute("data-sd",n),r.textContent=e,t.insertBefore(r,t.firstChild||null)}function cn(t,e){try{let n=t.currentSrc||t.src||"";if(!n)return;e.setAttribute("src",n),e.removeAttribute("srcset"),e.removeAttribute("sizes"),e.loading="eager",e.decoding="sync"}catch{}}function ln(t){let e=new Set;if(!t)return e;let n=/var\(\s*(--[A-Za-z0-9_-]+)\b/g,r;for(;r=n.exec(t);)e.add(r[1]);return e}function ao(t,e){try{let r=getComputedStyle(t).getPropertyValue(e).trim();if(r)return r}catch{}try{let r=getComputedStyle(document.documentElement).getPropertyValue(e).trim();if(r)return r}catch{}return""}function un(t,e,n){let r=[];for(let i of e){let o=ao(t,i);o&&r.push(`${i}: ${o};`)}return r.length?`${n}{${r.join("")}} +`:""}function fn(t){t&&(t.nodeType===Node.ELEMENT_NODE&&t.setAttribute("data-sd-slotted",""),t.querySelectorAll&&t.querySelectorAll("*").forEach(e=>e.setAttribute("data-sd-slotted","")))}async function co(t,e=3){let n=()=>{try{return t.contentDocument||t.contentWindow?.document||null}catch{return null}},r=n(),i=0;for(;isetTimeout(o,0)),r=n(),i++;return r&&(r.body||r.documentElement)?r:null}function lo(t){let e=t.getBoundingClientRect(),n=0,r=0,i=0,o=0;try{let a=getComputedStyle(t);n=parseFloat(a.borderLeftWidth)||0,r=parseFloat(a.borderRightWidth)||0,i=parseFloat(a.borderTopWidth)||0,o=parseFloat(a.borderBottomWidth)||0}catch{}let s=Math.max(0,Math.round(e.width-(n+r))),c=Math.max(0,Math.round(e.height-(i+o)));return{contentWidth:s,contentHeight:c,rect:e}}function J(t){let e=0,n=0;if(t.offsetWidth>0&&(e=t.offsetWidth),t.offsetHeight>0&&(n=t.offsetHeight),e===0||n===0)try{let r=getComputedStyle(t);if(e===0){let i=parseFloat(r.width);!isNaN(i)&&i>0&&(e=i)}if(n===0){let i=parseFloat(r.height);!isNaN(i)&&i>0&&(n=i)}}catch{}if(e===0||n===0)try{if(e===0){let r=parseFloat(t.getAttribute("width"));!isNaN(r)&&r>0&&(e=r)}if(n===0){let r=parseFloat(t.getAttribute("height"));!isNaN(r)&&r>0&&(n=r)}}catch{}if((e===0||n===0)&&(t.naturalWidth||t.naturalHeight))try{e===0&&t.naturalWidth>0&&(e=t.naturalWidth),n===0&&t.naturalHeight>0&&(n=t.naturalHeight)}catch{}return{width:e,height:n}}function uo(t,e,n){let r=t.defaultView,i=r?r.scrollX:0,o=r?r.scrollY:0,s=t.body?t.body.scrollLeft:0,c=t.body?t.body.scrollTop:0,a=t.documentElement?t.documentElement.scrollLeft:0,u=t.documentElement?t.documentElement.scrollTop:0,l=t.createElement("style");return l.setAttribute("data-sd-iframe-pin",""),l.textContent=`html, body {margin: 0 !important;padding: 0 !important;width: ${e}px !important;height: ${n}px !important;min-width: ${e}px !important;min-height: ${n}px !important;box-sizing: border-box !important;overflow: hidden !important;background-clip: border-box !important;}`,(t.head||t.documentElement).appendChild(l),()=>{try{l.remove()}catch{}try{r&&typeof r.scrollTo=="function"&&r.scrollTo(i,o),t.body&&(t.body.scrollLeft=s,t.body.scrollTop=c),t.documentElement&&(t.documentElement.scrollLeft=a,t.documentElement.scrollTop=u)}catch{}}}async function dn(t,e,n){let r=await co(t,3);if(!r)throw new Error("iframe document not accessible/ready");let{contentWidth:i,contentHeight:o,rect:s}=lo(t),c=n?.snap;if(!c&&typeof window<"u"&&window.snapdom&&(c=window.snapdom),!c||typeof c.toPng!="function")throw new Error("[snapdom] iframe capture requires snapdom.toPng. Use snapdom(el) or pass options.snap. With ESM, assign window.snapdom = snapdom after import if using iframes.");let a={...n,scale:1},u=uo(r,i,o),l;try{l=await c.toPng(r.documentElement,a)}finally{u()}l.style.display="block",l.style.width=`${i}px`,l.style.height=`${o}px`;let f=document.createElement("div");return e.nodeMap.set(f,t),it(t,f,e,n),f.style.overflow="hidden",f.style.display="block",f.style.width||(f.style.width=`${Math.round(s.width)}px`),f.style.height||(f.style.height=`${Math.round(s.height)}px`),f.appendChild(l),f}function mn(t){let{width:e,height:n}=J(t),r=t.getBoundingClientRect(),i;try{i=window.getComputedStyle(t)}catch{}let o=i?parseFloat(i.width):NaN,s=i?parseFloat(i.height):NaN,c=Math.round(e||r.width||0),a=Math.round(n||r.height||0),u=Number.isFinite(o)&&o>0?Math.round(o):Math.max(12,c||16),l=Number.isFinite(s)&&s>0?Math.round(s):Math.max(12,a||16),f=(t.type||"text").toLowerCase()==="checkbox",m=!!t.checked,d=!!t.indeterminate,p=Math.max(Math.min(u,l),12),h="middle";try{i&&i.verticalAlign&&(h=i.verticalAlign)}catch{}let g=document.createElement("div");g.setAttribute("data-snapdom-input-replacement",t.type||"checkbox"),g.style.cssText=`display:inline-block;width:${p}px;height:${p}px;vertical-align:${h};flex-shrink:0;line-height:0;`;let w=document.createElementNS("http://www.w3.org/2000/svg","svg");w.setAttribute("width",String(p)),w.setAttribute("height",String(p)),w.setAttribute("viewBox",`0 0 ${p} ${p}`),g.appendChild(w);function S(){let b="#0a6ed1";try{i&&(b=i.accentColor||i.color||b)}catch{}let x=2,v=x/2,A=p-x;if(w.innerHTML="",f){let k=document.createElementNS("http://www.w3.org/2000/svg","rect");if(k.setAttribute("x",String(v)),k.setAttribute("y",String(v)),k.setAttribute("width",String(A)),k.setAttribute("height",String(A)),k.setAttribute("rx","2"),k.setAttribute("ry","2"),k.setAttribute("fill",m?b:"none"),k.setAttribute("stroke",b),k.setAttribute("stroke-width",String(x)),w.appendChild(k),m){let E=document.createElementNS("http://www.w3.org/2000/svg","path");E.setAttribute("d",`M ${v+2} ${p/2} L ${p/2-1} ${p-v-2} L ${p-v-2} ${v+2}`),E.setAttribute("stroke","white"),E.setAttribute("stroke-width",String(Math.max(1.5,x))),E.setAttribute("fill","none"),E.setAttribute("stroke-linecap","round"),E.setAttribute("stroke-linejoin","round"),w.appendChild(E)}else if(d){let E=document.createElementNS("http://www.w3.org/2000/svg","rect"),T=Math.max(6,A-4);E.setAttribute("x",String((p-T)/2)),E.setAttribute("y",String((p-x)/2)),E.setAttribute("width",String(T)),E.setAttribute("height",String(x)),E.setAttribute("fill",b),E.setAttribute("rx","1"),w.appendChild(E)}}else{let k=document.createElementNS("http://www.w3.org/2000/svg","circle");if(k.setAttribute("cx",String(p/2)),k.setAttribute("cy",String(p/2)),k.setAttribute("r",String((p-x)/2)),k.setAttribute("fill",m?b:"none"),k.setAttribute("stroke",b),k.setAttribute("stroke-width",String(x)),w.appendChild(k),m){let E=document.createElementNS("http://www.w3.org/2000/svg","circle"),T=Math.max(2,(p-x*2)*.35);E.setAttribute("cx",String(p/2)),E.setAttribute("cy",String(p/2)),E.setAttribute("r",String(T)),E.setAttribute("fill","white"),w.appendChild(E)}}g.style.setProperty("width",`${p}px`,"important"),g.style.setProperty("height",`${p}px`,"important"),g.style.setProperty("min-width",`${p}px`,"important"),g.style.setProperty("min-height",`${p}px`,"important")}return S(),{el:g,applyVisual:S}}var Nt=new D(80);async function _t(t){if(C.resource?.has(t))return C.resource.get(t);if(Nt.has(t))return Nt.get(t);let e=(async()=>{let n=await O(t,{as:"dataURL",silent:!0});if(!n.ok||typeof n.data!="string")throw new Error(`[snapDOM] Failed to read blob URL: ${t}`);return C.resource?.set(t,n.data),n.data})();Nt.set(t,e);try{let n=await e;return Nt.set(t,n),n}catch(n){throw Nt.delete(t),n}}var fo=/\bblob:[^)"'\s]+/g;async function nn(t){if(!t||t.indexOf("blob:")===-1)return t;let e=Array.from(new Set(t.match(fo)||[]));if(e.length===0)return t;let n=t;for(let r of e)try{let i=await _t(r);n=n.split(r).join(i)}catch{}return n}function Jt(t){return typeof t=="string"&&t.startsWith("blob:")}function mo(t){return(t||"").split(",").map(e=>e.trim()).filter(Boolean).map(e=>{let n=e.match(/^(\S+)(\s+.+)?$/);return n?{url:n[1],desc:n[2]||""}:null}).filter(Boolean)}function po(t){return t.map(e=>e.desc?`${e.url} ${e.desc.trim()}`:e.url).join(", ")}async function pn(t,e=null){if(!t)return;let n=e,r=t.querySelectorAll?t.querySelectorAll("img"):[];for(let a of r)try{let l=a.getAttribute("src")||a.currentSrc||"";if(Jt(l)){let m=await _t(l);a.setAttribute("src",m)}let f=a.getAttribute("srcset");if(f&&f.includes("blob:")){let m=mo(f),d=!1;for(let y of m)if(Jt(y.url))try{y.url=await _t(y.url),d=!0}catch(p){$(n,"blobUrlToDataUrl for srcset item failed",p)}d&&a.setAttribute("srcset",po(m))}}catch(u){$(n,"resolveBlobUrls for img failed",u)}let i=t.querySelectorAll?t.querySelectorAll("image"):[];for(let a of i)try{let u="http://www.w3.org/1999/xlink",l=a.getAttribute("href")||a.getAttributeNS?.(u,"href");if(Jt(l)){let f=await _t(l);a.setAttribute("href",f),a.removeAttributeNS?.(u,"href")}}catch(u){$(n,"resolveBlobUrls for SVG image href failed",u)}let o=t.querySelectorAll?t.querySelectorAll("[style*='blob:']"):[];for(let a of o)try{let u=a.getAttribute("style");if(u&&u.includes("blob:")){let l=await nn(u);a.setAttribute("style",l)}}catch(u){$(n,"replaceBlobUrls in inline style failed",u)}let s=t.querySelectorAll?t.querySelectorAll("style"):[];for(let a of s)try{let u=a.textContent||"";u.includes("blob:")&&(a.textContent=await nn(u))}catch(u){$(n,"replaceBlobUrls in style tag failed",u)}let c=["poster"];for(let a of c){let u=t.querySelectorAll?t.querySelectorAll(`[${a}^='blob:']`):[];for(let l of u)try{let f=l.getAttribute(a);Jt(f)&&l.setAttribute(a,await _t(f))}catch(f){$(n,`resolveBlobUrls for ${a} failed`,f)}}}xt();async function Wt(t,e,n){if(!t)throw new Error("Invalid node");let r=new Set,i=null,o=null;if(t.nodeType===Node.ELEMENT_NODE){let l=(t.localName||t.tagName||"").toLowerCase();if(t.id==="snapdom-sandbox"||t.hasAttribute("data-snapdom-sandbox")||Gt.has(l))return null;if(l==="foreignobject"&&t.parentElement?.closest?.("foreignObject"))return $(e,"Nested skipped (SVG spec limitation \u2014 not rendered by browsers)"),null}if(t.nodeType===Node.TEXT_NODE||t.nodeType!==Node.ELEMENT_NODE)return t.cloneNode(!0);if(t.getAttribute("data-capture")==="exclude"){if(n.excludeMode==="hide"){let l=document.createElement("div"),{width:f,height:m}=J(t),d=f||t.getBoundingClientRect().width||0,y=m||t.getBoundingClientRect().height||0;return l.style.cssText=`display:inline-block;width:${d}px;height:${y}px;visibility:hidden;`,l}else if(n.excludeMode==="remove")return null}if(n.exclude&&Array.isArray(n.exclude))for(let l of n.exclude)try{if(t.matches?.(l)){if(n.excludeMode==="hide"){let f=document.createElement("div"),{width:m,height:d}=J(t),y=m||t.getBoundingClientRect().width||0,p=d||t.getBoundingClientRect().height||0;return f.style.cssText=`display:inline-block;width:${y}px;height:${p}px;visibility:hidden;`,f}else if(n.excludeMode==="remove")return null}}catch(f){console.warn(`Invalid selector in exclude option: ${l}`,f)}if(typeof n.filter=="function")try{if(!n.filter(t)){if(n.filterMode==="hide"){let l=document.createElement("div"),{width:f,height:m}=J(t),d=f||t.getBoundingClientRect().width||0,y=m||t.getBoundingClientRect().height||0;return l.style.cssText=`display:inline-block;width:${d}px;height:${y}px;visibility:hidden;`,l}else if(n.filterMode==="remove")return null}}catch(l){console.warn("Error in filter function:",l)}if(t.tagName==="IFRAME"){let l=!1;try{l=!!(t.contentDocument||t.contentWindow?.document)}catch(f){$(e,"iframe same-origin probe failed",f)}if(l)try{return await dn(t,e,n)}catch(f){console.warn("[SnapDOM] iframe rasterization failed, fallback:",f)}if(l||console.warn("[snapdom] cross-origin