asciify-engine 4.6.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/{model-Tyu-NpVf.d.ts → model-CMKdRB30.d.ts} +76 -1
- package/dist/{model-BR3qK_NW.d.cts → model-fP9NdG-w.d.cts} +76 -1
- package/dist/studio.cjs +1 -1
- package/dist/studio.d.cts +168 -5
- package/dist/studio.d.ts +168 -5
- package/dist/studio.js +1 -1
- package/examples/layered-composition.ts +24 -0
- package/examples/studio-composition.ts +4 -7
- package/package.json +2 -1
- package/skills/asciify-engine/SKILL.md +6 -2
- package/skills/asciify-engine/agents/openai.yaml +2 -2
- package/skills/asciify-engine/references/layered-projects.md +89 -0
- package/skills/asciify-engine/references/project-integration.md +1 -0
- package/skills/asciify-engine/references/source-shaping.md +54 -0
- package/skills/asciify-engine/references/studio-workspace.md +5 -1
- package/skills/asciify-engine/references/upgrading.md +8 -0
package/dist/studio.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t=[{value:"none",label:"Off",group:"Still",description:"Keep the artwork still under the pointer."},{value:"trail",label:"Trail",group:"Change characters",description:"A fluid wake changes character density and settles behind your cursor."},{value:"dissolve",label:"Dissolve",group:"Change characters",description:"Erase a soft path through the characters; the image gradually reforms."},{value:"contour",label:"Contour",group:"Change characters",description:"Fine tonal rings trace your path without moving the grid."},{value:"etch",label:"Emboss",group:"Change characters",description:"Press a light-and-shadow impression into the characters; the grid stays fixed."},{value:"water",label:"Water",group:"Move the image",description:"Soft ripples refract the image and settle after your stroke."},{value:"silk",label:"Silk",group:"Move the image",description:"Directional folds follow the movement of your hand."},{value:"vortex",label:"Vortex",group:"Move the image",description:"A swirling wake curls through the image."},{value:"magnetic",label:"Magnetic Pull",group:"Move the image",description:"The image gathers toward your stroke, then relaxes."},{value:"scatter",label:"Scatter",group:"Move the image",description:"A textured outward scatter settles behind your cursor."},{value:"elastic",label:"Elastic",group:"Move the image",description:"Push the image with your stroke; it recoils and springs back into place."},{value:"rake",label:"Rake",group:"Move the image",description:"Comb the image into alternating ribbons that glide back into alignment."}],e=[{value:"none",mode:"none",group:"Still",label:"Off",description:"Keep the image still. Hover stays available."},{value:"caustics",mode:"caustics",group:"Light and texture",label:"Caustics",description:"Soft ribbons of light travel across a stationary character grid."},{value:"current",mode:"current",group:"Flow and depth",label:"Slow Current",description:"A gentle flow through the image, with steady edges."},{value:"reform",mode:"reform",group:"Rebuild",label:"Reveal & Reform",description:"Disperse, gather, then hold the complete image."},{value:"sheen",mode:"sheen",group:"Light and texture",label:"Sheen",description:"A broad diagonal light sweep; characters stay anchored."},{value:"tidal",mode:"tidal",group:"Flow and depth",label:"Tidal Rings",description:"Concentric currents travel outward, with protected edges."},{value:"grain",mode:"grain",group:"Light and texture",label:"Living Grain",description:"Slow, individually phased tonal changes on a stationary grid."},{value:"parallax",mode:"parallax",group:"Flow and depth",label:"Parallax",description:"A shallow, continuous drift through the image, with the edges held in place."},{value:"weave",mode:"weave",group:"Flow and depth",label:"Woven Flow",description:"Interlaced bands move in opposing directions, like a flexible printed fabric."},{value:"print",mode:"print",group:"Rebuild",label:"Print Shift",description:"Staggered rows lift, soften and register back into the image."},{value:"trace",mode:"trace",group:"Light and texture",label:"Contour Light",description:"Light follows the source image’s tonal contours; every character stays anchored."}],i=t=>Math.max(0,Math.min(1,t)),a=(t,e,a)=>{const s=i((a-t)/(e-t));return s*s*(3-2*s)},s=(t,e)=>{const i=(.06711056*t+.00583715*e)%1*52.9829189;return i-Math.floor(i)},r=class{constructor(){this.last=null,this.mode="none",this.phase=0}update(t,e,i=1){return Number.isFinite(t)?((e!==this.mode||null!==this.last&&t<this.last)&&(this.mode=e,this.phase=0,this.last=t),null!==this.last&&(this.phase+=Math.max(0,t-this.last)*Math.max(.1,Math.min(3,Number.isFinite(i)?i:1))),this.last=t,this.phase):this.phase}};function o(t,e,r,o,n,h=.5){if(n[0]=n[1]=n[2]=0,n[3]=1,"none"===t)return n;const l=o*Math.PI/6,c=a(0,.12,Math.min(e,1-e,r,1-r));if("caustics"===t){const t=Math.sin(9*e+5*r+l)+Math.sin(8*r-3*e-l),i=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);n[2]=(.22*i-.045)*c}else if("current"===t)n[0]=Math.sin(9*r+l)*Math.cos(7*e-l)*10*c,n[1]=Math.cos(8*e+l)*Math.sin(6*r-l)*7*c;else if("sheen"===t)n[2]=.2*Math.pow(.5+.5*Math.cos(5*e+3*r-l),8)-.025;else if("tidal"===t){const t=e-.5,i=r-.5,a=Math.hypot(t,i),s=Math.sin(22*a-l)*c;n[0]=t*s*9,n[1]=i*s*9,n[2]=.035*s}else if("grain"===t){const t=s(Math.floor(160*e),Math.floor(100*r))*Math.PI*2;n[2]=.07*Math.sin(l+t)}else if("parallax"===t){const t=.45+.55*Math.max(0,1-1.4*Math.hypot(e-.5,r-.5));n[0]=12*Math.sin(l)*t*c,n[1]=6*(Math.cos(l)-1)*t*c}else if("weave"===t)n[0]=Math.sin(r*Math.PI*6+l)*Math.sin(l)*8*c,n[1]=Math.sin(e*Math.PI*6-l)*Math.sin(l)*6*c;else if("print"===t){const t=Math.floor(24*r),e=((o+3*s(t,3))%12+12)%12,i=a(1,2.5,e)*(1-a(3.5,5,e));n[0]=Math.sin(2.4*t)*i*9*c,n[1]=5*-i*c,n[2]=.22*-i,n[3]=1-.45*i}else if("trace"===t){const t=.5+.5*Math.cos(l);n[2]=.22*Math.pow(Math.max(0,1-Math.abs(i(h)-t)/.16),3)-.015}else if("reform"===t){const t=(o%12+12)%12,i=s(Math.floor(160*e),Math.floor(100*r)),h=.65*e+.2*r+.15*i+.08*Math.sin(8*e-5*r),m=a(1.8+1.2*h,3.8+1.2*h,t)*(1-a(5+1.7*h,7.2+1.7*h,t));n[0]=Math.sin(9*r+l)*m*(1-m)*24*c,n[1]=-m*(1-m)*(8+12*i)*c,n[2]=.45*-m,n[3]=1-.9*m}return n}function n(t,e){const a=Math.max(0,Math.min(2,Number.isFinite(e)?e:1));return t[0]*=a,t[1]*=a,t[2]*=a,t[3]=i(1+(t[3]-1)*a),t}var h=["rgb","red","green","blue"],l=t=>Math.max(0,Math.min(1,t));function c(t){const e=new Map([[0,0],[1,1]]);if(Array.isArray(t))for(const i of t.slice(0,64)){if(!Array.isArray(i)||i.length<2||"number"!=typeof i[0]||!Number.isFinite(i[0])||"number"!=typeof i[1]||!Number.isFinite(i[1]))continue;const t=Math.round(255*l(i[0]))/255;!e.has(t)&&e.size>=16||e.set(t,l(i[1]))}return[...e].sort((t,e)=>t[0]-e[0])}function m(t){const e=t&&"object"==typeof t?t:{};return Object.fromEntries(h.map(t=>[t,c(e[t])]))}function f(t){const e=c(t),i=e.length,a=e.slice(1).map((t,i)=>t[0]-e[i][0]),s=e.slice(1).map((t,i)=>(t[1]-e[i][1])/a[i]),r=new Float64Array(i);r[0]=s[0],r[i-1]=s[i-2];for(let t=1;t<i-1;t++){const e=s[t-1],i=s[t];if(e*i<=0)continue;const o=2*a[t]+a[t-1],n=a[t]+2*a[t-1];r[t]=(o+n)/(o/e+n/i)}const o=new Uint8Array(256);let n=0;for(let t=0;t<256;t++){const s=t/255;for(;n<i-2&&s>e[n+1][0];)n++;const h=a[n],c=(s-e[n][0])/h,m=c*c,f=m*c,d=(2*f-3*m+1)*e[n][1]+(f-2*m+c)*h*r[n]+(-2*f+3*m)*e[n+1][1]+(f-m)*h*r[n+1];o[t]=Math.round(255*l(d))}return o}var d=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk"],u=["none","bayer2","bayer4","bayer8","bayer16","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis","halftone","lines","noise","vertical-lines","diagonal-lines","radial","blue-noise"],g=["source-over","multiply","screen","overlay","soft-light","hard-light","color-dodge","color-burn","hue","saturation","color","luminosity"],p={original:[],gray4:["#000000","#555555","#aaaaaa","#ffffff"],gray8:["#000000","#242424","#494949","#6d6d6d","#929292","#b6b6b6","#dbdbdb","#ffffff"],rgb8:["#000000","#ff0000","#00ff00","#0000ff","#ffff00","#ff00ff","#00ffff","#ffffff"],cyberpunk:["#08081a","#3c1670","#ed299a","#29dfef","#fff7bf"],pastel:["#393448","#a5b4d4","#9ed9c6","#e7aac1","#f5e8be"],mono:["#080808","#f2f2e8"],asciify:["#080808","#625b38","#a19558","#e8b900"],gameboy:["#0f380f","#306230","#8bac0f","#9bbc0f"],cga:["#000000","#55ffff","#ff55ff","#ffffff"],pico8:["#000000","#1d2b53","#7e2553","#008751","#ab5236","#5f574f","#c2c3c7","#fff1e8","#ff004d","#ffa300","#ffec27","#00e436","#29adff","#83769c","#ff77a8","#ffccaa"],c64:["#000000","#ffffff","#880000","#aaffee","#cc44cc","#00cc55","#0000aa","#eeee77","#dd8855","#664400","#ff7777","#333333","#777777","#aaff66","#0088ff","#bbbbbb"],amber:["#100b00","#5f3b00","#c98014","#ffd17c"],ice:["#081b29","#25586e","#69a6b3","#d9ece7"],risograph:["#f4ebd0","#f2594b","#2853a5","#29232e"],sepia:["#201b17","#6b5039","#b49868","#f6e6c5"],nord:["#2e3440","#4c566a","#88c0d0","#eceff4"],dusk:["#211b35","#654271","#c3788c","#f5c9a3"],forest:["#101f1b","#355747","#87a16f","#e4e3ba"],ocean:["#071b33","#17577f","#3fa7a4","#d9efde"],newsprint:["#191919","#666666","#aaaaaa","#eee9df"],custom:["#080808","#e8b900"]},M={version:1,aspectRatio:"original",style:"ascii",cellSize:6,charset:" .:-=+*#%@",colorMode:"accent",ink:"#e8b900",crop:{x:.5,y:.5,zoom:1,rotation:0},backdrop:{mode:"solid",color:"#080808",color2:"#393323",blur:12,opacity:1},color:{brightness:0,contrast:1,saturation:1,grayscale:0,tint:"#e8b900",amount:0,blend:"source-over",blackPoint:0,whitePoint:1,gamma:1,shadows:0,highlights:0,curves:{rgb:[[0,0],[1,1]],red:[[0,0],[1,1]],green:[[0,0],[1,1]],blue:[[0,0],[1,1]]},denoise:0},dither:{algorithm:"none",palette:"mono",colors:["#080808","#e8b900"],amount:1,scale:2,threshold:.5,motion:"none",speed:1,direction:45,colorSpace:"rgb"},mask:{enabled:!1,invert:!1,shapes:[]},lights:[],effects:{bloom:0,characterBloom:0,grain:0,dust:0,scanlines:0,crt:0,prism:0,rgbSplit:0,sharpen:0,vignette:0,glitch:0,pixelate:0,blur:0,blurType:"gaussian",angle:0,focus:.5,halftone:0},motion:{type:"none",speed:1,amount:1},hover:{effect:"trail",strength:.55,radius:.2,edgeSafe:!1}},x=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},v=(t,e,i,a)=>"number"==typeof t&&Number.isFinite(t)?Math.min(a,Math.max(i,t)):e,b=(t,e)=>"string"==typeof t&&/^#[\da-f]{6}$/i.test(t)?t:e,w=(t,e,i)=>e.includes(t)?t:i;function y(i={}){const a=x(i),s=M;if(void 0!==a.version&&1!==a.version)throw new Error("Unsupported studio settings version. Update asciify-engine.");const r=x(a.crop),o=x(a.backdrop),n=x(a.color),h=x(a.dither),l=x(a.mask),c=x(a.effects),f=x(a.motion),y=x(a.hover),S={...s.effects};for(const t of["bloom","characterBloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","halftone"])S[t]=v(c[t],0,0,1);S.blur=v(c.blur,0,0,24),S.blurType=w(c.blurType,["gaussian","directional","radial","progressive"],s.effects.blurType),S.angle=v(c.angle,0,-180,180),S.focus=v(c.focus,.5,0,1);let k=2048;return{version:1,aspectRatio:w(a.aspectRatio,["original","16:9","9:16","1:1","4:3","3:4","21:9"],"original"),style:w(a.style,d,s.style),cellSize:v(a.cellSize,s.cellSize,["pixel","mosaic","lego","voxel","disco","dots","hex","led","cmyk"].includes(String(a.style))?1:3,60),charset:"string"==typeof a.charset&&a.charset.length?Array.from(a.charset).slice(0,128).join(""):s.charset,colorMode:w(a.colorMode,["accent","source","gray"],s.colorMode),ink:b(a.ink,s.ink),crop:{x:v(r.x,.5,0,1),y:v(r.y,.5,0,1),zoom:v(r.zoom,1,1,5),rotation:90*Math.round(v(r.rotation,0,-360,360)/90)},backdrop:{mode:w(o.mode,["solid","transparent","source","blurred","gradient"],s.backdrop.mode),color:b(o.color,s.backdrop.color),color2:b(o.color2,s.backdrop.color2),blur:v(o.blur,12,0,32),opacity:v(o.opacity,1,0,1)},color:{brightness:v(n.brightness,0,-1,1),contrast:v(n.contrast,1,0,3),saturation:v(n.saturation,1,0,3),grayscale:v(n.grayscale,0,0,1),tint:b(n.tint,s.color.tint),amount:v(n.amount,0,0,1),blend:w(n.blend,g,s.color.blend),blackPoint:v(n.blackPoint,0,0,.99),whitePoint:Math.max(v(n.blackPoint,0,0,.99)+1/255,v(n.whitePoint,1,1/255,1)),gamma:v(n.gamma,1,.25,4),shadows:v(n.shadows,0,-1,1),highlights:v(n.highlights,0,-1,1),curves:m(n.curves),denoise:v(n.denoise,0,0,1)},dither:{algorithm:w(h.algorithm,u,"none"),palette:"string"==typeof h.palette&&Object.prototype.hasOwnProperty.call(p,h.palette)?h.palette:"mono",colors:Array.isArray(h.colors)&&h.colors.length>=2?h.colors.slice(0,32).map(t=>b(t,"#000000")):[...s.dither.colors],amount:v(h.amount,1,0,2),scale:Math.round(v(h.scale,2,1,12)),threshold:v(h.threshold,.5,0,1),motion:w(h.motion,["none","drift","shimmer"],"none"),speed:v(h.speed,1,.1,3),direction:v(h.direction,45,-180,180),colorSpace:w(h.colorSpace,["rgb","luminance"],"rgb")},mask:{enabled:!0===l.enabled,invert:!0===l.invert,shapes:Array.isArray(l.shapes)?l.shapes.slice(0,64).map(t=>{const e=x(t),i=w(e.kind,["rectangle","ellipse","brush"],"rectangle"),a="brush"===i&&Array.isArray(e.points)?e.points.slice(0,k).map(t=>Array.isArray(t)?[Math.round(1e4*v(t[0],0,0,1))/1e4,Math.round(1e4*v(t[1],0,0,1))/1e4]:[0,0]):[];return k-=a.length,{kind:i,x:v(e.x,0,0,1),y:v(e.y,0,0,1),width:v(e.width,.5,0,1),height:v(e.height,.5,0,1),size:v(e.size,.05,.005,.5),points:a}}):[]},lights:Array.isArray(a.lights)?a.lights.slice(0,4).map(t=>{const e=x(t);return{x:v(e.x,.5,0,1),y:v(e.y,.5,0,1),radius:v(e.radius,.3,.02,1),intensity:v(e.intensity,.5,0,1),color:b(e.color,"#ffffff")}}):[],effects:S,motion:{type:w(f.type,e.map(t=>t.mode),"none"),speed:v(f.speed,1,.1,3),amount:v(f.amount,1,0,2)},hover:{effect:w(y.effect,t.map(t=>t.value),"trail"),strength:v(y.strength,.55,0,1),radius:v(y.radius,.2,.1,1),edgeSafe:!0===y.edgeSafe}}}function S(t,e,i,a,s){const r=Math.abs(s.rotation/90)%2==1,o=r?e:t,n=r?t:e,h=Math.max(i/o,a/n)*s.zoom;return{width:o*h,height:n*h,x:(i-o*h)*s.x,y:(a-n*h)*s.y,scale:h,rotated:r}}function k(t,e,i){if(Math.abs(i.crop.rotation/90)%2==1&&([t,e]=[e,t]),"original"===i.aspectRatio)return[t,e];const[a,s]=i.aspectRatio.split(":").map(Number);return t/e>a/s?[Math.round(e*a/s),e]:[t,Math.round(t*s/a)]}function A(t,e){const i={...t,...e};for(const a of["crop","backdrop","color","dither","mask","effects","motion","hover"])e[a]&&Object.assign(i,{[a]:{...t[a],...e[a]}});return e.color?.curves&&(i.color.curves={...t.color.curves,...e.color.curves}),y(i)}function E(t,e,i,a=12e3,s=1){const r=Math.max(2,Number.isFinite(t)?t:960),o=Math.max(2,Number.isFinite(e)?e:540),n=Math.max(1,Math.floor(Number.isFinite(a)?a:12e3)),h=Math.max(.01,Number.isFinite(s)?s:1),l=["dither","pixel","mosaic","lego","voxel","disco","dots","hex","led","cmyk"].includes(i.style)?1:1.65;let c=Math.max(1,Math.ceil(Math.sqrt(r*o/(n*l))/h));for(;Math.ceil(r/(c*h))*Math.ceil(o/(c*h*l))>n;)c++;const m="dither"===i.style?i.dither.scale:i.cellSize,f=Math.max(c,m)*h;return{cell:f,rowHeight:f*l,columns:Math.ceil(r/f),rows:Math.ceil(o/(f*l)),minimum:c,limited:m<c}}var T=[["ascii","Signature ASCII","Brand ink and clean characters.",{}],["print","Newsprint","Fine diffusion on warm paper.",{style:"dither",dither:{algorithm:"floyd-steinberg",palette:"newsprint"}}],["handheld","Pocket camera","Four-tone ordered dither.",{style:"dither",dither:{algorithm:"bayer4",palette:"gameboy",scale:3}}],["riso","Two inks","Limited-color print texture.",{style:"dither",dither:{algorithm:"atkinson",palette:"risograph",scale:2}}],["night","Night signal","Gray characters and optical fringe.",{ink:"#888888",effects:{prism:.7,scanlines:.2,vignette:.3}}],["terminal","Phosphor","Green glyphs with a soft glow.",{ink:"#83efad",effects:{bloom:.4,scanlines:.35,crt:.2}}],["mosaic","Mosaic study","Separated color tiles.",{style:"mosaic",cellSize:14,colorMode:"source"}],["bricks","Brickwork","Colorful studded cells.",{style:"lego",cellSize:18,colorMode:"source"}],["voxel","Little volumes","Three-face isometric tiles.",{style:"voxel",cellSize:22,colorMode:"source"}],["disco","Mirror room","Faceted tiles and warm light.",{style:"disco",cellSize:18,colorMode:"source",lights:[{x:.35,y:.25,radius:.25,intensity:.45,color:"#fff2d4"}]}],["wallpaper","Wallpaper","Living ASCII over a softened source.",{backdrop:{mode:"blurred",blur:18,opacity:.55},ink:"#f2e9c9",motion:{type:"caustics",speed:.5}}],["blueprint","Blueprint","Linework in a cool monochrome.",{style:"lines",ink:"#9bccdf",backdrop:{mode:"solid",color:"#0a1e30"}}]].map(([t,e,i,a])=>({id:t,name:e,description:i,settings:y(a)}));function F(t){const e=T.find(e=>e.id===t);if(!e)throw new Error("Unknown studio look.");return y(e.settings)}function I(t,e,i,a,s,r){a=Math.max(0,Math.min(e-1,a)),s=Math.max(0,Math.min(i-1,s));const o=Math.floor(a),n=Math.floor(s),h=a-o,l=s-n,c=4*(n*e+o);if(0===h&&0===l){for(let e=0;e<4;e++)r[e]=t[c+e];return}const m=4*(n*e+Math.min(e-1,o+1)),f=4*(Math.min(i-1,n+1)*e+o),d=4*(Math.min(i-1,n+1)*e+Math.min(e-1,o+1)),u=(1-h)*(1-l)*t[c+3],g=h*(1-l)*t[m+3],p=(1-h)*l*t[f+3],M=h*l*t[d+3],x=u+g+p+M;for(let e=0;e<3;e++)r[e]=x?(t[c+e]*u+t[m+e]*g+t[f+e]*p+t[d+e]*M)/x:0;r[3]=x}function P(t){const e=function(t){const e=t.blackPoint??0,i=t.whitePoint??1,a=t.gamma??1,s=t.shadows??0,r=t.highlights??0;if(0===e&&1===i&&1===a&&0===s&&0===r)return null;const o=[0,.25+.2*s,.5,.75+.2*r,1],n=o.slice(1).map((t,e)=>4*(t-o[e])),h=[n[0],...n.slice(1).map((t,e)=>2*t*n[e]/(t+n[e])),n[3]],l=new Uint8Array(256);for(let t=0;t<256;t++){const s=Math.pow(Math.max(0,Math.min(1,(t/255-e)/(i-e))),1/a),r=Math.min(3,Math.floor(4*s)),n=4*s-r,c=n*n,m=c*n,f=(2*m-3*c+1)*o[r]+(m-2*c+n)*h[r]/4+(-2*m+3*c)*o[r+1]+(m-c)*h[r+1]/4;l[t]=Math.round(255*Math.max(0,Math.min(1,f)))}return l}(t),i=t.curves;if(!e&&(!i||Object.values(i).every(t=>t.every(([t,e])=>t===e))))return null;const a=f(i?.rgb),s=[i?.red,i?.green,i?.blue].map(f),r=new Uint8Array(768);for(let t=0;t<256;t++)for(let i=0;i<3;i++)r[256*i+t]=s[i][a[e?e[t]:t]];return r}var R=class{constructor(t=0){this.amount=0,this.weights=new Float32Array(256),this.source=new Uint8ClampedArray(0),this.configure(t)}configure(t=0){const e=Math.max(0,Math.min(1,Number.isFinite(t)?t:0));if(e===this.amount)return;if(this.amount=e,0===e)return void(this.source=new Uint8ClampedArray(0));const i=8+24*e;for(let t=0;t<256;t++)this.weights[t]=Math.exp(-t*t/(2*i*i))}apply(t,e,i){if(!this.amount)return;if(!Number.isInteger(e)||!Number.isInteger(i)||e<1||i<1||e*i*4!==t.length)throw new Error("Denoise dimensions do not match the source.");this.source.length!==t.length&&(this.source=new Uint8ClampedArray(t.length));const a=this.source;a.set(t);for(let s=0;s<i;s++)for(let r=0;r<e;r++){const o=4*(s*e+r);if(!a[o+3])continue;const n=a[o],h=a[o+1],l=a[o+2];let c=0,m=0,f=0,d=0;for(let t=-1;t<=1;t++){const o=s+t;if(!(o<0||o>=i))for(let i=-1;i<=1;i++){const s=r+i;if(s<0||s>=e)continue;const u=4*(o*e+s);if(!a[u+3])continue;const g=Math.max(Math.abs(a[u]-n),Math.abs(a[u+1]-h),Math.abs(a[u+2]-l)),p=this.weights[g]*(0===i?1:.6)*(0===t?1:.6)*a[u+3];c+=a[u]*p,m+=a[u+1]*p,f+=a[u+2]*p,d+=p}}t[o]=n+(c/d-n)*this.amount,t[o+1]=h+(m/d-h)*this.amount,t[o+2]=l+(f/d-l)*this.amount}}},C=new Set(["none","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis"]);function L(t){return"dither"===t.style&&("shimmer"===t.dither.motion||"drift"===t.dither.motion&&t.dither.amount>0&&!C.has(t.dither.algorithm))}function D(t){return"none"!==t.motion.type&&(t.motion.amount??1)>0}var N="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",U="bMQYjHDKpjf6EUzN7AC93uOzgXvsNVfHx1l2cu1LpMPvBbbZ10jmCzthLIYkurDmc8GPNX7LCRq/H385DsSvLrkoUnx2Z+Nz5juXJuhKNfT/4jtn78fEmVBCZV8roMCjsH5FUEvRMz5WTMorXOhyw3p4GxnM5TBATt+PDWXajMwr5VUoIuyfd/pLSo8tytjQWAna1yhVUwyQNcWKnlz2aR5JFhhm/2pgEGZO3sAQ0PeODCk7GdxSQU16JowUVw2bfgKAmX+QYdIRkF9yPsIxcdUF/vY5Qxtvh6puMj63SCHKefl9+LYJPb6ZFfgNIWQe+xtjbDJ0ou/ibPhLwYIPfOtDPK1qKiT2znkHQ8pKXz/qquSbb9LZ+oqCdMjOE0OmXRzcBtcW0qrmdeAq1gsK6aCey7ejIX7VadGCyKeEtJ1eLyrGCYu+KZiW1faaq03HMEB2Sw5uF4RAl6Ec41QZ+DBXnBYGdzv5IK9rcKvaIijAOH6R00iPXDF5Rv08tp9gHEqxiLQOF2SlxjMYZbl+RQjhL/szmlz6Nq4SUfluATaV8JRVg23fnsVpsrBaUUmqfSzFklwgf02Su/LcqeX6k+U8wy8eDuonh9OUEx6dVixzFFZGuwCIshlb5KMHaAnD6+M84Vuz9Ann5DgvvOEq2NYE8STkB6WTgdrfI9/wO4o7WbxnIca3EN/mNkx+8+cDE/7sXYMraJAtV/8Wdg0AGr2zJng/R546W+tcffmNMs4Bdwn9KNTf7tbtwsAjhYSyxmazT9fbK8aHDTU6+nKUdlojG3wbiu+AEjZavviMcO4EEdk/7KTHvxdBkjSMJLvCPXrvHIpE+TsViCPqDDjXORobbVuIMdz5BH84RY1WB+p8QS9whP2XN/HoV+/QrpEojjI1pbBJkP2oO+lkrVQkyM5vOKaj3VQEnf1TR9DSy/Kat8N5e71bLtp1Go6OY6jp4cUm18jRRxKXzb58Yjs7/ZTK5MF8mbczqkJYbIvLiVYbwQEJWOxaeIqXj+Qpd72tWm+XvX1NWwspe664GhXKjPAygHpoJ8tidWLv87qlVbgB9ZZZrZA3XXzUg31pqTAifmKzcACi4sciG0mowRKsfTANySXy8CTljZ3zVsGR+9Kb5bkLJNnkBv4qzWKRuPN6ngeYGQRl9MD7KFzMa24ouqSi++0DVNGV60YQkvIN3boARdGp3Cir9IQaDbV0Muwc/Nmuz8tKVxqMgMTGEu3qW8rCiROitOFAL9yLftsFPCdYTSsvam8ZRhXBFjZp6pCVQ45kL8acmpwkVHpINaEMnGLGYsDYllxGhTA7yXPUaIB8xUmIUiI7upaboB7odVTCGzXlPMFd8RNWyv9qbOlNQX9BJtbL3Wls90Q+Cg6/mwxkA62pM0y+f9tH9lokdLyztXiHrh0RhUOldX/rh8xHdN7Dt2eX4QOsrnUK4ieJtz+rMccU6ApaNFfaxhIej/2Js56jfAxIi8ZQBZrWMN1nt3FundztB3WHb5rXixXEIn4WhEXToeEAlYJAOci5UGImY3AmT6E67wHu03A9Rq3rVYFOkORWIMbS8gLUo1FplIT5gJziC4YI/6Fo3oO0q4COanLSpVTqJToJ5pSPh3C0d4V36lR4gGvhHn14NIwEbdRprOHQ+5Qhby2vwiC11A/jldxe3yedXGuAm2ZfsqIZqGOJya9pptzIDygIXI7kJ/24E4swQ6kev8TOi3Y1+JR7hMzfD1+z12dqGWvfX9+4xONEjnsSK27bnETy/7GMlW6gNU0neyt47HYaTBrIgFM46UPYpCLOktP15oKn8kcp1xX0gKApZTS5k81XuNRnx6ZXib8VK917drA1snzpGtmZ44W0kaP+sXWIlG1DKEo2Hc37ZsDNyqPzdiAnqEeeypCHZnkbVAKvAomtHg8GZ2GFWEcbG/+vwTCqfGUgjxC+mT7cLxm9wNJa+tOBb0BRqoNwnmU7bBqIJG5UWDL4cRutOPIQv1bYADM39bQNcEj2TWq+et8/WlkE4gZY0vPOVvtR9mFTxBo30Shl4AQCoCu91vjcr8TEaU3iqQzxOXwpScHW0WUR4vfWrDFDjo5/ev/VGGybCZ67P5nLhD9KpRBi7reh2YnW6Vx5gUEIuL65BE0NO6Iho+EitfJOi+75KfnTdASZ5hPFccWcLfxteQDqMR7EBoyniJJcYAGS94ZvsChbcBs9DdQlaL2iUZwuISTQ1of/u4jgYwzDEDSa1MZkj0UVFYRzKlXjpH4pWuL5gmY2ub25gA+mOyUlvQC8gx3jGureg9ET/KtbCrkM99TcwFXbfxN89CRbvdnSf3KO42B1/zNekY7xvGHAovMWl1Ypp6L7R3Gg+bLovZeAJCQPxXpv+aicuvcyHjRTzSmW/XGnlXUpLqaNyVmS5qYvRuy1M2X/0wKBl4Rk3ZY/IbqYlxHT2PoxFlkN51AV1wRGo0VhxxZWpsJ7WXhG+Fbl4CEl8Dct4rr3ezUCqm4FmH6zDiLQYfzJCF8qkgtBCcbprLRy5rE+zvqcBdeWHPq2/RbsuYm+8vV5v4b3pnOWzsdCQy+/bjTguscQWQNvc4kszaIridF03TeFyIPIAdzOQztUisBxWslJ1jAPaFGTVTgysl2fgDOTqHTi0jMtVg3eJPfDvJXvhe8FTJ3EOAj9LBF6iUDoPWfQBO7WGNg17+AOwxLwrkCX7fKmydrH+ZD8ZC5dQRvyS2C75wk5r1W4flKrwoPny6IlOQ7QiGyF/3N4cHS3GU4aZ/JRfU7PiyxEO972AUpBP6JelmbUu505W266xgUY4Iy5jvMx0yTTteXJ56hX0mYVmL3Fg7HBSeuKLmqVco9WlptuVBLl19HZpA9GY0nF+8bzvKncQ1K1pWCK5sxCoojJ/JvHEhZEo8DtaOkQ1Pcr5Hw0Ef+NVDC2epp/ONcVrBHdXtsma9neJmk1EsS7I0e+PlFCU9nr2dfr8Lj5FQMwZxIT/WcsiN6tSYCm3BGITRgqC3V23Kdau8XsipKIWyArPcnA2wLRRL+GsjUdM/HLWprQfuKysyQr47lTBh+pLVmg59Rr/4Dv3ldcuHm78Yqixc/nbHv3N9XqBsTI36r20+gjqJB7Phs4ark0eHsxMO1Rrt8TFBkxID1mQQ86sYzlc6UchftY0Ld2JvyEn//sjLNt4PYFm8yJJqYz0JhNV9wOCJd9K4xwVMN0ZL2sCGWoLijDBF5PH9la0Cuee5WfD3RZx/YH1UGewvNSzZWM7GkTJhZPw/Sh92bunRFPfsLW8HHe5iB0VmlKEv6neoDJzGS6Bp0chzFq9uSptLFS3vPGi71VlwrTg59LH1h1Q7df6DtWRRe8qK7JcFO3It88nJ6GI+jw8xnpVQ+kH+n2D+a4P2pcf1LuqfBry2T03AYiqDwSPBauqt4eOYYnRfu7aDle9fcxO2rua6kXMedbpUZl9jFnXfQmA8zkMqrAwH1iGvoNZcxpMKT8EPoYxJiDNPcfvMS1Lzb/AMhiRF3dfkyP/aALz16eVVhvNKtklRQtDngZmK/BH2gPxor+igG+5lLYsLHtUq6bAK1Sv/80SDHprsN+wZ7Rb4ma/MYUEgkCUzKw97DE1sje/TZB3LAJUQpqDM4hgOyo57pZvEXoMas0Tdl8YBG9uZ4TY7/fGA5AbqzuU0MM1FSVCM89Ko0toFWgguwM26oVgcKWWiC/hczmbb3Of8Jwt9T3eq3DOn8UcazziZWksddTHVQqrjeN+C0OYrseHiWZPNFGck9dCoiSIE2DeaPQlCD9dtJsijqwKx6uABuRdjpdZ4mAU/c7AxPu7eDRMDYmQ/7dmvsT5RLkmQUbE2pf4YDjwlIopStyAvPrvVICOa5mlvzPWPJUlAQKK3jF/8m3t63JKqmF0lWh7SM9pF+MzAS9r401WUw8SHnXZDj78PFz4xN7v6+qqL1/asmEeUz0ugEEd3OMYSwmAs+6i/YLQTkJafSkhHXQ6TmieT9JoSaMB5MS7jwXFV4OyHdJRtGEawjiUHwtPwqZb+vzFUZjKQhd8fPSCpfI+WFbyUP8KTWFzEjKHySQhIE3uDTD/EFwj32jTn+SG6fFq3NxxR7mK502oL95EB2GLLUS1EDrSU2Ws6ekotZegrT7nbA/6vwINQ8yDUfvH031ByjsRH39xFBQoDZ84dl7NNcgq533iEtqb1DOrw5eY+NhzYIdq1QFXVKGoUxvjI4bTVagGHeSsEBV4zN2lMcnrRHFZ6uhglJ2VS4wP3Cn9cuCJpZMp2gY1YXWrl6LaPm6VO8ufZq9VfdQL0wfH5ssVz0oIHUABc/xQv3XerKCnV8NihZq43gftg7vaZBnRXKhux6cnC2yRPWLfzIVy0QHw1/gkyNC7qxTj1Gfvqk3Mlcq5azqUjEeKJnyRczCOGu2JQ0GMXEZkK6o07T1hQ9ODlju6HfXpkXgm0MfyCV8v0FtUsoQAcM70IFMf5rz11k9dIClW7JJjav+a5qb68X2F/esRmqrX+AbcN/DUP2/sJSJDejEO8tG+7cCBKiFF969dZlqUM/ttSP4FyqhbTQuukZHObxDLK0iGXjb7nBMdh2rQV9iwVbRmGVWL36kX5Gl+HqROkzT/hE73kREASjVop2xDH5gJM1Zo6KthhY9H/n7w477dk2QV1lBuf9SXhQ2sWAhw2cTIkXwii71AI3SKHm4+OEtc07FuiZrS+rElHLMtNfJIs3+RO/kvFnZPPylSgvWgkZSosMLimVyvY9sKLVXtsa/mMTsuFQs0UBY9zfnWRLHFRoRNoHl1QLspYgg2aZtOu1Imc4UvtMbn6emwqSrgCr5VkPxfoDz09Oh/PaCCukZXeqvDLi6H8dvEXiwaEH754BjTUuEEH0hfjOfbrzhifMT8nfcFx7IlybouUPE0zkmZFvn4tfKTpa85SFcKg9xqNDxfVTAEyZwz/VJG84LBq1dmCH6pJ9EhuGkuoTYyc7YNi1Bc1xuWr5G1Jp+83NAnK2cc99DmzZUHDsZ4GEkQoxdCt2UZ0Nmx9TmIv6XDIsa+ER1BgjfyODclit5STjUWV7MNDsP+fhJPj8OkVa7tlL+Zg3GwCMkWCn3c34DGOomVKHN7zP0rSLaTuAafC0XUhjCPTJg48Mn8llLUJpy+UYoknJ1qBhoDpq6eBmeU2giJicY6ytMPd/IWj0VdUweHzoTbgyxJ3oiCbrMLX6IRMik//S0BIbw5cyuJ6i9QceVvjiInvCDbK+glOuOXmG2vkDZyYrUSWdxxZCwhqJBebsuUXvu/lWa0F9HMQ3gxYPt2MpwGDYCnwIIg4MoCd6WQG1rBwjzXC2LcPvpXZD6oqx7F1fLrqlhRSC5YxqS+jAZ40KeYg0ehgwnI6P/7lpXb6/HW1gLBepQYTPR7Z0ZNYAz29PgdRHkRejlXkGybCCPkUVUzoLgd02EqP8mVrnNhSZNu3O16rG7Ss98h504d5J9XF6qz3Kj+Ks+2CM6w5bcSSrc9oNdULE5dSzehxLTRolUHY0d93KD20sGVCa1mk6KiBE8oZ5tsRAHwKoH6sra/ANTiQ8cwAACR+bEtdJx3wGB/uU3gexinPNuIFUO8sucPVkDELU+h2cJFiUTl3Hs1hewECuQ6hpP4NZJER2msg6BOFuVT+mffwD2ywGYt+SLZdxlMGhOYq2BQIgbTZIGdPujDhapTxlc45FgyNfeTLsQltJkqaBUdm3MsomUAlbk3RplalvNOooX8jgW35YKozPAjSXplgK7SKtIkdWeA+d+Yci4FLZz79MvlPfN+YJdp78QTvzgJjdD+hK+0bYW32QwoO5nIzsOMPjNPD9XBDdpOL0TZm5CRwFEZKz4Q5i2MFHC1G7hA2yeI2QfuTEa6Mv9I4zQAwfh/0HfOt8Ew7ohKp4JPyxMp5S84uX8PL1lEOdulfCs7CpzEpuanOBNjqyhG1gTXr/yc/06ppYe15vwVu7/HJttkS/FgpIw5zq8+dYMRsegj6Xu5ybXkfMCU1cL9PRD3NaYwGnh1tgETFG5zrrd6CAYd8JFvrCan8iOW/s8OwvUWvRIkWNsb76EKYUkr72AOOwJC6VoHXhsKdk2D5n1f+LjWGyROdviV4e1CQxNnqJ+toM+pmCNz9+1njCkg6mjr6NJUyCybmLCmD+laigQlZWt/U1Kaor074K6yr/oHScj4Xgwy39QVnv2fd9tbQBmiKStmm8Ktr3/SF+2Z5w9RN7BpOCScGoPFk0QN3bf5QEV/LTr28haXARJtV4MLNWdF+8bh74nyZWqt/CLSALnHHolNBg+FJQWVReuBWSBo40sLEBkaBHvrJDwQjniM14+pi0MJWaxPeEYfPriNM3cGJcm1uKK9ThZSO8IkcuySmhjx8c5Fas3J5e0GLaSxb2KdFvTI8Q3pxGc55h+27vA8oyWTauJkr30wdmr49ahieUtsf76nzSq3QinzKHMumYhFXdO6mjYyToEVGy8BPjyUuulitYOPm38qOJfXiDGqjLeW6oKOD82ysmB7iPkowSzBun+YZj89FcvOro9X4eCQJaTCf7XKccMGjOCt1Jb7aFrk6NjwWe4LbZR61TekI+yRBsDMiAGYR9aIa52doqs+INlFKzwt0AFaWyA3IfM9N0rHU6iiaR6Z1ARvgilIB/Yfq5Oz+L2AXwDUvIUzjD/kB3mexp9Urym91YXgn2OQbvodKW91kEQ/dqdAEdy2HKVhFxqU43PuGOEbFmRRaJKZI2+n5S/khe3MymYF3VLOvl5a0vbDgqz1aVIL13tX1tmO5GmT4sigR3ajt/9NLrYVaJzvlOxmPA0ivqWD4V6noAg9YIAjWQDmOVtxKOIpTXnCU73nue/GwjrwaDP0xtThCBzds62JV+3u0R27gjTxVBGTX4KeZJX+wg0p3ddDalnx0Z3ms+BPZXcEmt7fi5Xn00pEr/GYD4ZRgLh70xQfp0YS4tA3naey9Ijhn6JGZzdljZ9IySGrN4kTo/1X7M58MxWPHrxW5EF1cZisIKSc2/ptQMhXdmJP9EKyjTN9RMmhp6fCvbiH40/m/SXZuA5RUgtatrrI3d11Hs2bxHqNbY8lSLFf4CB8htaR8bvsbTj4fOqud96ChdEI/gVo/EWk4VcGi2lcXogPpgsDB5ZWYpeHmhryB6StEa+5LIgsB0kVeJl2RqUwhec7OLDyg9nu1Lp5NSnjdwwESVlkR34pD/SEn6QprUWNGkuFH+cK/gaDfcS1ziqXPyyO7vB4HR/1OavvIi0MA5Ew+JEm50HNnkkSd2hBlUIHxkANroGZyAue2uSRjiTMpVFCTqydGGqV7myy4CA8dN1nt+RQMB9UNvSb2PoyGZh5Ydn2IXNmnxs7uphL6HGoc6YjkYyGseLrPKM6PTbBfkqWJ7USEbnv7E18iaQrgeK9hxyW3hW7yQil//CYYD08pkpxfQn3xiY81FIenXLqAbaIOgS0KsNg8IY2gizDQr/IqoIA4unPaHhX3SNgzwzUaMUB/8Bn4Np9vDVmdei/ctPFmfRroAA4meRuBOpJInUQdDA2ZGatx3pE9MIxPoaak22IpYuodMZayr9K023Qg4/uMWnLdbN8ANynQVZ8ae9Oj0aTziA50dHrF0gAW+ibh2es1Sf0EioVqtFMVxrPfaX2qMJ+VYlKPj4Vd0BhR5IvPcwoyMgU5beqFgo5xHwSRtCf7/5DXvcQL53ghwLFvi1BS7ToWFWyDYPtwG4zRSuvD/bbGMBzVDF8zkwOgsAF7lzeDJyZ7Ew4lcI2TXSHRhko5UBlrzXRCqnGK+sDkWxKuTh/Of2xAIf0fWNO/eMzyCEOekGUD13lEAfUenxaGyiSIeP2kQAiXAe5BceLPh0CWkzGbsUnHR0JrWSel5fXMQBzL/eq7w6P7lFAkqq8XzHCxvmHbhA6wwjNgm1bAxLjBryB43YlQQ09/BTu6l09kWzpN6NclJHXUqg7NOVJD/+lDHaveVP+erKRilV9eqpZo4RVj6xfYZAwB3hEznYwPIJh4BLVEfyJS9+SjjGKkQ9Xx6FOZbJCCXHfB2nRK7pHO0uPJY4FNcZofhw2uFsbWLAx3FetZz7+uHrx4c+2VWBs/NZb8mhJ4aK1CEbWW2FILPiuWLJFZ+0h/rbNHTP9Uaq3UmxOS5+p0zBYtuuch21kieGsk1+pG9VI5sMBBlod6UxnI8wscykJZYNNOTwst4yhtSxNRhB",O=new Uint16Array(4096);for(let t=0;t<O.length;t++)O[t]=N.indexOf(U[2*t])<<6|N.indexOf(U[2*t+1]);var X=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};var Y=new Map([2,4,8,16].map(t=>[t,Float64Array.from({length:t*t},(e,i)=>function(t,e,i){let a=0;for(let s=1;s<i;s*=2){const i=(Math.floor(t/s)%2+2)%2;a=4*a+[[0,2],[3,1]][(Math.floor(e/s)%2+2)%2][i]}return(a+.5)/(i*i)-.5}(i%t,Math.floor(i/t),t))])),B={"floyd-steinberg":[[1,0,7/16],[-1,1,3/16],[0,1,5/16],[1,1,1/16]],atkinson:[[1,0,.125],[2,0,.125],[-1,1,.125],[0,1,.125],[1,1,.125],[0,2,.125]],stucki:[[1,0,8/42],[2,0,4/42],[-2,1,2/42],[-1,1,4/42],[0,1,8/42],[1,1,4/42],[2,1,2/42],[-2,2,1/42],[-1,2,2/42],[0,2,4/42],[1,2,2/42],[2,2,1/42]],sierra:[[1,0,5/32],[2,0,3/32],[-2,1,2/32],[-1,1,4/32],[0,1,5/32],[1,1,4/32],[2,1,2/32],[-1,2,2/32],[0,2,3/32],[1,2,2/32]],"sierra-lite":[[1,0,.5],[-1,1,.25],[0,1,.25]],burkes:[[1,0,.25],[2,0,4/32],[-2,1,2/32],[-1,1,4/32],[0,1,.25],[1,1,4/32],[2,1,2/32]],jarvis:[[1,0,7/48],[2,0,5/48],[-2,1,3/48],[-1,1,5/48],[0,1,7/48],[1,1,5/48],[2,1,3/48],[-2,2,1/48],[-1,2,3/48],[0,2,5/48],[1,2,3/48],[2,2,1/48]]},z=t=>[parseInt(t.slice(1,3),16),parseInt(t.slice(3,5),16),parseInt(t.slice(5,7),16)];function W(t,e,i){const a=Math.min(t*Math.max(1,i),(1-t)*Math.max(1,i),e*Math.max(1,1/i),(1-e)*Math.max(1,1/i)),s=Math.max(0,Math.min(1,(a-.035)/.105));return s*s*s*(s*(6*s-15)+10)}var G=t=>["dissolve","silk","vortex","magnetic","scatter","etch","elastic","rake"].includes(t),q=class{constructor(t,e){this.edgeSafe=!1,this.previous=null,this.peak=0,this.scatterDirections=null,this.springX=null,this.springY=null,this.mode="dissolve",this.width=t,this.height=e;const i=t*e;this.pixels=new Uint8Array(4*i),this.ink=new Float32Array(i),this.targetX=new Float32Array(i),this.targetY=new Float32Array(i),this.offsetX=new Float32Array(i),this.offsetY=new Float32Array(i),this.edge=new Float32Array(i);for(let i=0;i<e;i++)for(let a=0;a<t;a++)this.edge[i*t+a]=W(a/(t-1),i/(e-1),t/e);this.clear()}get active(){return this.peak>2e-4}setMode(t){if("elastic"!==t||this.springX||(this.springX=new Float32Array(this.ink.length),this.springY=new Float32Array(this.ink.length)),"scatter"===t&&!this.scatterDirections){const t=this.scatterDirections=new Float64Array(this.width*this.height*2);for(let e=0;e<this.height;e++)for(let i=0;i<this.width;i++){const a=43758.5453*Math.sin(127.1*i+311.7*e),s=(a-Math.floor(a))*Math.PI*2,r=2*(e*this.width+i);t[r]=.7*Math.cos(s),t[r+1]=.7*Math.sin(s)}}t!==this.mode&&(this.mode=t,this.clear())}clear(){for(const t of[this.ink,this.targetX,this.targetY,this.offsetX,this.offsetY,this.pixels])t.fill(0);if(this.previous=null,this.peak=0,this.springX?.fill(0),this.springY?.fill(0),"dissolve"!==this.mode)for(let t=0;t<this.pixels.length;t+=4)this.pixels[t]=this.pixels[t+2]=128}leave(){this.previous=null}move(t,e,i){if(!Number.isFinite(t+e+i))return;t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e));const a=this.previous;this.previous={x:t,y:e};const s=this.width,r=this.height,o=Math.max(1,s/r),n=Math.max(1,r/s),h=a?(t-a.x)*o:0,l=a?(e-a.y)*n:0,c=Math.hypot(h,l);if(!a&&"dissolve"!==this.mode&&"etch"!==this.mode)return;if(a&&c<1e-4)return;const m=.035+.11*Math.max(.1,Math.min(1,i)),f=Math.min(128,Math.max(1,Math.ceil(c/(.45*m)))),d=c?h/c:1,u=c?l/c:0,g=Math.min(1,c/(m*f)*2.2);for(let i=0;i<f;i++){const h=(i+.5)/f,l=a?a.x+(t-a.x)*h:t,c=a?a.y+(e-a.y)*h:e,p=Math.max(0,Math.floor((l-2.5*m/o)*(s-1))),M=Math.min(s-1,Math.ceil((l+2.5*m/o)*(s-1))),x=Math.max(0,Math.floor((c-2.5*m/n)*(r-1))),v=Math.min(r-1,Math.ceil((c+2.5*m/n)*(r-1)));for(let t=x;t<=v;t++)for(let e=p;e<=M;e++){const i=(e/(s-1)-l)*o/m,a=(t/(r-1)-c)*n/m,h=Math.exp(1.5*-(i*i+a*a)),f=t*s+e;if("dissolve"===this.mode||"etch"===this.mode)this.ink[f]=Math.max(this.ink[f],h);else if("elastic"===this.mode)this.springX[f]=Math.max(-24,Math.min(24,this.springX[f]+d*h*g*8)),this.springY[f]=Math.max(-24,Math.min(24,this.springY[f]+u*h*g*8));else{const s=(-i*u+a*d)*h*2.8,r="rake"===this.mode?d*Math.sin(t*Math.PI/3)*h*2:"magnetic"===this.mode?-i*h*2.5:"scatter"===this.mode?(i+this.scatterDirections[2*f])*h*2:"silk"===this.mode?d*s:-a*h*2.5,o="rake"===this.mode?u*Math.sin(e*Math.PI/3)*h*2:"magnetic"===this.mode?-a*h*2.5:"scatter"===this.mode?(a+this.scatterDirections[2*f+1])*h*2:"silk"===this.mode?u*s:i*h*2.5;this.targetX[f]=Math.max(-1,Math.min(1,this.targetX[f]+r*g)),this.targetY[f]=Math.max(-1,Math.min(1,this.targetY[f]+o*g))}}}this.peak=1}step(t){if(!this.active||!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t)),i=Math.exp(-("dissolve"===this.mode?2.15:3.2)*e),a=1-Math.exp(-22*e);let s=0;const r=Math.sqrt(336),o=Math.exp(-8*e),n=Math.cos(r*e),h=Math.sin(r*e)/r;for(let t=0;t<this.ink.length;t++)if("etch"===this.mode)this.ink[t]*=i,s=Math.max(s,this.ink[t]);else if("dissolve"===this.mode){this.ink[t]*=i,s=Math.max(s,this.ink[t]);const e=Math.round(65535*this.ink[t]);this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e}else{if("elastic"===this.mode){const e=this.offsetX[t],i=this.offsetY[t],a=this.springX[t],r=this.springY[t];this.offsetX[t]=Math.max(-1,Math.min(1,o*(e*n+(a+8*e)*h))),this.offsetY[t]=Math.max(-1,Math.min(1,o*(i*n+(r+8*i)*h))),this.springX[t]=o*(a*n-(8*a+400*e)*h),this.springY[t]=o*(r*n-(8*r+400*i)*h),s=Math.max(s,.05*Math.abs(this.springX[t]),.05*Math.abs(this.springY[t]))}else this.targetX[t]*=i,this.targetY[t]*=i,this.offsetX[t]+=(this.targetX[t]-this.offsetX[t])*a,this.offsetY[t]+=(this.targetY[t]-this.offsetY[t])*a;s=Math.max(s,Math.abs(this.offsetX[t]),Math.abs(this.offsetY[t]),Math.abs(this.targetX[t]),Math.abs(this.targetY[t]));const e=Math.round(this.offsetX[t]*(this.edgeSafe?this.edge[t]:1)*32767+32768),r=Math.round(this.offsetY[t]*(this.edgeSafe?this.edge[t]:1)*32767+32768);this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e,this.pixels[4*t+2]=r>>>8,this.pixels[4*t+3]=255&r}if("etch"===this.mode)for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const i=t*this.width+e,a=3*(this.ink[t*this.width+Math.max(0,e-1)]-this.ink[t*this.width+Math.min(this.width-1,e+1)]+this.ink[Math.max(0,t-1)*this.width+e]-this.ink[Math.min(this.height-1,t+1)*this.width+e]);this.offsetX[i]=Math.max(-1,Math.min(1,a))*(this.edgeSafe?this.edge[i]:1);const s=Math.round(32767*this.offsetX[i]+32768);this.pixels[4*i]=s>>>8,this.pixels[4*i+1]=255&s}this.peak=s,this.active||this.clear()}sample(t,e,i){const a=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),s=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),r=Math.floor(a),o=Math.floor(s),n=a-r,h=s-o,l=o*this.width+r,c=l+this.width,m=t=>(t[l]*(1-n)+t[l+1]*n)*(1-h)+(t[c]*(1-n)+t[c+1]*n)*h;if("etch"===this.mode)return i[0]=i[1]=0,void(i[2]=3*m(this.offsetX));i[0]=m(this.offsetX)*(this.edgeSafe?W(t,e,this.width/this.height):1)*.08,i[1]=m(this.offsetY)*(this.edgeSafe?W(t,e,this.width/this.height):1)*.08,i[2]="dissolve"===this.mode?6*-m(this.ink):0}},j=class{constructor(t,e){this.rings=[],this.previous=null,this.elapsed=1,this.echoPeak=0,this.width=t,this.height=e,this.pixels=new Uint8Array(t*e*4),this.echo=new Float32Array(t*e)}get active(){return this.rings.length>0||this.echoPeak>2e-4}clear(){this.rings=[],this.previous=null,this.elapsed=1,this.pixels.fill(0),this.echo.fill(0),this.echoPeak=0}leave(){this.previous=null}move(t,e,i){const a=Math.max(1,this.width/this.height),s=Math.max(1,this.height/this.width);this.previous&&(Math.hypot((t-this.previous.x)*a,(e-this.previous.y)*s)<.065||this.elapsed<.3)||4!==this.rings.length&&(this.previous={x:t,y:e},this.elapsed=0,this.rings.push({x:t,y:e,age:0,radius:i}))}ringSample(t,e){const i=Math.max(1,this.width/this.height),a=Math.max(1,this.height/this.width);let s=0;for(const r of this.rings){const o=.015+r.age*(.15+.22*r.radius),n=.009+.014*r.radius,h=(Math.hypot((t-r.x)*i,(e-r.y)*a)-o)/n,l=Math.sin(Math.min(1,r.age/.07)*Math.PI/2)*Math.max(0,1-r.age/1.35)**2;s=Math.max(s,Math.exp(-h*h)*l)}return s}sample(t,e){const i=Math.max(0,Math.min(this.width-1,Math.round(t*(this.width-1)))),a=Math.max(0,Math.min(this.height-1,Math.round(e*(this.height-1))));return Math.max(this.ringSample(t,e),this.echo[a*this.width+i])}step(t){if(!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t));this.elapsed+=e;for(const t of this.rings)t.age+=e;if(this.rings=this.rings.filter(t=>t.age<1.35),!this.active)return void this.pixels.fill(0);const i=Math.exp(-5.5*e);let a=0;for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const s=t*this.width+e;this.echo[s]=Math.max(this.ringSample(e/(this.width-1),t/(this.height-1)),this.echo[s]*i),a=Math.max(a,this.echo[s]);const r=Math.round(65535*this.echo[s]),o=4*s;this.pixels[o]=r>>>8,this.pixels[o+1]=255&r}this.echoPeak=a,this.active||(this.echo.fill(0),this.pixels.fill(0))}},H=class{constructor(t,e){this.previous=null,this.peak=0,this.width=t,this.height=e;const i=t*e;this.pixels=new Uint8Array(4*i),this.signal=new Float32Array(i),this.offsetX=new Float32Array(i),this.offsetY=new Float32Array(i),this.driftX=new Float32Array(i),this.driftY=new Float32Array(i),this.u=new Float32Array(i),this.v=new Float32Array(i),this.ink=new Float32Array(i),this.a=new Float32Array(i),this.b=new Float32Array(i),this.c=new Float32Array(i),this.pressure=new Float32Array(i),this.pressureNext=new Float32Array(i),this.divergence=new Float32Array(i),this.curl=new Float32Array(i)}get active(){return this.peak>2e-4}clear(){for(const t of[this.u,this.v,this.ink,this.a,this.b,this.c,this.pressure,this.pressureNext,this.divergence,this.curl,this.signal,this.pixels,this.offsetX,this.offsetY,this.driftX,this.driftY])t.fill(0);this.previous=null,this.peak=0}leave(){this.previous=null}move(t,e,i,a=performance.now()){if(!Number.isFinite(t+e+i+a))return;t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e)),i=Math.max(.1,Math.min(1,i));const s=this.previous;if(this.previous={x:t,y:e,time:a},!s)return;const r=(t-s.x)*(this.width-1),o=(e-s.y)*(this.height-1),n=Math.hypot(r,o);if(n<.001)return;const h=Math.min(this.width,this.height),l=a>s.time?Math.max(1/240,(a-s.time)/1e3):1/60,c=Math.min(12,n/h/l),m=1-Math.exp(-c/2.2),f=h*(.022+.075*i)*(.65+.95*m),d=Math.min(128,Math.max(1,Math.ceil(n/(.4*f)))),u=n/f*(.32+.22*m)/d,g=r/n,p=o/n,M=-p,x=g,v=n*(2+18*m)/d;for(let i=0;i<d;i++){const a=(i+.5)/d,r=(s.x+(t-s.x)*a)*(this.width-1),o=(s.y+(e-s.y)*a)*(this.height-1),n=Math.max(1,Math.floor(r-3*f)),h=Math.min(this.width-2,Math.ceil(r+3*f)),l=Math.max(1,Math.floor(o-3*f)),c=Math.min(this.height-2,Math.ceil(o+3*f));for(let t=l;t<=c;t++)for(let e=n;e<=h;e++){const i=((e-r)*g+(t-o)*p)/f,a=((e-r)*M+(t-o)*x)/f,s=Math.exp(-i*i*.65-a*a*1.7),n=t*this.width+e;this.ink[n]=1-(1-this.ink[n])*Math.exp(-s*u);const h=1-a*a*.55,l=i*a*.7;this.u[n]=Math.max(-80,Math.min(80,this.u[n]+(g*h+M*l)*s*v)),this.v[n]=Math.max(-80,Math.min(80,this.v[n]+(p*h+x*l)*s*v))}}this.peak=1}read(t,e,i){const a=0|(e=Math.max(.5,Math.min(this.width-1.5,e))),s=0|(i=Math.max(.5,Math.min(this.height-1.5,i))),r=e-a,o=i-s,n=s*this.width+a;return(t[n]*(1-r)+t[n+1]*r)*(1-o)+(t[n+this.width]*(1-r)+t[n+this.width+1]*r)*o}sample(t,e){return this.read(this.signal,t*(this.width-1),e*(this.height-1))}displacement(t,e,i){i[0]=this.read(this.offsetX,t*(this.width-1),e*(this.height-1)),i[1]=this.read(this.offsetY,t*(this.width-1),e*(this.height-1))}step(t){if(!this.active||!Number.isFinite(t))return;let e=Math.max(0,Math.min(.05,t));const i=this.width,a=this.height;for(;e>1e-7;){const t=Math.min(1/60,e);e-=t;const s=Math.exp(-1.9*t),r=Math.exp(-3.2*t);for(let e=1;e<a-1;e++)for(let o=1;o<i-1;o++){const n=e*i+o,h=Math.max(.5,Math.min(i-1.5,o-this.u[n]*t)),l=Math.max(.5,Math.min(a-1.5,e-this.v[n]*t)),c=0|h,m=0|l,f=h-c,d=l-m,u=m*i+c,g=(1-f)*(1-d),p=f*(1-d),M=(1-f)*d,x=f*d;this.a[n]=(this.u[u]*g+this.u[u+1]*p+this.u[u+i]*M+this.u[u+i+1]*x)*s,this.b[n]=(this.v[u]*g+this.v[u+1]*p+this.v[u+i]*M+this.v[u+i+1]*x)*s,this.c[n]=(this.ink[u]*g+this.ink[u+1]*p+this.ink[u+i]*M+this.ink[u+i+1]*x)*r}[this.u,this.a]=[this.a,this.u],[this.v,this.b]=[this.b,this.v],[this.ink,this.c]=[this.c,this.ink];for(let t=1;t<a-1;t++)for(let e=1;e<i-1;e++){const a=t*i+e;this.curl[a]=.5*(this.v[a+1]-this.v[a-1]-this.u[a+i]+this.u[a-i])}for(let e=1;e<a-1;e++)for(let a=1;a<i-1;a++){const s=e*i+a,r=Math.abs(this.curl[s+1])-Math.abs(this.curl[s-1]),o=Math.abs(this.curl[s+i])-Math.abs(this.curl[s-i]),n=Math.hypot(r,o)+1e-4,h=this.curl[s]*t*10,l=Math.hypot(this.u[s],this.v[s]);this.u[s]+=o/n*h,this.v[s]-=r/n*h;const c=Math.min(1,l/(Math.hypot(this.u[s],this.v[s])+1e-6));this.u[s]*=c,this.v[s]*=c,this.divergence[s]=-.5*(this.u[s+1]-this.u[s-1]+this.v[s+i]-this.v[s-i])}this.pressure.fill(0);for(let t=0;t<4;t++){for(let t=1;t<a-1;t++)for(let e=1;e<i-1;e++){const a=t*i+e;this.pressureNext[a]=.25*(this.divergence[a]+this.pressure[a-1]+this.pressure[a+1]+this.pressure[a-i]+this.pressure[a+i])}[this.pressure,this.pressureNext]=[this.pressureNext,this.pressure]}let o=0;for(let e=1;e<a-1;e++)for(let a=1;a<i-1;a++){const s=e*i+a;this.u[s]=Math.max(-80,Math.min(80,this.u[s]-.5*(this.pressure[s+1]-this.pressure[s-1]))),this.v[s]=Math.max(-80,Math.min(80,this.v[s]-.5*(this.pressure[s+i]-this.pressure[s-i]))),this.driftX[s]+=(3.6*this.u[s]-58*this.offsetX[s]-12*this.driftX[s])*t,this.driftY[s]+=(3.6*this.v[s]-58*this.offsetY[s]-12*this.driftY[s])*t,this.offsetX[s]=Math.max(-2,Math.min(2,this.offsetX[s]+this.driftX[s]*t)),this.offsetY[s]=Math.max(-2,Math.min(2,this.offsetY[s]+this.driftY[s]*t)),this.signal[s]=1-Math.exp(.06*-Math.hypot(this.u[s],this.v[s])-.16*this.ink[s]),o=Math.max(o,this.signal[s])}this.peak=o}if(this.active)for(let t=0;t<this.ink.length;t++){const e=Math.round(65535*Math.min(1,this.signal[t]));this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e,this.pixels[4*t+2]=Math.round(128+63.5*this.offsetX[t]),this.pixels[4*t+3]=Math.round(128+63.5*this.offsetY[t])}else this.clear()}};function V(t,e){const i=Math.max(0,Math.min(1,e/.38));return t+(1-2*t)*(i*i*(3-2*i))}var K=(t,e)=>"water"===t?30*e/.55:"silk"===t?28*e:"vortex"===t?38*e:["magnetic","scatter","elastic","rake"].includes(t)?32*e:0,Q=class{constructor(t=1){this.mode="water",this.amount=.55,this.radius=.2,this.lensX=.5,this.lensY=.5,this.lensStrength=0,this.previous=null,this.energy=0,this.pending=!1,this.remainder=0,t=Math.max(.25,Math.min(4,t)),this.columns=Math.round(t>=1?128:128*t),this.rows=Math.round(t>=1?128/t:128),this.xScale=Math.max(1,t),this.yScale=Math.max(1,1/t),this.heights=new Float32Array(this.columns*this.rows),this.velocity=new Float32Array(this.heights.length),this.next=new Float32Array(this.heights.length),this.normals=new Float32Array(2*this.heights.length),this.edgeMask=new Float32Array(this.heights.length);for(let e=0;e<this.rows;e++)for(let i=0;i<this.columns;i++)this.edgeMask[e*this.columns+i]=W(i/(this.columns-1),e/(this.rows-1),t);this.refraction={width:this.columns,height:this.rows,pixels:new Uint8Array(4*this.heights.length),strength:30,mode:"water",focus:[.5,.5,0,.2]},this.waterPixels=this.refraction.pixels,this.trail=new H(this.columns,this.rows),this.contour=new j(this.columns,this.rows),this.afterimage=new q(this.columns,this.rows),this.clear()}get invertsDensity(){return"trail"===this.mode}get densityTrail(){return["trail","contour","dissolve","etch"].includes(this.mode)}get hasRefraction(){return this.active||this.lensStrength>15e-5}get active(){return G(this.mode)?this.afterimage.active:"contour"===this.mode?this.contour.active:"trail"===this.mode?this.trail.active:this.pending||this.energy>15e-5}setMode(t){t!==this.mode&&(this.clear(),this.mode=t,this.refraction.mode=t,G(t)&&this.afterimage.setMode(t),this.refraction.pixels="trail"===t?this.trail.pixels:"contour"===t?this.contour.pixels:G(t)?this.afterimage.pixels:this.waterPixels,this.refraction.strength=K(t,this.amount))}configure(t,e=.55,i=.2,a=!1){this.setMode(t),this.refraction.edgeSafe=a,this.afterimage.edgeSafe=a,this.amount=Number.isFinite(e)?Math.max(0,Math.min(1,e)):.55,this.radius=Number.isFinite(i)?Math.max(.1,Math.min(1,i)):.2,this.refraction.strength=K(t,this.amount),this.refraction.focus[2]=this.densityTrail?this.amount:this.lensStrength*this.amount,this.refraction.focus[3]=this.radius}move(t,e,i){if("none"===this.mode||0===this.amount)return;if(!Number.isFinite(t+e))return;if(t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e)),G(this.mode))return void this.afterimage.move(t,e,this.radius);if("contour"===this.mode)return void this.contour.move(t,e,this.radius);if("trail"===this.mode)return void this.trail.move(t,e,this.radius,i);if("water"!==this.mode)return!this.previous&&this.lensStrength<.001&&(this.lensX=t,this.lensY=e),this.previous={x:t,y:e},void(this.pending=!0);if(!this.previous)return void(this.previous={x:t,y:e});const a=this.previous;this.previous={x:t,y:e};const s=(t-a.x)*this.xScale,r=(e-a.y)*this.yScale,o=Math.hypot(s,r);if(o<1e-5)return;const n=.035+.1*this.radius,h=3*n,l=Math.min(192,Math.max(1,Math.ceil(o/(.5*n)))),c=95*Math.min(o,1)/l;for(let i=0;i<l;i++){const s=(i+.5)/l,r=a.x+(t-a.x)*s,o=a.y+(e-a.y)*s,m=Math.max(1,Math.floor((r-h/this.xScale)*(this.columns-1))),f=Math.min(this.columns-2,Math.ceil((r+h/this.xScale)*(this.columns-1))),d=Math.max(1,Math.floor((o-h/this.yScale)*(this.rows-1))),u=Math.min(this.rows-2,Math.ceil((o+h/this.yScale)*(this.rows-1)));for(let t=d;t<=u;t++)for(let e=m;e<=f;e++){const i=(e/(this.columns-1)-r)*this.xScale,a=(t/(this.rows-1)-o)*this.yScale,s=Math.exp(-(i*i+a*a)/(n*n))*c,h=t*this.columns+e;this.velocity[h]=Math.max(-12,this.velocity[h]-s)}}this.pending=!0}leave(){this.afterimage.leave(),this.contour.leave(),this.trail.leave(),this.previous=null,"water"!==this.mode&&this.lensStrength&&(this.pending=!0)}clear(){this.trail.clear(),this.contour.clear(),this.afterimage.clear(),this.heights.fill(0),this.velocity.fill(0),this.next.fill(0),this.normals.fill(0),this.refraction.focus[2]=0,this.previous=null,this.lensStrength=0,this.energy=0,this.pending=!1,this.remainder=0;for(let t=0;t<this.waterPixels.length;t+=4)this.waterPixels[t]=this.waterPixels[t+2]=128,this.waterPixels[t+1]=this.waterPixels[t+3]=0}step(t){if(!this.active||!Number.isFinite(t))return;if(G(this.mode))return void this.afterimage.step(t);if("contour"===this.mode)return void this.contour.step(t);if("trail"===this.mode)return void this.trail.step(t);if("water"!==this.mode)return void this.stepLight(Math.max(0,Math.min(.05,t)));this.remainder+=Math.max(0,Math.min(.05,t));const e=1/120,i=Math.exp(-3.8*e),a=.3*Math.min(this.columns,this.rows);for(;this.remainder+1e-8>=e;){this.remainder-=e;let t=0;for(let s=1;s<this.rows-1;s++)for(let r=1;r<this.columns-1;r++){const o=s*this.columns+r,n=this.heights[o],h=this.heights[o-1]+this.heights[o+1]+this.heights[o-this.columns]+this.heights[o+this.columns]-4*n,l=Math.min(r,s,this.columns-1-r,this.rows-1-s),c=l<5?.88+.024*l:1,m=(this.velocity[o]+(h*a*a-8*n)*e)*i*c;this.velocity[o]=m,this.next[o]=(n+m*e)*c,t=Math.max(t,Math.abs(this.next[o]),.1*Math.abs(m))}this.heights.set(this.next),this.energy=t,this.pending=!1}if(!this.active)return void this.clear();const s=.18*Math.min(this.columns,this.rows);for(let t=0;t<this.rows;t++)for(let e=0;e<this.columns;e++){const i=t*this.columns+e,a=(this.heights[t*this.columns+Math.max(0,e-1)]-this.heights[t*this.columns+Math.min(this.columns-1,e+1)])*s,r=(this.heights[Math.max(0,t-1)*this.columns+e]-this.heights[Math.min(this.rows-1,t+1)*this.columns+e])*s,o=Math.tanh(a)*(this.refraction.edgeSafe?this.edgeMask[i]:1),n=Math.tanh(r)*(this.refraction.edgeSafe?this.edgeMask[i]:1);this.normals[2*i]=o,this.normals[2*i+1]=n;const h=Math.round(32767*o+32768),l=Math.round(32767*n+32768);this.refraction.pixels[4*i]=h>>>8,this.refraction.pixels[4*i+1]=255&h,this.refraction.pixels[4*i+2]=l>>>8,this.refraction.pixels[4*i+3]=255&l}}stepLight(t){const e=this.previous,i=1-Math.exp(-30*t),a=1-Math.exp(-12*t);e&&(this.lensX+=(e.x-this.lensX)*i,this.lensY+=(e.y-this.lensY)*i),this.lensStrength+=((e?1:0)-this.lensStrength)*a,this.energy=Math.max(e?Math.abs(e.x-this.lensX)+Math.abs(e.y-this.lensY):0,Math.abs((e?1:0)-this.lensStrength)),this.pending=!1,e||this.active?this.refraction.focus=[this.lensX,this.lensY,this.lensStrength*this.amount,this.radius]:this.clear()}sample(t,e,i){if(G(this.mode))return this.afterimage.sample(t,e,i),i[0]*=this.amount,i[1]*=this.amount,void(i[2]*=this.amount);if("contour"===this.mode)return i[0]=i[1]=0,void(i[2]=this.contour.sample(t,e)*this.amount*3);if("trail"===this.mode)return i[0]=i[1]=0,void(i[2]=this.trail.sample(t,e)*this.amount*3);const a=Math.max(0,Math.min(this.columns-1.001,t*(this.columns-1))),s=Math.max(0,Math.min(this.rows-1.001,e*(this.rows-1))),r=Math.floor(a),o=Math.floor(s),n=a-r,h=s-o,l=2*(o*this.columns+r),c=l+2*this.columns;for(let t=0;t<2;t++)i[t]=.08*((this.normals[l+t]*(1-n)+this.normals[l+2+t]*n)*(1-h)+(this.normals[c+t]*(1-n)+this.normals[c+2+t]*n)*h);i[0]*=this.amount/.55,i[1]*=this.amount/.55,i[2]="light"===this.mode||"scan"===this.mode?function(t,e,i,a){const[s,r,o,n]=i.focus,h=(t-s)*Math.max(1,a)/n,l=(e-r)*Math.max(1,1/a)/n;return"light"===i.mode?Math.exp(-3*(h*h+l*l))*o:"scan"===i.mode?(1.3*Math.exp(-h*h*110)-.3*Math.exp(-h*h*12))*Math.exp(-l*l*1.8)*o:0}(t,e,this.refraction,this.xScale/this.yScale):0}};function J(t){return"videoWidth"in t?[t.videoWidth,t.videoHeight]:"naturalWidth"in t?[t.naturalWidth,t.naturalHeight]:[t.width,t.height]}var Z=(t=!1)=>{const e=document.createElement("canvas"),i=e.getContext("2d",{willReadFrequently:t});if(!i)throw new Error("Canvas 2D is unavailable.");return{canvas:e,ctx:i}},_=(t,e,i)=>{t.width===e&&t.height===i||(t.width=e,t.height=i)},$={blocks:" ░▒▓█",braille:" ⠁⠃⠇⡇⣇⣧⣷⣿",lines:" -═╪╬",cross:" ·+xX#",diagonal:" /╱╳",diamond:" ·◇◈◆",mixed:" .:+/◇#@"};function tt(t,e={},i={}){const a=t.getContext("2d");if(!a)throw new Error("Canvas is already owned by another renderer.");const s=Z(),r=Z(!0),h=Z(),l=Z(),c=Z(),m=Z(),f=Z(),d=Z(),u=Z(),g=Z();let M,x=0,v=y(e),b=0,w="",k="",A="",T=new Uint8ClampedArray(0),F=new Uint8ClampedArray(0),C=0,N=0,U=0,W=null,G="",q=new Q,j=0;const H=[0,0,0],K=[0,0,0,1],tt=[0,0,0,0];let et=P(v.color);const it=new R(v.color.denoise),at=Math.max(64,Math.min(4096,Number.isFinite(i.maxDimension)?i.maxDimension:960)),st=Math.max(256,Math.min(1048576,Number.isFinite(i.maxCells)?i.maxCells:12e3));let rt=st,ot=Math.max(.1,Math.min(8,i.pixelRatio??1));return{canvas:t,render:function(e,i=0,y=960,P=540,R=i*v.motion.speed){if(Number.isFinite(i)||(i=0),!Number.isFinite(y)||!Number.isFinite(P)||y<1||P<1)throw new Error("Render dimensions must be positive finite numbers.");const[Z,st]=J(e);if(!Z||!st)return;const nt=Math.min(1,at/Math.max(y,P)),ht=Math.max(2,Math.round(y*nt)),lt=Math.max(2,Math.round(P*nt));_(t,ht,lt),_(s.canvas,ht,lt),_(h.canvas,ht,lt),_(l.canvas,ht,lt),_(c.canvas,ht,lt),j!==ht/lt&&(j=ht/lt,q=new Q(j)),q.configure(v.hover.effect,v.hover.strength,v.hover.radius,v.hover.edgeSafe),q.step(Math.max(0,Math.min(.05,i-U))),U=i;const ct="currentTime"in e?e.getVideoPlaybackQuality?.().totalVideoFrames??e.currentTime:0,mt=[b,ht,lt,ct].join(":"),ft="dither"===v.style,dt=E(ht,lt,v,rt,ot),ut=dt.cell,gt=dt.rowHeight,pt=dt.columns,Mt=dt.rows;if(w!==mt||W!==e||C!==pt||N!==Mt){W=e,w=mt,k="",A="",C=pt,N=Mt,s.ctx.clearRect(0,0,ht,lt),s.ctx.save();const t=S(Z,st,ht,lt,v.crop);s.ctx.translate(t.x+t.width/2,t.y+t.height/2),s.ctx.rotate(v.crop.rotation*Math.PI/180),s.ctx.drawImage(e,-Z*t.scale/2,-st*t.scale/2,Z*t.scale,st*t.scale),s.ctx.restore(),_(r.canvas,C,N),r.ctx.clearRect(0,0,C,N),r.ctx.drawImage(s.canvas,0,0,C,N),T=r.ctx.getImageData(0,0,C,N).data,it.apply(T,C,N);const i=v.color;for(let t=0;t<T.length;t+=4){const e=.299*T[t]+.587*T[t+1]+.114*T[t+2];for(let a=0;a<3;a++){const s=e+(T[t+a]-e)*i.saturation;T[t+a]=((s*(1-i.grayscale)+e*i.grayscale)/255-.5)*i.contrast*255+127.5+255*i.brightness}}et&&function(t,e){for(let i=0;i<t.length;i+=4)t[i+3]&&(t[i]=e[t[i]],t[i+1]=e[256+t[i+1]],t[i+2]=e[512+t[i+2]])}(T,et)}const xt=D(v),vt=L(v),bt=!q.active&&!xt&&!vt,wt=[mt,C,N,ut,gt,ot].join(":");if(!bt||A!==wt){h.ctx.clearRect(0,0,ht,lt),h.ctx.globalAlpha=1,h.ctx.globalCompositeOperation="source-over";const t=R,e=xt?v.motion.type:"none",a=["none","caustics","sheen","grain","trace"].includes(e);if(ft){const a=bt;if(!a||k!==mt){F.length!==T.length&&(F=new Uint8ClampedArray(T.length));const s=F;if(s.set(T),q.active||"none"!==e)for(let i=0;i<N;i++)for(let a=0;a<C;a++){const r=a/C,h=i/N;let l=a,c=i,m=0,f=1,d=1;q.active&&(q.sample(r,h,H),l-=H[0]*C,c-=H[1]*N,m=H[2]/3);const u=4*(i*C+a);o(e,r,h,t,K,(.299*T[u]+.587*T[u+1]+.114*T[u+2])/255),n(K,v.motion.amount??1),l-=K[0]/960*C,c-=K[1]/960*N,f=1+K[2],d=K[3],l=Math.max(0,Math.min(C-1,l)),c=Math.max(0,Math.min(N-1,c));const g=Math.floor(l),p=Math.floor(c),M=l-g,x=c-p,b=4*(i*C+a),w=4*(p*C+g),y=4*(p*C+Math.min(C-1,g+1)),S=4*(Math.min(N-1,p+1)*C+g),k=4*(Math.min(N-1,p+1)*C+Math.min(C-1,g+1));for(let t=0;t<3;t++){const e=((T[w+t]*(1-M)+T[y+t]*M)*(1-x)+(T[S+t]*(1-M)+T[k+t]*M)*x)/255;let i=(["trail","contour"].includes(v.hover.effect)?V(e,m):"etch"===v.hover.effect?Math.max(0,Math.min(1,e+.35*m)):"dissolve"===v.hover.effect?e*Math.max(0,1+m):e)*f;s[b+t]=255*i}s[b+3]=T[w+3]*d}!function(t,e,i,a,s=0){const{algorithm:r,amount:o,threshold:n}=a,h="blue-noise"===r,l=r.startsWith("bayer")?Number(r.slice(5)):0,c=Y.get(l),m=l-1,f="luminance"===a.colorSpace,d=("custom"===a.palette?a.colors:p[a.palette]??p.mono).map(z),u=B[r],g=u?new Float32Array(3*e*3):null,M="drift"===a.motion?s*a.speed*3:0,x=(a.direction??45)*Math.PI/180,v=Math.round(Math.cos(x)*M),b=Math.round(Math.sin(x)*M),w=(t,e)=>(t%e+e)%e,y=d.map(t=>.299*t[0]+.587*t[1]+.114*t[2]),S="shimmer"===a.motion?.15*Math.sin(s*a.speed*2):0;for(let a=0;a<i;a++)for(let s=0;s<e;s++){const p=4*(a*e+s),x=3*(a%3*e+s);if(0===t[p+3]){g&&(g[x]=g[x+1]=g[x+2]=0);continue}let k=0;const A=h?(O[64*(a-b&63)+(s-v&63)]+.5)/O.length:0;c?k=c[(a-b&m)*l+(s-v&m)]:"noise"===r?k=X(s-v,a-b)-.5:"lines"===r?k=w(a-b,4)/3-.5:"vertical-lines"===r?k=w(s-v,4)/3-.5:"diagonal-lines"===r?k=w(s-v+a-b,4)/3-.5:"radial"===r?k=w(Math.hypot(s-e/2,a-i/2)-M,6)/6-.5:"halftone"===r&&(k=Math.hypot(w(s-v,6)-2.5,w(a-b,6)-2.5)/3.54-.5);const E=128*(k*o+S+(.5-n)),T=t[p]+E+(g?.[x]??0),F=t[p+1]+E+(g?.[x+1]??0),I=t[p+2]+E+(g?.[x+2]??0);let P=0,R=0,C=0;if(d.length){let t=1/0,e=1/0,i=0,a=0;const s=.299*T+.587*F+.114*I;for(let r=0;r<d.length;r++){const o=d[r],n=f?(s-y[r])**2:(T-o[0])**2*.299+(F-o[1])**2*.587+(I-o[2])**2*.114;n<t?(h&&(e=t,a=i,i=r),t=n,[P,R,C]=o):h&&n<e&&(e=n,a=r)}if(h&&o>0&&Number.isFinite(e)){const t=d[a],e=t[0]-P,r=t[1]-R,n=t[2]-C,h=y[a]-y[i],l=f?h*h:e*e*.299+r*r*.587+n*n*.114,c=f?(s-y[i])*h:(T-P)*e*.299+(F-R)*r*.587+(I-C)*n*.114;A<(l?Math.max(0,Math.min(1,c/l*o)):0)&&([P,R,C]=t)}}else if(h){const t=Math.max(0,Math.min(1,.5+(A-.5)*o));P=51*Math.floor(T/51+1-t),R=51*Math.floor(F/51+1-t),C=51*Math.floor(I/51+1-t)}else P=51*Math.round(T/51),R=51*Math.round(F/51),C=51*Math.round(I/51);if(t[p]=P,t[p+1]=R,t[p+2]=C,g&&u){g[x]=g[x+1]=g[x+2]=0;for(const[t,r,n]of u){const h=s+t;if(h<0||h>=e||a+r>=i)continue;const l=3*((a+r)%3*e+h);g[l]+=(T-P)*n*o,g[l+1]+=(F-R)*n*o,g[l+2]+=(I-C)*n*o}}}}(s,C,N,v.dither,i),r.ctx.putImageData(new ImageData(s,C,N),0,0),k=a?mt:""}h.ctx.imageSmoothingEnabled=!1,h.ctx.drawImage(r.canvas,0,0,ht,lt)}else{const i=Array.from($[v.style]??v.charset),s=h.ctx,r=z(v.ink),l="ascii"===v.style||!!$[v.style],c=Math.max(3,Math.round(.92*gt)),m=Math.ceil(ut+4),d=Math.ceil(gt+4),u=[i.join(""),c,m,d,v.ink,v.colorMode].join(":");if(l&&u!==G&&(G=u,_(f.canvas,m*i.length,d),f.ctx.clearRect(0,0,f.canvas.width,d),f.ctx.font=`${c}px monospace`,f.ctx.textBaseline="middle",f.ctx.textAlign="center",f.ctx.fillStyle="accent"===v.colorMode?v.ink:"#ffffff",i.forEach((t,e)=>f.ctx.fillText(t,e*m+m/2,d/2))),"lego"===v.style&&x!==ut){x=ut,_(g.canvas,Math.ceil(ut),Math.ceil(gt));const t=g.ctx;t.clearRect(0,0,g.canvas.width,g.canvas.height),t.fillStyle="rgba(255,255,255,.2)",t.strokeStyle="rgba(0,0,0,.25)",t.lineWidth=Math.max(.5,.6*ot),t.beginPath(),t.arc(ut/2,gt/2,.28*ut,0,2*Math.PI),t.fill(),t.stroke()}s.font=`${c}px monospace`,s.textBaseline="middle",s.textAlign="center";for(let h=0;h<N;h++)for(let c=0;c<C;c++){let u=c,p=h,M=0;if(q.active&&(q.sample(c/C,h/N,H),u=Math.max(0,Math.min(C-1,c-H[0]*C)),p=Math.max(0,Math.min(N-1,h-H[1]*N)),M=H[2]/3),I(T,C,N,u,p,tt),!tt[3])continue;const x=tt[0],b=tt[1],w=tt[2],y=(.299*x+.587*b+.114*w)/255;let S=y;["trail","contour"].includes(v.hover.effect)&&M?S=V(S,M):"etch"===v.hover.effect?S=Math.max(0,Math.min(1,S+.35*M)):"dissolve"===v.hover.effect&&(S*=Math.max(0,1+M));let k=c*ut,A=h*gt,E=1;o(e,c/C,h/N,t,K,y),n(K,v.motion.amount??1),k+=K[0]*ht/960,A+=K[1]*lt/960,S=Math.max(0,Math.min(1,S+K[2])),E=K[3]*tt[3]/255,l||"accent"!==v.colorMode||"cmyk"===v.style||(E*=S),s.globalAlpha=E;const F=255*(S-y),P="source"===v.colorMode?`rgb(${x+F},${b+F},${w+F})`:"gray"===v.colorMode?`rgb(${Math.round(255*S)},${Math.round(255*S)},${Math.round(255*S)})`:v.ink;if(s.fillStyle=P,l){const t=Math.max(0,Math.min(i.length-1,Math.round(S*(i.length-1))));"accent"===v.colorMode?s.drawImage(f.canvas,t*m,0,m,d,a?Math.round(k+(ut-m)/2):k+(ut-m)/2,a?Math.round(A+(gt-d)/2):A+(gt-d)/2,m,d):s.fillText(i[t],k+ut/2,A+gt/2)}else if("dots"===v.style)s.beginPath(),s.arc(k+ut/2,A+gt/2,.48*ut*Math.sqrt(S),0,2*Math.PI),s.fill();else if("led"===v.style)s.beginPath(),s.arc(k+ut/2,A+gt/2,.39*ut,0,2*Math.PI),s.fill(),s.globalAlpha=.35*E,s.fillStyle="#ffffff",s.beginPath(),s.arc(k+.43*ut,A+.4*gt,.11*ut,0,2*Math.PI),s.fill();else if("hex"===v.style){const t=k+ut/2,e=A+gt/2;s.beginPath();for(let i=0;i<6;i++){const a=Math.PI/3*i,r=t+Math.cos(a)*ut*.49,o=e+Math.sin(a)*gt*.49;0===i?s.moveTo(r,o):s.lineTo(r,o)}s.closePath(),s.fill()}else if("cmyk"===v.style){s.fillStyle="#ffffff",s.fillRect(k,A,ut,gt);const t=(t,e)=>Math.max(0,Math.min(255,"source"===v.colorMode?t+F:"gray"===v.colorMode?255*S:e*S)),e=t(x,r[0]),i=t(b,r[1]),a=t(w,r[2]),o=1-Math.max(e,i,a)/255,n=Math.max(.001,1-o),h=[["#00ffff",(1-e/255-o)/n,.36,.36],["#ff00ff",(1-i/255-o)/n,.64,.36],["#ffff00",(1-a/255-o)/n,.5,.66],["#000000",o,.5,.5]];s.globalCompositeOperation="multiply";for(const[t,e,i,a]of h)s.fillStyle=t,s.beginPath(),s.arc(k+ut*i,A+gt*a,.48*ut*Math.sqrt(Math.max(0,e)),0,2*Math.PI),s.fill();s.globalCompositeOperation="source-over"}else if("voxel"===v.style){const t=k+ut/2,e=A+gt/2;s.beginPath(),s.moveTo(t,A),s.lineTo(k+ut,A+.25*gt),s.lineTo(t,e),s.lineTo(k,A+.25*gt),s.closePath(),s.fill(),s.globalAlpha=.72*E,s.beginPath(),s.moveTo(k,A+.25*gt),s.lineTo(t,e),s.lineTo(t,A+gt),s.lineTo(k,A+.75*gt),s.closePath(),s.fill(),s.globalAlpha=.42*E,s.beginPath(),s.moveTo(t,e),s.lineTo(k+ut,A+.25*gt),s.lineTo(k+ut,A+.75*gt),s.lineTo(t,A+gt),s.closePath(),s.fill()}else{const t="pixel"===v.style?0:Math.max(.5,.06*ut);s.fillRect(k,A,ut-t,gt-t),"lego"===v.style&&s.drawImage(g.canvas,k,A),"disco"===v.style&&(s.fillStyle=`rgba(255,255,255,${.1+.25*X(c,h)})`,s.fillRect(k,A,ut-t,.35*gt),s.fillStyle="rgba(0,0,0,.25)",s.fillRect(k,A+.65*gt,ut-t,.35*gt-t))}}}h.ctx.globalAlpha=1,(v.color.amount||v.lights.length)&&(_(d.canvas,ht,lt),d.ctx.clearRect(0,0,ht,lt),d.ctx.drawImage(h.canvas,0,0)),v.color.amount&&(h.ctx.save(),h.ctx.globalCompositeOperation=v.color.blend,h.ctx.globalAlpha=v.color.amount,h.ctx.fillStyle=v.color.tint,h.ctx.fillRect(0,0,ht,lt),h.ctx.restore());for(const t of v.lights){const e=t.radius*Math.max(ht,lt),i=h.ctx.createRadialGradient(t.x*ht,t.y*lt,0,t.x*ht,t.y*lt,e);i.addColorStop(0,t.color),i.addColorStop(1,"transparent"),h.ctx.save(),h.ctx.globalCompositeOperation="screen",h.ctx.globalAlpha=t.intensity,h.ctx.fillStyle=i,h.ctx.fillRect(0,0,ht,lt),h.ctx.restore()}if((v.color.amount||v.lights.length)&&(h.ctx.globalCompositeOperation="destination-in",h.ctx.drawImage(d.canvas,0,0),h.ctx.globalCompositeOperation="source-over"),v.mask.enabled&&v.mask.shapes.length){const t=c.ctx;t.clearRect(0,0,ht,lt),t.fillStyle="#fff",t.strokeStyle="#fff",t.lineCap="round",t.lineJoin="round";for(const e of v.mask.shapes){if(t.beginPath(),"ellipse"===e.kind)t.ellipse((e.x+e.width/2)*ht,(e.y+e.height/2)*lt,e.width*ht/2,e.height*lt/2,0,0,2*Math.PI);else{if("rectangle"!==e.kind){if(t.lineWidth=(e.size??.05)*ht,1===e.points?.length){t.arc(e.points[0][0]*ht,e.points[0][1]*lt,t.lineWidth/2,0,2*Math.PI),t.fill();continue}e.points?.forEach(([e,i],a)=>a?t.lineTo(e*ht,i*lt):t.moveTo(e*ht,i*lt)),t.stroke();continue}t.rect(e.x*ht,e.y*lt,e.width*ht,e.height*lt)}t.fill()}h.ctx.globalCompositeOperation=v.mask.invert?"destination-out":"destination-in",h.ctx.drawImage(c.canvas,0,0),h.ctx.globalCompositeOperation="source-over"}const M=l.ctx;M.clearRect(0,0,ht,lt),M.globalAlpha=v.backdrop.opacity;const b=v.backdrop;if("solid"===b.mode&&(M.fillStyle=b.color,M.fillRect(0,0,ht,lt)),"gradient"===b.mode){const t=M.createLinearGradient(0,0,ht,lt);t.addColorStop(0,b.color),t.addColorStop(1,b.color2),M.fillStyle=t,M.fillRect(0,0,ht,lt)}if("source"===b.mode&&M.drawImage(s.canvas,0,0),"blurred"===b.mode){const t=Math.max(1,b.blur);_(m.canvas,Math.max(2,Math.round(ht/t)),Math.max(2,Math.round(lt/t))),m.ctx.drawImage(s.canvas,0,0,m.canvas.width,m.canvas.height),M.imageSmoothingEnabled=!0,M.drawImage(m.canvas,0,0,ht,lt)}M.globalAlpha=1,v.effects.characterBloom>0&&(_(u.canvas,Math.max(2,Math.round(ht/3)),Math.max(2,Math.round(lt/3))),u.ctx.clearRect(0,0,u.canvas.width,u.canvas.height),u.ctx.drawImage(h.canvas,0,0,u.canvas.width,u.canvas.height),M.save(),M.globalAlpha=.8*v.effects.characterBloom,M.globalCompositeOperation="screen",M.filter=`blur(${1+4*v.effects.characterBloom}px)`,M.drawImage(u.canvas,0,0,ht,lt),M.restore()),M.drawImage(h.canvas,0,0),A=bt?wt:""}const yt=Object.entries(v.effects).some(([t,e])=>!["angle","focus","blurType","characterBloom"].includes(t)&&"number"==typeof e&&e>0);a.clearRect(0,0,ht,lt),yt?(void 0===M&&(M=function(){const t=document.createElement("canvas"),e=t.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,antialias:!1,preserveDrawingBuffer:!0});if(!e)return null;const i=[],a=(t,a)=>{const s=e.createShader(t);if(i.push(s),e.shaderSource(s,a),e.compileShader(s),!e.getShaderParameter(s,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(s)||"Finish shader failed");return s},s=e.createProgram();if(e.attachShader(s,a(e.VERTEX_SHADER,"attribute vec2 p;varying vec2 uv;void main(){uv=(p+1.)*.5;gl_Position=vec4(p,0.,1.);}")),e.attachShader(s,a(e.FRAGMENT_SHADER,"precision mediump float;varying vec2 uv;uniform sampler2D src;uniform vec2 size;uniform float t,bloom,grain,dust,scanlines,crt,prism,vignette,glitch,pixelate,blur,blurMode,angle,focus,halftone,rgbSplit,sharpen;\n float hash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\n vec4 sampleAt(vec2 p){if(min(min(p.x,p.y),min(1.-p.x,1.-p.y))<0.)return vec4(0.);return texture2D(src,vec2(p.x,1.-p.y));}\n void main(){vec2 q=uv,c=q-.5;q=c*(1.+dot(c,c)*crt*.25)+.5;\n if(glitch>0.)q.x+=(hash(vec2(floor(q.y*35.),floor(t*5.)))-.5)*.07*glitch*step(.82,hash(vec2(floor(q.y*35.),floor(t*5.)+3.)));\n if(pixelate>0.){vec2 grid=size/(1.+pixelate*20.);q=(floor(q*grid)+.5)/grid;}\n vec4 base=sampleAt(q);float edge=smoothstep(.12,.65,length(c));\n vec2 shift=vec2((prism*3.*edge+rgbSplit*8.)/size.x,prism*edge/size.y);\n if(prism>0.||rgbSplit>0.)base.rgb=vec3(sampleAt(q+shift).r,base.g,sampleAt(q-shift).b);\n vec2 dir=vec2(cos(angle),sin(angle))/size;float amount=blur;\n if(blurMode>1.5&&blurMode<2.5){dir=normalize(c+vec2(.0001))/size;amount*=length(c)*2.;}\n if(blurMode>2.5)amount*=smoothstep(.05,.5,abs(q.y-focus));\n vec4 blurred=base;\n if(amount>0.){blurred=base*.2;for(int i=1;i<=4;i++){float f=float(i)*amount*.35;vec2 off=dir*f;if(blurMode<.5)off=vec2(cos(float(i)*1.57),sin(float(i)*1.57))*amount/size;blurred+=sampleAt(q+off)*.1+sampleAt(q-off)*.1;}}\n vec3 light=vec3(0.);if(bloom>0.)for(int i=0;i<4;i++){float a=float(i)*1.5708;vec3 s=sampleAt(q+vec2(cos(a),sin(a))*6./size).rgb;light+=max(vec3(0.),s-.35)*.25;}\n vec3 col=blurred.rgb+light*bloom;\n if(sharpen>0.){vec2 px=1./size;vec3 near=sampleAt(q+vec2(px.x,0.)).rgb+sampleAt(q-vec2(px.x,0.)).rgb+sampleAt(q+vec2(0.,px.y)).rgb+sampleAt(q-vec2(0.,px.y)).rgb;col+=(base.rgb*4.-near)*sharpen*.5;}\ncol*=1.-scanlines*.4*(.5+.5*cos(q.y*size.y*3.14159));\n col*=1.-vignette*smoothstep(.15,.72,length(c));\n col+=(hash(floor(q*size)+floor(t*12.))-.5)*grain*.2;\n if(dust>0.)col+=step(1.-dust*.002,hash(floor(q*size*.25)+floor(t*2.)))*.4;\n if(halftone>0.)col*=mix(1.,smoothstep(.1,.65,length(fract(q*size/6.)-.5)),halftone);\n gl_FragColor=vec4(clamp(col,0.,1.),blurred.a);}")),e.linkProgram(s),!e.getProgramParameter(s,e.LINK_STATUS))throw new Error("Finish link failed");e.useProgram(s);const r=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,r),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),e.STATIC_DRAW);const o=e.getAttribLocation(s,"p");e.enableVertexAttribArray(o),e.vertexAttribPointer(o,2,e.FLOAT,!1,0,0);const n=e.createTexture();e.bindTexture(e.TEXTURE_2D,n),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE);const h=["t","bloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","blur","blurMode","angle","focus","halftone"],l=Object.fromEntries(h.map(t=>[t,e.getUniformLocation(s,t)])),c=e.getUniformLocation(s,"size");return{canvas:t,render(i,a,r,o=1){t.width===i.width&&t.height===i.height||(t.width=i.width,t.height=i.height,e.viewport(0,0,t.width,t.height)),e.useProgram(s),e.bindTexture(e.TEXTURE_2D,n),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,i),e.uniform2f(c,t.width/o,t.height/o);for(const t of h)e.uniform1f(l[t],"t"===t?r:"blurMode"===t?["gaussian","directional","radial","progressive"].indexOf(a.blurType):"angle"===t?a.angle*Math.PI/180:a[t]??0);return e.drawArrays(e.TRIANGLE_STRIP,0,4),t},destroy(){e.deleteTexture(n),e.deleteBuffer(r),e.deleteProgram(s),i.forEach(t=>e.deleteShader(t)),t.width=t.height=1,e.getExtension("WEBGL_lose_context")?.loseContext()}}}()),M?a.drawImage(M.render(l.canvas,v.effects,i,ot),0,0):a.drawImage(l.canvas,0,0),t.dataset.studioFinish=M?"gpu":"unavailable"):(a.drawImage(l.canvas,0,0),t.dataset.studioFinish="none")},setPixelRatio(t){ot=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1))},get pixelRatio(){return ot},setBudget(t){rt=Math.max(256,Math.min(st,Number.isFinite(t)?Math.round(t):st))},get maxCells(){return rt},configure(t){v=y(t),et=P(v.color),it.configure(v.color.denoise),b++},pointer:(t,e,i)=>{q.configure(v.hover.effect,v.hover.strength,v.hover.radius,v.hover.edgeSafe),q.move(t,e,i)},leave(){q.leave()},get active(){return q.active},get settings(){return y(v)},get capabilities(){return{gpuFinish:null!==M}},invalidate(){w=""},destroy(){M?.destroy();for(const t of[s,r,h,l,c,m,f,d,u,g])t.canvas.width=t.canvas.height=1;W=null,T=new Uint8ClampedArray(0)}}}function et(t,e,i){return new Promise((a,s)=>{const r=()=>{l(),a()},o=()=>{l(),s(new Error("Unable to load this media. Check its format and cross-origin permissions."))},n=()=>{l(),s(new DOMException("Cancelled","AbortError"))},h=setTimeout(o,2e4),l=()=>{clearTimeout(h),t.removeEventListener(e,r),t.removeEventListener("error",o),i?.removeEventListener("abort",n)};t.addEventListener(e,r,{once:!0}),t.addEventListener("error",o,{once:!0}),i?.addEventListener("abort",n,{once:!0}),i?.aborted&&n()})}async function it(t,e){if("string"==typeof t&&t.startsWith("blob:")){const i=await fetch(t,{signal:e}),a=await i.blob();return it(new File([a],"Imported media",{type:a.type}),e)}const i="string"!=typeof t,a=i?t.name:t;if(i?"image/gif"===t.type:/\.gif(?:[?#]|$)/i.test(a)){const a=await import("gifuct-js"),{parseGIF:s,decompressFrames:r}="function"==typeof a.parseGIF?a:a.default,o=i?await t.arrayBuffer():await fetch(t,{signal:e}).then(t=>{if(!t.ok)throw new Error("GIF download failed.");return t.arrayBuffer()});if(e?.aborted)throw new DOMException("Cancelled","AbortError");const n=s(o),h=n.lsd.width,l=n.lsd.height;if(h*l>4e6)throw new Error("GIF is too large. Use a smaller GIF or an MP4.");const c=n.frames.filter(t=>"image"in t).length;if(!c||c*h*l*4>128e6)throw new Error("GIF exceeds the decoded memory budget. Use MP4 for long animations.");const m=r(n,!0);if(m.length*h*l*4>128e6)throw new Error("GIF exceeds the 128 MB decoded budget. Use MP4 for long animations.");const f=document.createElement("canvas");f.width=h,f.height=l;const d=f.getContext("2d"),u=document.createElement("canvas"),g=u.getContext("2d"),p=m.reduce((t,e)=>t+Math.max(20,e.delay),0)/1e3;let M=-1,x=null;const v=t=>{const e=(t%p+p)%p*1e3;let i=0,a=0;for(;a<m.length-1&&(i+=Math.max(20,m[a].delay),!(e<i));a++);a<M&&(d.clearRect(0,0,h,l),M=-1,x=null);for(let t=M+1;t<=a;t++){const e=m[t-1];2===e?.disposalType&&d.clearRect(e.dims.left,e.dims.top,e.dims.width,e.dims.height),3===e?.disposalType&&x&&d.putImageData(x,0,0);const i=m[t];x=3===i.disposalType?d.getImageData(0,0,h,l):null,u.width=i.dims.width,u.height=i.dims.height,g.putImageData(new ImageData(new Uint8ClampedArray(i.patch),u.width,u.height),0,0),d.drawImage(u,i.dims.left,i.dims.top)}return M=a,f};return v(0),{source:f,width:h,height:l,duration:p,animated:!0,seek:async()=>{},frame:v,destroy(){f.width=u.width=1,m.length=0,x=null}}}const s=i?t.type.startsWith("video/"):/\.(mp4|webm|mov)(?:[?#]|$)/i.test(a),r=i?URL.createObjectURL(t):t,o=s?document.createElement("video"):new Image;o.crossOrigin="anonymous",o instanceof HTMLVideoElement&&(o.muted=!0,o.playsInline=!0,o.preload="auto");const n=()=>{o instanceof HTMLVideoElement?(o.pause(),o.removeAttribute("src"),o.load()):o.src="",i&&URL.revokeObjectURL(r)};try{const t=et(o,s?"loadeddata":"load",e);o.src=r,await t;const i=o instanceof HTMLVideoElement?o.videoWidth:o.naturalWidth,a=o instanceof HTMLVideoElement?o.videoHeight:o.naturalHeight;return{source:o,width:i,height:a,duration:o instanceof HTMLVideoElement?o.duration:0,animated:s,async seek(t,e){if(!(o instanceof HTMLVideoElement))return;if(!Number.isFinite(o.duration)||o.duration<=0)throw new Error("Video duration is unavailable.");const i=Math.max(0,Math.min(o.duration-.001,t%o.duration));if(Math.abs(o.currentTime-i)<.001&&o.readyState>=2)return;const a=et(o,"seeked",e);o.currentTime=i,await a},frame:()=>o,destroy:n}}catch(t){throw n(),t}}var at=t=>{if(t?.aborted)throw new DOMException("Export cancelled","AbortError")};function st(t,e,i={}){let a=y(i.settings),s=i.width??e.width,o=i.height??e.height;const n=tt(t,a,i),h=new r;let l=0,c=!1,m=!0,f=!1,d=!0,u=0,g=0,p=0,M=0,x=-1,v=!1!==i.adaptive,b=0,w=0,S=0;const E=matchMedia("(prefers-reduced-motion: reduce)"),T=e.source instanceof HTMLVideoElement?e.source:null,F=()=>{c||l||!d||document.hidden||(l=requestAnimationFrame(R))},I=()=>!f&&!E.matches&&d&&!document.hidden,P=()=>{T&&(T.loop=!0,I()?T.play().catch(()=>{f=!0,m=!0,F()}):T.pause()),p=0,m=!0,F()};function R(t){if(l=0,c||!d||document.hidden)return;const r=I();r&&(u+=p?Math.min(.1,(t-p)/1e3):0),p=t;const y=function(t){return D(t)||L(t)||t.effects.grain>0||t.effects.dust>0||t.effects.glitch>0}(a),A=r&&(e.animated||y),E=T?.getVideoPlaybackQuality?.().totalVideoFrames??-1,P=!T||E<0||E!==x;if(m||n.active||A&&(P||y)&&t-M>=1e3/Math.max(1,Math.min(60,i.fps??60))-.5){const r=performance.now();try{e.animated&&!T&&n.invalidate();const[t,l]=k(s,o,a);g=h.update(u,a.motion.type,a.motion.speed),n.render(e.frame(T?.currentTime??u),u,t,l,g);const c=performance.now()-r;i.onFrame?.(T?.currentTime??u,c),w=w?.9*w+.1*c:c,++b>20&&v&&(A||n.active)&&(S=w>13?S+1:0,S>=12&&n.maxCells>3e3&&(n.setBudget(Math.max(3e3,.8*n.maxCells)),i.onQualityChange?.(n.maxCells),S=0,w=0))}catch(t){f=!0,i.onError?.(t instanceof Error?t:new Error(String(t)))}m=!1,M=t,x=E}r&&(A||n.active)&&F()}const C=e=>{if(!I())return;const i=t.getBoundingClientRect();n.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),F()},N=()=>{n.leave(),F()},U=new IntersectionObserver(([t])=>{d=t.isIntersecting,P()});U.observe(t),t.addEventListener("pointermove",C),t.addEventListener("pointerleave",N),t.addEventListener("pointercancel",N),document.addEventListener("visibilitychange",P),E.addEventListener("change",P);const O=()=>{c||(c=!0,cancelAnimationFrame(l),U.disconnect(),t.removeEventListener("pointermove",C),t.removeEventListener("pointerleave",N),t.removeEventListener("pointercancel",N),document.removeEventListener("visibilitychange",P),E.removeEventListener("change",P),i.signal?.removeEventListener("abort",O),n.destroy(),e.destroy())};if(i.signal?.addEventListener("abort",O,{once:!0}),i.signal?.aborted)throw O(),new DOMException("Cancelled","AbortError");return P(),{canvas:t,media:e,update(t){a=A(a,t),n.configure(a),m=!0,F()},resize(t,e,i){void 0!==i&&n.setPixelRatio(i),s=Math.max(2,t),o=Math.max(2,e),m=!0,F()},pause(t=!0){f=t,P()},async seek(t){u=Math.max(0,t),await e.seek(u),n.invalidate(),m=!0,F()},redraw(){n.invalidate(),m=!0,F()},get time(){return T?.currentTime??u},get settings(){return y(a)},get motionTime(){return g},get paused(){return f||E.matches},setAdaptive(t){v=t,b=S=w=0},setBudget(t){n.setBudget(t),i.onQualityChange?.(n.maxCells),m=!0,F()},get pixelRatio(){return n.pixelRatio},get maxCells(){return n.maxCells},get capabilities(){return n.capabilities},destroy:O}}var rt={Standard:()=>import("figlet/fonts/Standard"),Slant:()=>import("figlet/fonts/Slant"),Small:()=>import("figlet/fonts/Small"),Big:()=>import("figlet/fonts/Big"),Banner:()=>import("figlet/fonts/Banner"),Block:()=>import("figlet/fonts/Block"),Bubble:()=>import("figlet/fonts/Bubble"),Digital:()=>import("figlet/fonts/Digital"),Doom:()=>import("figlet/fonts/Doom"),Lean:()=>import("figlet/fonts/Lean"),Mini:()=>import("figlet/fonts/Mini"),Script:()=>import("figlet/fonts/Script"),Shadow:()=>import("figlet/fonts/Shadow"),Speed:()=>import("figlet/fonts/Speed"),Starwars:()=>import("figlet/fonts/Star Wars"),Stop:()=>import("figlet/fonts/Stop"),Straight:()=>import("figlet/fonts/Straight"),Thin:()=>import("figlet/fonts/Thin"),ThreeD:()=>import("figlet/fonts/3-D"),Univers:()=>import("figlet/fonts/Univers"),Wavy:()=>import("figlet/fonts/Wavy")},ot=Object.keys(rt);var nt={standard:{label:"Classic ASCII",chars:" .:-=+*#%@"},asciify:{label:"Asciify",chars:" .:-=+ASCIIFY#@"},minimal:{label:"Minimal",chars:" .:+"},detailed:{label:"Detailed",chars:" .,:;i1tfLCG08@"},letters:{label:"Letters",chars:" .ilLCFTYASMW"},technical:{label:"Technical",chars:" .:;>_/[{}]=+*#@$"},blocks:{label:"Tonal blocks",chars:" ░▒▓█"},braille:{label:"Braille",chars:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},ht=nt;exports.BLEND_MODES=g,exports.CHARACTER_SETS=nt,exports.DEFAULT_STUDIO_SETTINGS=M,exports.DITHER_ALGORITHMS=u,exports.STUDIO_CHARACTER_SETS=ht,exports.STUDIO_CURVE_CHANNELS=h,exports.STUDIO_HOVERS=t,exports.STUDIO_LOOKS=T,exports.STUDIO_MOTIONS=e,exports.STUDIO_PALETTES=p,exports.STUDIO_STYLES=d,exports.STUDIO_TEXT_FONTS=ot,exports.createStudioCurveLookup=f,exports.createStudioRenderer=tt,exports.createStudioText=async function(t,e="Standard",i="#ffffff"){if(!Object.prototype.hasOwnProperty.call(rt,e))throw new Error("Unknown text font.");const{default:a}=await import("figlet/browser"),s=await rt[e]();a.parseFont(e,s.default),a.defaults({fetchFontIfMissing:!1});const r=a.textSync(t.slice(0,120),{font:e}),o=r.split("\n"),n=Math.max(1,...o.map(t=>t.length)),h=Math.max(1,o.length),l=Math.min(1,2048/(9*n)),c=document.createElement("canvas");c.width=Math.ceil(9*n*l+32),c.height=Math.ceil(15*h*l+32);const m=c.getContext("2d");return m.fillStyle="#080808",m.fillRect(0,0,c.width,c.height),m.fillStyle=i,m.font=15*l+"px monospace",m.textBaseline="top",o.forEach((t,e)=>m.fillText(t,16,16+15*e*l)),{canvas:c,ascii:r}},exports.exportStudio=async function(t,e,i){const{format:a,signal:s}=i,r=Math.round(i.width),o=Math.round(i.height);if(!Number.isFinite(r)||!Number.isFinite(o)||r<2||o<2||r>4096||o>4096||r*o>16777216)throw new Error("Choose export dimensions between 2 and 4096 pixels.");if(!["png","jpeg","mp4","webm","gif"].includes(a))throw new Error("Unknown export format.");if(void 0!==i.fps&&!Number.isFinite(i.fps))throw new Error("Frames per second must be finite.");const n=Math.max(1,Math.min(60,Math.round(i.fps??24))),h=i.duration??5;if(!Number.isFinite(h)||h<=0||h>60)throw new Error("Choose a duration from 0 to 60 seconds.");const l="png"===a||"jpeg"===a,c=i.time??0;if(!Number.isFinite(c)||c<0)throw new Error("Image time must be a finite non-negative number.");if(void 0!==i.motionTime&&(!Number.isFinite(i.motionTime)||i.motionTime<0))throw new Error("Motion time must be a finite non-negative number.");if(!l&&r*o>8294400)throw new Error("Video exports support up to 3840 × 2160 pixels.");if("gif"===a&&(r*o>921600||h*n>600))throw new Error("GIF export supports up to 1280 × 720 and 600 frames. Use MP4 for larger exports.");if(void 0!==i.referenceWidth&&(!Number.isFinite(i.referenceWidth)||i.referenceWidth<1))throw new Error("Reference width must be a positive number.");if("gif"===a&&n>30)throw new Error("GIF exports support up to 30 fps. Choose MP4 or WebM for higher frame rates.");const m=document.createElement("canvas"),f=tt(m,y(e),{maxDimension:4096,maxCells:i.maxCells??12e3,pixelRatio:r/(i.referenceWidth??Math.min(r,960))});let d;try{if(at(s),i.onProgress?.(0),l){if(f.render(await t.frame(c,s),c,r,o,i.motionTime),"unavailable"===m.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");at(s);const e=await new Promise((t,e)=>m.toBlob(i=>i?t(i):e(new Error("Image export failed.")),"png"===a?"image/png":"image/jpeg",i.quality??.92));return i.onProgress?.(1),e}const e=Math.ceil(h*n);if("gif"===a){const a=await import("gifenc"),{GIFEncoder:l,quantize:c,applyPalette:d}="function"==typeof a.GIFEncoder?a:a.default,u=l(),g=m.getContext("2d");for(let a=0;a<e;a++){at(s);const l=a/n;if(f.invalidate(),f.render(await t.frame(l,s),l,r,o),"unavailable"===m.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");const p=g.getImageData(0,0,r,o).data,M=c(p,256),x=d(p,M);u.writeFrame(x,r,o,{palette:M,delay:10*(Math.round(100*Math.min((a+1)/n,h))-Math.round(100*a/n)),repeat:0}),i.onProgress?.((a+1)/e*.98),await new Promise(t=>setTimeout(t,0))}return u.finish(),i.onProgress?.(1),new Blob([new Uint8Array(u.bytes())],{type:"image/gif"})}const{Output:u,Mp4OutputFormat:g,WebMOutputFormat:p,BufferTarget:M,CanvasSource:x,canEncodeVideo:v}=await import("mediabunny"),b="mp4"===a?"avc":"vp9";if(!await v(b,{width:r,height:o}))throw new Error(`${a.toUpperCase()} encoding is unavailable in this browser. Try another format or a current browser with WebCodecs.`);const w=new u({format:"mp4"===a?new g({fastStart:"in-memory"}):new p,target:new M});m.width=r,m.height=o,d=()=>w.cancel();const y=new x(m,{codec:b,bitrate:Math.max(5e5,Math.round(r*o*n*.15))});w.addVideoTrack(y,{frameRate:n}),m.width=r,m.height=o,await w.start();for(let a=0;a<e;a++){at(s);const l=a/n;if(f.invalidate(),f.render(await t.frame(l,s),l,r,o),"unavailable"===m.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");await y.add(l,Math.min(1/n,h-l)),i.onProgress?.((a+1)/e*.98),a%4==0&&await new Promise(t=>setTimeout(t,0))}return y.close(),at(s),await w.finalize(),d=void 0,i.onProgress?.(1),new Blob([w.target.buffer],{type:"mp4"===a?"video/mp4":"video/webm"})}catch(t){throw await(d?.().catch(()=>{})),t}finally{f.destroy(),m.width=m.height=1}},exports.loadStudioMedia=it,exports.mountStudio=async function(t,e,i={}){const a=await it(e,i.signal);try{return st(t,a,i)}catch(t){throw a.destroy(),t}},exports.mountStudioMedia=st,exports.normalizeStudioCurve=c,exports.normalizeStudioCurves=m,exports.normalizeStudioSettings=y,exports.parseStudioSettings=function(t){if(t.length>1e5)throw new Error("Settings exceed 100 KB.");return y(JSON.parse(t))},exports.restyleStudio=function(t,e=Math.random){const i=T.filter(e=>e.settings.style!==t.style||e.settings.ink!==t.ink),a=F(i[Math.min(i.length-1,Math.max(0,Math.floor(e()*i.length)))].id);return a.aspectRatio=t.aspectRatio,a.crop={...t.crop},a.mask=y(t).mask,a},exports.serializeStudioSettings=function(t){return JSON.stringify(y(t))},exports.studioCrop=S,exports.studioDimensions=k,exports.studioGrid=E,exports.studioLook=F,exports.studioSourceSize=J,exports.updateStudioSettings=A;//# sourceMappingURL=studio.cjs.map
|
|
1
|
+
"use strict";var t=[{value:"none",label:"Off",group:"Still",description:"Keep the artwork still under the pointer."},{value:"trail",label:"Trail",group:"Change characters",description:"A fluid wake changes character density and settles behind your cursor."},{value:"dissolve",label:"Dissolve",group:"Change characters",description:"Erase a soft path through the characters; the image gradually reforms."},{value:"contour",label:"Contour",group:"Change characters",description:"Fine tonal rings trace your path without moving the grid."},{value:"etch",label:"Emboss",group:"Change characters",description:"Press a light-and-shadow impression into the characters; the grid stays fixed."},{value:"water",label:"Water",group:"Move the image",description:"Soft ripples refract the image and settle after your stroke."},{value:"silk",label:"Silk",group:"Move the image",description:"Directional folds follow the movement of your hand."},{value:"vortex",label:"Vortex",group:"Move the image",description:"A swirling wake curls through the image."},{value:"magnetic",label:"Magnetic Pull",group:"Move the image",description:"The image gathers toward your stroke, then relaxes."},{value:"scatter",label:"Scatter",group:"Move the image",description:"A textured outward scatter settles behind your cursor."},{value:"elastic",label:"Elastic",group:"Move the image",description:"Push the image with your stroke; it recoils and springs back into place."},{value:"rake",label:"Rake",group:"Move the image",description:"Comb the image into alternating ribbons that glide back into alignment."}],e=[{value:"none",mode:"none",group:"Still",label:"Off",description:"Keep the image still. Hover stays available."},{value:"caustics",mode:"caustics",group:"Light and texture",label:"Caustics",description:"Soft ribbons of light travel across a stationary character grid."},{value:"current",mode:"current",group:"Flow and depth",label:"Slow Current",description:"A gentle flow through the image, with steady edges."},{value:"reform",mode:"reform",group:"Rebuild",label:"Reveal & Reform",description:"Disperse, gather, then hold the complete image."},{value:"sheen",mode:"sheen",group:"Light and texture",label:"Sheen",description:"A broad diagonal light sweep; characters stay anchored."},{value:"tidal",mode:"tidal",group:"Flow and depth",label:"Tidal Rings",description:"Concentric currents travel outward, with protected edges."},{value:"grain",mode:"grain",group:"Light and texture",label:"Living Grain",description:"Slow, individually phased tonal changes on a stationary grid."},{value:"parallax",mode:"parallax",group:"Flow and depth",label:"Parallax",description:"A shallow, continuous drift through the image, with the edges held in place."},{value:"weave",mode:"weave",group:"Flow and depth",label:"Woven Flow",description:"Interlaced bands move in opposing directions, like a flexible printed fabric."},{value:"print",mode:"print",group:"Rebuild",label:"Print Shift",description:"Staggered rows lift, soften and register back into the image."},{value:"trace",mode:"trace",group:"Light and texture",label:"Contour Light",description:"Light follows the source image’s tonal contours; every character stays anchored."}],i=t=>Math.max(0,Math.min(1,t)),a=(t,e,a)=>{const r=i((a-t)/(e-t));return r*r*(3-2*r)},r=(t,e)=>{const i=(.06711056*t+.00583715*e)%1*52.9829189;return i-Math.floor(i)},s=class{constructor(){this.last=null,this.mode="none",this.phase=0}update(t,e,i=1){return Number.isFinite(t)?((e!==this.mode||null!==this.last&&t<this.last)&&(this.mode=e,this.phase=0,this.last=t),null!==this.last&&(this.phase+=Math.max(0,t-this.last)*Math.max(.1,Math.min(3,Number.isFinite(i)?i:1))),this.last=t,this.phase):this.phase}};function o(t,e,s,o,n,h=.5){if(n[0]=n[1]=n[2]=0,n[3]=1,"none"===t)return n;const l=o*Math.PI/6,c=a(0,.12,Math.min(e,1-e,s,1-s));if("caustics"===t){const t=Math.sin(9*e+5*s+l)+Math.sin(8*s-3*e-l),i=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);n[2]=(.22*i-.045)*c}else if("current"===t)n[0]=Math.sin(9*s+l)*Math.cos(7*e-l)*10*c,n[1]=Math.cos(8*e+l)*Math.sin(6*s-l)*7*c;else if("sheen"===t)n[2]=.2*Math.pow(.5+.5*Math.cos(5*e+3*s-l),8)-.025;else if("tidal"===t){const t=e-.5,i=s-.5,a=Math.hypot(t,i),r=Math.sin(22*a-l)*c;n[0]=t*r*9,n[1]=i*r*9,n[2]=.035*r}else if("grain"===t){const t=r(Math.floor(160*e),Math.floor(100*s))*Math.PI*2;n[2]=.07*Math.sin(l+t)}else if("parallax"===t){const t=.45+.55*Math.max(0,1-1.4*Math.hypot(e-.5,s-.5));n[0]=12*Math.sin(l)*t*c,n[1]=6*(Math.cos(l)-1)*t*c}else if("weave"===t)n[0]=Math.sin(s*Math.PI*6+l)*Math.sin(l)*8*c,n[1]=Math.sin(e*Math.PI*6-l)*Math.sin(l)*6*c;else if("print"===t){const t=Math.floor(24*s),e=((o+3*r(t,3))%12+12)%12,i=a(1,2.5,e)*(1-a(3.5,5,e));n[0]=Math.sin(2.4*t)*i*9*c,n[1]=5*-i*c,n[2]=.22*-i,n[3]=1-.45*i}else if("trace"===t){const t=.5+.5*Math.cos(l);n[2]=.22*Math.pow(Math.max(0,1-Math.abs(i(h)-t)/.16),3)-.015}else if("reform"===t){const t=(o%12+12)%12,i=r(Math.floor(160*e),Math.floor(100*s)),h=.65*e+.2*s+.15*i+.08*Math.sin(8*e-5*s),d=a(1.8+1.2*h,3.8+1.2*h,t)*(1-a(5+1.7*h,7.2+1.7*h,t));n[0]=Math.sin(9*s+l)*d*(1-d)*24*c,n[1]=-d*(1-d)*(8+12*i)*c,n[2]=.45*-d,n[3]=1-.9*d}return n}function n(t,e){const a=Math.max(0,Math.min(2,Number.isFinite(e)?e:1));return t[0]*=a,t[1]*=a,t[2]*=a,t[3]=i(1+(t[3]-1)*a),t}var h=["rgb","red","green","blue"],l=t=>Math.max(0,Math.min(1,t));function c(t){const e=new Map([[0,0],[1,1]]);if(Array.isArray(t))for(const i of t.slice(0,64)){if(!Array.isArray(i)||i.length<2||"number"!=typeof i[0]||!Number.isFinite(i[0])||"number"!=typeof i[1]||!Number.isFinite(i[1]))continue;const t=Math.round(255*l(i[0]))/255;!e.has(t)&&e.size>=16||e.set(t,l(i[1]))}return[...e].sort((t,e)=>t[0]-e[0])}function d(t){const e=t&&"object"==typeof t?t:{};return Object.fromEntries(h.map(t=>[t,c(e[t])]))}function m(t){const e=c(t),i=e.length,a=e.slice(1).map((t,i)=>t[0]-e[i][0]),r=e.slice(1).map((t,i)=>(t[1]-e[i][1])/a[i]),s=new Float64Array(i);s[0]=r[0],s[i-1]=r[i-2];for(let t=1;t<i-1;t++){const e=r[t-1],i=r[t];if(e*i<=0)continue;const o=2*a[t]+a[t-1],n=a[t]+2*a[t-1];s[t]=(o+n)/(o/e+n/i)}const o=new Uint8Array(256);let n=0;for(let t=0;t<256;t++){const r=t/255;for(;n<i-2&&r>e[n+1][0];)n++;const h=a[n],c=(r-e[n][0])/h,d=c*c,m=d*c,f=(2*m-3*d+1)*e[n][1]+(m-2*d+c)*h*s[n]+(-2*m+3*d)*e[n+1][1]+(m-d)*h*s[n+1];o[t]=Math.round(255*l(f))}return o}function f(t,e,i,a,r,s){a=Math.max(0,Math.min(e-1,a)),r=Math.max(0,Math.min(i-1,r));const o=Math.floor(a),n=Math.floor(r),h=a-o,l=r-n,c=4*(n*e+o);if(0===h&&0===l){for(let e=0;e<4;e++)s[e]=t[c+e];return}const d=4*(n*e+Math.min(e-1,o+1)),m=4*(Math.min(i-1,n+1)*e+o),f=4*(Math.min(i-1,n+1)*e+Math.min(e-1,o+1)),u=(1-h)*(1-l)*t[c+3],p=h*(1-l)*t[d+3],g=(1-h)*l*t[m+3],M=h*l*t[f+3],x=u+p+g+M;for(let e=0;e<3;e++)s[e]=x?(t[c+e]*u+t[d+e]*p+t[m+e]*g+t[f+e]*M)/x:0;s[3]=x}function u(t,e,i,a,r,s){if(a>=0&&a<=e-1&&r>=0&&r<=i-1)return f(t,e,i,a,r,s);if(s[0]=s[1]=s[2]=s[3]=0,a<=-1||a>=e||r<=-1||r>=i)return;const o=Math.floor(a),n=Math.floor(r),h=a-o,l=r-n;for(let a=0;a<=1;a++)for(let r=0;r<=1;r++){const c=o+r,d=n+a;if(c<0||c>=e||d<0||d>=i)continue;const m=4*(d*e+c),f=(r?h:1-h)*(a?l:1-l)*t[m+3];s[0]+=t[m]*f,s[1]+=t[m+1]*f,s[2]+=t[m+2]*f,s[3]+=f}s[3]&&(s[0]/=s[3],s[1]/=s[3],s[2]/=s[3])}var p=[{value:"twirl",label:"Twirl",description:"Rotate the center into a smooth spiral; the outer boundary stays fixed.",direction:!1,frequency:!1},{value:"pinch",label:"Pinch",description:"Contract the center, or expand it with negative strength.",direction:!1,frequency:!1},{value:"sphere",label:"Spherize",description:"Magnify a rounded lens through the source; negative strength recedes.",direction:!1,frequency:!1},{value:"ripple",label:"Ripple",description:"Bend the image through concentric, soft-edged waves.",direction:!1,frequency:!0},{value:"zigzag",label:"Zigzag",description:"Alternate the twist in sharp, concentric bands.",direction:!1,frequency:!0},{value:"shear",label:"Shear",description:"Slant a region along an adjustable direction.",direction:!0,frequency:!1},{value:"smudge",label:"Smudge",description:"Draw a soft region of the source along one direction.",direction:!0,frequency:!1},{value:"polar",label:"Polar",description:"Unwrap a region into polar coordinates; negative strength wraps it.",direction:!0,frequency:!1},{value:"fragment",label:"Fragment",description:"Offset small source tiles into a stable fractured texture.",direction:!0,frequency:!0}],g=(t,e,i,a)=>"number"==typeof t&&Number.isFinite(t)?Math.max(i,Math.min(a,t)):e;function M(t){if(!Array.isArray(t))return[];const e=[];for(const i of t.slice(0,64))if(i&&"object"==typeof i&&p.some(t=>t.value===i.type)&&(e.push({type:i.type,enabled:!1!==i.enabled,amount:g(i.amount,.35,-1,1),x:g(i.x,.5,0,1),y:g(i.y,.5,0,1),radius:g(i.radius,.55,.05,2),angle:g(i.angle,0,-180,180),frequency:g(i.frequency,5,1,24)}),8===e.length))break;return e}var x=2*Math.PI,w=(t,e)=>{let i=Math.imul(t,374761393)^Math.imul(e,668265263);return i=Math.imul(i^i>>>13,1274126177),((i^i>>>16)>>>0)/4294967296},v=class{constructor(t=[],e="clamp"){this.warps=[],this.signature="",this.geometry="",this.coordinates=new Float32Array(0),this.output=new Uint8ClampedArray(0),this.sampled=[0,0,0,0],this.edge="clamp",this.configure(t,e)}configure(t=[],e="clamp"){const i=M(t).filter(t=>t.enabled&&0!==t.amount),a=JSON.stringify(i);this.edge="transparent"===e?"transparent":"clamp",a!==this.signature&&(this.signature=a,this.geometry="",this.warps=i.map(t=>({...t,cos:Math.cos(t.angle*Math.PI/180),sin:Math.sin(t.angle*Math.PI/180)})),i.length||this.clear())}get active(){return this.warps.length>0}apply(t,e,i,a=e/i){if(!this.active)return t;if(!Number.isInteger(e)||!Number.isInteger(i)||e<1||i<1||e*i*4!==t.length||!Number.isFinite(a)||a<=0)throw new Error("Warp dimensions do not match the source.");const r=`${e}:${i}:${a}`;if(r!==this.geometry){this.coordinates.length!==e*i*2&&(this.coordinates=new Float32Array(e*i*2));const t=Math.max(1,a),s=Math.max(1,1/a);for(let a=0;a<i;a++)for(let r=0;r<e;r++){let o=(r+.5)/e,n=(a+.5)/i;for(let e=this.warps.length-1;e>=0;e--){const i=this.warps[e],a=(o-i.x)*t/i.radius,r=(n-i.y)*s/i.radius,h=a*a+r*r;if(h>=1)continue;const l=Math.sqrt(h),c=(1-h)*(1-h),d=i.amount;let m=a,f=r;if("twirl"===i.type||"zigzag"===i.type){const t="twirl"===i.type?-d*x*c:.65*d*(2/Math.PI*Math.asin(Math.sin(l*x*i.frequency)))*c,e=Math.cos(t),s=Math.sin(t);m=a*e-r*s,f=a*s+r*e}else if("pinch"===i.type){const t=Math.exp(2*d*c);m=a*t,f=r*t}else if("sphere"===i.type&&l>0){const t=1+d*c*(2*Math.asin(l)/Math.PI/l-1);m=a*t,f=r*t}else if("ripple"===i.type&&l>0){const t=1+.12*d*Math.sin(l*x*i.frequency)*c/l;m=a*t,f=r*t}else if("shear"===i.type){const t=-a*i.sin+r*i.cos;m-=d*t*.9*c*i.cos,f-=d*t*.9*c*i.sin}else if("smudge"===i.type)m-=.65*d*c*i.cos,f-=.65*d*c*i.sin;else if("polar"===i.type){const t=a*i.cos+r*i.sin,e=-a*i.sin+r*i.cos,s=Math.atan2(e,t),o=d>0?s/Math.PI:Math.cos(t*Math.PI)*(e+1)/2,n=d>0?2*l-1:Math.sin(t*Math.PI)*(e+1)/2,h=o*i.cos-n*i.sin,u=o*i.sin+n*i.cos;m+=(h-a)*Math.abs(d)*c,f+=(u-r)*Math.abs(d)*c}else if("fragment"===i.type){const t=Math.floor((a*i.cos+r*i.sin)*i.frequency),e=Math.floor((-a*i.sin+r*i.cos)*i.frequency),s=(w(t,e)-.5)*d*.5*c,o=(w(e+71,t-31)-.5)*d*.5*c;m+=s*i.cos-o*i.sin,f+=s*i.sin+o*i.cos}o=i.x+m*i.radius/t,n=i.y+f*i.radius/s}const h=2*(a*e+r);this.coordinates[h]=o*e-.5,this.coordinates[h+1]=n*i-.5}this.geometry=r}this.output.length!==t.length&&(this.output=new Uint8ClampedArray(t.length));const s=t===this.output?t.slice():t,o="transparent"===this.edge?u:f;for(let a=0,r=0;a<t.length;a+=4,r+=2){o(s,e,i,this.coordinates[r],this.coordinates[r+1],this.sampled);for(let t=0;t<4;t++)this.output[a+t]=this.sampled[t]}return this.output}clear(){this.coordinates=new Float32Array(0),this.output=new Uint8ClampedArray(0),this.geometry=""}},y=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk"],b=["none","bayer2","bayer4","bayer8","bayer16","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis","halftone","lines","noise","vertical-lines","diagonal-lines","radial","blue-noise"],S=["source-over","multiply","screen","overlay","soft-light","hard-light","color-dodge","color-burn","hue","saturation","color","luminosity"],E={original:[],gray4:["#000000","#555555","#aaaaaa","#ffffff"],gray8:["#000000","#242424","#494949","#6d6d6d","#929292","#b6b6b6","#dbdbdb","#ffffff"],rgb8:["#000000","#ff0000","#00ff00","#0000ff","#ffff00","#ff00ff","#00ffff","#ffffff"],cyberpunk:["#08081a","#3c1670","#ed299a","#29dfef","#fff7bf"],pastel:["#393448","#a5b4d4","#9ed9c6","#e7aac1","#f5e8be"],mono:["#080808","#f2f2e8"],asciify:["#080808","#625b38","#a19558","#e8b900"],gameboy:["#0f380f","#306230","#8bac0f","#9bbc0f"],cga:["#000000","#55ffff","#ff55ff","#ffffff"],pico8:["#000000","#1d2b53","#7e2553","#008751","#ab5236","#5f574f","#c2c3c7","#fff1e8","#ff004d","#ffa300","#ffec27","#00e436","#29adff","#83769c","#ff77a8","#ffccaa"],c64:["#000000","#ffffff","#880000","#aaffee","#cc44cc","#00cc55","#0000aa","#eeee77","#dd8855","#664400","#ff7777","#333333","#777777","#aaff66","#0088ff","#bbbbbb"],amber:["#100b00","#5f3b00","#c98014","#ffd17c"],ice:["#081b29","#25586e","#69a6b3","#d9ece7"],risograph:["#f4ebd0","#f2594b","#2853a5","#29232e"],sepia:["#201b17","#6b5039","#b49868","#f6e6c5"],nord:["#2e3440","#4c566a","#88c0d0","#eceff4"],dusk:["#211b35","#654271","#c3788c","#f5c9a3"],forest:["#101f1b","#355747","#87a16f","#e4e3ba"],ocean:["#071b33","#17577f","#3fa7a4","#d9efde"],newsprint:["#191919","#666666","#aaaaaa","#eee9df"],custom:["#080808","#e8b900"]},k={version:1,aspectRatio:"original",style:"ascii",cellSize:6,charset:" .:-=+*#%@",colorMode:"accent",ink:"#e8b900",crop:{x:.5,y:.5,zoom:1,rotation:0},warps:[],warpEdge:"clamp",backdrop:{mode:"solid",color:"#080808",color2:"#393323",blur:12,opacity:1},color:{brightness:0,contrast:1,saturation:1,grayscale:0,tint:"#e8b900",amount:0,blend:"source-over",blackPoint:0,whitePoint:1,gamma:1,shadows:0,highlights:0,curves:{rgb:[[0,0],[1,1]],red:[[0,0],[1,1]],green:[[0,0],[1,1]],blue:[[0,0],[1,1]]},denoise:0},dither:{algorithm:"none",palette:"mono",colors:["#080808","#e8b900"],amount:1,scale:2,threshold:.5,motion:"none",speed:1,direction:45,colorSpace:"rgb"},mask:{enabled:!1,invert:!1,shapes:[]},lights:[],effects:{bloom:0,characterBloom:0,grain:0,dust:0,scanlines:0,crt:0,prism:0,rgbSplit:0,sharpen:0,vignette:0,glitch:0,pixelate:0,blur:0,blurType:"gaussian",angle:0,focus:.5,halftone:0},motion:{type:"none",speed:1,amount:1},hover:{effect:"trail",strength:.55,radius:.2,edgeSafe:!1}},A=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},F=(t,e,i,a)=>"number"==typeof t&&Number.isFinite(t)?Math.min(a,Math.max(i,t)):e,T=(t,e)=>"string"==typeof t&&/^#[\da-f]{6}$/i.test(t)?t:e,P=(t,e,i)=>e.includes(t)?t:i;function I(i={}){const a=A(i),r=k;if(void 0!==a.version&&1!==a.version)throw new Error("Unsupported studio settings version. Update asciify-engine.");const s=A(a.crop),o=A(a.backdrop),n=A(a.color),h=A(a.dither),l=A(a.mask),c=A(a.effects),m=A(a.motion),f=A(a.hover),u={...r.effects};for(const t of["bloom","characterBloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","halftone"])u[t]=F(c[t],0,0,1);u.blur=F(c.blur,0,0,24),u.blurType=P(c.blurType,["gaussian","directional","radial","progressive"],r.effects.blurType),u.angle=F(c.angle,0,-180,180),u.focus=F(c.focus,.5,0,1);let p=2048;return{version:1,aspectRatio:P(a.aspectRatio,["original","16:9","9:16","1:1","4:3","3:4","21:9"],"original"),style:P(a.style,y,r.style),cellSize:F(a.cellSize,r.cellSize,["pixel","mosaic","lego","voxel","disco","dots","hex","led","cmyk"].includes(String(a.style))?1:3,60),charset:"string"==typeof a.charset&&a.charset.length?Array.from(a.charset).slice(0,128).join(""):r.charset,colorMode:P(a.colorMode,["accent","source","gray"],r.colorMode),ink:T(a.ink,r.ink),warps:M(a.warps),warpEdge:P(a.warpEdge,["clamp","transparent"],"clamp"),crop:{x:F(s.x,.5,0,1),y:F(s.y,.5,0,1),zoom:F(s.zoom,1,1,5),rotation:90*Math.round(F(s.rotation,0,-360,360)/90)},backdrop:{mode:P(o.mode,["solid","transparent","source","blurred","gradient"],r.backdrop.mode),color:T(o.color,r.backdrop.color),color2:T(o.color2,r.backdrop.color2),blur:F(o.blur,12,0,32),opacity:F(o.opacity,1,0,1)},color:{brightness:F(n.brightness,0,-1,1),contrast:F(n.contrast,1,0,3),saturation:F(n.saturation,1,0,3),grayscale:F(n.grayscale,0,0,1),tint:T(n.tint,r.color.tint),amount:F(n.amount,0,0,1),blend:P(n.blend,S,r.color.blend),blackPoint:F(n.blackPoint,0,0,.99),whitePoint:Math.max(F(n.blackPoint,0,0,.99)+1/255,F(n.whitePoint,1,1/255,1)),gamma:F(n.gamma,1,.25,4),shadows:F(n.shadows,0,-1,1),highlights:F(n.highlights,0,-1,1),curves:d(n.curves),denoise:F(n.denoise,0,0,1)},dither:{algorithm:P(h.algorithm,b,"none"),palette:"string"==typeof h.palette&&Object.prototype.hasOwnProperty.call(E,h.palette)?h.palette:"mono",colors:Array.isArray(h.colors)&&h.colors.length>=2?h.colors.slice(0,32).map(t=>T(t,"#000000")):[...r.dither.colors],amount:F(h.amount,1,0,2),scale:Math.round(F(h.scale,2,1,12)),threshold:F(h.threshold,.5,0,1),motion:P(h.motion,["none","drift","shimmer"],"none"),speed:F(h.speed,1,.1,3),direction:F(h.direction,45,-180,180),colorSpace:P(h.colorSpace,["rgb","luminance"],"rgb")},mask:{enabled:!0===l.enabled,invert:!0===l.invert,shapes:Array.isArray(l.shapes)?l.shapes.slice(0,64).map(t=>{const e=A(t),i=P(e.kind,["rectangle","ellipse","brush"],"rectangle"),a="brush"===i&&Array.isArray(e.points)?e.points.slice(0,p).map(t=>Array.isArray(t)?[Math.round(1e4*F(t[0],0,0,1))/1e4,Math.round(1e4*F(t[1],0,0,1))/1e4]:[0,0]):[];return p-=a.length,{kind:i,x:F(e.x,0,0,1),y:F(e.y,0,0,1),width:F(e.width,.5,0,1),height:F(e.height,.5,0,1),size:F(e.size,.05,.005,.5),points:a}}):[]},lights:Array.isArray(a.lights)?a.lights.slice(0,4).map(t=>{const e=A(t);return{x:F(e.x,.5,0,1),y:F(e.y,.5,0,1),radius:F(e.radius,.3,.02,1),intensity:F(e.intensity,.5,0,1),color:T(e.color,"#ffffff")}}):[],effects:u,motion:{type:P(m.type,e.map(t=>t.mode),"none"),speed:F(m.speed,1,.1,3),amount:F(m.amount,1,0,2)},hover:{effect:P(f.effect,t.map(t=>t.value),"trail"),strength:F(f.strength,.55,0,1),radius:F(f.radius,.2,.1,1),edgeSafe:!0===f.edgeSafe}}}function C(t,e,i,a,r){const s=Math.abs(r.rotation/90)%2==1,o=s?e:t,n=s?t:e,h=Math.max(i/o,a/n)*r.zoom;return{width:o*h,height:n*h,x:(i-o*h)*r.x,y:(a-n*h)*r.y,scale:h,rotated:s}}function R(t,e,i){if(Math.abs(i.crop.rotation/90)%2==1&&([t,e]=[e,t]),"original"===i.aspectRatio)return[t,e];const[a,r]=i.aspectRatio.split(":").map(Number);return t/e>a/r?[Math.round(e*a/r),e]:[t,Math.round(t*r/a)]}function L(t,e){const i={...t,...e};for(const a of["crop","backdrop","color","dither","mask","effects","motion","hover"])e[a]&&Object.assign(i,{[a]:{...t[a],...e[a]}});return e.color?.curves&&(i.color.curves={...t.color.curves,...e.color.curves}),I(i)}function N(t,e,i,a=12e3,r=1){const s=Math.max(2,Number.isFinite(t)?t:960),o=Math.max(2,Number.isFinite(e)?e:540),n=Math.max(1,Math.floor(Number.isFinite(a)?a:12e3)),h=Math.max(.01,Number.isFinite(r)?r:1),l=["dither","pixel","mosaic","lego","voxel","disco","dots","hex","led","cmyk"].includes(i.style)?1:1.65;let c=Math.max(1,Math.ceil(Math.sqrt(s*o/(n*l))/h));for(;Math.ceil(s/(c*h))*Math.ceil(o/(c*h*l))>n;)c++;const d="dither"===i.style?i.dither.scale:i.cellSize,m=Math.max(c,d)*h;return{cell:m,rowHeight:m*l,columns:Math.ceil(s/m),rows:Math.ceil(o/(m*l)),minimum:c,limited:d<c}}var O=[["ascii","Signature ASCII","Brand ink and clean characters.",{}],["print","Newsprint","Fine diffusion on warm paper.",{style:"dither",dither:{algorithm:"floyd-steinberg",palette:"newsprint"}}],["handheld","Pocket camera","Four-tone ordered dither.",{style:"dither",dither:{algorithm:"bayer4",palette:"gameboy",scale:3}}],["riso","Two inks","Limited-color print texture.",{style:"dither",dither:{algorithm:"atkinson",palette:"risograph",scale:2}}],["night","Night signal","Gray characters and optical fringe.",{ink:"#888888",effects:{prism:.7,scanlines:.2,vignette:.3}}],["terminal","Phosphor","Green glyphs with a soft glow.",{ink:"#83efad",effects:{bloom:.4,scanlines:.35,crt:.2}}],["mosaic","Mosaic study","Separated color tiles.",{style:"mosaic",cellSize:14,colorMode:"source"}],["bricks","Brickwork","Colorful studded cells.",{style:"lego",cellSize:18,colorMode:"source"}],["voxel","Little volumes","Three-face isometric tiles.",{style:"voxel",cellSize:22,colorMode:"source"}],["disco","Mirror room","Faceted tiles and warm light.",{style:"disco",cellSize:18,colorMode:"source",lights:[{x:.35,y:.25,radius:.25,intensity:.45,color:"#fff2d4"}]}],["wallpaper","Wallpaper","Living ASCII over a softened source.",{backdrop:{mode:"blurred",blur:18,opacity:.55},ink:"#f2e9c9",motion:{type:"caustics",speed:.5}}],["blueprint","Blueprint","Linework in a cool monochrome.",{style:"lines",ink:"#9bccdf",backdrop:{mode:"solid",color:"#0a1e30"}}]].map(([t,e,i,a])=>({id:t,name:e,description:i,settings:I(a)}));function D(t){const e=O.find(e=>e.id===t);if(!e)throw new Error("Unknown studio look.");return I(e.settings)}function U(t){const e=function(t){const e=t.blackPoint??0,i=t.whitePoint??1,a=t.gamma??1,r=t.shadows??0,s=t.highlights??0;if(0===e&&1===i&&1===a&&0===r&&0===s)return null;const o=[0,.25+.2*r,.5,.75+.2*s,1],n=o.slice(1).map((t,e)=>4*(t-o[e])),h=[n[0],...n.slice(1).map((t,e)=>2*t*n[e]/(t+n[e])),n[3]],l=new Uint8Array(256);for(let t=0;t<256;t++){const r=Math.pow(Math.max(0,Math.min(1,(t/255-e)/(i-e))),1/a),s=Math.min(3,Math.floor(4*r)),n=4*r-s,c=n*n,d=c*n,m=(2*d-3*c+1)*o[s]+(d-2*c+n)*h[s]/4+(-2*d+3*c)*o[s+1]+(d-c)*h[s+1]/4;l[t]=Math.round(255*Math.max(0,Math.min(1,m)))}return l}(t),i=t.curves;if(!e&&(!i||Object.values(i).every(t=>t.every(([t,e])=>t===e))))return null;const a=m(i?.rgb),r=[i?.red,i?.green,i?.blue].map(m),s=new Uint8Array(768);for(let t=0;t<256;t++)for(let i=0;i<3;i++)s[256*i+t]=r[i][a[e?e[t]:t]];return s}var X=class{constructor(t=0){this.amount=0,this.weights=new Float32Array(256),this.source=new Uint8ClampedArray(0),this.configure(t)}configure(t=0){const e=Math.max(0,Math.min(1,Number.isFinite(t)?t:0));if(e===this.amount)return;if(this.amount=e,0===e)return void(this.source=new Uint8ClampedArray(0));const i=8+24*e;for(let t=0;t<256;t++)this.weights[t]=Math.exp(-t*t/(2*i*i))}apply(t,e,i){if(!this.amount)return;if(!Number.isInteger(e)||!Number.isInteger(i)||e<1||i<1||e*i*4!==t.length)throw new Error("Denoise dimensions do not match the source.");this.source.length!==t.length&&(this.source=new Uint8ClampedArray(t.length));const a=this.source;a.set(t);for(let r=0;r<i;r++)for(let s=0;s<e;s++){const o=4*(r*e+s);if(!a[o+3])continue;const n=a[o],h=a[o+1],l=a[o+2];let c=0,d=0,m=0,f=0;for(let t=-1;t<=1;t++){const o=r+t;if(!(o<0||o>=i))for(let i=-1;i<=1;i++){const r=s+i;if(r<0||r>=e)continue;const u=4*(o*e+r);if(!a[u+3])continue;const p=Math.max(Math.abs(a[u]-n),Math.abs(a[u+1]-h),Math.abs(a[u+2]-l)),g=this.weights[p]*(0===i?1:.6)*(0===t?1:.6)*a[u+3];c+=a[u]*g,d+=a[u+1]*g,m+=a[u+2]*g,f+=g}}t[o]=n+(c/f-n)*this.amount,t[o+1]=h+(d/f-h)*this.amount,t[o+2]=l+(m/f-l)*this.amount}}},j=new Set(["none","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis"]);function Y(t){return"dither"===t.style&&("shimmer"===t.dither.motion||"drift"===t.dither.motion&&t.dither.amount>0&&!j.has(t.dither.algorithm))}function B(t){return"none"!==t.motion.type&&(t.motion.amount??1)>0}function z(t){return B(t)||Y(t)||t.effects.grain>0||t.effects.dust>0||t.effects.glitch>0}var q="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",W="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",G=new Uint16Array(4096);for(let t=0;t<G.length;t++)G[t]=q.indexOf(W[2*t])<<6|q.indexOf(W[2*t+1]);var H=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};var V=new Map([2,4,8,16].map(t=>[t,Float64Array.from({length:t*t},(e,i)=>function(t,e,i){let a=0;for(let r=1;r<i;r*=2){const i=(Math.floor(t/r)%2+2)%2;a=4*a+[[0,2],[3,1]][(Math.floor(e/r)%2+2)%2][i]}return(a+.5)/(i*i)-.5}(i%t,Math.floor(i/t),t))])),J={"floyd-steinberg":[[1,0,7/16],[-1,1,3/16],[0,1,5/16],[1,1,1/16]],atkinson:[[1,0,.125],[2,0,.125],[-1,1,.125],[0,1,.125],[1,1,.125],[0,2,.125]],stucki:[[1,0,8/42],[2,0,4/42],[-2,1,2/42],[-1,1,4/42],[0,1,8/42],[1,1,4/42],[2,1,2/42],[-2,2,1/42],[-1,2,2/42],[0,2,4/42],[1,2,2/42],[2,2,1/42]],sierra:[[1,0,5/32],[2,0,3/32],[-2,1,2/32],[-1,1,4/32],[0,1,5/32],[1,1,4/32],[2,1,2/32],[-1,2,2/32],[0,2,3/32],[1,2,2/32]],"sierra-lite":[[1,0,.5],[-1,1,.25],[0,1,.25]],burkes:[[1,0,.25],[2,0,4/32],[-2,1,2/32],[-1,1,4/32],[0,1,.25],[1,1,4/32],[2,1,2/32]],jarvis:[[1,0,7/48],[2,0,5/48],[-2,1,3/48],[-1,1,5/48],[0,1,7/48],[1,1,5/48],[2,1,3/48],[-2,2,1/48],[-1,2,3/48],[0,2,5/48],[1,2,3/48],[2,2,1/48]]},Q=t=>[parseInt(t.slice(1,3),16),parseInt(t.slice(3,5),16),parseInt(t.slice(5,7),16)];function K(t,e,i){const a=Math.min(t*Math.max(1,i),(1-t)*Math.max(1,i),e*Math.max(1,1/i),(1-e)*Math.max(1,1/i)),r=Math.max(0,Math.min(1,(a-.035)/.105));return r*r*r*(r*(6*r-15)+10)}var Z=t=>["dissolve","silk","vortex","magnetic","scatter","etch","elastic","rake"].includes(t),_=class{constructor(t,e){this.edgeSafe=!1,this.previous=null,this.peak=0,this.scatterDirections=null,this.springX=null,this.springY=null,this.mode="dissolve",this.width=t,this.height=e;const i=t*e;this.pixels=new Uint8Array(4*i),this.ink=new Float32Array(i),this.targetX=new Float32Array(i),this.targetY=new Float32Array(i),this.offsetX=new Float32Array(i),this.offsetY=new Float32Array(i),this.edge=new Float32Array(i);for(let i=0;i<e;i++)for(let a=0;a<t;a++)this.edge[i*t+a]=K(a/(t-1),i/(e-1),t/e);this.clear()}get active(){return this.peak>2e-4}setMode(t){if("elastic"!==t||this.springX||(this.springX=new Float32Array(this.ink.length),this.springY=new Float32Array(this.ink.length)),"scatter"===t&&!this.scatterDirections){const t=this.scatterDirections=new Float64Array(this.width*this.height*2);for(let e=0;e<this.height;e++)for(let i=0;i<this.width;i++){const a=43758.5453*Math.sin(127.1*i+311.7*e),r=(a-Math.floor(a))*Math.PI*2,s=2*(e*this.width+i);t[s]=.7*Math.cos(r),t[s+1]=.7*Math.sin(r)}}t!==this.mode&&(this.mode=t,this.clear())}clear(){for(const t of[this.ink,this.targetX,this.targetY,this.offsetX,this.offsetY,this.pixels])t.fill(0);if(this.previous=null,this.peak=0,this.springX?.fill(0),this.springY?.fill(0),"dissolve"!==this.mode)for(let t=0;t<this.pixels.length;t+=4)this.pixels[t]=this.pixels[t+2]=128}leave(){this.previous=null}move(t,e,i){if(!Number.isFinite(t+e+i))return;t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e));const a=this.previous;this.previous={x:t,y:e};const r=this.width,s=this.height,o=Math.max(1,r/s),n=Math.max(1,s/r),h=a?(t-a.x)*o:0,l=a?(e-a.y)*n:0,c=Math.hypot(h,l);if(!a&&"dissolve"!==this.mode&&"etch"!==this.mode)return;if(a&&c<1e-4)return;const d=.035+.11*Math.max(.1,Math.min(1,i)),m=Math.min(128,Math.max(1,Math.ceil(c/(.45*d)))),f=c?h/c:1,u=c?l/c:0,p=Math.min(1,c/(d*m)*2.2);for(let i=0;i<m;i++){const h=(i+.5)/m,l=a?a.x+(t-a.x)*h:t,c=a?a.y+(e-a.y)*h:e,g=Math.max(0,Math.floor((l-2.5*d/o)*(r-1))),M=Math.min(r-1,Math.ceil((l+2.5*d/o)*(r-1))),x=Math.max(0,Math.floor((c-2.5*d/n)*(s-1))),w=Math.min(s-1,Math.ceil((c+2.5*d/n)*(s-1)));for(let t=x;t<=w;t++)for(let e=g;e<=M;e++){const i=(e/(r-1)-l)*o/d,a=(t/(s-1)-c)*n/d,h=Math.exp(1.5*-(i*i+a*a)),m=t*r+e;if("dissolve"===this.mode||"etch"===this.mode)this.ink[m]=Math.max(this.ink[m],h);else if("elastic"===this.mode)this.springX[m]=Math.max(-24,Math.min(24,this.springX[m]+f*h*p*8)),this.springY[m]=Math.max(-24,Math.min(24,this.springY[m]+u*h*p*8));else{const r=(-i*u+a*f)*h*2.8,s="rake"===this.mode?f*Math.sin(t*Math.PI/3)*h*2:"magnetic"===this.mode?-i*h*2.5:"scatter"===this.mode?(i+this.scatterDirections[2*m])*h*2:"silk"===this.mode?f*r:-a*h*2.5,o="rake"===this.mode?u*Math.sin(e*Math.PI/3)*h*2:"magnetic"===this.mode?-a*h*2.5:"scatter"===this.mode?(a+this.scatterDirections[2*m+1])*h*2:"silk"===this.mode?u*r:i*h*2.5;this.targetX[m]=Math.max(-1,Math.min(1,this.targetX[m]+s*p)),this.targetY[m]=Math.max(-1,Math.min(1,this.targetY[m]+o*p))}}}this.peak=1}step(t){if(!this.active||!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t)),i=Math.exp(-("dissolve"===this.mode?2.15:3.2)*e),a=1-Math.exp(-22*e);let r=0;const s=Math.sqrt(336),o=Math.exp(-8*e),n=Math.cos(s*e),h=Math.sin(s*e)/s;for(let t=0;t<this.ink.length;t++)if("etch"===this.mode)this.ink[t]*=i,r=Math.max(r,this.ink[t]);else if("dissolve"===this.mode){this.ink[t]*=i,r=Math.max(r,this.ink[t]);const e=Math.round(65535*this.ink[t]);this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e}else{if("elastic"===this.mode){const e=this.offsetX[t],i=this.offsetY[t],a=this.springX[t],s=this.springY[t];this.offsetX[t]=Math.max(-1,Math.min(1,o*(e*n+(a+8*e)*h))),this.offsetY[t]=Math.max(-1,Math.min(1,o*(i*n+(s+8*i)*h))),this.springX[t]=o*(a*n-(8*a+400*e)*h),this.springY[t]=o*(s*n-(8*s+400*i)*h),r=Math.max(r,.05*Math.abs(this.springX[t]),.05*Math.abs(this.springY[t]))}else this.targetX[t]*=i,this.targetY[t]*=i,this.offsetX[t]+=(this.targetX[t]-this.offsetX[t])*a,this.offsetY[t]+=(this.targetY[t]-this.offsetY[t])*a;r=Math.max(r,Math.abs(this.offsetX[t]),Math.abs(this.offsetY[t]),Math.abs(this.targetX[t]),Math.abs(this.targetY[t]));const e=Math.round(this.offsetX[t]*(this.edgeSafe?this.edge[t]:1)*32767+32768),s=Math.round(this.offsetY[t]*(this.edgeSafe?this.edge[t]:1)*32767+32768);this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e,this.pixels[4*t+2]=s>>>8,this.pixels[4*t+3]=255&s}if("etch"===this.mode)for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const i=t*this.width+e,a=3*(this.ink[t*this.width+Math.max(0,e-1)]-this.ink[t*this.width+Math.min(this.width-1,e+1)]+this.ink[Math.max(0,t-1)*this.width+e]-this.ink[Math.min(this.height-1,t+1)*this.width+e]);this.offsetX[i]=Math.max(-1,Math.min(1,a))*(this.edgeSafe?this.edge[i]:1);const r=Math.round(32767*this.offsetX[i]+32768);this.pixels[4*i]=r>>>8,this.pixels[4*i+1]=255&r}this.peak=r,this.active||this.clear()}sample(t,e,i){const a=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),r=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),s=Math.floor(a),o=Math.floor(r),n=a-s,h=r-o,l=o*this.width+s,c=l+this.width,d=t=>(t[l]*(1-n)+t[l+1]*n)*(1-h)+(t[c]*(1-n)+t[c+1]*n)*h;if("etch"===this.mode)return i[0]=i[1]=0,void(i[2]=3*d(this.offsetX));i[0]=d(this.offsetX)*(this.edgeSafe?K(t,e,this.width/this.height):1)*.08,i[1]=d(this.offsetY)*(this.edgeSafe?K(t,e,this.width/this.height):1)*.08,i[2]="dissolve"===this.mode?6*-d(this.ink):0}},$=class{constructor(t,e){this.rings=[],this.previous=null,this.elapsed=1,this.echoPeak=0,this.width=t,this.height=e,this.pixels=new Uint8Array(t*e*4),this.echo=new Float32Array(t*e)}get active(){return this.rings.length>0||this.echoPeak>2e-4}clear(){this.rings=[],this.previous=null,this.elapsed=1,this.pixels.fill(0),this.echo.fill(0),this.echoPeak=0}leave(){this.previous=null}move(t,e,i){const a=Math.max(1,this.width/this.height),r=Math.max(1,this.height/this.width);this.previous&&(Math.hypot((t-this.previous.x)*a,(e-this.previous.y)*r)<.065||this.elapsed<.3)||4!==this.rings.length&&(this.previous={x:t,y:e},this.elapsed=0,this.rings.push({x:t,y:e,age:0,radius:i}))}ringSample(t,e){const i=Math.max(1,this.width/this.height),a=Math.max(1,this.height/this.width);let r=0;for(const s of this.rings){const o=.015+s.age*(.15+.22*s.radius),n=.009+.014*s.radius,h=(Math.hypot((t-s.x)*i,(e-s.y)*a)-o)/n,l=Math.sin(Math.min(1,s.age/.07)*Math.PI/2)*Math.max(0,1-s.age/1.35)**2;r=Math.max(r,Math.exp(-h*h)*l)}return r}sample(t,e){const i=Math.max(0,Math.min(this.width-1,Math.round(t*(this.width-1)))),a=Math.max(0,Math.min(this.height-1,Math.round(e*(this.height-1))));return Math.max(this.ringSample(t,e),this.echo[a*this.width+i])}step(t){if(!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t));this.elapsed+=e;for(const t of this.rings)t.age+=e;if(this.rings=this.rings.filter(t=>t.age<1.35),!this.active)return void this.pixels.fill(0);const i=Math.exp(-5.5*e);let a=0;for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const r=t*this.width+e;this.echo[r]=Math.max(this.ringSample(e/(this.width-1),t/(this.height-1)),this.echo[r]*i),a=Math.max(a,this.echo[r]);const s=Math.round(65535*this.echo[r]),o=4*r;this.pixels[o]=s>>>8,this.pixels[o+1]=255&s}this.echoPeak=a,this.active||(this.echo.fill(0),this.pixels.fill(0))}},tt=class{constructor(t,e){this.previous=null,this.peak=0,this.width=t,this.height=e;const i=t*e;this.pixels=new Uint8Array(4*i),this.signal=new Float32Array(i),this.offsetX=new Float32Array(i),this.offsetY=new Float32Array(i),this.driftX=new Float32Array(i),this.driftY=new Float32Array(i),this.u=new Float32Array(i),this.v=new Float32Array(i),this.ink=new Float32Array(i),this.a=new Float32Array(i),this.b=new Float32Array(i),this.c=new Float32Array(i),this.pressure=new Float32Array(i),this.pressureNext=new Float32Array(i),this.divergence=new Float32Array(i),this.curl=new Float32Array(i)}get active(){return this.peak>2e-4}clear(){for(const t of[this.u,this.v,this.ink,this.a,this.b,this.c,this.pressure,this.pressureNext,this.divergence,this.curl,this.signal,this.pixels,this.offsetX,this.offsetY,this.driftX,this.driftY])t.fill(0);this.previous=null,this.peak=0}leave(){this.previous=null}move(t,e,i,a=performance.now()){if(!Number.isFinite(t+e+i+a))return;t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e)),i=Math.max(.1,Math.min(1,i));const r=this.previous;if(this.previous={x:t,y:e,time:a},!r)return;const s=(t-r.x)*(this.width-1),o=(e-r.y)*(this.height-1),n=Math.hypot(s,o);if(n<.001)return;const h=Math.min(this.width,this.height),l=a>r.time?Math.max(1/240,(a-r.time)/1e3):1/60,c=Math.min(12,n/h/l),d=1-Math.exp(-c/2.2),m=h*(.022+.075*i)*(.65+.95*d),f=Math.min(128,Math.max(1,Math.ceil(n/(.4*m)))),u=n/m*(.32+.22*d)/f,p=s/n,g=o/n,M=-g,x=p,w=n*(2+18*d)/f;for(let i=0;i<f;i++){const a=(i+.5)/f,s=(r.x+(t-r.x)*a)*(this.width-1),o=(r.y+(e-r.y)*a)*(this.height-1),n=Math.max(1,Math.floor(s-3*m)),h=Math.min(this.width-2,Math.ceil(s+3*m)),l=Math.max(1,Math.floor(o-3*m)),c=Math.min(this.height-2,Math.ceil(o+3*m));for(let t=l;t<=c;t++)for(let e=n;e<=h;e++){const i=((e-s)*p+(t-o)*g)/m,a=((e-s)*M+(t-o)*x)/m,r=Math.exp(-i*i*.65-a*a*1.7),n=t*this.width+e;this.ink[n]=1-(1-this.ink[n])*Math.exp(-r*u);const h=1-a*a*.55,l=i*a*.7;this.u[n]=Math.max(-80,Math.min(80,this.u[n]+(p*h+M*l)*r*w)),this.v[n]=Math.max(-80,Math.min(80,this.v[n]+(g*h+x*l)*r*w))}}this.peak=1}read(t,e,i){const a=0|(e=Math.max(.5,Math.min(this.width-1.5,e))),r=0|(i=Math.max(.5,Math.min(this.height-1.5,i))),s=e-a,o=i-r,n=r*this.width+a;return(t[n]*(1-s)+t[n+1]*s)*(1-o)+(t[n+this.width]*(1-s)+t[n+this.width+1]*s)*o}sample(t,e){return this.read(this.signal,t*(this.width-1),e*(this.height-1))}displacement(t,e,i){i[0]=this.read(this.offsetX,t*(this.width-1),e*(this.height-1)),i[1]=this.read(this.offsetY,t*(this.width-1),e*(this.height-1))}step(t){if(!this.active||!Number.isFinite(t))return;let e=Math.max(0,Math.min(.05,t));const i=this.width,a=this.height;for(;e>1e-7;){const t=Math.min(1/60,e);e-=t;const r=Math.exp(-1.9*t),s=Math.exp(-3.2*t);for(let e=1;e<a-1;e++)for(let o=1;o<i-1;o++){const n=e*i+o,h=Math.max(.5,Math.min(i-1.5,o-this.u[n]*t)),l=Math.max(.5,Math.min(a-1.5,e-this.v[n]*t)),c=0|h,d=0|l,m=h-c,f=l-d,u=d*i+c,p=(1-m)*(1-f),g=m*(1-f),M=(1-m)*f,x=m*f;this.a[n]=(this.u[u]*p+this.u[u+1]*g+this.u[u+i]*M+this.u[u+i+1]*x)*r,this.b[n]=(this.v[u]*p+this.v[u+1]*g+this.v[u+i]*M+this.v[u+i+1]*x)*r,this.c[n]=(this.ink[u]*p+this.ink[u+1]*g+this.ink[u+i]*M+this.ink[u+i+1]*x)*s}[this.u,this.a]=[this.a,this.u],[this.v,this.b]=[this.b,this.v],[this.ink,this.c]=[this.c,this.ink];for(let t=1;t<a-1;t++)for(let e=1;e<i-1;e++){const a=t*i+e;this.curl[a]=.5*(this.v[a+1]-this.v[a-1]-this.u[a+i]+this.u[a-i])}for(let e=1;e<a-1;e++)for(let a=1;a<i-1;a++){const r=e*i+a,s=Math.abs(this.curl[r+1])-Math.abs(this.curl[r-1]),o=Math.abs(this.curl[r+i])-Math.abs(this.curl[r-i]),n=Math.hypot(s,o)+1e-4,h=this.curl[r]*t*10,l=Math.hypot(this.u[r],this.v[r]);this.u[r]+=o/n*h,this.v[r]-=s/n*h;const c=Math.min(1,l/(Math.hypot(this.u[r],this.v[r])+1e-6));this.u[r]*=c,this.v[r]*=c,this.divergence[r]=-.5*(this.u[r+1]-this.u[r-1]+this.v[r+i]-this.v[r-i])}this.pressure.fill(0);for(let t=0;t<4;t++){for(let t=1;t<a-1;t++)for(let e=1;e<i-1;e++){const a=t*i+e;this.pressureNext[a]=.25*(this.divergence[a]+this.pressure[a-1]+this.pressure[a+1]+this.pressure[a-i]+this.pressure[a+i])}[this.pressure,this.pressureNext]=[this.pressureNext,this.pressure]}let o=0;for(let e=1;e<a-1;e++)for(let a=1;a<i-1;a++){const r=e*i+a;this.u[r]=Math.max(-80,Math.min(80,this.u[r]-.5*(this.pressure[r+1]-this.pressure[r-1]))),this.v[r]=Math.max(-80,Math.min(80,this.v[r]-.5*(this.pressure[r+i]-this.pressure[r-i]))),this.driftX[r]+=(3.6*this.u[r]-58*this.offsetX[r]-12*this.driftX[r])*t,this.driftY[r]+=(3.6*this.v[r]-58*this.offsetY[r]-12*this.driftY[r])*t,this.offsetX[r]=Math.max(-2,Math.min(2,this.offsetX[r]+this.driftX[r]*t)),this.offsetY[r]=Math.max(-2,Math.min(2,this.offsetY[r]+this.driftY[r]*t)),this.signal[r]=1-Math.exp(.06*-Math.hypot(this.u[r],this.v[r])-.16*this.ink[r]),o=Math.max(o,this.signal[r])}this.peak=o}if(this.active)for(let t=0;t<this.ink.length;t++){const e=Math.round(65535*Math.min(1,this.signal[t]));this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e,this.pixels[4*t+2]=Math.round(128+63.5*this.offsetX[t]),this.pixels[4*t+3]=Math.round(128+63.5*this.offsetY[t])}else this.clear()}};function et(t,e){const i=Math.max(0,Math.min(1,e/.38));return t+(1-2*t)*(i*i*(3-2*i))}var it=(t,e)=>"water"===t?30*e/.55:"silk"===t?28*e:"vortex"===t?38*e:["magnetic","scatter","elastic","rake"].includes(t)?32*e:0,at=class{constructor(t=1){this.mode="water",this.amount=.55,this.radius=.2,this.lensX=.5,this.lensY=.5,this.lensStrength=0,this.previous=null,this.energy=0,this.pending=!1,this.remainder=0,t=Math.max(.25,Math.min(4,t)),this.columns=Math.round(t>=1?128:128*t),this.rows=Math.round(t>=1?128/t:128),this.xScale=Math.max(1,t),this.yScale=Math.max(1,1/t),this.heights=new Float32Array(this.columns*this.rows),this.velocity=new Float32Array(this.heights.length),this.next=new Float32Array(this.heights.length),this.normals=new Float32Array(2*this.heights.length),this.edgeMask=new Float32Array(this.heights.length);for(let e=0;e<this.rows;e++)for(let i=0;i<this.columns;i++)this.edgeMask[e*this.columns+i]=K(i/(this.columns-1),e/(this.rows-1),t);this.refraction={width:this.columns,height:this.rows,pixels:new Uint8Array(4*this.heights.length),strength:30,mode:"water",focus:[.5,.5,0,.2]},this.waterPixels=this.refraction.pixels,this.trail=new tt(this.columns,this.rows),this.contour=new $(this.columns,this.rows),this.afterimage=new _(this.columns,this.rows),this.clear()}get invertsDensity(){return"trail"===this.mode}get densityTrail(){return["trail","contour","dissolve","etch"].includes(this.mode)}get hasRefraction(){return this.active||this.lensStrength>15e-5}get active(){return Z(this.mode)?this.afterimage.active:"contour"===this.mode?this.contour.active:"trail"===this.mode?this.trail.active:this.pending||this.energy>15e-5}setMode(t){t!==this.mode&&(this.clear(),this.mode=t,this.refraction.mode=t,Z(t)&&this.afterimage.setMode(t),this.refraction.pixels="trail"===t?this.trail.pixels:"contour"===t?this.contour.pixels:Z(t)?this.afterimage.pixels:this.waterPixels,this.refraction.strength=it(t,this.amount))}configure(t,e=.55,i=.2,a=!1){this.setMode(t),this.refraction.edgeSafe=a,this.afterimage.edgeSafe=a,this.amount=Number.isFinite(e)?Math.max(0,Math.min(1,e)):.55,this.radius=Number.isFinite(i)?Math.max(.1,Math.min(1,i)):.2,this.refraction.strength=it(t,this.amount),this.refraction.focus[2]=this.densityTrail?this.amount:this.lensStrength*this.amount,this.refraction.focus[3]=this.radius}move(t,e,i){if("none"===this.mode||0===this.amount)return;if(!Number.isFinite(t+e))return;if(t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e)),Z(this.mode))return void this.afterimage.move(t,e,this.radius);if("contour"===this.mode)return void this.contour.move(t,e,this.radius);if("trail"===this.mode)return void this.trail.move(t,e,this.radius,i);if("water"!==this.mode)return!this.previous&&this.lensStrength<.001&&(this.lensX=t,this.lensY=e),this.previous={x:t,y:e},void(this.pending=!0);if(!this.previous)return void(this.previous={x:t,y:e});const a=this.previous;this.previous={x:t,y:e};const r=(t-a.x)*this.xScale,s=(e-a.y)*this.yScale,o=Math.hypot(r,s);if(o<1e-5)return;const n=.035+.1*this.radius,h=3*n,l=Math.min(192,Math.max(1,Math.ceil(o/(.5*n)))),c=95*Math.min(o,1)/l;for(let i=0;i<l;i++){const r=(i+.5)/l,s=a.x+(t-a.x)*r,o=a.y+(e-a.y)*r,d=Math.max(1,Math.floor((s-h/this.xScale)*(this.columns-1))),m=Math.min(this.columns-2,Math.ceil((s+h/this.xScale)*(this.columns-1))),f=Math.max(1,Math.floor((o-h/this.yScale)*(this.rows-1))),u=Math.min(this.rows-2,Math.ceil((o+h/this.yScale)*(this.rows-1)));for(let t=f;t<=u;t++)for(let e=d;e<=m;e++){const i=(e/(this.columns-1)-s)*this.xScale,a=(t/(this.rows-1)-o)*this.yScale,r=Math.exp(-(i*i+a*a)/(n*n))*c,h=t*this.columns+e;this.velocity[h]=Math.max(-12,this.velocity[h]-r)}}this.pending=!0}leave(){this.afterimage.leave(),this.contour.leave(),this.trail.leave(),this.previous=null,"water"!==this.mode&&this.lensStrength&&(this.pending=!0)}clear(){this.trail.clear(),this.contour.clear(),this.afterimage.clear(),this.heights.fill(0),this.velocity.fill(0),this.next.fill(0),this.normals.fill(0),this.refraction.focus[2]=0,this.previous=null,this.lensStrength=0,this.energy=0,this.pending=!1,this.remainder=0;for(let t=0;t<this.waterPixels.length;t+=4)this.waterPixels[t]=this.waterPixels[t+2]=128,this.waterPixels[t+1]=this.waterPixels[t+3]=0}step(t){if(!this.active||!Number.isFinite(t))return;if(Z(this.mode))return void this.afterimage.step(t);if("contour"===this.mode)return void this.contour.step(t);if("trail"===this.mode)return void this.trail.step(t);if("water"!==this.mode)return void this.stepLight(Math.max(0,Math.min(.05,t)));this.remainder+=Math.max(0,Math.min(.05,t));const e=1/120,i=Math.exp(-3.8*e),a=.3*Math.min(this.columns,this.rows);for(;this.remainder+1e-8>=e;){this.remainder-=e;let t=0;for(let r=1;r<this.rows-1;r++)for(let s=1;s<this.columns-1;s++){const o=r*this.columns+s,n=this.heights[o],h=this.heights[o-1]+this.heights[o+1]+this.heights[o-this.columns]+this.heights[o+this.columns]-4*n,l=Math.min(s,r,this.columns-1-s,this.rows-1-r),c=l<5?.88+.024*l:1,d=(this.velocity[o]+(h*a*a-8*n)*e)*i*c;this.velocity[o]=d,this.next[o]=(n+d*e)*c,t=Math.max(t,Math.abs(this.next[o]),.1*Math.abs(d))}this.heights.set(this.next),this.energy=t,this.pending=!1}if(!this.active)return void this.clear();const r=.18*Math.min(this.columns,this.rows);for(let t=0;t<this.rows;t++)for(let e=0;e<this.columns;e++){const i=t*this.columns+e,a=(this.heights[t*this.columns+Math.max(0,e-1)]-this.heights[t*this.columns+Math.min(this.columns-1,e+1)])*r,s=(this.heights[Math.max(0,t-1)*this.columns+e]-this.heights[Math.min(this.rows-1,t+1)*this.columns+e])*r,o=Math.tanh(a)*(this.refraction.edgeSafe?this.edgeMask[i]:1),n=Math.tanh(s)*(this.refraction.edgeSafe?this.edgeMask[i]:1);this.normals[2*i]=o,this.normals[2*i+1]=n;const h=Math.round(32767*o+32768),l=Math.round(32767*n+32768);this.refraction.pixels[4*i]=h>>>8,this.refraction.pixels[4*i+1]=255&h,this.refraction.pixels[4*i+2]=l>>>8,this.refraction.pixels[4*i+3]=255&l}}stepLight(t){const e=this.previous,i=1-Math.exp(-30*t),a=1-Math.exp(-12*t);e&&(this.lensX+=(e.x-this.lensX)*i,this.lensY+=(e.y-this.lensY)*i),this.lensStrength+=((e?1:0)-this.lensStrength)*a,this.energy=Math.max(e?Math.abs(e.x-this.lensX)+Math.abs(e.y-this.lensY):0,Math.abs((e?1:0)-this.lensStrength)),this.pending=!1,e||this.active?this.refraction.focus=[this.lensX,this.lensY,this.lensStrength*this.amount,this.radius]:this.clear()}sample(t,e,i){if(Z(this.mode))return this.afterimage.sample(t,e,i),i[0]*=this.amount,i[1]*=this.amount,void(i[2]*=this.amount);if("contour"===this.mode)return i[0]=i[1]=0,void(i[2]=this.contour.sample(t,e)*this.amount*3);if("trail"===this.mode)return i[0]=i[1]=0,void(i[2]=this.trail.sample(t,e)*this.amount*3);const a=Math.max(0,Math.min(this.columns-1.001,t*(this.columns-1))),r=Math.max(0,Math.min(this.rows-1.001,e*(this.rows-1))),s=Math.floor(a),o=Math.floor(r),n=a-s,h=r-o,l=2*(o*this.columns+s),c=l+2*this.columns;for(let t=0;t<2;t++)i[t]=.08*((this.normals[l+t]*(1-n)+this.normals[l+2+t]*n)*(1-h)+(this.normals[c+t]*(1-n)+this.normals[c+2+t]*n)*h);i[0]*=this.amount/.55,i[1]*=this.amount/.55,i[2]="light"===this.mode||"scan"===this.mode?function(t,e,i,a){const[r,s,o,n]=i.focus,h=(t-r)*Math.max(1,a)/n,l=(e-s)*Math.max(1,1/a)/n;return"light"===i.mode?Math.exp(-3*(h*h+l*l))*o:"scan"===i.mode?(1.3*Math.exp(-h*h*110)-.3*Math.exp(-h*h*12))*Math.exp(-l*l*1.8)*o:0}(t,e,this.refraction,this.xScale/this.yScale):0}};function rt(t){return"videoWidth"in t?[t.videoWidth,t.videoHeight]:"naturalWidth"in t?[t.naturalWidth,t.naturalHeight]:[t.width,t.height]}var st=(t=!1)=>{const e=document.createElement("canvas"),i=e.getContext("2d",{willReadFrequently:t});if(!i)throw new Error("Canvas 2D is unavailable.");return{canvas:e,ctx:i}},ot=(t,e,i)=>{t.width===e&&t.height===i||(t.width=e,t.height=i)},nt={blocks:" ░▒▓█",braille:" ⠁⠃⠇⡇⣇⣧⣷⣿",lines:" -═╪╬",cross:" ·+xX#",diagonal:" /╱╳",diamond:" ·◇◈◆",mixed:" .:+/◇#@"};function ht(t,e={},i={}){const a=t.getContext("2d");if(!a)throw new Error("Canvas is already owned by another renderer.");const r=st(),s=st(!0),h=st(),l=st(),c=st(),d=st(),m=st(),u=st(),p=st(),g=st();let M,x=0,w=I(e),y=0,b="",S="",k="",A=new Uint8ClampedArray(0),F=new Uint8ClampedArray(0),T=0,P=0,R=0,L=null,O="",D=new at,j=0;const z=[0,0,0],q=[0,0,0,1],W=[0,0,0,0];let K=U(w.color);const Z=new X(w.color.denoise),_=new v(w.warps,w.warpEdge),$=Math.max(64,Math.min(4096,Number.isFinite(i.maxDimension)?i.maxDimension:960)),tt=Math.max(256,Math.min(1048576,Number.isFinite(i.maxCells)?i.maxCells:12e3));let it=tt,ht=Math.max(.1,Math.min(8,i.pixelRatio??1));return{canvas:t,render:function(e,i=0,v=960,I=540,U=i*w.motion.speed){if(Number.isFinite(i)||(i=0),!Number.isFinite(v)||!Number.isFinite(I)||v<1||I<1)throw new Error("Render dimensions must be positive finite numbers.");const[X,tt]=rt(e);if(!X||!tt)return;const st=Math.min(1,$/Math.max(v,I)),lt=Math.max(2,Math.round(v*st)),ct=Math.max(2,Math.round(I*st));ot(t,lt,ct),ot(r.canvas,lt,ct),ot(h.canvas,lt,ct),ot(l.canvas,lt,ct),ot(c.canvas,lt,ct),j!==lt/ct&&(j=lt/ct,D=new at(j)),D.configure(w.hover.effect,w.hover.strength,w.hover.radius,w.hover.edgeSafe),D.step(Math.max(0,Math.min(.05,i-R))),R=i;const dt="currentTime"in e?e.getVideoPlaybackQuality?.().totalVideoFrames??e.currentTime:0,mt=[y,lt,ct,dt].join(":"),ft="dither"===w.style,ut=N(lt,ct,w,it,ht),pt=ut.cell,gt=ut.rowHeight,Mt=ut.columns,xt=ut.rows;if(b!==mt||L!==e||T!==Mt||P!==xt){L=e,b=mt,S="",k="",T=Mt,P=xt,r.ctx.clearRect(0,0,lt,ct),r.ctx.save();const t=C(X,tt,lt,ct,w.crop);r.ctx.translate(t.x+t.width/2,t.y+t.height/2),r.ctx.rotate(w.crop.rotation*Math.PI/180),r.ctx.drawImage(e,-X*t.scale/2,-tt*t.scale/2,X*t.scale,tt*t.scale),r.ctx.restore(),ot(s.canvas,T,P),s.ctx.clearRect(0,0,T,P),s.ctx.drawImage(r.canvas,0,0,T,P),A=s.ctx.getImageData(0,0,T,P).data,Z.apply(A,T,P);const i=w.color;for(let t=0;t<A.length;t+=4){const e=.299*A[t]+.587*A[t+1]+.114*A[t+2];for(let a=0;a<3;a++){const r=e+(A[t+a]-e)*i.saturation;A[t+a]=((r*(1-i.grayscale)+e*i.grayscale)/255-.5)*i.contrast*255+127.5+255*i.brightness}}K&&function(t,e){for(let i=0;i<t.length;i+=4)t[i+3]&&(t[i]=e[t[i]],t[i+1]=e[256+t[i+1]],t[i+2]=e[512+t[i+2]])}(A,K),A=_.apply(A,T,P,lt/ct)}const wt=B(w),vt=Y(w),yt=!D.active&&!wt&&!vt,bt=[mt,T,P,pt,gt,ht].join(":");if(!yt||k!==bt){h.ctx.clearRect(0,0,lt,ct),h.ctx.globalAlpha=1,h.ctx.globalCompositeOperation="source-over";const t=U,e=wt?w.motion.type:"none",a=["none","caustics","sheen","grain","trace"].includes(e);if(ft){const a=yt;if(!a||S!==mt){F.length!==A.length&&(F=new Uint8ClampedArray(A.length));const r=F;if(r.set(A),D.active||"none"!==e)for(let i=0;i<P;i++)for(let a=0;a<T;a++){const s=a/T,h=i/P;let l=a,c=i,d=0,m=1,u=1;D.active&&(D.sample(s,h,z),l-=z[0]*T,c-=z[1]*P,d=z[2]/3);const p=4*(i*T+a);o(e,s,h,t,q,(.299*A[p]+.587*A[p+1]+.114*A[p+2])/255),n(q,w.motion.amount??1),l-=q[0]/960*T,c-=q[1]/960*P,m=1+q[2],u=q[3];const g=4*(i*T+a);f(A,T,P,l,c,W);for(let t=0;t<3;t++){const e=W[t]/255;let i=(["trail","contour"].includes(w.hover.effect)?et(e,d):"etch"===w.hover.effect?Math.max(0,Math.min(1,e+.35*d)):"dissolve"===w.hover.effect?e*Math.max(0,1+d):e)*m;r[g+t]=255*i}r[g+3]=W[3]*u}!function(t,e,i,a,r=0){const{algorithm:s,amount:o,threshold:n}=a,h="blue-noise"===s,l=s.startsWith("bayer")?Number(s.slice(5)):0,c=V.get(l),d=l-1,m="luminance"===a.colorSpace,f=("custom"===a.palette?a.colors:E[a.palette]??E.mono).map(Q),u=J[s],p=u?new Float32Array(3*e*3):null,g="drift"===a.motion?r*a.speed*3:0,M=(a.direction??45)*Math.PI/180,x=Math.round(Math.cos(M)*g),w=Math.round(Math.sin(M)*g),v=(t,e)=>(t%e+e)%e,y=f.map(t=>.299*t[0]+.587*t[1]+.114*t[2]),b="shimmer"===a.motion?.15*Math.sin(r*a.speed*2):0;for(let a=0;a<i;a++)for(let r=0;r<e;r++){const M=4*(a*e+r),S=3*(a%3*e+r);if(0===t[M+3]){p&&(p[S]=p[S+1]=p[S+2]=0);continue}let E=0;const k=h?(G[64*(a-w&63)+(r-x&63)]+.5)/G.length:0;c?E=c[(a-w&d)*l+(r-x&d)]:"noise"===s?E=H(r-x,a-w)-.5:"lines"===s?E=v(a-w,4)/3-.5:"vertical-lines"===s?E=v(r-x,4)/3-.5:"diagonal-lines"===s?E=v(r-x+a-w,4)/3-.5:"radial"===s?E=v(Math.hypot(r-e/2,a-i/2)-g,6)/6-.5:"halftone"===s&&(E=Math.hypot(v(r-x,6)-2.5,v(a-w,6)-2.5)/3.54-.5);const A=128*(E*o+b+(.5-n)),F=t[M]+A+(p?.[S]??0),T=t[M+1]+A+(p?.[S+1]??0),P=t[M+2]+A+(p?.[S+2]??0);let I=0,C=0,R=0;if(f.length){let t=1/0,e=1/0,i=0,a=0;const r=.299*F+.587*T+.114*P;for(let s=0;s<f.length;s++){const o=f[s],n=m?(r-y[s])**2:(F-o[0])**2*.299+(T-o[1])**2*.587+(P-o[2])**2*.114;n<t?(h&&(e=t,a=i,i=s),t=n,[I,C,R]=o):h&&n<e&&(e=n,a=s)}if(h&&o>0&&Number.isFinite(e)){const t=f[a],e=t[0]-I,s=t[1]-C,n=t[2]-R,h=y[a]-y[i],l=m?h*h:e*e*.299+s*s*.587+n*n*.114,c=m?(r-y[i])*h:(F-I)*e*.299+(T-C)*s*.587+(P-R)*n*.114;k<(l?Math.max(0,Math.min(1,c/l*o)):0)&&([I,C,R]=t)}}else if(h){const t=Math.max(0,Math.min(1,.5+(k-.5)*o));I=51*Math.floor(F/51+1-t),C=51*Math.floor(T/51+1-t),R=51*Math.floor(P/51+1-t)}else I=51*Math.round(F/51),C=51*Math.round(T/51),R=51*Math.round(P/51);if(t[M]=I,t[M+1]=C,t[M+2]=R,p&&u){p[S]=p[S+1]=p[S+2]=0;for(const[t,s,n]of u){const h=r+t;if(h<0||h>=e||a+s>=i)continue;const l=3*((a+s)%3*e+h);p[l]+=(F-I)*n*o,p[l+1]+=(T-C)*n*o,p[l+2]+=(P-R)*n*o}}}}(r,T,P,w.dither,i),s.ctx.putImageData(new ImageData(r,T,P),0,0),S=a?mt:""}h.ctx.imageSmoothingEnabled=!1,h.ctx.drawImage(s.canvas,0,0,lt,ct)}else{const i=Array.from(nt[w.style]??w.charset),r=h.ctx,s=Q(w.ink),l="ascii"===w.style||!!nt[w.style],c=Math.max(3,Math.round(.92*gt)),d=Math.ceil(pt+4),u=Math.ceil(gt+4),p=[i.join(""),c,d,u,w.ink,w.colorMode].join(":");if(l&&p!==O&&(O=p,ot(m.canvas,d*i.length,u),m.ctx.clearRect(0,0,m.canvas.width,u),m.ctx.font=`${c}px monospace`,m.ctx.textBaseline="middle",m.ctx.textAlign="center",m.ctx.fillStyle="accent"===w.colorMode?w.ink:"#ffffff",i.forEach((t,e)=>m.ctx.fillText(t,e*d+d/2,u/2))),"lego"===w.style&&x!==pt){x=pt,ot(g.canvas,Math.ceil(pt),Math.ceil(gt));const t=g.ctx;t.clearRect(0,0,g.canvas.width,g.canvas.height),t.fillStyle="rgba(255,255,255,.2)",t.strokeStyle="rgba(0,0,0,.25)",t.lineWidth=Math.max(.5,.6*ht),t.beginPath(),t.arc(pt/2,gt/2,.28*pt,0,2*Math.PI),t.fill(),t.stroke()}r.font=`${c}px monospace`,r.textBaseline="middle",r.textAlign="center";for(let h=0;h<P;h++)for(let c=0;c<T;c++){let p=c,M=h,x=0;if(D.active&&(D.sample(c/T,h/P,z),p=Math.max(0,Math.min(T-1,c-z[0]*T)),M=Math.max(0,Math.min(P-1,h-z[1]*P)),x=z[2]/3),f(A,T,P,p,M,W),!W[3])continue;const v=W[0],y=W[1],b=W[2],S=(.299*v+.587*y+.114*b)/255;let E=S;["trail","contour"].includes(w.hover.effect)&&x?E=et(E,x):"etch"===w.hover.effect?E=Math.max(0,Math.min(1,E+.35*x)):"dissolve"===w.hover.effect&&(E*=Math.max(0,1+x));let k=c*pt,F=h*gt,I=1;o(e,c/T,h/P,t,q,S),n(q,w.motion.amount??1),k+=q[0]*lt/960,F+=q[1]*ct/960,E=Math.max(0,Math.min(1,E+q[2])),I=q[3]*W[3]/255,l||"accent"!==w.colorMode||"cmyk"===w.style||(I*=E),r.globalAlpha=I;const C=255*(E-S),R="source"===w.colorMode?`rgb(${v+C},${y+C},${b+C})`:"gray"===w.colorMode?`rgb(${Math.round(255*E)},${Math.round(255*E)},${Math.round(255*E)})`:w.ink;if(r.fillStyle=R,l){const t=Math.max(0,Math.min(i.length-1,Math.round(E*(i.length-1))));"accent"===w.colorMode?r.drawImage(m.canvas,t*d,0,d,u,a?Math.round(k+(pt-d)/2):k+(pt-d)/2,a?Math.round(F+(gt-u)/2):F+(gt-u)/2,d,u):r.fillText(i[t],k+pt/2,F+gt/2)}else if("dots"===w.style)r.beginPath(),r.arc(k+pt/2,F+gt/2,.48*pt*Math.sqrt(E),0,2*Math.PI),r.fill();else if("led"===w.style)r.beginPath(),r.arc(k+pt/2,F+gt/2,.39*pt,0,2*Math.PI),r.fill(),r.globalAlpha=.35*I,r.fillStyle="#ffffff",r.beginPath(),r.arc(k+.43*pt,F+.4*gt,.11*pt,0,2*Math.PI),r.fill();else if("hex"===w.style){const t=k+pt/2,e=F+gt/2;r.beginPath();for(let i=0;i<6;i++){const a=Math.PI/3*i,s=t+Math.cos(a)*pt*.49,o=e+Math.sin(a)*gt*.49;0===i?r.moveTo(s,o):r.lineTo(s,o)}r.closePath(),r.fill()}else if("cmyk"===w.style){r.fillStyle="#ffffff",r.fillRect(k,F,pt,gt);const t=(t,e)=>Math.max(0,Math.min(255,"source"===w.colorMode?t+C:"gray"===w.colorMode?255*E:e*E)),e=t(v,s[0]),i=t(y,s[1]),a=t(b,s[2]),o=1-Math.max(e,i,a)/255,n=Math.max(.001,1-o),h=[["#00ffff",(1-e/255-o)/n,.36,.36],["#ff00ff",(1-i/255-o)/n,.64,.36],["#ffff00",(1-a/255-o)/n,.5,.66],["#000000",o,.5,.5]];r.globalCompositeOperation="multiply";for(const[t,e,i,a]of h)r.fillStyle=t,r.beginPath(),r.arc(k+pt*i,F+gt*a,.48*pt*Math.sqrt(Math.max(0,e)),0,2*Math.PI),r.fill();r.globalCompositeOperation="source-over"}else if("voxel"===w.style){const t=k+pt/2,e=F+gt/2;r.beginPath(),r.moveTo(t,F),r.lineTo(k+pt,F+.25*gt),r.lineTo(t,e),r.lineTo(k,F+.25*gt),r.closePath(),r.fill(),r.globalAlpha=.72*I,r.beginPath(),r.moveTo(k,F+.25*gt),r.lineTo(t,e),r.lineTo(t,F+gt),r.lineTo(k,F+.75*gt),r.closePath(),r.fill(),r.globalAlpha=.42*I,r.beginPath(),r.moveTo(t,e),r.lineTo(k+pt,F+.25*gt),r.lineTo(k+pt,F+.75*gt),r.lineTo(t,F+gt),r.closePath(),r.fill()}else{const t="pixel"===w.style?0:Math.max(.5,.06*pt);r.fillRect(k,F,pt-t,gt-t),"lego"===w.style&&r.drawImage(g.canvas,k,F),"disco"===w.style&&(r.fillStyle=`rgba(255,255,255,${.1+.25*H(c,h)})`,r.fillRect(k,F,pt-t,.35*gt),r.fillStyle="rgba(0,0,0,.25)",r.fillRect(k,F+.65*gt,pt-t,.35*gt-t))}}}h.ctx.globalAlpha=1,(w.color.amount||w.lights.length)&&(ot(u.canvas,lt,ct),u.ctx.clearRect(0,0,lt,ct),u.ctx.drawImage(h.canvas,0,0)),w.color.amount&&(h.ctx.save(),h.ctx.globalCompositeOperation=w.color.blend,h.ctx.globalAlpha=w.color.amount,h.ctx.fillStyle=w.color.tint,h.ctx.fillRect(0,0,lt,ct),h.ctx.restore());for(const t of w.lights){const e=t.radius*Math.max(lt,ct),i=h.ctx.createRadialGradient(t.x*lt,t.y*ct,0,t.x*lt,t.y*ct,e);i.addColorStop(0,t.color),i.addColorStop(1,"transparent"),h.ctx.save(),h.ctx.globalCompositeOperation="screen",h.ctx.globalAlpha=t.intensity,h.ctx.fillStyle=i,h.ctx.fillRect(0,0,lt,ct),h.ctx.restore()}if((w.color.amount||w.lights.length)&&(h.ctx.globalCompositeOperation="destination-in",h.ctx.drawImage(u.canvas,0,0),h.ctx.globalCompositeOperation="source-over"),w.mask.enabled&&w.mask.shapes.length){const t=c.ctx;t.clearRect(0,0,lt,ct),t.fillStyle="#fff",t.strokeStyle="#fff",t.lineCap="round",t.lineJoin="round";for(const e of w.mask.shapes){if(t.beginPath(),"ellipse"===e.kind)t.ellipse((e.x+e.width/2)*lt,(e.y+e.height/2)*ct,e.width*lt/2,e.height*ct/2,0,0,2*Math.PI);else{if("rectangle"!==e.kind){if(t.lineWidth=(e.size??.05)*lt,1===e.points?.length){t.arc(e.points[0][0]*lt,e.points[0][1]*ct,t.lineWidth/2,0,2*Math.PI),t.fill();continue}e.points?.forEach(([e,i],a)=>a?t.lineTo(e*lt,i*ct):t.moveTo(e*lt,i*ct)),t.stroke();continue}t.rect(e.x*lt,e.y*ct,e.width*lt,e.height*ct)}t.fill()}h.ctx.globalCompositeOperation=w.mask.invert?"destination-out":"destination-in",h.ctx.drawImage(c.canvas,0,0),h.ctx.globalCompositeOperation="source-over"}const M=l.ctx;M.clearRect(0,0,lt,ct),M.globalAlpha=w.backdrop.opacity;const v=w.backdrop;if("solid"===v.mode&&(M.fillStyle=v.color,M.fillRect(0,0,lt,ct)),"gradient"===v.mode){const t=M.createLinearGradient(0,0,lt,ct);t.addColorStop(0,v.color),t.addColorStop(1,v.color2),M.fillStyle=t,M.fillRect(0,0,lt,ct)}if("source"===v.mode&&M.drawImage(r.canvas,0,0),"blurred"===v.mode){const t=Math.max(1,v.blur);ot(d.canvas,Math.max(2,Math.round(lt/t)),Math.max(2,Math.round(ct/t))),d.ctx.drawImage(r.canvas,0,0,d.canvas.width,d.canvas.height),M.imageSmoothingEnabled=!0,M.drawImage(d.canvas,0,0,lt,ct)}M.globalAlpha=1,w.effects.characterBloom>0&&(ot(p.canvas,Math.max(2,Math.round(lt/3)),Math.max(2,Math.round(ct/3))),p.ctx.clearRect(0,0,p.canvas.width,p.canvas.height),p.ctx.drawImage(h.canvas,0,0,p.canvas.width,p.canvas.height),M.save(),M.globalAlpha=.8*w.effects.characterBloom,M.globalCompositeOperation="screen",M.filter=`blur(${1+4*w.effects.characterBloom}px)`,M.drawImage(p.canvas,0,0,lt,ct),M.restore()),M.drawImage(h.canvas,0,0),k=yt?bt:""}const St=Object.entries(w.effects).some(([t,e])=>!["angle","focus","blurType","characterBloom"].includes(t)&&"number"==typeof e&&e>0);a.clearRect(0,0,lt,ct),St?(void 0===M&&(M=function(){const t=document.createElement("canvas"),e=t.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,antialias:!1,preserveDrawingBuffer:!0});if(!e)return null;const i=[],a=(t,a)=>{const r=e.createShader(t);if(i.push(r),e.shaderSource(r,a),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(r)||"Finish shader failed");return r},r=e.createProgram();if(e.attachShader(r,a(e.VERTEX_SHADER,"attribute vec2 p;varying vec2 uv;void main(){uv=(p+1.)*.5;gl_Position=vec4(p,0.,1.);}")),e.attachShader(r,a(e.FRAGMENT_SHADER,"precision mediump float;varying vec2 uv;uniform sampler2D src;uniform vec2 size;uniform float t,bloom,grain,dust,scanlines,crt,prism,vignette,glitch,pixelate,blur,blurMode,angle,focus,halftone,rgbSplit,sharpen;\n float hash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\n vec4 sampleAt(vec2 p){if(min(min(p.x,p.y),min(1.-p.x,1.-p.y))<0.)return vec4(0.);return texture2D(src,vec2(p.x,1.-p.y));}\n void main(){vec2 q=uv,c=q-.5;q=c*(1.+dot(c,c)*crt*.25)+.5;\n if(glitch>0.)q.x+=(hash(vec2(floor(q.y*35.),floor(t*5.)))-.5)*.07*glitch*step(.82,hash(vec2(floor(q.y*35.),floor(t*5.)+3.)));\n if(pixelate>0.){vec2 grid=size/(1.+pixelate*20.);q=(floor(q*grid)+.5)/grid;}\n vec4 base=sampleAt(q);float edge=smoothstep(.12,.65,length(c));\n vec2 shift=vec2((prism*3.*edge+rgbSplit*8.)/size.x,prism*edge/size.y);\n if(prism>0.||rgbSplit>0.)base.rgb=vec3(sampleAt(q+shift).r,base.g,sampleAt(q-shift).b);\n vec2 dir=vec2(cos(angle),sin(angle))/size;float amount=blur;\n if(blurMode>1.5&&blurMode<2.5){dir=normalize(c+vec2(.0001))/size;amount*=length(c)*2.;}\n if(blurMode>2.5)amount*=smoothstep(.05,.5,abs(q.y-focus));\n vec4 blurred=base;\n if(amount>0.){blurred=base*.2;for(int i=1;i<=4;i++){float f=float(i)*amount*.35;vec2 off=dir*f;if(blurMode<.5)off=vec2(cos(float(i)*1.57),sin(float(i)*1.57))*amount/size;blurred+=sampleAt(q+off)*.1+sampleAt(q-off)*.1;}}\n vec3 light=vec3(0.);if(bloom>0.)for(int i=0;i<4;i++){float a=float(i)*1.5708;vec3 s=sampleAt(q+vec2(cos(a),sin(a))*6./size).rgb;light+=max(vec3(0.),s-.35)*.25;}\n vec3 col=blurred.rgb+light*bloom;\n if(sharpen>0.){vec2 px=1./size;vec3 near=sampleAt(q+vec2(px.x,0.)).rgb+sampleAt(q-vec2(px.x,0.)).rgb+sampleAt(q+vec2(0.,px.y)).rgb+sampleAt(q-vec2(0.,px.y)).rgb;col+=(base.rgb*4.-near)*sharpen*.5;}\ncol*=1.-scanlines*.4*(.5+.5*cos(q.y*size.y*3.14159));\n col*=1.-vignette*smoothstep(.15,.72,length(c));\n col+=(hash(floor(q*size)+floor(t*12.))-.5)*grain*.2;\n if(dust>0.)col+=step(1.-dust*.002,hash(floor(q*size*.25)+floor(t*2.)))*.4;\n if(halftone>0.)col*=mix(1.,smoothstep(.1,.65,length(fract(q*size/6.)-.5)),halftone);\n gl_FragColor=vec4(clamp(col,0.,1.),blurred.a);}")),e.linkProgram(r),!e.getProgramParameter(r,e.LINK_STATUS))throw new Error("Finish link failed");e.useProgram(r);const s=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,s),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),e.STATIC_DRAW);const o=e.getAttribLocation(r,"p");e.enableVertexAttribArray(o),e.vertexAttribPointer(o,2,e.FLOAT,!1,0,0);const n=e.createTexture();e.bindTexture(e.TEXTURE_2D,n),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE);const h=["t","bloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","blur","blurMode","angle","focus","halftone"],l=Object.fromEntries(h.map(t=>[t,e.getUniformLocation(r,t)])),c=e.getUniformLocation(r,"size");return{canvas:t,render(i,a,s,o=1){t.width===i.width&&t.height===i.height||(t.width=i.width,t.height=i.height,e.viewport(0,0,t.width,t.height)),e.useProgram(r),e.bindTexture(e.TEXTURE_2D,n),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,i),e.uniform2f(c,t.width/o,t.height/o);for(const t of h)e.uniform1f(l[t],"t"===t?s:"blurMode"===t?["gaussian","directional","radial","progressive"].indexOf(a.blurType):"angle"===t?a.angle*Math.PI/180:a[t]??0);return e.drawArrays(e.TRIANGLE_STRIP,0,4),t},destroy(){e.deleteTexture(n),e.deleteBuffer(s),e.deleteProgram(r),i.forEach(t=>e.deleteShader(t)),t.width=t.height=1,e.getExtension("WEBGL_lose_context")?.loseContext()}}}()),M?a.drawImage(M.render(l.canvas,w.effects,i,ht),0,0):a.drawImage(l.canvas,0,0),t.dataset.studioFinish=M?"gpu":"unavailable"):(a.drawImage(l.canvas,0,0),t.dataset.studioFinish="none")},setPixelRatio(t){ht=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1))},get pixelRatio(){return ht},setBudget(t){it=Math.max(256,Math.min(tt,Number.isFinite(t)?Math.round(t):tt))},get maxCells(){return it},configure(t){w=I(t),K=U(w.color),Z.configure(w.color.denoise),_.configure(w.warps,w.warpEdge),y++},pointer:(t,e,i)=>{D.configure(w.hover.effect,w.hover.strength,w.hover.radius,w.hover.edgeSafe),D.move(t,e,i)},leave(){D.leave()},get active(){return D.active},get settings(){return I(w)},get capabilities(){return{gpuFinish:null!==M}},invalidate(){b=""},destroy(){M?.destroy(),_.clear(),Z.configure(0);for(const t of[r,s,h,l,c,d,m,u,p,g])t.canvas.width=t.canvas.height=1;L=null,A=new Uint8ClampedArray(0),F=new Uint8ClampedArray(0)}}}function lt(t,e,i){return new Promise((a,r)=>{const s=()=>{l(),a()},o=()=>{l(),r(new Error("Unable to load this media. Check its format and cross-origin permissions."))},n=()=>{l(),r(new DOMException("Cancelled","AbortError"))},h=setTimeout(o,2e4),l=()=>{clearTimeout(h),t.removeEventListener(e,s),t.removeEventListener("error",o),i?.removeEventListener("abort",n)};t.addEventListener(e,s,{once:!0}),t.addEventListener("error",o,{once:!0}),i?.addEventListener("abort",n,{once:!0}),i?.aborted&&n()})}async function ct(t,e){if("string"==typeof t&&t.startsWith("blob:")){const i=await fetch(t,{signal:e}),a=await i.blob();return ct(new File([a],"Imported media",{type:a.type}),e)}const i="string"!=typeof t,a=i?t.name:t;if(i?"image/gif"===t.type:/\.gif(?:[?#]|$)/i.test(a)){const a=await import("gifuct-js"),{parseGIF:r,decompressFrames:s}="function"==typeof a.parseGIF?a:a.default,o=i?await t.arrayBuffer():await fetch(t,{signal:e}).then(t=>{if(!t.ok)throw new Error("GIF download failed.");return t.arrayBuffer()});if(e?.aborted)throw new DOMException("Cancelled","AbortError");const n=r(o),h=n.lsd.width,l=n.lsd.height;if(h*l>4e6)throw new Error("GIF is too large. Use a smaller GIF or an MP4.");const c=n.frames.filter(t=>"image"in t).length;if(!c||c*h*l*4>128e6)throw new Error("GIF exceeds the decoded memory budget. Use MP4 for long animations.");const d=s(n,!0);if(d.length*h*l*4>128e6)throw new Error("GIF exceeds the 128 MB decoded budget. Use MP4 for long animations.");const m=document.createElement("canvas");m.width=h,m.height=l;const f=m.getContext("2d"),u=document.createElement("canvas"),p=u.getContext("2d"),g=d.reduce((t,e)=>t+Math.max(20,e.delay),0)/1e3;let M=-1,x=null;const w=t=>{const e=(t%g+g)%g*1e3;let i=0,a=0;for(;a<d.length-1&&(i+=Math.max(20,d[a].delay),!(e<i));a++);a<M&&(f.clearRect(0,0,h,l),M=-1,x=null);for(let t=M+1;t<=a;t++){const e=d[t-1];2===e?.disposalType&&f.clearRect(e.dims.left,e.dims.top,e.dims.width,e.dims.height),3===e?.disposalType&&x&&f.putImageData(x,0,0);const i=d[t];x=3===i.disposalType?f.getImageData(0,0,h,l):null,u.width=i.dims.width,u.height=i.dims.height,p.putImageData(new ImageData(new Uint8ClampedArray(i.patch),u.width,u.height),0,0),f.drawImage(u,i.dims.left,i.dims.top)}return M=a,m};return w(0),{source:m,width:h,height:l,duration:g,animated:!0,seek:async()=>{},frame:w,destroy(){m.width=u.width=1,d.length=0,x=null}}}const r=i?t.type.startsWith("video/"):/\.(mp4|webm|mov)(?:[?#]|$)/i.test(a),s=i?URL.createObjectURL(t):t,o=r?document.createElement("video"):new Image;o.crossOrigin="anonymous",o instanceof HTMLVideoElement&&(o.muted=!0,o.playsInline=!0,o.preload="auto");const n=()=>{o instanceof HTMLVideoElement?(o.pause(),o.removeAttribute("src"),o.load()):o.src="",i&&URL.revokeObjectURL(s)};try{const t=lt(o,r?"loadeddata":"load",e);o.src=s,await t;const i=o instanceof HTMLVideoElement?o.videoWidth:o.naturalWidth,a=o instanceof HTMLVideoElement?o.videoHeight:o.naturalHeight;return{source:o,width:i,height:a,duration:o instanceof HTMLVideoElement?o.duration:0,animated:r,async seek(t,e){if(!(o instanceof HTMLVideoElement))return;if(!Number.isFinite(o.duration)||o.duration<=0)throw new Error("Video duration is unavailable.");const i=Math.max(0,Math.min(o.duration-.001,t%o.duration));if(Math.abs(o.currentTime-i)<.001&&o.readyState>=2)return;const a=lt(o,"seeked",e);o.currentTime=i,await a},frame:()=>o,destroy:n}}catch(t){throw n(),t}}var dt=t=>{if(t?.aborted)throw new DOMException("Export cancelled","AbortError")};async function mt(t,e){const{format:i,signal:a}=e,r=Math.round(e.width),s=Math.round(e.height);if(!Number.isFinite(r)||!Number.isFinite(s)||r<2||s<2||r>4096||s>4096||r*s>16777216)throw new Error("Choose export dimensions between 2 and 4096 pixels.");if(!["png","jpeg","mp4","webm","gif"].includes(i))throw new Error("Unknown export format.");if(void 0!==e.fps&&!Number.isFinite(e.fps))throw new Error("Frames per second must be finite.");const o=Math.max(1,Math.min(60,Math.round(e.fps??24))),n=e.duration??5;if(!Number.isFinite(n)||n<=0||n>60)throw new Error("Choose a duration from 0 to 60 seconds.");const h="png"===i||"jpeg"===i,l=e.time??0;if(!Number.isFinite(l)||l<0)throw new Error("Image time must be a finite non-negative number.");if(void 0!==e.motionTime&&(!Number.isFinite(e.motionTime)||e.motionTime<0))throw new Error("Motion time must be a finite non-negative number.");if(!h&&r*s>8294400)throw new Error("Video exports support up to 3840 × 2160 pixels.");if("gif"===i&&(r*s>921600||n*o>600))throw new Error("GIF export supports up to 1280 × 720 and 600 frames. Use MP4 for larger exports.");if(void 0!==e.referenceWidth&&(!Number.isFinite(e.referenceWidth)||e.referenceWidth<1))throw new Error("Reference width must be a positive number.");if("gif"===i&&o>30)throw new Error("GIF exports support up to 30 fps. Choose MP4 or WebM for higher frame rates.");const c=document.createElement("canvas");let d;try{if(dt(a),e.onProgress?.(0),h){if(await t(c,l,r,s,a,e.motionTime),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");dt(a);const o=await new Promise((t,a)=>c.toBlob(e=>e?t(e):a(new Error("Image export failed.")),"png"===i?"image/png":"image/jpeg",e.quality??.92));return dt(a),e.onProgress?.(1),o}const m=Math.ceil(n*o);if("gif"===i){const i=await import("gifenc"),{GIFEncoder:h,quantize:l,applyPalette:d}="function"==typeof i.GIFEncoder?i:i.default,f=h(),u=c.getContext("2d");for(let i=0;i<m;i++){dt(a);const h=i/o;if(await t(c,h,r,s,a),dt(a),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");const p=u.getImageData(0,0,r,s).data,g=l(p,256),M=d(p,g);f.writeFrame(M,r,s,{palette:g,delay:10*(Math.round(100*Math.min((i+1)/o,n))-Math.round(100*i/o)),repeat:0}),e.onProgress?.((i+1)/m*.98),await new Promise(t=>setTimeout(t,0))}return dt(a),f.finish(),e.onProgress?.(1),new Blob([new Uint8Array(f.bytes())],{type:"image/gif"})}const{Output:f,Mp4OutputFormat:u,WebMOutputFormat:p,BufferTarget:g,CanvasSource:M,canEncodeVideo:x}=await import("mediabunny"),w="mp4"===i?"avc":"vp9";if(!await x(w,{width:r,height:s}))throw new Error(`${i.toUpperCase()} encoding is unavailable in this browser. Try another format or a current browser with WebCodecs.`);const v=new f({format:"mp4"===i?new u({fastStart:"in-memory"}):new p,target:new g});c.width=r,c.height=s,d=()=>v.cancel();const y=new M(c,{codec:w,bitrate:Math.max(5e5,Math.round(r*s*o*.15))});v.addVideoTrack(y,{frameRate:o}),c.width=r,c.height=s,await v.start();for(let i=0;i<m;i++){dt(a);const h=i/o;if(await t(c,h,r,s,a),dt(a),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");await y.add(h,Math.min(1/o,n-h)),e.onProgress?.((i+1)/m*.98),i%4==0&&await new Promise(t=>setTimeout(t,0))}return y.close(),dt(a),await v.finalize(),dt(a),d=void 0,e.onProgress?.(1),new Blob([v.target.buffer],{type:"mp4"===i?"video/mp4":"video/webm"})}catch(t){throw await(d?.().catch(()=>{})),t}finally{c.width=c.height=1}}function ft(t,e,i={}){let a=I(i.settings),r=i.width??e.width,o=i.height??e.height;const n=ht(t,a,i),h=new s;let l=0,c=!1,d=!0,m=!1,f=!0,u=0,p=0,g=0,M=0,x=-1,w=!1!==i.adaptive,v=0,y=0,b=0;const S=matchMedia("(prefers-reduced-motion: reduce)"),E=e.source instanceof HTMLVideoElement?e.source:null,k=()=>{c||l||!f||document.hidden||(l=requestAnimationFrame(T))},A=()=>!m&&!S.matches&&f&&!document.hidden,F=()=>{E&&(E.loop=!0,A()?E.play().catch(()=>{m=!0,d=!0,k()}):E.pause()),g=0,d=!0,k()};function T(t){if(l=0,c||!f||document.hidden)return;const s=A();s&&(u+=g?Math.min(.1,(t-g)/1e3):0),g=t;const S=z(a),F=s&&(e.animated||S),T=E?.getVideoPlaybackQuality?.().totalVideoFrames??-1,P=!E||T<0||T!==x;if(d||n.active||F&&(P||S)&&t-M>=1e3/Math.max(1,Math.min(60,i.fps??60))-.5){const s=performance.now();try{e.animated&&!E&&n.invalidate();const[t,l]=R(r,o,a);p=h.update(u,a.motion.type,a.motion.speed),n.render(e.frame(E?.currentTime??u),u,t,l,p);const c=performance.now()-s;i.onFrame?.(E?.currentTime??u,c),y=y?.9*y+.1*c:c,++v>20&&w&&(F||n.active)&&(b=y>13?b+1:0,b>=12&&n.maxCells>3e3&&(n.setBudget(Math.max(3e3,.8*n.maxCells)),i.onQualityChange?.(n.maxCells),b=0,y=0))}catch(t){m=!0,i.onError?.(t instanceof Error?t:new Error(String(t)))}d=!1,M=t,x=T}s&&(F||n.active)&&k()}const P=e=>{if(!A())return;const i=t.getBoundingClientRect();n.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),k()},C=()=>{n.leave(),k()},N=new IntersectionObserver(([t])=>{f=t.isIntersecting,F()});N.observe(t),t.addEventListener("pointermove",P),t.addEventListener("pointerleave",C),t.addEventListener("pointercancel",C),document.addEventListener("visibilitychange",F),S.addEventListener("change",F);const O=()=>{c||(c=!0,cancelAnimationFrame(l),N.disconnect(),t.removeEventListener("pointermove",P),t.removeEventListener("pointerleave",C),t.removeEventListener("pointercancel",C),document.removeEventListener("visibilitychange",F),S.removeEventListener("change",F),i.signal?.removeEventListener("abort",O),n.destroy(),e.destroy())};if(i.signal?.addEventListener("abort",O,{once:!0}),i.signal?.aborted)throw O(),new DOMException("Cancelled","AbortError");return F(),{canvas:t,media:e,update(t){a=L(a,t),n.configure(a),d=!0,k()},resize(t,e,i){void 0!==i&&n.setPixelRatio(i),r=Math.max(2,t),o=Math.max(2,e),d=!0,k()},pause(t=!0){m=t,F()},async seek(t){u=Math.max(0,t),await e.seek(u),n.invalidate(),d=!0,k()},redraw(){n.invalidate(),d=!0,k()},get time(){return E?.currentTime??u},get settings(){return I(a)},get motionTime(){return p},get paused(){return m||S.matches},setAdaptive(t){w=t,v=b=y=0},setBudget(t){n.setBudget(t),i.onQualityChange?.(n.maxCells),d=!0,k()},get pixelRatio(){return n.pixelRatio},get maxCells(){return n.maxCells},get capabilities(){return n.capabilities},destroy:O}}var ut={Standard:()=>import("figlet/fonts/Standard"),Slant:()=>import("figlet/fonts/Slant"),Small:()=>import("figlet/fonts/Small"),Big:()=>import("figlet/fonts/Big"),Banner:()=>import("figlet/fonts/Banner"),Block:()=>import("figlet/fonts/Block"),Bubble:()=>import("figlet/fonts/Bubble"),Digital:()=>import("figlet/fonts/Digital"),Doom:()=>import("figlet/fonts/Doom"),Lean:()=>import("figlet/fonts/Lean"),Mini:()=>import("figlet/fonts/Mini"),Script:()=>import("figlet/fonts/Script"),Shadow:()=>import("figlet/fonts/Shadow"),Speed:()=>import("figlet/fonts/Speed"),Starwars:()=>import("figlet/fonts/Star Wars"),Stop:()=>import("figlet/fonts/Stop"),Straight:()=>import("figlet/fonts/Straight"),Thin:()=>import("figlet/fonts/Thin"),ThreeD:()=>import("figlet/fonts/3-D"),Univers:()=>import("figlet/fonts/Univers"),Wavy:()=>import("figlet/fonts/Wavy")},pt=Object.keys(ut);async function gt(t,e="Standard",i="#ffffff",a="#080808"){if(!Object.prototype.hasOwnProperty.call(ut,e))throw new Error("Unknown text font.");const{default:r}=await import("figlet/browser"),s=await ut[e]();r.parseFont(e,s.default),r.defaults({fetchFontIfMissing:!1});const o=r.textSync(t.slice(0,120),{font:e}),n=o.split("\n"),h=Math.max(1,...n.map(t=>t.length)),l=Math.max(1,n.length),c=Math.min(1,2048/(9*h)),d=document.createElement("canvas");d.width=Math.ceil(9*h*c+32),d.height=Math.ceil(15*l*c+32);const m=d.getContext("2d");return null!==a&&(m.fillStyle=a,m.fillRect(0,0,d.width,d.height)),m.fillStyle=i,m.font=15*c+"px monospace",m.textBaseline="top",n.forEach((t,e)=>m.fillText(t,16,16+15*e*c)),{canvas:d,ascii:o}}var Mt={standard:{label:"Classic ASCII",chars:" .:-=+*#%@"},asciify:{label:"Asciify",chars:" .:-=+ASCIIFY#@"},minimal:{label:"Minimal",chars:" .:+"},detailed:{label:"Detailed",chars:" .,:;i1tfLCG08@"},letters:{label:"Letters",chars:" .ilLCFTYASMW"},technical:{label:"Technical",chars:" .:;>_/[{}]=+*#@$"},blocks:{label:"Tonal blocks",chars:" ░▒▓█"},braille:{label:"Braille",chars:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},xt=Mt,wt=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},vt=(t,e,i,a)=>"number"==typeof t&&Number.isFinite(t)?Math.max(i,Math.min(a,t)):e,yt=(t,e)=>{if("string"!=typeof t||!/^[a-zA-Z0-9][a-zA-Z0-9:_-]{0,63}$/.test(t))throw new Error(`${e} must be 1–64 letters, numbers, colons, dashes or underscores, starting with a letter or number.`);return t};function bt(t={}){const e=wt(t);if(void 0!==e.kind&&"asciify-project"!==e.kind||void 0!==e.version&&1!==e.version)throw new Error("Unsupported Studio project. Update asciify-engine.");if(void 0!==e.layers&&!Array.isArray(e.layers))throw new Error("Project layers must be an array.");const i=Array.isArray(e.layers)?e.layers:[];if(i.length>8)throw new Error("A project supports up to 8 layers.");const a=new Set;return{kind:"asciify-project",version:1,width:Math.round(vt(e.width,1280,2,4096)),height:Math.round(vt(e.height,720,2,4096)),background:null===e.background?null:"string"==typeof e.background&&/^#[a-f\d]{6}$/i.test(e.background)?e.background:"#0c1711",pointerMode:"all"===e.pointerMode?"all":"top",layers:i.map((t,e)=>{const i=wt(t),r=wt(i.placement),s=wt(i.settings),o=wt(s.backdrop),n=yt(i.id,"Layer id"),h=yt(i.source,"Source key");if(a.has(n))throw new Error(`Duplicate layer id: ${n}`);return a.add(n),{id:n,source:h,name:"string"==typeof i.name?i.name.slice(0,80):`Layer ${e+1}`,visible:!1!==i.visible,opacity:vt(i.opacity,1,0,1),blend:S.includes(i.blend)?i.blend:"source-over",placement:{x:vt(r.x,.5,-1,2),y:vt(r.y,.5,-1,2),width:vt(r.width,1,.01,2),height:vt(r.height,1,.01,2),rotation:vt(r.rotation,0,-180,180),flipX:!0===r.flipX,flipY:!0===r.flipY},settings:I({...s,backdrop:{mode:"transparent",...o}})}})}}function St(t,e,i){if(!t.layers.some(t=>t.id===e))throw new Error(`Unknown layer: ${e}`);return bt({...t,layers:t.layers.map(t=>t.id!==e?t:{...t,...i,id:e,placement:{...t.placement,...i.placement},settings:L(t.settings,i.settings??{})})})}function Et(t,e,i,a,r){const s=t.placement,o=s.rotation*Math.PI/180,n=Math.cos(o),h=Math.sin(o),l=(e-s.x)*a,c=(i-s.y)*r,d=(l*n+c*h)/(s.width*a),m=(-l*h+c*n)/(s.height*r);return[.5+d*(s.flipX?-1:1),.5+m*(s.flipY?-1:1)]}function kt(t){return t.layers.filter(e=>{if(!e.visible||e.opacity<=0)return!1;const i=e.placement,a=i.rotation*Math.PI/180,r=Math.abs(Math.cos(a)),s=Math.abs(Math.sin(a)),o=(r*i.width*t.width+s*i.height*t.height)/2,n=(s*i.width*t.width+r*i.height*t.height)/2;return i.x*t.width+o>0&&i.x*t.width-o<t.width&&i.y*t.height+n>0&&i.y*t.height-n<t.height})}function At(t,e=24e3,i=4194304,a=t.width,r=t.height){const s=kt(t),o=Math.round(vt(e,24e3,2048,1048576)),n=vt(i,4194304,65536,16777216),h=s.map(t=>t.placement.width*t.placement.height),l=h.reduce((t,e)=>t+e,0),c=o-256*s.length,d=s.map(t=>{const e=a*t.placement.width,i=r*t.placement.height,s=Math.min(1,4096/Math.max(e,i));return{width:Math.max(2,e*s),height:Math.max(2,i*s)}}),m=d.reduce((t,e)=>t+e.width*e.height,0);let f=0,u=0;return s.map((t,e)=>{const i=e===s.length-1?o-f:256+Math.floor(c*h[e]/l);f+=i;const a=d[e],r=e===s.length-1?n-u:4+Math.floor((n-4*s.length)*a.width*a.height/Math.max(1,m));u+=r;const p=Math.min(1,Math.sqrt(r/(a.width*a.height)));let g=Math.max(2,Math.floor(a.width*p)),M=Math.max(2,Math.floor(a.height*p));return g*M>r&&(g>=M?g=Math.max(2,Math.floor(r/M)):M=Math.max(2,Math.floor(r/g))),{id:t.id,maxCells:i,width:g,height:M}})}function Ft(t,e={},i={}){const a=t.getContext("2d");if(!a)throw new Error("Project canvas is already owned by another renderer.");let r=bt(e),s=!0,o=!1,n=new Map(r.layers.map(t=>[t.id,JSON.stringify(t.settings)]));const h=Math.max(64,Math.min(4096,Number.isFinite(i.maxDimension)?i.maxDimension:960)),l=Math.max(2048,Math.min(1048576,Number.isFinite(i.maxCells)?i.maxCells:24e3));let c=l,d=Math.max(.1,Math.min(8,Number.isFinite(i.pixelRatio)?i.pixelRatio:1)),m=[];const f=new Map,u=()=>{if(o)throw new Error("Project renderer has been destroyed.")};return{canvas:t,render(e,o=0,p=r.width,g=r.height,M={}){if(u(),!Number.isFinite(p)||!Number.isFinite(g)||p<2||g<2)throw new Error("Project dimensions must be positive finite numbers.");const x=Math.min(1,h/Math.max(p,g)),w=Math.max(2,Math.round(p*x)),v=Math.max(2,Math.round(g*x));t.width===w&&t.height===v||(t.width=w,t.height=v,s=!0);const y={...r,width:w,height:v},b=kt(y);for(const t of b)if(!e.has(t.source))throw new Error(`Missing project source: ${t.source}`);const S=new Set(b.map(t=>t.id));for(const[t,e]of f)S.has(t)||(e.renderer.destroy(),f.delete(t),s=!0);m=At(y,c,i.maxRasterPixels,w,v);for(let t=0;t<b.length;t++){const i=b[t],a=m[t],r=e.get(i.source);if(!r)throw new Error(`Missing project source: ${i.source}`);let h=f.get(i.id);const c=n.get(i.id);h?h.signature!==c&&(h.renderer.configure(i.settings),h.signature=c,h.dirty=!0):(h={renderer:ht(document.createElement("canvas"),i.settings,{maxDimension:4096,maxCells:l}),signature:c,dirty:!0,geometry:""},f.set(i.id,h));const u=d*a.width/(p*i.placement.width),g=`${a.width}:${a.height}:${a.maxCells}:${u}`;h.geometry!==g&&(h.renderer.setBudget(a.maxCells),h.renderer.setPixelRatio(u),h.geometry=g,h.dirty=!0);const x="currentTime"in r?r.getVideoPlaybackQuality?.().totalVideoFrames??r.currentTime:0;if(h.dirty||h.source!==r||h.stamp!==x||h.renderer.active||z(i.settings)){const t=Object.prototype.hasOwnProperty.call(M,i.id)?M[i.id]:void 0;h.renderer.render(r,o,a.width,a.height,t),h.dirty=!1,h.source=r,h.stamp=x,s=!0}}if(!s)return!1;a.clearRect(0,0,w,v),a.globalCompositeOperation="source-over",a.globalAlpha=1,null!==r.background&&(a.fillStyle=r.background,a.fillRect(0,0,w,v));let E="none";for(const t of b){const e=f.get(t.id),i=t.placement;a.save(),a.globalAlpha=t.opacity,a.globalCompositeOperation=t.blend;try{a.translate(i.x*w,i.y*v),a.rotate(i.rotation*Math.PI/180),a.scale(i.flipX?-1:1,i.flipY?-1:1),a.drawImage(e.renderer.canvas,-i.width*w/2,-i.height*v/2,i.width*w,i.height*v)}finally{a.restore()}"unavailable"===e.renderer.canvas.dataset.studioFinish?E="unavailable":"unavailable"!==E&&"gpu"===e.renderer.canvas.dataset.studioFinish&&(E="gpu")}return a.globalAlpha=1,a.globalCompositeOperation="source-over",t.dataset.studioFinish=E,s=!1,!0},configure(t){u(),r=bt(t),n=new Map(r.layers.map(t=>[t.id,JSON.stringify(t.settings)])),(()=>{const t=new Set(kt(r).map(t=>t.id));for(const[e,i]of f)t.has(e)||(i.renderer.destroy(),f.delete(e))})(),s=!0},pointer(e,i,a){if(o||!Number.isFinite(e)||!Number.isFinite(i))return;if(e<0||e>1||i<0||i>1){for(const t of f.values())t.renderer.leave();return}let s=!1;for(const o of kt({...r,width:t.width,height:t.height}).reverse()){const n=f.get(o.id);if(!n)continue;const[h,l]=Et(o,e,i,t.width,t.height);(!s||"all"===r.pointerMode)&&h>=0&&h<=1&&l>=0&&l<=1&&"none"!==o.settings.hover.effect&&o.settings.hover.strength>0?(n.renderer.pointer(h,l,a),s=!0):n.renderer.leave()}},leave(){for(const t of f.values())t.renderer.leave()},invalidate(t){u();for(const e of r.layers)if(void 0===t||t===e.source){const t=f.get(e.id);t&&(t.renderer.invalidate(),t.dirty=!0)}s=!0},setBudget(t){u(),c=Math.max(2048,Math.min(l,Number.isFinite(t)?Math.round(t):l)),s=!0},setPixelRatio(t){u(),d=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1)),s=!0},get maxCells(){return c},get pixelRatio(){return d},get quality(){return m.map(t=>({...t}))},get active(){return[...f.values()].some(t=>t.renderer.active)},destroy(){if(!o){o=!0;for(const t of f.values())t.renderer.destroy();f.clear(),t.width=t.height=1}}}}function Tt(t,e){for(const i of t.layers)if(!e.has(i.source))throw new Error(`Missing project source: ${i.source}`)}async function Pt(t,e,i){const a=Object.entries(e),r=new Map;if(a.length>8)throw new Error("A project supports up to 8 media bindings.");Tt(t,new Map(a));try{for(const[t,e]of a){if(i?.aborted)throw new DOMException("Cancelled","AbortError");if("string"==typeof e||"undefined"!=typeof File&&e instanceof File)r.set(t,await ct(e,i));else{if(!e||"object"!=typeof e||!("text"in e)||"string"!=typeof e.text)throw new Error(`Invalid project source: ${t}`);{const i=e,{canvas:a}=await gt(i.text,i.font,i.ink??"#ffffff",null);r.set(t,{source:a,width:a.width,height:a.height,duration:0,animated:!1,frame:()=>a,seek:async()=>{},destroy:()=>{a.width=a.height=1}})}}}if(i?.aborted)throw new DOMException("Cancelled","AbortError");return r}catch(t){for(const t of r.values())t.destroy();throw t}}function It(t,e,i,a={}){if((i=new Map(i)).size>8)throw new Error("A project supports up to 8 media bindings.");let r=bt(e);if(Tt(r,i),a.signal?.aborted)throw new DOMException("Cancelled","AbortError");const o=Ft(t,r,a),n=matchMedia("(prefers-reduced-motion: reduce)"),h=[...new Set(i.values())],l=h.filter(t=>t.source instanceof HTMLVideoElement).map(t=>t.source),c=new Map;let d,m={},f=0,u=0,p=0,g=0,M=!0,x=!1,w=!0,v=!1,y=!1!==a.adaptive,b=0,S=0,E=0,k=r.width,A=r.height,F=0,T=!1;const P=new WeakSet,I=Math.max(1,Math.min(60,Number.isFinite(a.fps)?a.fps:60)),C=()=>!v&&!x&&!T&&!n.matches&&w&&!document.hidden,R=()=>{v||g||!w||document.hidden||(g=requestAnimationFrame(D))},L=()=>new Set(kt({...r,width:k,height:A}).map(t=>i.get(t.source).source)),N=()=>{const t=L();for(const e of l)e.loop=!0,C()&&t.has(e)?e.paused&&!P.has(e)&&(P.add(e),e.play().then(()=>{P.delete(e),C()&&L().has(e)||e.pause()}).catch(t=>{P.delete(e),v||(x=!0,N(),a.onError?.(t instanceof Error?t:new Error(String(t))),M=!0,R())})):e.pause()},O=()=>{u=0,M=!0,N(),R()};function D(t){if(g=0,v||!w||document.hidden)return;const e=C();e&&(f+=u?Math.min(.1,(t-u)/1e3):0),u=t;const n=kt({...r,width:k,height:A}),h=n.some(t=>i.get(t.source).animated||z(t.settings));if(M||e&&o.active||e&&h&&t-p>=1e3/I-.5){const r=performance.now();try{const t=new Map,l=new Set(n.map(t=>t.source));for(const a of l){const r=i.get(a);!r.animated||r.source instanceof HTMLVideoElement||!e||o.invalidate(a),t.set(a,r.frame(f))}m={};for(const t of n){let e=c.get(t.id);e||(e=new s,c.set(t.id,e)),m[t.id]=e.update(f,t.settings.motion.type,t.settings.motion.speed)}o.render(t,f,k,A,m);const d=performance.now()-r;a.onFrame?.(f,d),S=S?.9*S+.1*d:d,++b>20&&y&&e&&(h||o.active)&&(E=S>13?E+1:0,E>=12&&o.maxCells>2048&&(o.setBudget(Math.max(2048,.8*o.maxCells)),a.onQualityChange?.(o.maxCells),S=E=0,M=!0))}catch(t){x=!0,N(),a.onError?.(t instanceof Error?t:new Error(String(t)))}M=!1,p=t}e&&(h||o.active)&&R()}const U=e=>{if(!C())return;const i=t.getBoundingClientRect();i.width&&i.height&&(o.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),R())},X=()=>{o.leave(),R()},j=new IntersectionObserver(([t])=>{w=t.isIntersecting,O()});j.observe(t),t.addEventListener("pointermove",U),t.addEventListener("pointerleave",X),t.addEventListener("pointercancel",X),document.addEventListener("visibilitychange",O),n.addEventListener("change",O);const Y=()=>{if(!v){v=!0,F++,d?.abort(),cancelAnimationFrame(g),g=0,j.disconnect(),t.removeEventListener("pointermove",U),t.removeEventListener("pointerleave",X),t.removeEventListener("pointercancel",X),document.removeEventListener("visibilitychange",O),n.removeEventListener("change",O),a.signal?.removeEventListener("abort",Y),o.destroy();for(const t of h)t.destroy();c.clear()}};a.signal?.addEventListener("abort",Y,{once:!0});const B=()=>{if(v)throw new Error("Project player has been destroyed.")},q=t=>{B();const e=bt(t);Tt(e,i),k===r.width&&A===r.height&&(k=e.width,A=e.height),r=e,o.configure(r);for(const t of c.keys())r.layers.some(e=>e.id===t)||c.delete(t);O()};return O(),{canvas:t,get project(){return bt(r)},get time(){return f},get motionTimes(){return{...m}},get paused(){return x||n.matches},get maxCells(){return o.maxCells},get pixelRatio(){return o.pixelRatio},get quality(){return o.quality},update:q,updateLayer:(t,e)=>q(St(r,t,e)),resize(t,e,i){if(B(),!Number.isFinite(t)||!Number.isFinite(e)||t<2||e<2)throw new Error("Project dimensions must be positive finite numbers.");k=t,A=e,void 0!==i&&o.setPixelRatio(i),O()},pause(t=!0){B(),x=t,O()},async seek(t){if(B(),!Number.isFinite(t)||t<0)throw new Error("Project time must be finite and non-negative.");const e=++F;d?.abort(),d=new AbortController;const i=d.signal;T=!0,N();try{if(await Promise.all(h.map(e=>e.seek(t,i))),v||e!==F)return;f=t,c.clear(),o.invalidate()}finally{v||e!==F||(T=!1,O())}},redraw(){B(),o.invalidate(),M=!0,R()},setBudget(t){B(),o.setBudget(t),a.onQualityChange?.(o.maxCells),M=!0,R()},setAdaptive(t){y=t,b=E=S=0},destroy:Y}}exports.BLEND_MODES=S,exports.CHARACTER_SETS=Mt,exports.DEFAULT_STUDIO_SETTINGS=k,exports.DITHER_ALGORITHMS=b,exports.MAX_STUDIO_LAYERS=8,exports.MAX_STUDIO_WARPS=8,exports.STUDIO_CHARACTER_SETS=xt,exports.STUDIO_CURVE_CHANNELS=h,exports.STUDIO_HOVERS=t,exports.STUDIO_LOOKS=O,exports.STUDIO_MOTIONS=e,exports.STUDIO_PALETTES=E,exports.STUDIO_STYLES=y,exports.STUDIO_TEXT_FONTS=pt,exports.STUDIO_WARPS=p,exports.createStudioCurveLookup=m,exports.createStudioProjectRenderer=Ft,exports.createStudioRenderer=ht,exports.createStudioText=gt,exports.exportStudio=async function(t,e,i){let a;const r=I(e),s="png"!==i.format&&"jpeg"!==i.format;try{return await mt(async(e,o,n,h,l,c)=>{a??(a=ht(e,r,{maxDimension:4096,maxCells:i.maxCells??12e3,pixelRatio:n/(i.referenceWidth??Math.min(n,960))})),s&&a.invalidate(),a.render(await t.frame(o,l),o,n,h,c)},i)}finally{a?.destroy()}},exports.exportStudioProject=async function(t,e,i){const a=bt(t),r={...i.motionTimes};if(Object.values(r).some(t=>!Number.isFinite(t)||t<0))throw new Error("Layer motion times must be finite non-negative numbers.");const s=Object.fromEntries(Object.entries(e).map(([t,e])=>[t,e&&"object"==typeof e&&"text"in e&&"string"==typeof e.text?{...e}:e]));let o,n;const h=new AbortController,l=()=>h.abort();i.signal?.aborted?l():i.signal?.addEventListener("abort",l,{once:!0});const c="png"===i.format||"jpeg"===i.format;try{return await mt(async(t,e,h,l,d)=>{n??(n=await Pt(a,s,d)),o??(o=Ft(t,a,{maxDimension:4096,maxCells:i.maxCells??24e3,maxRasterPixels:i.maxRasterPixels,pixelRatio:h/(i.referenceWidth??Math.min(h,960))}));const m=new Set(kt({...a,width:h,height:l}).map(t=>t.source)),f=new Map;await Promise.all([...m].map(async t=>{const i=n.get(t);await i.seek(e,d),f.set(t,i.frame(e)),i.animated&&o.invalidate(t)})),o.render(f,e,h,l,c?r:{})},{...i,signal:h.signal})}finally{if(h.abort(),i.signal?.removeEventListener("abort",l),o?.destroy(),n)for(const t of new Set(n.values()))t.destroy()}},exports.loadStudioMedia=ct,exports.mountStudio=async function(t,e,i={}){const a=await ct(e,i.signal);try{return ft(t,a,i)}catch(t){throw a.destroy(),t}},exports.mountStudioMedia=ft,exports.mountStudioProject=async function(t,e,i,a={}){const r=bt(e),s=await Pt(r,i,a.signal);try{return It(t,r,s,a)}catch(t){for(const t of new Set(s.values()))t.destroy();throw t}},exports.mountStudioProjectMedia=It,exports.normalizeStudioCurve=c,exports.normalizeStudioCurves=d,exports.normalizeStudioProject=bt,exports.normalizeStudioSettings=I,exports.normalizeStudioWarps=M,exports.parseStudioProject=function(t){if(t.length>1e6)throw new Error("Project exceeds the 1 MB settings limit.");const e=JSON.parse(t);if("asciify-project"!==e?.kind||1!==e.version||!Array.isArray(e.layers))throw new Error("This is not an Asciify layered project.");return bt(e)},exports.parseStudioSettings=function(t){if(t.length>1e5)throw new Error("Settings exceed 100 KB.");return I(JSON.parse(t))},exports.restyleStudio=function(t,e=Math.random){const i=O.filter(e=>e.settings.style!==t.style||e.settings.ink!==t.ink),a=D(i[Math.min(i.length-1,Math.max(0,Math.floor(e()*i.length)))].id);return a.aspectRatio=t.aspectRatio,a.crop={...t.crop},a.mask=I(t).mask,a},exports.serializeStudioProject=t=>JSON.stringify(bt(t)),exports.serializeStudioSettings=function(t){return JSON.stringify(I(t))},exports.studioCrop=C,exports.studioDimensions=R,exports.studioGrid=N,exports.studioLayerPoint=Et,exports.studioLook=D,exports.studioProjectBudget=At,exports.studioSourceSize=rt,exports.updateStudioProjectLayer=St,exports.updateStudioSettings=L,exports.visibleStudioLayers=kt;//# sourceMappingURL=studio.cjs.map
|