1var Pt=Object.defineProperty;var Rt=(a,t,o)=>t in a?Pt(a,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):a[t]=o;var w=(a,t,o)=>Rt(a,typeof t!="symbol"?t+"":t,o);function mt(a,t,o=!1){const e=a.vertices.find(l=>l.id===(o?t.from:t.to)),n=a.vertices.find(l=>l.id===(o?t.to:t.from)),i=(o?t.c2:t.c1)??n,s=(o?t.c1:t.c2)??e;return t.c1||t.c2?{op:"C",c1x:i.x,c1y:i.y,c2x:s.x,c2y:s.y,x:e.x,y:e.y}:{op:"L",x:e.x,y:e.y}}function Ft(a){const t=new Map(a.vertices.map(i=>[i.id,a.edges.filter(s=>s.from===i.id||s.to===i.id)])),o=new Set,e=[],n=(i,s)=>{const l=a.vertices.find(c=>c.id===i);e.push({op:"M",x:l.x,y:l.y});let r=i,f=s;for(;f&&!o.has(f.id);){o.add(f.id);const c=f.to===r,d=c?f.from:f.to;if(e.push(mt(a,f,c)),d===i){e.push({op:"Z"});break}if(t.get(d).length!==2)break;r=d,f=t.get(d).find(h=>!o.has(h.id))}};for(const i of a.vertices)if(t.get(i.id).length!==2)for(const s of t.get(i.id))o.has(s.id)||n(i.id,s);for(const i of a.edges)o.has(i.id)||n(i.from,i);return e}function At(a){const t=new Map(a.vertices.map(i=>[i.id,i])),o=new Map;for(const i of a.edges)for(const s of[!1,!0]){const l=s?i.to:i.from,r=s?i.from:i.to,f=t.get(l),c=[s?i.c2:i.c1,s?i.c1:i.c2,t.get(r)].find(h=>h&&Math.hypot(h.x-f.x,h.y-f.y)>1e-8)??t.get(r),d={edge:i,reverse:s,from:l,to:r,key:i.id+(s?"-":"+"),angle:Math.atan2(c.y-f.y,c.x-f.x)};o.set(l,[...o.get(l)??[],d])}for(const i of o.values())i.sort((s,l)=>s.angle-l.angle);const e=new Set,n=[];for(const i of o.values())for(const s of i){if(e.has(s.key))continue;const l=[];let r=s;for(;r&&!e.has(r.key);){e.add(r.key),l.push(r);const h=o.get(r.to),u=h.findIndex(p=>p.edge===r.edge&&p.reverse!==r.reverse);r=h[(u+h.length-1)%h.length]}if((r==null?void 0:r.key)!==s.key||l.length<2)continue;const f=[];for(const h of l){const u=t.get(h.from),p=t.get(h.to),g=(h.reverse?h.edge.c2:h.edge.c1)??u,m=(h.reverse?h.edge.c1:h.edge.c2)??p;for(let x=0;x<12;x++){const k=x/12,b=1-k;f.push({x:b*b*b*u.x+3*b*b*k*g.x+3*b*k*k*m.x+k*k*k*p.x,y:b*b*b*u.y+3*b*b*k*g.y+3*b*k*k*m.y+k*k*k*p.y})}}if(f.reduce((h,u,p)=>{const g=f[(p+1)%f.length];return h+u.x*g.y-g.x*u.y},0)<=1e-6)continue;const d=t.get(s.from);n.push({op:"M",x:d.x,y:d.y},...l.map(h=>mt(a,h.edge,h.reverse)),{op:"Z"})}return n}const zt={alignment:"center",cap:"butt",join:"miter",miterLimit:4,dash:0,gap:0,offset:0};function ut(a){return typeof a=="string"?a:a.kind==="solid"||a.kind==="pattern"?a.color:a.stops[0].color}function pt(a){return typeof a!="string"&&(a.kind==="linear"||a.kind==="radial")?a:null}function O(a){const t=e=>{const n=e.trim().toLowerCase();if(["transparent","none"].includes(n))return!1;if(/^#[0-9a-f]{8}$/.test(n))return parseInt(n.slice(7),16)>0;if(/^#[0-9a-f]{4}$/.test(n))return parseInt(n.slice(4),16)>0;const i=n.match(/^rgba\([^,]+,[^,]+,[^,]+,\s*([\d.]+)\s*\)$/);return!i||Number(i[1])>0};if(typeof a!="string"&&a.kind==="pattern")return t(a.color)||t(a.background);const o=pt(a);return o?o.stops.some(e=>t(e.color)):t(ut(a))}function ot(a,t,o,e){return{x:(a.from.x+(a.to.x-a.from.x)*t)*o,y:(a.from.y+(a.to.y-a.from.y)*t)*e}}const at=a=>{var t;return((t=a.effects)==null?void 0:t.backdrop)===!0},Lt=["#000000","#FFFFFF","#FF3B30","#FFCC00","#4CD964","#007AFF"],X=(a,t,o)=>Math.min(o,Math.max(t,a)),M=1e-8,T=(a,t)=>({x:a.x+t.x,y:a.y+t.y}),S=(a,t)=>({x:a.x-t.x,y:a.y-t.y}),I=(a,t)=>({x:a.x*t,y:a.y*t}),F=a=>Math.hypot(a.x,a.y),gt=(a,t)=>a.x*t.y-a.y*t.x,xt=(a,t)=>({x:a.x*Math.cos(t)-a.y*Math.sin(t),y:a.x*Math.sin(t)+a.y*Math.cos(t)});function kt(a,t){const o=xt(S(t,{x:a.x+a.width/2,y:a.y+a.height/2}),-(a.rotation??0)*Math.PI/180);return{x:o.x*(a.flipX?-1:1)+a.width/2,y:o.y*(a.flipY?-1:1)+a.height/2}}function Bt(a){const{width:t,height:o}=a;if(a.shape==="rectangle")return[{x:0,y:0},{x:t,y:0},{x:t,y:o},{x:0,y:o}];const e=X(Math.round(a.count),3,60),n=a.shape==="star";return Array.from({length:e*(n?2:1)},(i,s)=>{const l=-Math.PI/2+s*Math.PI*2/(e*(n?2:1)),r=n&&s%2?X(a.ratio,.01,1):1;return{x:t/2+Math.cos(l)*t/2*r,y:o/2+Math.sin(l)*o/2*r}})}function Nt(a,t){if(a.length<3)return[];const o=a.map((n,i)=>{const s=a[(i+a.length-1)%a.length],l=a[(i+1)%a.length],r=I(S(s,n),1/Math.max(M,F(S(s,n)))),f=I(S(l,n),1/Math.max(M,F(S(l,n)))),c=Math.acos(X(r.x*f.x+r.y*f.y,-1,1)),d=c<M||Math.PI-c<M?0:1/Math.tan(c/2);return{p:n,u:r,v:f,angle:c,cot:d,turn:Math.sign(gt(I(r,-1),f))*(Math.PI-c)}});let e=Math.max(0,t);return o.forEach((n,i)=>{const s=o[(i+1)%o.length],l=n.cot+s.cot;l>M&&(e=Math.min(e,F(S(s.p,n.p))/l))}),o.map(n=>{const i=e*n.cot,s=T(n.u,n.v),l=F(s),r=l>M&&n.cot>0?T(n.p,I(s,e/Math.sin(n.angle/2)/l)):n.p;return{vertex:n.p,entry:T(n.p,I(n.u,i)),exit:T(n.p,I(n.v,i)),center:r,radius:n.cot>0?e:0,turn:n.turn}})}function Wt(a,t){if(!a.length)return[];if(a.length<3||t<=M)return[{op:"M",...a[0]},...a.slice(1).map(n=>({op:"L",...n})),{op:"Z"}];const o=Nt(a,t),e=[{op:"M",...o[0].entry}];for(let n=0;n<o.length;n++){const i=o[n];if(n>0&&e.push({op:"L",...i.entry}),i.radius<=M||Math.abs(i.turn)<=M){e.push({op:"L",...i.exit});continue}const s=Math.ceil(Math.abs(i.turn)/(Math.PI/2)),l=i.turn/s;let r=i.entry;for(let f=0;f<s;f++){const c=S(r,i.center),d=xt(c,l),h=f===s-1?i.exit:T(i.center,d),u=4/3*Math.tan(l/4),p=T(r,I({x:-c.y,y:c.x},u)),g=S(h,I({x:-d.y,y:d.x},u));e.push({op:"C",c1x:p.x,c1y:p.y,c2x:g.x,c2y:g.y,...h}),r=h}}return e.push({op:"Z"}),e}function bt(a){if(a.shape==="path")return a.network?Ft(a.network):[];if(a.shape!=="ellipse")return Wt(Bt(a),a.radius);const t=a.width/2,o=a.height/2,e=.5522847498307936;return[{op:"M",x:t,y:0},{op:"C",c1x:t+e*t,c1y:0,c2x:2*t,c2y:o-e*o,x:2*t,y:o},{op:"C",c1x:2*t,c1y:o+e*o,c2x:t+e*t,c2y:2*o,x:t,y:2*o},{op:"C",c1x:t-e*t,c1y:2*o,c2x:0,c2y:o+e*o,x:0,y:o},{op:"C",c1x:0,c1y:o-e*o,c2x:t-e*t,c2y:0,x:t,y:0},{op:"Z"}]}function qt(a){const t=[];let o={x:0,y:0};
1return a.forEach(e=>{if(e.op!=="Z"){if(e.op==="C"){const n=o;for(let i=1;i<=16;i++){const s=i/16,l=1-s;t.push({x:l**3*n.x+3*l*l*s*e.c1x+3*l*s*s*e.c2x+s**3*e.x,y:l**3*n.y+3*l*l*s*e.c1y+3*l*s*s*e.c2y+s**3*e.y})}}else t.push({x:e.x,y:e.y});o={x:e.x,y:e.y}}}),t.length>1&&F(S(t[t.length-1],t[0]))<M&&t.pop(),t}function yt(a,t,o){const e=S(o,t),n=e.x*e.x+e.y*e.y,i=n?X(((a.x-t.x)*e.x+(a.y-t.y)*e.y)/n,0,1):0;return F(S(a,T(t,I(e,i))))}function J(a,t,o=0){let e=!1;for(let n=0,i=a.length-1;n<a.length;i=n++){const s=a[n],l=a[i];if(yt(t,s,l)<=o+M)return!0;s.y>t.y!=l.y>t.y&&t.x<(l.x-s.x)*(t.y-s.y)/(l.y-s.y)+s.x&&(e=!e)}return e}function Ut(a,t,o,e){for(let n=0;n<a.length;n++){const i=a[n],s=a[(n+1)%a.length],l=a[(n+a.length-1)%a.length],r=S(s,i),f=F(r);if(f<M)continue;const c=I(r,1/f),d={x:-c.y*o,y:c.x*o};if(J([T(i,d),T(s,d),S(s,d),S(i,d)],t,e))return!0;const h=S(i,l),u=F(h);if(u<M)continue;const p=I(h,1/u),g=gt(p,c);if(Math.abs(g)<M)continue;const m=Math.sign(g),x={x:p.y*m,y:-p.x*m},k={x:c.y*m,y:-c.x*m},b=T(i,I(x,o)),y=T(i,I(k,o)),E=1+x.x*k.x+x.y*k.y,v=E>M?I(T(x,k),o/E):void 0,P=v&&F(v)<=o*4+M?[i,b,T(i,v),y]:[i,b,y];if(J(P,t,e))return!0}return!1}function Dt(a,t,o=0){if(!a.visible||a.opacity<=0)return!1;const e=kt(a,t);if(a.kind==="brush")return a.points.some((i,s)=>yt(e,a.points[Math.max(0,s-1)],i)<=a.size/2+o);if(a.kind!=="shape")return e.x>=-o&&e.y>=-o&&e.x<=a.width+o&&e.y<=a.height+o;const n=qt(bt(a));return O(a.fill)&&J(n,e,o)?!0:a.strokeEnabled!==!1&&a.strokeWidth>0&&O(a.stroke)&&Ut(n,e,a.strokeWidth/2,o)}class Ht{constructor(t){w(this,"entries",new Map);w(this,"bytes",0);w(this,"byteLimit",128*1024*1024);this.kit=t}get(t,o,e){var c,d;const n=((c=t.mask)==null?void 0:c.strokes)??[],i=Math.max(0,n.length-1);if(!i)return;const s=Math.max(1,Math.round(t.naturalWidth)),l=Math.max(1,Math.round(t.naturalHeight)),r=s*l*8;if(r>this.byteLimit)return;let f=this.entries.get(t.id);if(f&&(f.width!==s||f.height!==l||f.base!==o||f.strokes.length>i||f.strokes.some((h,u)=>n[u]!==h))&&(this.remove(t.id),f=void 0),!f){for(;this.bytes+r>this.byteLimit&&this.entries.size;)this.remove(this.entries.keys().next().value);const h=this.kit.MakeSurface(s,l);if(!h)return;f={surface:h,width:s,height:l,base:o,strokes:[],bytes:r},this.entries.set(t.id,f),this.bytes+=r;const u=h.getCanvas();u.clear(this.kit.WHITE),o&&(u.clear(this.kit.TRANSPARENT),u.drawImageRectOptions(o,this.kit.XYWHRect(0,0,o.width(),o.height()),this.kit.XYWHRect(0,0,s,l),this.kit.FilterMode.Linear,this.kit.MipmapMode.None))}return f.strokes.length<i&&((d=f.image)==null||d.delete(),f.image=void 0,e(f.surface.getCanvas(),n.slice(f.strokes.length,i)),f.surface.flush(),f.strokes=n.slice(0,i),f.image=f.surface.makeImageSnapshot()),this.entries.delete(t.id),this.entries.set(t.id,f),f.image}retain(t){for(const o of this.entries.keys())t.has(o)||this.remove(o)}remove(t){var e;const o=this.entries.get(t);o&&((e=o.image)==null||e.delete(),o.surface.dispose(),this.bytes-=o.bytes,this.entries.delete(t))}dispose(){for(const t of this.entries.keys())this.remove(t)}}function Ot(a,t,o,e){const n=new a.ContourMeasureIter(t,!1,1),i=new a.PathBuilder;try{for(let s=n.next();s;s=n.next())try{const l=s.length(),r=Math.max(8,Math.min(2048,Math.ceil(l/2))),f=[],c=[];for(let h=0;h<=r;h++){const u=h/r,p=s.getPosTan(u*l),g=e==="taper-start"?u:e==="taper-end"?1-u:Math.sin(Math.PI*u),m=o*g/2;f.push([p[0]-p[3]*m,p[1]+p[2]*m]),c.push([p[0]+p[3]*m,p[1]-p[2]*m])}[...f,...c.reverse()].forEach((h,u)=>u?i.lineTo(h[0],h[1]):i.moveTo(h[0],h[1])),i.close()}finally{s.delete()}return i.detach()}finally{i.delete(),n.delete()}}const N=(a,t)=>["transparent","none"].includes(t.trim().toLowerCase())?a.TRANSPARENT:a.parseColorString(t);function nt(a,t,o,e){const n=new a.Paint;if(n.setAntiAlias(!0),typeof t!="string"&&t.kind==="pattern"){const h=new a.PictureRecorder,u=a.XYWHRect(0,0,t.size,t.size),p=h.beginRecording(u),g=new a.Paint;g.setAntiAlias(!0),g.setColor(N(a,t.background)),p.drawRect(u,g),g.setColor(N(a,t.color)),t.pattern==="dots"?p.drawCircle(t.size/2,t.size/2,t.size/6,g):t.pattern==="stripes"?p.drawRect(a.XYWHRect(0,0,t.size/2,t.size),g):(p.drawRect(a.XYWHRect(0,0,t.size,Math.max(.5,t.size/12)),g),p.drawRect(a.XYWHRect(0,0,Math.max(.5,t.size/12),t.size),g));const m=h.finishRecordingAsPicture(),x=t.angle*Math.PI/180,k=Math.cos(x),b=Math.sin(x),y=m.makeShader(a.TileMode.Repeat,a.TileMode.Repeat,a.FilterMode.Linear,[k,-b,0,b,k,0,0,0,1],u);return n.setShader(y),y.delete(),m.delete(),h.delete(),g.delete(),n}const i=pt(t);if(!i)return n.setColor(N(a,ut(t))),n;const s=ot(i,0,o,e),l=ot(i,1,o,e),r=i.stops.map(h=>N(a,h.color)),f=i.stops.map(h=>h.offset),c=Math.hypot(l.x-s.x,l.y-s.y);if(c<1e-4)return n.setColor(r[r.length-1]),n;const d=i.kind==="linear"?a.Shader.MakeLinearGradient([s.x,s.y],[l.x,l.y],r,f,a.TileMode.Clamp,void 0,1):a.Shader.MakeRadialGradient([s.x,s.y],c,r,f,a.TileMode.Clamp,void 0,1);return n.setShader(d),d.delete(),n}function Xt(a,t,o){if(o.strokeEnabled===!1||o.strokeWidth<=0)return null;const e=o.strokeStyle??zt;if(e.profile&&e.profile!=="uniform")return Ot(a,t,o.strokeWidth,e.profile);const n=e.dash>0&&e.gap>0?t.makeDashed(e.dash,e.gap,e.offset):null;try{const i=(n??t).makeStroked({width:o.strokeWidth*(e.alignment==="center"?1:2),join:e.join==="round"?a.StrokeJoin.Round:e.join==="bevel"?a.StrokeJoin.Bevel:a.StrokeJoin.Miter,cap:e.cap==="round"?a.StrokeCap.Round:e.cap==="square"?a.StrokeCap.Square:a.StrokeCap.Butt,miter_limit:e.miterLimit});if(!i||e.alignment==="center")return i;try{const s=a.Path.MakeFromOp(i,t,e.alignment==="inside"?a.PathOp.Intersect:a.PathOp.Difference);if(!s)throw new Error("Could not construct the aligned stroke.");return s}finally{i.delete()}}finally{n==null||n.delete()}}const wt=a=>a==="Arial"?"Arial":`Editor ${a}`;var _t="/assets/dm-sans-latin-wght-normal-Xz1IZZA0.woff2",Gt="/assets/dm-sans-latin-wght-italic-Cz4n9dED.woff2",Yt="/assets/space-grotesk-latin-wght-normal-BhU9QXUp.woff2",$t="/assets/lora-latin-wght-normal-BiLcIKcI.woff2",Vt="/assets/lora-latin-wght-italic-DBI-iqMr.woff2",jt="/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2",Jt="/assets/ibm-plex-mono-latin-700-normal-7sUh57Bg.woff2",
1Kt="/assets/ibm-plex-mono-latin-400-italic-BqAiT5Ww.woff2",Zt="/assets/ibm-plex-mono-latin-700-italic-J6kahdQd.woff2",Qt="/assets/canvaskit-SCAxUyCS.wasm",te="/assets/Inter-Regular-Bgz_edWN.ttf",ee="/assets/Inter-Bold-B7mUoIuP.ttf",oe="/assets/Inter-RegularItalic-Vyr2d_q1.ttf",ae="/assets/Inter-BoldItalic-Cn4L1aoe.ttf",ne="/assets/NotoSansCJKsc-Regular-DxgKpThH.otf",ie="/assets/NotoColorEmoji-DsYfJ5Xi.ttf",se="/assets/NotoSansArabic-Regular-CszAr9CM.ttf";const D=["Editor Noto CJK","Editor Noto Arabic","Editor Noto Emoji"];let Mt=0;const H=()=>Mt,it="Editor Inter";let _,G;function tt(){return _??(_=import("./canvaskit-CEd3iVQw.js").then(function(a){return a.c}).then(({default:a})=>a({locateFile:()=>Qt})).catch(a=>{throw _=void 0,a})),_}function et(){return G??(G=(async()=>{const a=await tt(),t=[{url:te,weight:"400",style:"normal"},{url:ee,weight:"700",style:"normal"},{url:oe,weight:"400",style:"italic"},{url:ae,weight:"700",style:"italic"}],o=await Promise.all(t.map(async({url:n})=>{const i=await fetch(n);if(!i.ok)throw new Error(`Could not load editor font (${i.status}).`);return i.arrayBuffer()})),e=a.TypefaceFontProvider.Make();try{return o.forEach(n=>e.registerFont(n,it)),typeof FontFace<"u"&&typeof document<"u"&&(await Promise.all(o.map((i,s)=>new FontFace(it,i,{weight:t[s].weight,style:t[s].style}).load()))).forEach(i=>document.fonts.add(i)),e}catch(n){throw e.delete(),n}})().catch(a=>{throw G=void 0,a})),G}const Y=new Map;async function W(a,t,o={}){let e=Y.get(t);e||(e=(async()=>{const n=await et(),i=await fetch(t);if(!i.ok)throw new Error(`Could not load ${a} (${i.status}).`);const s=await i.arrayBuffer();if(n.registerFont(s,a),typeof FontFace<"u")try{const l=typeof document<"u"?document.fonts:globalThis.fonts;l==null||l.add(await new FontFace(a,s,o).load())}catch{}Mt+=1})().catch(n=>{throw Y.delete(t),n}),Y.set(t,e)),await e}async function re(a){const t=a.layers.filter(i=>i.kind==="text").map(i=>i.text).join(""),o=[],e=new Set(a.layers.filter(i=>i.kind==="text").map(i=>i.fontFamily)),n={"DM Sans":[{url:_t,weight:"100 1000"},{url:Gt,weight:"100 1000",style:"italic"}],"Space Grotesk":[{url:Yt,weight:"300 700"}],Lora:[{url:$t,weight:"400 700"},{url:Vt,weight:"400 700",style:"italic"}],"IBM Plex Mono":[{url:jt,weight:"400"},{url:Jt,weight:"700"},{url:Kt,weight:"400",style:"italic"},{url:Zt,weight:"700",style:"italic"}]};for(const i of e)for(const s of n[i]??[])o.push(W(wt(i),s.url,{weight:s.weight,style:s.style??"normal"}));/[\u1100-\u11ff\u2e80-\u9fff\uac00-\ud7af\uf900-\ufaff\uff00-\uffef\u{20000}-\u{3134f}]/u.test(t)&&o.push(W(D[0],ne)),/[\u0600-\u06ff\u0750-\u077f\u0860-\u08ff\ufb50-\ufdff\ufe70-\ufeff]/u.test(t)&&o.push(W(D[1],se)),new RegExp("\\p{Extended_Pictographic}|\\p{Regional_Indicator}|[\\ufe0f\\u20e3]","u").test(t)&&o.push(W(D[2],ie)),await Promise.all(o)}const st=a=>{const t=Intl.Segmenter;if(t)return Array.from(new t(void 0,{granularity:"grapheme"}).segment(a));let o=0;return Array.from(a,e=>{const n={index:o,segment:e};return o+=e.length,n})};class rt{constructor(t,o){w(this,"image");w(this,"lines",[]);w(this,"glyphs",[]);w(this,"surface");w(this,"ctx");w(this,"height");if(this.kit=t,this.layer=o,this.surface=typeof OffscreenCanvas<"u"?new OffscreenCanvas(1,1):document.createElement("canvas"),this.ctx=this.surface.getContext("2d"),!this.ctx)throw new Error("Text rendering is unavailable.");const e=`${o.italic?"italic ":""}${o.fontWeight==="bold"?700:400} ${o.fontSize}px Arial, sans-serif`;this.ctx.font=e;const n=o.fontSize*1.2,i=Math.max(1,o.width),s=st(o.text),l=(g,m,x)=>{const k=this.ctx.measureText(g),b=k.width,y=o.align==="right"?i-b:o.align==="center"?(i-b)/2:0,E=this.ctx.measureText("Mg"),v=E.fontBoundingBoxAscent||o.fontSize*.9,P=E.fontBoundingBoxDescent||o.fontSize*.2,A=this.lines.length*n,B=A+(n-v-P)/2+v;this.lines.push({startIndex:m,endIndex:x,left:y,width:b,baseline:B,ascent:v,descent:P,height:n,text:g});const Tt=st(g);for(const L of Tt){const Ct=y+this.ctx.measureText(g.slice(0,L.index)).width,Et=y+this.ctx.measureText(g.slice(0,L.index+L.segment.length)).width;this.glyphs.push({start:m+L.index,end:m+L.index+L.segment.length,rect:new Float32Array([Ct,A,Et,A+n])})}};let r=0,f="",c=0;for(const g of s){if(g.segment===` 2`){l(f,r,g.index+1),r=g.index+1,f="",c=r;continue}f&&this.ctx.measureText(f+g.segment).width>i&&(l(f,r,g.index),r=g.index,f=""),f+=g.segment,c=g.index+g.segment.length}l(f,r,c),this.height=this.lines.length*n;const d=Math.ceil(o.fontSize),h=i+d*2,u=this.height+d*2,p=Math.min(2,8192/h,8192/u,Math.sqrt(16777216/(h*u)));
2this.surface.width=Math.max(1,Math.ceil(h*p)),this.surface.height=Math.max(1,Math.ceil(u*p)),this.ctx.scale(p,p),this.ctx.translate(d,d),this.ctx.font=e,this.ctx.fillStyle=/^(none|transparent)$/i.test(o.color.trim())?"transparent":o.color,this.ctx.textBaseline="alphabetic";for(const g of this.lines)this.ctx.fillText(g.text,g.left,g.baseline),o.underline&&this.ctx.fillRect(g.left,g.baseline+Math.max(1,o.fontSize*.08),g.width,Math.max(1,o.fontSize*.05))}getHeight(){return this.height}getLongestLine(){return Math.max(0,...this.lines.map(t=>t.width))}getLineMetrics(){return this.lines}unresolvedCodepoints(){return[]}getGlyphInfoAt(t){const o=this.glyphs.find(e=>t>=e.start&&t<e.end);return o?{graphemeLayoutBounds:o.rect,dir:this.kit.TextDirection.LTR}:null}getGlyphPositionAtCoordinate(t,o){var s;const e=this.lines[Math.min(this.lines.length-1,Math.max(0,Math.floor(o/(this.layer.fontSize*1.2))))],n=this.glyphs.filter(l=>l.start>=e.startIndex&&l.start<e.endIndex),i=n.find(l=>t<(l.rect[0]+l.rect[2])/2);return{pos:(i==null?void 0:i.start)??((s=n.at(-1))==null?void 0:s.end)??e.startIndex}}getRectsForRange(t,o,e,n){return this.glyphs.filter(i=>i.end>t&&i.start<o).map(i=>({rect:i.rect,dir:this.kit.TextDirection.LTR}))}draw(t){this.image??(this.image=this.kit.MakeImageFromCanvasImageSource(this.surface));const o=Math.ceil(this.layer.fontSize),e=new this.kit.Paint;try{t.drawImageRect(this.image,this.kit.XYWHRect(0,0,this.image.width(),this.image.height()),this.kit.XYWHRect(-o,-o,Math.max(1,this.layer.width)+o*2,this.height+o*2),e)}finally{e.delete()}}delete(){var t;(t=this.image)==null||t.delete(),this.image=void 0,this.surface.width=1,this.surface.height=1}}class le{constructor(t,o){w(this,"entries",new Map);this.kit=t,this.fonts=o}paragraph(t){const o=JSON.stringify([H(),t.text,t.width,t.fontFamily,t.fontSize,t.fontWeight,t.italic,t.underline,t.align,t.color]),e=this.entries.get(t.id);if((e==null?void 0:e.key)===o)return e.paragraph;if(e==null||e.paragraph.delete(),t.fontFamily==="Arial"){const l=new rt(this.kit,t);return this.entries.set(t.id,{key:o,paragraph:l}),l}const n=this.kit,i={fontFamilies:[wt(t.fontFamily),...D],fontSize:t.fontSize,color:/^(transparent|none)$/i.test(t.color.trim())?new Float32Array(n.TRANSPARENT):n.parseColorString(t.color),fontStyle:{weight:t.fontWeight==="bold"?n.FontWeight.Bold:n.FontWeight.Normal,slant:t.italic?n.FontSlant.Italic:n.FontSlant.Upright},decoration:t.underline?n.UnderlineDecoration:n.NoDecoration,heightMultiplier:1.2,halfLeading:!0},s=n.ParagraphBuilder.MakeFromFontProvider(new n.ParagraphStyle({textStyle:i,textAlign:t.align==="center"?n.TextAlign.Center:t.align==="right"?n.TextAlign.Right:n.TextAlign.Left,applyRoundingHack:!1}),this.fonts);try{s.addText(t.text||"â");const l=s.build();return l.layout(Math.max(1,t.width)),this.entries.set(t.id,{key:o,paragraph:l}),l}finally{s.delete()}}draw(t,o){const e=this.paragraph(o);e instanceof rt?e.draw(t):t.drawParagraph(e,0,0)}hitTest(t,o,e){return Math.max(0,Math.min(t.text.length,this.paragraph(t).getGlyphPositionAtCoordinate(o,e).pos))}caret(t,o,e="downstream"){const n=this.paragraph(t),i=Math.max(0,Math.min(t.text.length,o));if(e==="upstream"&&i>0&&t.text[i-1]!==` 3`){const f=n.getGlyphInfoAt(i-1);if(f){const c=f.graphemeLayoutBounds;return{x:f.dir===this.kit.TextDirection.RTL?c[0]:c[2],y:c[1],height:Math.max(1,c[3]-c[1])}}}const s=i<t.text.length?n.getGlyphInfoAt(i):null;if(s){const f=s.graphemeLayoutBounds;return{x:s.dir===this.kit.TextDirection.RTL?f[2]:f[0],y:f[1],height:Math.max(1,f[3]-f[1])}}const l=n.getLineMetrics(),r=l[l.length-1];if(i>0&&t.text[i-1]!==` 4`){const f=n.getGlyphInfoAt(i-1);if(f){const c=f.graphemeLayoutBounds;return{x:f.dir===this.kit.TextDirection.RTL?c[0]:c[2],y:c[1],height:Math.max(1,c[3]-c[1])}}}return{x:(r==null?void 0:r.left)??0,y:r?r.baseline-r.ascent:0,height:(r==null?void 0:r.height)??t.fontSize*1.2}}navigate(t,o,e,n,i){const s=this.paragraph(t),l=this.caret(t,o,i),r=s.getLineMetrics(),f=Math.max(0,r.findIndex(m=>l.y+l.height/2<m.baseline+m.descent)),c=r[f],d=n??l.x;if(!c)return{index:0,x:d,affinity:"downstream"};const h=m=>{let x=Math.min(t.text.length,m.endIndex);for(;x>m.startIndex&&/[\r\n]/.test(t.text[x-1]);)x--;return x};if(e==="home")return{index:c.startIndex,x:d,affinity:"downstream"};if(e==="end")return{index:h(c),x:d,affinity:"upstream"};const u=f+(e==="up"?-1:1);if(u<0)return{index:0,x:d,affinity:"downstream"};if(u>=r.length)return{index:t.text.length,x:d,affinity:"upstream"};const p=r[u],g=Math.max(p.startIndex,Math.min(h(p),this.hitTest(t,d,p.baseline-p.ascent/2)));return{index:g,x:d,affinity:g===h(p)?"upstream":"downstream"}}
4retain(t){for(const[o,e]of this.entries)t.has(o)||(e.paragraph.delete(),this.entries.delete(o))}dispose(){for(const t of this.entries.values())t.paragraph.delete();this.entries.clear()}}const K=1e3,lt=12,fe=16e3,ce=28,he=140,de=["","px","%","°","x","s"],me=/^[a-z][A-Za-z0-9]{0,23}$/,St=/^#[0-9a-f]{6}([0-9a-f]{2})?$/i,ue=new Set(["iImage","iResolution","iTime","iPixel","main","effect","sampleImage","sampleUV","toUV","luma","hash12","hash22","noise","fbm","rotate2d","rgb2hsv","hsv2rgb","bayer2","bayer4","bayer8","blendScreen","blendOverlay","blendSoftLight","palette","blurImage","edgeStrength","PI","TAU","float","float2","float3","float4","half","half2","half3","half4","int","int2","int3","int4","bool","vec2","vec3","vec4","mat2","mat3","mat4","float2x2","float3x3","float4x4","shader","uniform","const","in","out","inout","if","else","for","while","do","break","continue","return","true","false","discard","struct","switch","case","default","layout","highp","mediump","lowp","sin","cos","tan","mix","step","clamp","min","max","abs","floor","fract","mod","pow","exp","log","sqrt","length","distance","dot","cross","normalize","smoothstep","sign","ceil","atan","asin","acos","radians","degrees","saturate","unpremul","color"]),pe=` 5const float PI = 3.14159265; 6const float TAU = 6.28318531; 7float2 toUV(float2 p) { return p / iResolution; } 8float4 sampleImage(float2 p) { return float4(unpremul(iImage.eval(p))); } 9float4 sampleUV(float2 uv) { return sampleImage(uv * iResolution); } 10float luma(float3 c) { return dot(c, float3(0.2126, 0.7152, 0.0722)); } 11float hash12(float2 p) { 12 float3 q = fract(float3(p.xyx) * 0.1031); 13 q += dot(q, q.yzx + 33.33); 14 return fract((q.x + q.y) * q.z); 15} 16float2 hash22(float2 p) { 17 float3 q = fract(float3(p.xyx) * float3(0.1031, 0.1030, 0.0973)); 18 q += dot(q, q.yzx + 33.33); 19 return fract((q.xx + q.yz) * q.zy); 20} 21float noise(float2 p) { 22 float2 i = floor(p); 23 float2 f = fract(p); 24 float2 u = f * f * (3.0 - 2.0 * f); 25 return mix(mix(hash12(i), hash12(i + float2(1.0, 0.0)), u.x), 26 mix(hash12(i + float2(0.0, 1.0)), hash12(i + float2(1.0, 1.0)), u.x), u.y); 27} 28float fbm(float2 p) { 29 float value = 0.0; 30 float amplitude = 0.5; 31 for (int i = 0; i < 5; i++) { 32 value += amplitude * noise(p); 33 p = p * 2.03 + float2(17.0, 9.0); 34 amplitude *= 0.5; 35 } 36 return value; 37} 38float2x2 rotate2d(float angle) { 39 float s = sin(angle); 40 float c = cos(angle); 41 return float2x2(c, s, -s, c); 42} 43float3 rgb2hsv(float3 c) { 44 float4 k = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 45 float4 p = mix(float4(c.bg, k.wz), float4(c.gb, k.xy), step(c.b, c.g)); 46 float4 q = mix(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r)); 47 float d = q.x - min(q.w, q.y); 48 return float3(abs(q.z + (q.w - q.y) / (6.0 * d + 0.0001)), d / (q.x + 0.0001), q.x); 49} 50float3 hsv2rgb(float3 c) { 51 float3 p = abs(fract(c.xxx + float3(1.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0); 52 return c.z * mix(float3(1.0), clamp(p - 1.0, 0.0, 1.0), c.y); 53} 54float bayer2(float2 a) { a = floor(a); return fract(dot(a, float2(0.5, a.y * 0.75))); } 55float bayer4(float2 a) { return bayer2(0.5 * a) * 0.25 + bayer2(a); } 56float bayer8(float2 a) { return bayer4(0.5 * a) * 0.25 + bayer2(a); } 57float3 blendScreen(float3 a, float3 b) { return 1.0 - (1.0 - a) * (1.0 - b); } 58float3 blendOverlay(float3 a, float3 b) { 59 return mix(2.0 * a * b, 1.0 - 2.0 * (1.0 - a) * (1.0 - b), step(0.5, a)); 60} 61float3 blendSoftLight(float3 a, float3 b) {
62 return mix(2.0 * a * b + a * a * (1.0 - 2.0 * b), sqrt(a) * (2.0 * b - 1.0) + 2.0 * a * (1.0 - b), step(0.5, b)); 63} 64float3 palette(float t, float3 a, float3 b, float3 c, float3 d) { return a + b * cos(TAU * (c * t + d)); } 65float4 blurImage(float2 p, float radius) { 66 float4 sum = float4(0.0); 67 float total = 0.0; 68 for (int x = -3; x <= 3; x++) { 69 for (int y = -3; y <= 3; y++) { 70 float2 o = float2(float(x), float(y)); 71 float w = exp(-dot(o, o) / 8.0); 72 sum += w * sampleImage(p + o * radius / 3.0); 73 total += w; 74 } 75 } 76 return sum / total; 77} 78float edgeStrength(float2 p, float radius) { 79 float tl = luma(sampleImage(p + float2(-radius, -radius)).rgb); 80 float t = luma(sampleImage(p + float2(0.0, -radius)).rgb); 81 float tr = luma(sampleImage(p + float2(radius, -radius)).rgb); 82 float l = luma(sampleImage(p + float2(-radius, 0.0)).rgb); 83 float r = luma(sampleImage(p + float2(radius, 0.0)).rgb); 84 float bl = luma(sampleImage(p + float2(-radius, radius)).rgb); 85 float b = luma(sampleImage(p + float2(0.0, radius)).rgb); 86 float br = luma(sampleImage(p + float2(radius, radius)).rgb); 87 float gx = -tl - 2.0 * l - bl + tr + 2.0 * r + br; 88 float gy = -tl - 2.0 * t - tr + bl + 2.0 * b + br; 89 return sqrt(gx * gx + gy * gy); 90} 91`,Z=(a,t,o)=>{if(typeof a!="string"||!a.trim())throw new Error(`The effect ${o} is missing.`);return a.trim().replace(/\s+/g," ").slice(0,t)},q=(a,t)=>{const o=typeof a=="string"&&a.trim()?Number(a):a;if(typeof o!="number"||!Number.isFinite(o))throw new Error(`The effect setting â${t}â has an invalid number.`);return o},ge=(a,t,o)=>Number((t+Math.round((a-t)/o)*o).toFixed(6));function xe(a){if(!Array.isArray(a))throw new Error("The effect settings are invalid.");if(a.length>lt)throw new Error(`An effect can have at most ${lt} settings.`);const t=new Set;return a.map(o=>{const e=typeof(o==null?void 0:o.key)=="string"?o.key.trim():"";if(!me.test(e)||ue.has(e)||t.has(e))throw new Error(`The effect setting â${e||"?"}â has an invalid name.`);t.add(e);const n=Z(o.label,24,"setting label");if(o.kind==="number"){const i=q(o.min,n),s=q(o.max,n);if(!(s>i)||s-i>1e6)throw new Error(`The effect setting â${n}â has an invalid range.`);let l=q(o.step??(s-i)/100,n);(!(l>0)||l>s-i)&&(l=(s-i)/100);const r=de.includes(o.unit??"")&&o.unit||void 0,f=Math.min(s,Math.max(i,q(o.default??i,n)));return{kind:"number",key:e,label:n,min:i,max:s,step:l,default:ge(f,i,l),...r?{unit:r}:{}}}if(o.kind==="color"){if(typeof o.default!="string"||!St.test(o.default.trim()))throw new Error(`The effect setting â${n}â needs a hex color.`);return{kind:"color",key:e,label:n,default:o.default.trim().toUpperCase()}}if(o.kind==="toggle")return{kind:"toggle",key:e,label:n,default:o.default===!0};if(o.kind==="select"){const i=Array.isArray(o.options)?o.options.map(l=>Z(l,16,"option")):[];if(i.length<2||i.length>8||new Set(i).size!==i.length)throw new Error(`The effect setting â${n}â needs 2â8 distinct options.`);const s=Number.isInteger(o.default)&&o.default>=0&&o.default<i.length?o.default:0;return{kind:"select",key:e,label:n,options:i,default:s}}throw new Error(`The effect setting â${n}â has an unsupported type.`)})}const ke=/\b(half4|float4|vec4)\s+effect\s*\(\s*(float2|vec2)\s+[A-Za-z_]\w*\s*\)/;function be(a){if(typeof a!="string"||!a.trim())throw new Error("The effect has no shader code.");const t=a.replace(/\r\n?/g,` 92`).trim();if(new TextEncoder().encode(t).length>fe)throw new Error("The effect shader is too long.");if(!ke.test(t))throw new Error("The effect shader must define half4 effect(float2 p).");if(/\buniform\b|\bmain\s*\(|#\s*(define|include|version|extension|pragma)/.test(t))throw new Error("The effect shader declares reserved inputs.");return t}function ye(a){return{name:Z(a==null?void 0:a.name,ce,"name"),description:typeof(a==null?void 0:a.description)=="string"?a.description.trim().replace(/\s+/g," ").slice(0,he):"",code:be(a==null?void 0:a.code),params:xe((a==null?void 0:a.params)??[])}}const we=a=>/\biTime\b/.test(a.code),Me=a=>a.kind==="color"?"half4":"float";function Se(a){return`uniform shader iImage; 93uniform float2 iResolution; 94uniform float iTime; 95uniform float iPixel; 96${a.params.map(o=>`uniform ${Me(o)} ${o.key};`).join(` 97`)} 98${pe} 99${a.code} 100half4 main(float2 p) { 101 half4 color = clamp(half4(effect(p)), half4(0.0), half4(1.0));
102 return half4(color.rgb * color.a, color.a); 103} 104`}function Ie(a,t={}){const o={};for(const e of a){const n=t[e.key];if(e.kind==="number"){const i=typeof n=="number"&&Number.isFinite(n)?n:e.default;o[e.key]=Math.min(e.max,Math.max(e.min,i))}else e.kind==="color"?o[e.key]=typeof n=="string"&&St.test(n)?n.toUpperCase():e.default:e.kind==="toggle"?o[e.key]=typeof n=="boolean"?n:e.default:o[e.key]=typeof n=="number"&&Number.isInteger(n)&&n>=0&&n<e.options.length?n:e.default}return o}function ve(a){const t=a.replace("#",""),o=e=>parseInt(t.slice(e,e+2),16)/255;return[o(0),o(2),o(4),t.length===8?o(6):1]}function Q(a,t){const o=Math.max(1,Math.min(a,t));return[a/o*K,t/o*K]}function Te(a,t,o,e){if(a==="iResolution")return Q(e.width,e.height);if(a==="iTime")return[e.time];if(a==="iPixel")return[K/Math.max(1,Math.min(e.width,e.height))/Math.max(1e-6,e.scale)];const n=t.find(s=>s.key===a);if(!n)return[0];const i=o[a]??n.default;return n.kind==="color"?ve(String(i)):n.kind==="toggle"?[i===!0?1:0]:[Number(i)||0]}class U extends Error{constructor(t){super(t),this.name="EffectCompileError"}}const z=new Map,Ce=48;function Ee(a,t){var l;const o=Se(t),e=z.get(o);if(e){if(z.delete(o),z.set(o,e),e instanceof U)throw e;return e}let n="";const s=a.RuntimeEffect.Make(o,r=>n=r)??new U(((l=n.split(` 105`).find(r=>r.startsWith("error:")))==null?void 0:l.replace(/^error:\s*\d*:?\s*/,""))??"The shader could not be compiled.");for(z.set(o,s);z.size>Ce;){const[r,f]=z.entries().next().value;f instanceof U||f.delete(),z.delete(r)}if(s instanceof U)throw s;return s}function Pe(a,t,o,e){const n=new Float32Array(a.getUniformFloatCount());for(let i=0;i<a.getUniformCount();i+=1){const s=a.getUniform(i).slot;Te(a.getUniformName(i),t.params,o,e).forEach((l,r)=>n[s+r]=l)}return n}const C={halftoneInk:"#151515",halftonePaper:"#F3F0E8",ditherShadow:"#1D1E3A",ditherHighlight:"#EDEAE0",asciiInk:"#E9E7E1",asciiBackground:"#0C0C0E",mapShadows:"#1B1236",mapMidtones:"#C93F7A",mapHighlights:"#FFE2B0",risoPink:"#FF4FA3",risoBlue:"#1F6FD0",risoPaper:"#F3EEE3",mosaicBackground:"#0D0D0F"},Re={id:"halftone",name:"Halftone",description:"Print-style dots, lines or squares sized by tone.",params:[{kind:"number",key:"cellSize",label:"Cell size",min:3,max:60,step:.5,default:12},{kind:"number",key:"angle",label:"Angle",min:0,max:90,step:1,default:45,unit:"°"},{kind:"select",key:"shape",label:"Shape",options:["Dots","Lines","Squares","Diamonds"],default:0},{kind:"number",key:"dotScale",label:"Dot size",min:30,max:160,step:1,default:100,unit:"%"},{kind:"number",key:"contrast",label:"Contrast",min:50,max:250,step:1,default:115,unit:"%"},{kind:"color",key:"ink",label:"Ink",default:C.halftoneInk},{kind:"color",key:"paper",label:"Paper",default:C.halftonePaper},{kind:"toggle",key:"sourceColor",label:"Full color",default:!1},{kind:"toggle",key:"invert",label:"Invert",default:!1}],code:` 106half4 effect(float2 p) { 107 float cell = max(cellSize, 1.0); 108 float a = radians(angle); 109 float2 q = rotate2d(a) * p; 110 float2 id = floor(q / cell); 111 float2 local = q - (id + 0.5) * cell; 112 float2 center = rotate2d(-a) * ((id + 0.5) * cell); 113 float4 src = sampleImage(center) * 0.4 114 + sampleImage(center + float2(cell * 0.25, 0.0)) * 0.15 115 + sampleImage(center - float2(cell * 0.25, 0.0)) * 0.15 116 + sampleImage(center + float2(0.0, cell * 0.25)) * 0.15 117 + sampleImage(center - float2(0.0, cell * 0.25)) * 0.15; 118 float tone = clamp((luma(src.rgb) - 0.5) * (contrast / 100.0) + 0.5, 0.0, 1.0); 119 if (invert > 0.5) tone = 1.0 - tone; 120 float cover = clamp(1.0 - tone, 0.0, 1.0); 121 float aa = iPixel * 0.75; 122 float d = 0.0; 123 float r = 0.0; 124 if (shape < 0.5) { d = length(local); r = sqrt(cover) * 0.7071 * cell * (dotScale / 100.0); } 125 else if (shape < 1.5) { d = abs(local.y); r = cover * 0.5 * cell * (dotScale / 100.0); } 126 else if (shape < 2.5) { d = max(abs(local.x), abs(local.y)); r = sqrt(cover) * 0.5 * cell * (dotScale / 100.0); } 127 else { d = abs(local.x) + abs(local.y); r = sqrt(cover) * 0.7071 * cell * (dotScale / 100.0); } 128 float inside = 1.0 - smoothstep(r - aa, r + aa, d); 129 float3 inkColor = sourceColor > 0.5 ? src.rgb : float3(ink.rgb); 130 float3 color = mix(float3(paper.rgb), inkColor, inside * ink.a); 131 return float4(color, sampleImage(p).a); 132}`},Fe={id:"dither",name:"Dither",description:"Ordered dithering in two tones or reduced color.",params:[{kind:"select",key:"mode",label:"Mode",options:["Two-tone","Color"],default:0},{kind:"select",key:"pattern",label:"Pattern",options:["Bayer 4Ã4","Bayer 8Ã8","Noise"],default:1},{kind:"number",key:"pixelSize",label:"Pixel size",min:1,max:16,step:.5,default:3},{kind:"number",key:"levels",label:"Levels",min:2,max:8,step:1,default:2},{kind:"number",key:"contrast",label:"Contrast",min:50,max:250,step:1,default:110,unit:"%"},{kind:"number",key:"brightness",label:"Brightness",min:-50,max:50,step:1,default:0,unit:"%"},{kind:"color",key:"shadow",label:"Shadow",default:C.ditherShadow},{kind:"color",key:"highlight",label:"Highlight",default:C.ditherHighlight}],code:` 133half4 effect(float2 p) { 134 float size = max(pixelSize, 1.0); 135 float2 cell = floor(p / size); 136 float4 src = sampleImage((cell + 0.5) * size); 137 float t = pattern < 0.5 ? bayer4(cell) : pattern < 1.5 ? bayer8(cell) : hash12(cell); 138 float3 c = clamp((src.rgb - 0.5) * (contrast / 100.0) + 0.5 + (brightness / 100.0), 0.0, 1.0); 139 float n = max(floor(levels) - 1.0, 1.0); 140 if (mode < 0.5) { 141 float q = clamp(floor(luma(c) * n + t) / n, 0.0, 1.0); 142 return float4(mix(float3(shadow.rgb), float3(highlight.rgb), q), src.a); 143 } 144 return float4(clamp(floor(c * n + t) / n, 0.0, 1.0), src.a); 145}`},Ae={id:"ascii",name:"ASCII",description:"Rebuilds the image from characters.",params:[{kind:"number",key:"cellSize",label:"Cell size",min:4,max:40,step:.5,default:12},{kind:"select",key:"colorMode",label:"Color",options:["Source","Ink"],default:0},{kind:"color",key:"ink",label:"Ink",default:C.asciiInk}
145,{kind:"color",key:"background",label:"Background",default:C.asciiBackground},{kind:"number",key:"contrast",label:"Contrast",min:50,max:250,step:1,default:125,unit:"%"},{kind:"toggle",key:"invert",label:"Invert",default:!1}],code:` 146float glyph(float n, float2 g) { 147 g = floor(g * float2(-4.0, 4.0) + 2.5); 148 if (g.x < 0.0 || g.x > 4.0 || g.y < 0.0 || g.y > 4.0) return 0.0; 149 float bit = g.x + 5.0 * g.y; 150 return mod(floor(n / exp2(bit)), 2.0); 151} 152half4 effect(float2 p) { 153 float size = max(cellSize, 2.0); 154 float2 cell = floor(p / size); 155 float4 src = sampleImage((cell + 0.5) * size); 156 float tone = clamp((luma(src.rgb) - 0.5) * (contrast / 100.0) + 0.5, 0.0, 1.0); 157 if (invert > 0.5) tone = 1.0 - tone; 158 float n = 0.0; 159 if (tone > 0.1) n = 4096.0; 160 if (tone > 0.22) n = 65600.0; 161 if (tone > 0.34) n = 332772.0; 162 if (tone > 0.46) n = 15255086.0; 163 if (tone > 0.58) n = 23385164.0; 164 if (tone > 0.7) n = 15252014.0; 165 if (tone > 0.8) n = 13199452.0; 166 if (tone > 0.9) n = 11512810.0; 167 float2 g = (p / size - cell) * 2.0 - 1.0; 168 float on = glyph(n, g * 0.7); 169 float3 inkColor = colorMode < 0.5 ? src.rgb * 1.15 : float3(ink.rgb); 170 return float4(mix(float3(background.rgb), inkColor, on), src.a); 171}`},ze={id:"crt",name:"CRT",description:"Curved glass, scanlines, phosphor mask and glow.",params:[{kind:"number",key:"curvature",label:"Curvature",min:0,max:100,step:1,default:35,unit:"%"},{kind:"number",key:"scanlines",label:"Scanlines",min:0,max:100,step:1,default:55,unit:"%"},{kind:"number",key:"lineCount",label:"Lines",min:120,max:720,step:1,default:320},{kind:"number",key:"mask",label:"Phosphor",min:0,max:100,step:1,default:30,unit:"%"},{kind:"number",key:"bleed",label:"Bleed",min:0,max:100,step:1,default:30,unit:"%"},{kind:"number",key:"glow",label:"Glow",min:0,max:100,step:1,default:35,unit:"%"},{kind:"number",key:"vignette",label:"Vignette",min:0,max:100,step:1,default:50,unit:"%"},{kind:"number",key:"roll",label:"Roll",min:0,max:100,step:1,default:25,unit:"%"}],code:` 172half4 effect(float2 p) { 173 float2 uv = toUV(p); 174 float2 c = uv * 2.0 - 1.0; 175 c *= 1.0 + (curvature / 100.0) * 0.12 * dot(c, c); 176 float2 screen = c * 0.5 + 0.5; 177 float edge = min(min(screen.x, 1.0 - screen.x), min(screen.y, 1.0 - screen.y)); 178 float frame = smoothstep(0.0, 0.004 + iPixel / iResolution.y, edge); 179 float2 sp = screen * iResolution; 180 float offset = (bleed / 100.0) * 4.0; 181 float3 col = float3(sampleImage(sp + float2(offset, 0.0)).r, sampleImage(sp).g, sampleImage(sp - float2(offset, 0.0)).b); 182 col += blurImage(sp, 14.0).rgb * (glow / 100.0) * 0.55; 183 float period = iResolution.y / lineCount; 184 float lineFade = smoothstep(1.5, 3.0, period / iPixel); 185 float scan = 0.5 + 0.5 * cos(screen.y * lineCount * TAU); 186 col *= mix(1.0, 0.35 + 0.65 * scan, (scanlines / 100.0) * lineFade); 187 float stripe = fract(sp.x / 3.0); 188 float3 phosphor = float3(step(stripe, 0.333), step(0.333, stripe) * step(stripe, 0.666), step(0.666, stripe)); 189 float maskFade = smoothstep(1.0, 2.0, 1.0 / iPixel); 190 col *= mix(float3(1.0), 0.55 + phosphor * 0.9, (mask / 100.0) * maskFade); 191 float band = fract(screen.y - iTime * 0.12); 192 col *= 1.0 + (roll / 100.0) * 0.18 * exp(-pow((band - 0.5) * 7.0, 2.0)); 193 float v = pow(clamp(16.0 * screen.x * screen.y * (1.0 - screen.x) * (1.0 - screen.y), 0.0, 1.0), (vignette / 100.0) * 0.6); 194 col *= v * 1.08; 195 return float4(col * frame, 1.0); 196}`},Le={id:"gradient-map",name:"Gradient map",description:"Maps tones to a three-color gradient.",params:[{kind:"color",key:"shadows",label:"Shadows",default:C.mapShadows},{kind:"color",key:"midtones",label:"Midtones",default:C.mapMidtones},{kind:"color",key:"highlights",label:"Highlights",default:C.mapHighlights},{kind:"number",key:"midpoint",label:"Midpoint",min:5,max:95,step:1,default:50,unit:"%"},{kind:"number",key:"contrast",label:"Contrast",min:50,max:250,step:1,default:100,unit:"%"},{kind:"number",key:"intensity",label:"Intensity",min:0,max:100,step:1,default:100,unit:"%"}],code:` 197half4 effect(float2 p) { 198 float4 src = sampleImage(p); 199 float t = clamp((luma(src.rgb) - 0.5) * (contrast / 100.0) + 0.5, 0.0, 1.0);
200 float m = clamp((midpoint / 100.0), 0.05, 0.95); 201 float3 low = mix(float3(shadows.rgb), float3(midtones.rgb), smoothstep(0.0, 1.0, t / m)); 202 float3 high = mix(float3(midtones.rgb), float3(highlights.rgb), smoothstep(0.0, 1.0, (t - m) / (1.0 - m))); 203 float3 mapped = t < m ? low : high; 204 return float4(mix(src.rgb, mapped, intensity / 100.0), src.a); 205}`},Be={id:"risograph",name:"Risograph",description:"Two grainy inks, slightly out of register.",params:[{kind:"color",key:"inkOne",label:"Ink 1",default:C.risoPink},{kind:"color",key:"inkTwo",label:"Ink 2",default:C.risoBlue},{kind:"color",key:"paper",label:"Paper",default:C.risoPaper},{kind:"number",key:"shift",label:"Offset",min:0,max:16,step:.1,default:4},{kind:"number",key:"grain",label:"Grain",min:0,max:100,step:1,default:65,unit:"%"},{kind:"number",key:"grainSize",label:"Grain size",min:.5,max:4,step:.05,default:1.1},{kind:"number",key:"contrast",label:"Contrast",min:50,max:250,step:1,default:115,unit:"%"}],code:` 206float inkCoverage(float density, float2 p, float seed) { 207 float threshold = mix(0.5, noise(p / max(grainSize, 0.1) + seed) * 0.8 + hash12(floor(p / max(grainSize, 0.1)) + seed) * 0.2, (grain / 100.0)); 208 return smoothstep(threshold - 0.08, threshold + 0.08, density); 209} 210half4 effect(float2 p) { 211 float2 dir = normalize(float2(1.0, 0.6)); 212 float4 a = sampleImage(p + dir * shift); 213 float4 b = sampleImage(p - dir * shift); 214 float3 ca = clamp((a.rgb - 0.5) * (contrast / 100.0) + 0.5, 0.0, 1.0); 215 float3 cb = clamp((b.rgb - 0.5) * (contrast / 100.0) + 0.5, 0.0, 1.0); 216 float densityOne = clamp(1.0 - ca.g * 0.8 - ca.b * 0.2, 0.0, 1.0); 217 float densityTwo = clamp(1.0 - cb.r * 0.75 - cb.g * 0.25, 0.0, 1.0); 218 float one = inkCoverage(densityOne, p, 3.1); 219 float two = inkCoverage(densityTwo, p, 11.7); 220 float3 color = float3(paper.rgb); 221 color *= mix(float3(1.0), float3(inkOne.rgb), one * inkOne.a); 222 color *= mix(float3(1.0), float3(inkTwo.rgb), two * inkTwo.a); 223 float fiber = (noise(p * 0.35) - 0.5) * 0.04; 224 return float4(color + fiber, sampleImage(p).a); 225}`},Ne={id:"film",name:"Film",description:"Grain, halation, faded blacks and warmth.",params:[{kind:"number",key:"grain",label:"Grain",min:0,max:100,step:1,default:40,unit:"%"},{kind:"number",key:"grainSize",label:"Grain size",min:.5,max:4,step:.05,default:1.2},{kind:"number",key:"halation",label:"Halation",min:0,max:100,step:1,default:45,unit:"%"},{kind:"number",key:"fade",label:"Fade",min:0,max:100,step:1,default:30,unit:"%"},{kind:"number",key:"warmth",label:"Warmth",min:-100,max:100,step:1,default:25,unit:"%"},{kind:"number",key:"vignette",label:"Vignette",min:0,max:100,step:1,default:35,unit:"%"},{kind:"toggle",key:"animateGrain",label:"Animate",default:!0}],code:` 226half4 effect(float2 p) { 227 float4 src = sampleImage(p); 228 float3 c = src.rgb; 229 float3 soft = blurImage(p, 22.0).rgb; 230 float glow = smoothstep(0.55, 1.0, luma(soft)); 231 c += float3(1.0, 0.32, 0.12) * glow * (halation / 100.0) * 0.45; 232 c = c * (1.0 - (fade / 100.0) * 0.14) + (fade / 100.0) * float3(0.075, 0.065, 0.08); 233 c *= float3(1.0 + (warmth / 100.0) * 0.08, 1.0 + (warmth / 100.0) * 0.015, 1.0 - (warmth / 100.0) * 0.09); 234 float frame = animateGrain > 0.5 ? floor(iTime * 24.0) : 0.0; 235 float2 g = p / max(grainSize, 0.1) + frame * float2(37.1, 17.3); 236 float n = (noise(g) + noise(g * 1.7 + 5.2)) * 0.5 - 0.5; 237 float l = luma(c); 238 c += n * (grain / 100.0) * 0.32 * (0.35 + 0.65 * (1.0 - abs(l - 0.5) * 2.0)); 239 float2 v = toUV(p) - 0.5; 240 c *= clamp(1.0 - dot(v, v) * (vignette / 100.0) * 1.5, 0.0, 1.0); 241 return float4(c, src.a); 242}`},We={id:"chromatic",name:"Chromatic",description:"Prism-like color fringing, radial or directional.",params:[{kind:"number",key:"strength",label:"Strength",min:0,max:60,step:.5,default:20},{kind:"select",key:"direction",label:"Direction",options:["Radial","Linear"],default:0},{kind:"number",key:"angle",label:"Angle",min:0,max:360,step:1,default:0,unit:"°"},{kind:"number",key:"falloff",label:"Falloff",min:.5,max:3,step:.01,default:1.2}],code:` 243half4 effect(float2 p) { 244 float2 center = iResolution * 0.5; 245 float2 d = p - center; 246 float r = length(d) / length(center); 247 float2 dir = direction < 0.5 ? normalize(d + 0.0001) * pow(r, falloff) : float2(cos(radians(angle)), sin(radians(angle))); 248 float3 sum = float3(0.0); 249 float3 weights = float3(0.0); 250 float alpha = 0.0; 251 for (int i = 0; i < 9; i++) { 252 float t = float(i) / 8.0; 253 float3 w = clamp(float3(1.0 - abs(t - 0.0) * 2.2, 1.0 - abs(t - 0.5) * 2.2, 1.0 - abs(t - 1.0) * 2.2), 0.0, 1.0); 254 float4 s = sampleImage(p + dir * strength * (t - 0.5) * 2.0); 255 sum += s.rgb * w; 256 weights += w; 257 alpha += s.a / 9.0; 258 } 259 return float4(sum / weights, alpha); 260}`},qe={id:"pixelate",name:"Pixelate",description:"Square, hexagonal or LED mosaics.",params:[{kind:"number",key:"size",label:"Size",min:2,max:100,step:.5,default:18},{kind:"select",key:"shape",label:"Shape",options:["Squares","Hexagons","LEDs"],default:0},{kind:"number",key:"gap",label:"Gap",min:0,max:50,step:1,default:0,unit:"%"},{kind:"number",key:"colors",label:"Colors",min:2,max:64,step:1,default:64}
260,{kind:"color",key:"background",label:"Background",default:C.mosaicBackground}],code:` 261half4 effect(float2 p) { 262 float s = max(size, 1.0); 263 float2 center = float2(0.0); 264 float d = 0.0; 265 if (shape > 0.5 && shape < 1.5) { 266 float2 ratio = float2(1.0, 1.7320508); 267 float2 q = p / s; 268 float2 a = mod(q, ratio) - ratio * 0.5; 269 float2 b = mod(q - ratio * 0.5, ratio) - ratio * 0.5; 270 float2 g = dot(a, a) < dot(b, b) ? a : b; 271 center = (q - g) * s; 272 float2 h = abs(g); 273 d = max(dot(h, normalize(float2(1.0, 1.7320508))), h.x) * 2.0; 274 } else { 275 float2 cell = floor(p / s); 276 center = (cell + 0.5) * s; 277 float2 local = (p - center) / s; 278 d = shape < 0.5 ? max(abs(local.x), abs(local.y)) * 2.0 : length(local) * 2.0; 279 } 280 float4 src = (sampleImage(center) * 2.0 + sampleImage(center + float2(s * 0.25, s * 0.25)) 281 + sampleImage(center - float2(s * 0.25, s * 0.25))) / 4.0; 282 float n = max(colors - 1.0, 1.0); 283 float3 col = colors < 63.5 ? floor(src.rgb * n + 0.5) / n : src.rgb; 284 float limit = shape > 1.5 ? 0.86 - (gap / 100.0) : 1.0 - (gap / 100.0); 285 float aa = iPixel / s * 2.0; 286 float inside = shape < 1.5 && (gap / 100.0) < 0.001 ? 1.0 : 1.0 - smoothstep(limit - aa, limit + aa, d); 287 return float4(mix(float3(background.rgb), col, inside), src.a); 288}`},Ue={id:"glitch",name:"Glitch",description:"Displaced slices, split channels and corrupted blocks.",params:[{kind:"number",key:"amount",label:"Amount",min:0,max:100,step:1,default:45,unit:"%"},{kind:"number",key:"displacement",label:"Offset",min:0,max:200,step:1,default:60},{kind:"number",key:"split",label:"RGB split",min:0,max:40,step:.5,default:8},{kind:"number",key:"bands",label:"Bands",min:4,max:80,step:1,default:24},{kind:"number",key:"blocks",label:"Blocks",min:0,max:100,step:1,default:40,unit:"%"},{kind:"number",key:"speed",label:"Speed",min:0,max:300,step:1,default:100,unit:"%"}],code:` 289half4 effect(float2 p) { 290 float2 uv = toUV(p); 291 float t = floor(iTime * (speed / 100.0) * 10.0); 292 float band = floor(uv.y * bands + hash12(float2(t, 9.0)) * 3.0); 293 float r = hash12(float2(band, t + 1.3)); 294 float active = step(1.0 - (amount / 100.0) * 0.55, r); 295 float shift = active * (hash12(float2(band * 1.7, t + 4.1)) - 0.5) * 2.0 * displacement; 296 float2 q = p + float2(shift, 0.0); 297 float s = split * (0.5 + active * 1.5); 298 float4 mid = sampleImage(q); 299 float3 col = float3(sampleImage(q + float2(s, 0.0)).r, mid.g, sampleImage(q - float2(s, 0.0)).b); 300 float2 block = floor(p / float2(90.0, 22.0)); 301 float corrupt = step(1.0 - (blocks / 100.0) * (amount / 100.0) * 0.22, hash12(block + t * 7.3)); 302 float2 jump = (hash22(block + t) - 0.5) * float2(420.0, 120.0); 303 float3 moved = sampleImage(p + jump).rgb; 304 col = mix(col, moved.brg * 1.05, corrupt); 305 float tear = step(0.996 - (amount / 100.0) * 0.004, hash12(float2(floor(p.y / 3.0), t))); 306 col = mix(col, col * 0.4 + 0.5, tear * 0.5); 307 return float4(col, mid.a); 308}`},De={id:"ripple",name:"Ripple",description:"Concentric waves moving out from a point.",params:[{kind:"number",key:"amplitude",label:"Amplitude",min:0,max:40,step:.5,default:10},{kind:"number",key:"wavelength",label:"Wavelength",min:10,max:300,step:1,default:90},{kind:"number",key:"speed",label:"Speed",min:0,max:300,step:1,default:100,unit:"%"},{kind:"number",key:"reach",label:"Reach",min:10,max:200,step:1,default:90,unit:"%"},{kind:"number",key:"centerX",label:"Center X",min:0,max:100,step:1,default:50,unit:"%"},{kind:"number",key:"centerY",label:"Center Y",min:0,max:100,step:1,default:50,unit:"%"},{kind:"number",key:"shine",label:"Shine",min:0,max:100,step:1,default:30,unit:"%"}],code:` 309half4 effect(float2 p) { 310 float2 center = iResolution * float2(centerX, centerY) / 100.0; 311 float2 d = p - center; 312 float dist = length(d); 313 float phase = dist / max(wavelength, 1.0) * TAU - iTime * (speed / 100.0) * TAU; 314 float wave = sin(phase); 315 float atten = exp(-dist / ((reach / 100.0) * 1000.0)); 316 float2 offset = normalize(d + 0.0001) * wave * amplitude * atten; 317 float4 col = sampleImage(p + offset); 318 col.rgb += (shine / 100.0) * 0.18 * cos(phase) * atten; 319 return col; 320}`},He={id:"thermal",name:"Thermal",description:"Heat camera, night vision or X-ray looks.",params:[{kind:"select",key:"look",label:"Look",options:["Thermal","Night vision","X-ray"],default:0},{kind:"number",key:"contrast",label:"Contrast",min:50,max:250,step:1,default:120,unit:"%"},{kind:"number",key:"shift",label:"Shift",min:-50,max:50,step:1,default:0,unit:"%"},{kind:"number",key:"noiseAmount",label:"Noise",min:0,max:100,step:1,default:20,unit:"%"}],code:` 321float3 heat(float t) { 322 float3 c = mix(float3(0.0, 0.0, 0.02), float3(0.23, 0.06, 0.44), smoothstep(0.0, 0.2, t)); 323 c = mix(c, float3(0.55, 0.16, 0.51), smoothstep(0.2, 0.4, t)); 324 c = mix(c, float3(0.87, 0.29, 0.41), smoothstep(0.4, 0.55, t)); 325 c = mix(c, float3(0.99, 0.62, 0.43), smoothstep(0.55, 0.72, t)); 326 c = mix(c, float3(0.99, 0.91, 0.5), smoothstep(0.72, 0.88, t)); 327 return mix(c, float3(1.0), smoothstep(0.88, 1.0, t)); 328} 329half4 effect(float2 p) { 330 float4 src = sampleImage(p); 331 float grainValue = (hash12(floor(p / 1.5)) - 0.5) * (noiseAmount / 100.0) * 0.25; 332 float t = clamp((luma(blurImage(p, 3.0).rgb) - 0.5) * (contrast / 100.0) + 0.5 + (shift / 100.0) + grainValue, 0.0, 1.0); 333 float3 col = heat(t); 334 if (look > 0.5 && look < 1.5) { 335 float2 v = toUV(p) - 0.5; 336 col = float3(0.1, 1.0, 0.25) * (pow(t, 1.2) * 1.1 + 0.04) * clamp(1.2 - dot(v, v) * 2.2, 0.0, 1.0); 337 } else if (look > 1.5) { 338 float x = 1.0 - t; 339 col = mix(float3(0.02, 0.05, 0.1), float3(0.78, 0.9, 1.0), pow(x, 1.4)); 340 } 341 return float4(col, src.a); 342}`},Oe=[Re,Fe,Ae,ze,Le,Be,Ne,We,qe,Ue,De,He],Xe=a=>Oe.find(t=>
342t.id===a),$=new WeakMap;function _e(a){if(!a||typeof a!="object")return null;if($.has(a))return $.get(a)??null;let t=null;try{t=ye(a)}catch{t=null}return $.set(a,t),t}function Ge(a){if(!a)return;const t=a.origin==="template"?Xe(a.id):_e(a.program);if(t)return{program:t,values:Ie(t.params,a.values),animated:we(t)}}const ft=.6;class Ye extends Error{}async function $e(a,t){const o=t.startsWith("https://firebasestorage.googleapis.com")?[t,t.replace("https://firebasestorage.googleapis.com","/firebase-storage")]:[t];let e;for(const n of o)try{const i=await fetch(n);if(!i.ok)throw new Error(`Image request failed (${i.status}).`);const s=await i.arrayBuffer(),l=a.MakeImageFromEncoded(s);if(l)return l;if(typeof createImageBitmap<"u"&&typeof OffscreenCanvas<"u"){const r=await createImageBitmap(new Blob([s],{type:i.headers.get("content-type")||"image/png"}));try{const c=new OffscreenCanvas(r.width,r.height).getContext("2d");if(!c)throw new Error("Image conversion canvas unavailable.");c.drawImage(r,0,0);const d=c.getImageData(0,0,r.width,r.height),h=a.MakeImage({width:r.width,height:r.height,colorType:a.ColorType.RGBA_8888,alphaType:a.AlphaType.Unpremul,colorSpace:a.ColorSpace.SRGB},d.data,r.width*4);if(h)return h}finally{r.close()}}throw new Error("The image could not be decoded.")}catch(i){e=i}try{if(typeof window>"u")throw e;const n=new window.Image;return n.crossOrigin="anonymous",n.src=t,await n.decode(),a.MakeImageFromCanvasImageSource(n)}catch{throw e instanceof Error?e:new Error("Could not load the source image.")}}function R(a,t,o=1){const e=new a.Paint;e.setAntiAlias(!0);const n=typeof t=="string"?/^(transparent|none)$/i.test(t.trim())?new Float32Array(a.TRANSPARENT):a.parseColorString(t):new Float32Array(t);return n[3]*=Math.max(0,Math.min(1,o)),e.setColor(n),e}function ct(a,t){a.translate(t.x+t.width/2,t.y+t.height/2),a.rotate(t.rotation,0,0),a.scale(t.flipX?-1:1,t.flipY?-1:1),a.translate(-t.width/2,-t.height/2)}function Ve(a,t){return a.Matrix.multiply(a.Matrix.translated(t.x+t.width/2,t.y+t.height/2),a.Matrix.rotated(t.rotation*Math.PI/180),a.Matrix.scaled(t.flipX?-1:1,t.flipY?-1:1),a.Matrix.translated(-t.width/2,-t.height/2))}function ht(a){return Math.sqrt(Math.abs(a[0]*a[4]-a[1]*a[3]))||1}function V(a,t,o,e){const n=R(a,a.WHITE);n.setBlendMode(a.BlendMode.DstOut),n.setStyle(a.PaintStyle.Stroke),n.setStrokeCap(a.StrokeCap.Round),n.setStrokeJoin(a.StrokeJoin.Round),n.setStrokeWidth(2);try{for(const i of o){const s=Math.max(.001,i.radiusX),l=Math.max(.001,i.radiusY);if(!i.points.length)continue;let r=e.get(i.id);if(!r||r.points!==i.points||r.count!==i.points.length){const f=r&&r.rx===s&&r.ry===l&&r.count<i.points.length&&r.points.every((u,p)=>u===i.points[p]),c=f?r.count:0,d=f?r.builder:new a.PathBuilder;r==null||r.path.delete(),f||r==null||r.builder.delete();for(let u=c;u<i.points.length;u++){const p=i.points[u];u===0?d.moveTo(p.x/s,p.y/l):d.lineTo(p.x/s,p.y/l)}const h=d.snapshot();r={count:i.points.length,points:i.points,path:h,builder:d,rx:s,ry:l},e.set(i.id,r)}t.save(),t.scale(s,l),i.points.length===1?(n.setStyle(a.PaintStyle.Fill),t.drawCircle(i.points[0].x/s,i.points[0].y/l,1,n),n.setStyle(a.PaintStyle.Stroke)):t.drawPath(r.path,n),t.restore()}}finally{n.delete()}}class It{constructor(t,o,e,n=()=>{},i=()=>{}){w(this,"text");w(this,"maskCheckpoints");w(this,"disposed",!1);w(this,"fontRevision",H());w(this,"glyphKey","");w(this,"images",new Map);w(this,"paths",new Map);w(this,"strokes",new Map);w(this,"brushPaths",new Map);w(this,"maskPaths",new Map);w(this,"videoFrames",new Map);this.kit=t,this.invalidate=e,this.fontsChanged=n,this.missingGlyphs=i,this.text=new le(t,o),this.maskCheckpoints=new Ht(t)}async prepare(t){var e;const o=new Set;for(const n of t.layers)n.kind==="image"&&(o.add(n.assetId),(e=n.mask)!=null&&e.assetId&&o.add(n.mask.assetId));if(await Promise.all([re(t),...[...o].filter(n=>{var i;return!((i=t.assets[n])!=null&&i.mimeType.startsWith("video/"))}).map(n=>this.image(t,n))]),!this.disposed&&H()!==this.fontRevision&&(this.fontRevision=H(),this.fontsChanged(),this.invalidate()),!this.disposed){const n=t.layers.filter(s=>s.kind==="text"),i=JSON.stringify([this.fontRevision,...n.map(s=>[s.text,s.fontWeight,s.italic])]);if(i!==this.glyphKey){this.glyphKey=i;const s=new Set(n.flatMap(l=>
342this.text.paragraph(l).unresolvedCodepoints()));this.missingGlyphs([...s])}}}updateVideoFrames(t,o){var n,i,s;const e=new Set;for(const l of t.layers){if(l.kind!=="image"||!((n=t.assets[l.assetId])!=null&&n.mimeType.startsWith("video/")))continue;const r=l.assetId;e.add(r);const f=o==null?void 0:o(r);if(!f||f.readyState<2||!f.videoWidth)continue;const c=this.videoFrames.get(r);if((c==null?void 0:c.source)===f&&c.time===f.currentTime&&c.width===f.videoWidth&&c.height===f.videoHeight)continue;const d=this.kit.MakeImageFromCanvasImageSource(f);d&&((s=(i=this.images.get(r))==null?void 0:i.image)==null||s.delete(),this.images.set(r,{url:t.assets[r].url,image:d,promise:Promise.resolve(d)}),this.videoFrames.set(r,{source:f,time:f.currentTime,width:f.videoWidth,height:f.videoHeight}))}for(const l of this.videoFrames.keys())e.has(l)||this.videoFrames.delete(l)}image(t,o){var s;const e=t.assets[o];if(!e)return Promise.reject(new Error(`Missing editor image asset: ${o}`));const n=this.images.get(o);if((n==null?void 0:n.url)===e.url)return n.promise;(s=n==null?void 0:n.image)==null||s.delete();const i={url:e.url,promise:$e(this.kit,e.url).then(l=>{if(this.disposed||this.images.get(o)!==i)throw l.delete(),new Ye("Image load was superseded.");return i.image=l,this.invalidate(),l}).catch(l=>{throw this.images.get(o)===i&&this.images.delete(o),l})};return this.images.set(o,i),i.promise}stroke(t,o){var s;const e=JSON.stringify([t.strokeEnabled,t.strokeWidth,t.strokeStyle]),n=this.strokes.get(t.id);if((n==null?void 0:n.key)===e&&n.source===o)return n.path;(s=n==null?void 0:n.path)==null||s.delete();const i=Xt(this.kit,o,t);return this.strokes.set(t.id,{key:e,source:o,path:i}),i}hitTest(t,o,e=0){if(!t.visible||t.opacity<=0)return!1;if(t.kind!=="shape")return Dt(t,o,e);const n=kt(t,o),i=this.shape(t),s=r=>{if(r.contains(n.x,n.y))return!0;if(!e)return!1;const f=r.makeStroked({width:e*2,join:this.kit.StrokeJoin.Round});try{return(f==null?void 0:f.contains(n.x,n.y))??!1}finally{f==null||f.delete()}};if(O(t.fill)&&s(t.network?this.shape(t,!0):i))return!0;const l=t.strokeEnabled!==!1&&t.strokeWidth>0&&O(t.stroke)?this.stroke(t,i):null;return!!l&&s(l)}shape(t,o=!1){const e=JSON.stringify([t.shape,t.width,t.height,t.radius,t.count,t.ratio]),n=t.id+(o?"/fill":""),i=this.paths.get(n);if((i==null?void 0:i.key)===e&&i.network===t.network)return i.path;i==null||i.path.delete();const s=new this.kit.PathBuilder;for(const r of o&&t.network?At(t.network):bt(t))r.op==="M"?s.moveTo(r.x,r.y):r.op==="L"?s.lineTo(r.x,r.y):r.op==="C"?s.cubicTo(r.c1x,r.c1y,r.c2x,r.c2y,r.x,r.y):s.close();const l=s.detach();return o&&t.network&&l.setFillType(this.kit.FillType.EvenOdd),s.delete(),this.paths.set(n,{key:e,path:l,network:t.network}),l}drawImage(t,o,e,n){var r,f,c,d;const i=(r=this.images.get(e.assetId))==null?void 0:r.image;if(!i)return;const s=this.kit,l=s.XYWHRect(0,0,e.width,e.height);if((f=e.mask)!=null&&f.assetId||(c=e.mask)!=null&&c.strokes.length){o.saveLayer(n,l),o.drawImageRectOptions(i,s.XYWHRect(0,0,i.width(),i.height()),l,s.FilterMode.Linear,s.MipmapMode.None);const h=e.mask.assetId?(d=this.images.get(e.mask.assetId))==null?void 0:d.image:void 0,u=this.maskCheckpoints.get(e,h,(g,m)=>V(s,g,m,this.maskPaths)),p=u??h;if(p){const g=R(s,s.WHITE);g.setBlendMode(s.BlendMode.DstIn),o.drawImageRectOptions(p,s.XYWHRect(0,0,p.width(),p.height()),l,s.FilterMode.Linear,s.MipmapMode.None,g),g.delete()}o.save(),o.scale(e.width/Math.max(1,e.naturalWidth),e.height/Math.max(1,e.naturalHeight)),V(s,o,u?e.mask.strokes.slice(-1):e.mask.strokes,this.maskPaths),o.restore(),o.restore()}else o.drawImageRectOptions(i,s.XYWHRect(0,0,i.width(),i.height()),l,s.FilterMode.Linear,s.MipmapMode.None,n)}activeShaders(t){var o;return(((o=t.effects)==null?void 0:o.shaders)??[]).flatMap(e=>{if(!e.visible)return[];const n=Ge(e.effect);return n?[n]:[]})}surfaceLike(t,o,e){const n=this.kit;return t.makeSurface({width:o,height:e,alphaType:n.AlphaType.Premul,colorType:n.ColorType.RGBA_8888,colorSpace:n.ColorSpace.SRGB})}compositeFor(t,o){if(!t.layers.some(n=>n.visible&&n.opacity>0&&at(n)&&this.activeShaders(n).length))return null;const e=o.getDeviceClipBounds();return e[0]!==0||e[1]!==0||e[2]<=0||e[3]<=0?null:this.surfaceLike(o,e[2],e[3])}effectShader(t,o,e,n,i){const s=this.kit,l=Ee(s,t.program),r=o.makeShaderOptions(s.TileMode.Clamp,s.TileMode.Clamp,s.FilterMode.Linear,s.MipmapMode.None,e);try{return l.makeShaderWithChildren(Pe(l,t.program,t.values,i),[r],n)}finally{r.delete()}}chain(t,o,e,n,i,s){const l=this.kit;let r=o;for(const f of e.slice(0,-1)){const c=this.surfaceLike(t,r.width(),r.height());if(!c)break;const d=new l.Paint,h=this.effectShader(f,r,i,n,s);
342try{d.setShader(h),d.setBlendMode(l.BlendMode.Src),c.getCanvas().drawRect(l.XYWHRect(0,0,r.width(),r.height()),d),c.flush();const u=c.makeImageSnapshot();r!==o&&r.delete(),r=u}finally{d.delete(),h.delete(),c.delete()}}return r}drawShaded(t,o,e,n,i,s,l,r){const f=this.kit,c=o.getDeviceClipBounds(),d=c[2]-c[0],h=c[3]-c[1],u=o.getTotalMatrix(),[p,g]=Q(e.width,e.height),m=f.Matrix.scaled(e.width/p,e.height/g),x=f.Matrix.multiply(f.Matrix.translated(-c[0],-c[1]),u,m),k=f.Matrix.invert(x),b=d>0&&h>0&&k?this.surfaceLike(o,d,h):null;if(!b||!k){d>0&&h>0&&this.drawContent(t,o,e,i,s,l,r);return}const y=R(f,f.WHITE);let E=null,v=null,P=null;try{const A=b.getCanvas();A.clear(f.TRANSPARENT),A.translate(-c[0],-c[1]),A.concat(u),this.drawContent(t,A,{...e,opacity:1},y,s,l,r),b.flush(),E=b.makeImageSnapshot();const B={width:e.width,height:e.height,time:ft,scale:ht(u)};v=this.chain(o,E,n,x,k,B),P=this.effectShader(n[n.length-1],v,k,m,B),i.setShader(P),o.drawRect(f.XYWHRect(0,0,e.width,e.height),i)}catch{this.drawContent(t,o,e,i,s,l,r)}finally{i.setShader(null),P==null||P.delete(),v&&v!==E&&v.delete(),E==null||E.delete(),y.delete(),b.delete()}}drawBackdrop(t,o,e,n){const i=this.kit,s=this.activeShaders(n);if(!s.length)return;const l=o.getTotalMatrix(),r=t.artboard,[f,c]=Q(r.width,r.height),d=i.Matrix.multiply(i.Matrix.translated(r.x,r.y),i.Matrix.scaled(r.width/f,r.height/c)),h=i.Matrix.multiply(l,d),u=i.Matrix.invert(h),p=i.Matrix.invert(Ve(i,n));if(!u||!p)return;e.flush();const g=e.makeImageSnapshot(),m=R(i,i.WHITE,n.opacity);let x=null,k=null;try{const b={width:r.width,height:r.height,time:ft,scale:ht(l)};x=this.chain(o,g,s,h,u,b),k=this.effectShader(s[s.length-1],x,u,d,b),m.setShader(k),o.save();try{ct(o,n),n.kind==="shape"?o.clipPath(this.shape(n),i.ClipOp.Intersect,!0):o.clipRect(i.XYWHRect(0,0,n.width,n.height),i.ClipOp.Intersect,!0),o.concat(p),o.drawRect(i.XYWHRect(r.x,r.y,r.width,r.height),m)}finally{o.restore()}}catch{}finally{k==null||k.delete(),m.delete(),x&&x!==g&&x.delete(),g.delete()}}drawContent(t,o,e,n,i,s,l){var f;const r=this.kit;if(e.kind==="shape"){const c=this.shape(e),d=this.stroke(e,c);if(e.opacity<1){const u=c.getBounds(),p=(d==null?void 0:d.getBounds())??u,g=[Math.min(u[0],p[0]),Math.min(u[1],p[1]),Math.max(u[2],p[2]),Math.max(u[3],p[3])],m=e.strokeWidth*2+1/Math.max(.001,i.zoom*s);o.saveLayer(n,r.LTRBRect(g[0]-m,g[1]-m,g[2]+m,g[3]+m))}const h=nt(r,e.fill,e.width,e.height);try{o.drawPath(e.network?this.shape(e,!0):c,h)}finally{h.delete()}if(d){const u=nt(r,e.stroke,e.width,e.height);try{o.drawPath(d,u)}finally{u.delete()}}e.opacity<1&&o.restore()}else if(e.kind==="image")this.drawImage(t,o,e,n);else if(e.kind==="text"){const c=this.text.paragraph(e),d=((f=l.textSelection)==null?void 0:f.layerId)===e.id?l.textSelection:null;if(d&&d.start!==d.end){const h=R(r,Lt[5],.375);for(const{rect:u}of c.getRectsForRange(Math.min(d.start,d.end),Math.max(d.start,d.end),r.RectHeightStyle.Max,r.RectWidthStyle.Tight))o.drawRect(u,h);h.delete()}if(e.opacity<1){const h=Math.max(1,e.fontSize),u=Math.max(e.width,c.getLongestLine()),p=Math.max(e.height,c.getHeight());o.saveLayer(n,r.LTRBRect(-h,-h,u+h,p+h))}if(this.text.draw(o,e),e.opacity<1&&o.restore(),d&&d.start===d.end&&d.caretVisible!==!1){const h=this.text.caret(e,d.end,d.affinity),u=R(r,e.color);u.setStrokeWidth(1/Math.max(.001,i.zoom)),o.drawLine(h.x,h.y,h.x,h.y+h.height,u),u.delete()}}else if(e.kind==="brush"&&e.points.length){const c=R(r,e.color,e.opacity);c.setStyle(r.PaintStyle.Stroke),c.setStrokeCap(r.StrokeCap.Round),c.setStrokeJoin(r.StrokeJoin.Round),c.setStrokeWidth(e.size);let d=this.brushPaths.get(e.id);if(!d||d.points!==e.points){d==null||d.path.delete();const u=new r.PathBuilder;e.points.forEach((p,g)=>g===0?u.moveTo(p.x,p.y):u.lineTo(p.x,p.y)),d={points:e.points,path:u.detach()},u.delete(),this.brushPaths.set(e.id,d)}const h=d.path;e.points.length===1?(c.setStyle(r.PaintStyle.Fill),o.drawCircle(e.points[0].x,e.points[0].y,e.size/2,c)):o.drawPath(h,c),c.delete()}}draw(t,o,e,n,i={}){var h,u,p,g;const s=this.kit,l=this.compositeFor(t,o),r=l?l.getCanvas():o;if(l&&o.clear(s.TRANSPARENT),r.clear(s.TRANSPARENT),r.save(),r.scale(n,n),r.translate(e.x,e.y),r.scale(e.zoom,e.zoom),i.clipArtboard!==!1){const{x:m,y:x,width:k,height:b}=i.previewArtboard??t.artboard;r.clipRect(s.XYWHRect(m,x,k,b),s.ClipOp.Intersect,!0)}if(t.background){const{x:m,y:x,width:k,height:b}=i.previewArtboard??t.artboard,y=R(s,t.background);try{r.drawRect(s.XYWHRect(m,x,k,b),y)}finally{y.delete()}}
342for(const m of t.layers){if(!m.visible||m.opacity<=0)continue;if(at(m)){l&&this.drawBackdrop(t,r,l,m);continue}r.save(),ct(r,m);const x=R(s,s.WHITE,m.opacity);let k=null,b=null;if((h=m.effects)!=null&&h.shadow){const y=m.effects.shadow;k=s.ImageFilter.MakeDropShadow(y.x,y.y,y.blur/2,y.blur/2,s.parseColorString(y.color),null)}if((u=m.effects)!=null&&u.blur){const y=s.ImageFilter.MakeBlur(m.effects.blur/2,m.effects.blur/2,s.TileMode.Decal,k);k==null||k.delete(),k=y}k&&(b=R(s,s.WHITE),b.setImageFilter(k),k.delete(),r.saveLayer(b));try{const y=this.activeShaders(m);y.length?this.drawShaded(t,r,m,y,x,e,n,i):this.drawContent(t,r,m,x,e,n,i)}finally{b&&(r.restore(),b.delete()),x.delete(),r.restore()}}if(r.restore(),l){l.flush();const m=l.makeImageSnapshot();try{o.drawImage(m,0,0,null)}finally{m.delete(),l.delete()}}const f=new Set(t.layers.flatMap(m=>[m.id,m.id+"/fill"]));this.text.retain(f),this.maskCheckpoints.retain(f);for(const[m,x]of this.paths)f.has(m)||(x.path.delete(),this.paths.delete(m));for(const[m,x]of this.strokes)f.has(m)||((p=x.path)==null||p.delete(),this.strokes.delete(m));for(const[m,x]of this.brushPaths)f.has(m)||(x.path.delete(),this.brushPaths.delete(m));const c=new Set(t.layers.flatMap(m=>{var x;return m.kind==="image"?((x=m.mask)==null?void 0:x.strokes.map(k=>k.id))??[]:[]}));for(const[m,x]of this.maskPaths)c.has(m)||(x.path.delete(),x.builder.delete(),this.maskPaths.delete(m));const d=new Set(t.layers.flatMap(m=>{var x;return m.kind==="image"?[m.assetId,(x=m.mask)==null?void 0:x.assetId]:[]}));for(const[m,x]of this.images)d.has(m)||((g=x.image)==null||g.delete(),this.images.delete(m))}async bakeMask(t,o){var l,r;if(!((l=o.mask)!=null&&l.assetId)&&!((r=o.mask)!=null&&r.strokes.length))return null;const e=this.kit,n=Math.max(1,Math.round(o.naturalWidth)),i=Math.max(1,Math.round(o.naturalHeight)),s=e.MakeSurface(n,i);if(!s)throw new Error("Could not allocate the image mask.");try{const f=s.getCanvas();if(f.clear(e.WHITE),o.mask.assetId){const c=await this.image(t,o.mask.assetId);f.clear(e.TRANSPARENT),f.drawImageRectOptions(c,e.XYWHRect(0,0,c.width(),c.height()),e.XYWHRect(0,0,n,i),e.FilterMode.Linear,e.MipmapMode.None)}return V(e,f,o.mask.strokes,this.maskPaths),s.flush(),vt(e,s)}finally{s.dispose()}}dispose(){var t,o;this.disposed=!0;for(const e of this.images.values())(t=e.image)==null||t.delete();for(const e of this.paths.values())e.path.delete();for(const e of this.maskPaths.values())e.path.delete(),e.builder.delete();for(const e of this.brushPaths.values())e.path.delete();this.images.clear(),this.paths.clear();for(const e of this.strokes.values())(o=e.path)==null||o.delete();this.strokes.clear(),this.maskPaths.clear(),this.brushPaths.clear(),this.text.dispose(),this.maskCheckpoints.dispose()}}function vt(a,t){const o=t.makeImageSnapshot();try{const e=o.encodeToBytes(a.ImageFormat.PNG);if(!e)throw new Error("Could not encode the editor PNG.");return new Blob([new Uint8Array(e)],{type:"image/png"})}finally{o.delete()}}async function je(a){const[t,o]=await Promise.all([tt(),et()]),e=new It(t,o,()=>{}),n=Math.max(1,Math.round(a.artboard.width)),i=Math.max(1,Math.round(a.artboard.height)),s=t.MakeSurface(n,i);if(!s)throw e.dispose(),new Error("Could not allocate the export image.");try{return await e.prepare(a),e.draw(a,s.getCanvas(),{x:-a.artboard.x,y:-a.artboard.y,zoom:1},1),s.flush(),vt(t,s)}finally{s.dispose(),e.dispose()}}async function Je(a,t){const[o,e]=await Promise.all([tt(),et()]),n=new It(o,e,()=>{});try{return await n.bakeMask(a,t)}finally{n.dispose()}}const j=globalThis;let dt=Promise.resolve();j.onmessage=({data:a})=>{dt=dt.then(async()=>{try{const t=a.operation==="png"?await je(a.document):await Je(a.document,a.layer);j.postMessage({id:a.id,ok:!0,blob:t})}catch(t){j.postMessage({id:a.id,ok:!1,error:t instanceof Error?t.message:"Background image export failed."})}})};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.