asciify-engine 4.3.0 → 4.4.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/dist/studio.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var t=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk"],e=["none","bayer2","bayer4","bayer8","bayer16","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis","halftone","lines","noise","vertical-lines","diagonal-lines","radial"],i=["source-over","multiply","screen","overlay","soft-light","hard-light","color-dodge","color-burn","hue","saturation","color","luminosity"],s={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"]},a={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"},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}},o=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},r=(t,e,i,s)=>"number"==typeof t&&Number.isFinite(t)?Math.min(s,Math.max(i,t)):e,n=(t,e)=>"string"==typeof t&&/^#[\da-f]{6}$/i.test(t)?t:e,h=(t,e,i)=>e.includes(t)?t:i;function l(l={}){const c=o(l),f=a;if(void 0!==c.version&&1!==c.version)throw new Error("Unsupported studio settings version. Update asciify-engine.");const d=o(c.crop),m=o(c.backdrop),u=o(c.color),p=o(c.dither),g=o(c.mask),M=o(c.effects),x=o(c.motion),v=o(c.hover),b={...f.effects};for(const t of["bloom","characterBloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","halftone"])b[t]=r(M[t],0,0,1);b.blur=r(M.blur,0,0,24),b.blurType=h(M.blurType,["gaussian","directional","radial","progressive"],f.effects.blurType),b.angle=r(M.angle,0,-180,180),b.focus=r(M.focus,.5,0,1);let w=2048;return{version:1,aspectRatio:h(c.aspectRatio,["original","16:9","9:16","1:1","4:3","3:4","21:9"],"original"),style:h(c.style,t,f.style),cellSize:r(c.cellSize,f.cellSize,["pixel","mosaic","lego","voxel","disco","dots","hex","led","cmyk"].includes(String(c.style))?1:3,60),charset:"string"==typeof c.charset&&c.charset.length?Array.from(c.charset).slice(0,128).join(""):f.charset,colorMode:h(c.colorMode,["accent","source","gray"],f.colorMode),ink:n(c.ink,f.ink),crop:{x:r(d.x,.5,0,1),y:r(d.y,.5,0,1),zoom:r(d.zoom,1,1,5),rotation:90*Math.round(r(d.rotation,0,-360,360)/90)},backdrop:{mode:h(m.mode,["solid","transparent","source","blurred","gradient"],f.backdrop.mode),color:n(m.color,f.backdrop.color),color2:n(m.color2,f.backdrop.color2),blur:r(m.blur,12,0,32),opacity:r(m.opacity,1,0,1)},color:{brightness:r(u.brightness,0,-1,1),contrast:r(u.contrast,1,0,3),saturation:r(u.saturation,1,0,3),grayscale:r(u.grayscale,0,0,1),tint:n(u.tint,f.color.tint),amount:r(u.amount,0,0,1),blend:h(u.blend,i,f.color.blend)},dither:{algorithm:h(p.algorithm,e,"none"),palette:"string"==typeof p.palette&&Object.prototype.hasOwnProperty.call(s,p.palette)?p.palette:"mono",colors:Array.isArray(p.colors)&&p.colors.length>=2?p.colors.slice(0,32).map(t=>n(t,"#000000")):[...f.dither.colors],amount:r(p.amount,1,0,2),scale:Math.round(r(p.scale,2,1,12)),threshold:r(p.threshold,.5,0,1),motion:h(p.motion,["none","drift","shimmer"],"none"),speed:r(p.speed,1,.1,3),direction:r(p.direction,45,-180,180),colorSpace:h(p.colorSpace,["rgb","luminance"],"rgb")},mask:{enabled:!0===g.enabled,invert:!0===g.invert,shapes:Array.isArray(g.shapes)?g.shapes.slice(0,64).map(t=>{const e=o(t),i=h(e.kind,["rectangle","ellipse","brush"],"rectangle"),s="brush"===i&&Array.isArray(e.points)?e.points.slice(0,w).map(t=>Array.isArray(t)?[Math.round(1e4*r(t[0],0,0,1))/1e4,Math.round(1e4*r(t[1],0,0,1))/1e4]:[0,0]):[];return w-=s.length,{kind:i,x:r(e.x,0,0,1),y:r(e.y,0,0,1),width:r(e.width,.5,0,1),height:r(e.height,.5,0,1),size:r(e.size,.05,.005,.5),points:s}}):[]},lights:Array.isArray(c.lights)?c.lights.slice(0,4).map(t=>{const e=o(t);return{x:r(e.x,.5,0,1),y:r(e.y,.5,0,1),radius:r(e.radius,.3,.02,1),intensity:r(e.intensity,.5,0,1),color:n(e.color,"#ffffff")}}):[],effects:b,motion:{type:h(x.type,["none","caustics","current","reform","sheen","tidal","grain"],"none"),speed:r(x.speed,1,.1,3),amount:r(x.amount,1,0,2)},hover:{effect:h(v.effect,["none","trail","water","contour","dissolve","silk","vortex","magnetic","scatter"],"trail"),strength:r(v.strength,.55,0,1),radius:r(v.radius,.2,.1,1),edgeSafe:!0===v.edgeSafe}}}function c(t,e,i,s,a){const o=Math.abs(a.rotation/90)%2==1,r=o?e:t,n=o?t:e,h=Math.max(i/r,s/n)*a.zoom;return{width:r*h,height:n*h,x:(i-r*h)*a.x,y:(s-n*h)*a.y,scale:h,rotated:o}}function f(t,e,i){if(Math.abs(i.crop.rotation/90)%2==1&&([t,e]=[e,t]),"original"===i.aspectRatio)return[t,e];const[s,a]=i.aspectRatio.split(":").map(Number);return t/e>s/a?[Math.round(e*s/a),e]:[t,Math.round(t*a/s)]}function d(t,e){const i={...t,...e};for(const s of["crop","backdrop","color","dither","mask","effects","motion","hover"])e[s]&&Object.assign(i,{[s]:{...t[s],...e[s]}});return l(i)}function m(t,e,i,s=12e3,a=1){const o=Math.max(2,Number.isFinite(t)?t:960),r=Math.max(2,Number.isFinite(e)?e:540),n=Math.max(1,Math.floor(Number.isFinite(s)?s:12e3)),h=Math.max(.01,Number.isFinite(a)?a: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(o*r/(n*l))/h));for(;Math.ceil(o/(c*h))*Math.ceil(r/(c*h*l))>n;)c++;const f="dither"===i.style?i.dither.scale:i.cellSize,d=Math.max(c,f)*h;return{cell:d,rowHeight:d*l,columns:Math.ceil(o/d),rows:Math.ceil(r/(d*l)),minimum:c,limited:f<c}}var u=[["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,s])=>({id:t,name:e,description:i,settings:l(s)}));function p(t){const e=u.find(e=>e.id===t);if(!e)throw new Error("Unknown studio look.");return l(e.settings)}var g=t=>Math.max(0,Math.min(1,t)),M=(t,e,i)=>{const s=g((i-t)/(e-t));return s*s*(3-2*s)},x=(t,e)=>{const i=(.06711056*t+.00583715*e)%1*52.9829189;return i-Math.floor(i)},v=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 b(t,e,i,s,a){if(a[0]=a[1]=a[2]=0,a[3]=1,"none"===t)return a;const o=s*Math.PI/6,r=M(0,.12,Math.min(e,1-e,i,1-i));if("caustics"===t){const t=Math.sin(9*e+5*i+o)+Math.sin(8*i-3*e-o),s=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);a[2]=(.22*s-.045)*r}else if("current"===t)a[0]=Math.sin(9*i+o)*Math.cos(7*e-o)*10*r,a[1]=Math.cos(8*e+o)*Math.sin(6*i-o)*7*r;else if("sheen"===t)a[2]=.2*Math.pow(.5+.5*Math.cos(5*e+3*i-o),8)-.025;else if("tidal"===t){const t=e-.5,s=i-.5,n=Math.hypot(t,s),h=Math.sin(22*n-o)*r;a[0]=t*h*9,a[1]=s*h*9,a[2]=.035*h}else if("grain"===t){const t=x(Math.floor(160*e),Math.floor(100*i))*Math.PI*2;a[2]=.07*Math.sin(o+t)}else if("reform"===t){const t=(s%12+12)%12,n=x(Math.floor(160*e),Math.floor(100*i)),h=.65*e+.2*i+.15*n+.08*Math.sin(8*e-5*i),l=M(1.8+1.2*h,3.8+1.2*h,t)*(1-M(5+1.7*h,7.2+1.7*h,t));a[0]=Math.sin(9*i+o)*l*(1-l)*24*r,a[1]=-l*(1-l)*(8+12*n)*r,a[2]=.45*-l,a[3]=1-.9*l}return a}function w(t,e){const i=Math.max(0,Math.min(2,Number.isFinite(e)?e:1));return t[0]*=i,t[1]*=i,t[2]*=i,t[3]=g(1+(t[3]-1)*i),t}var y=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};function S(t,e,i){let s=0;for(let a=1;a<i;a*=2){const i=(Math.floor(t/a)%2+2)%2;s=4*s+[[0,2],[3,1]][(Math.floor(e/a)%2+2)%2][i]}return(s+.5)/(i*i)-.5}var E={"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]]},k=t=>[parseInt(t.slice(1,3),16),parseInt(t.slice(3,5),16),parseInt(t.slice(5,7),16)];function A(t,e,i){const s=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)),a=Math.max(0,Math.min(1,(s-.035)/.105));return a*a*a*(a*(6*a-15)+10)}var T=class{constructor(t,e){this.edgeSafe=!1,this.previous=null,this.peak=0,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 s=0;s<t;s++)this.edge[i*t+s]=A(s/(t-1),i/(e-1),t/e);this.clear()}get active(){return this.peak>2e-4}setMode(t){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,"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 s=this.previous;this.previous={x:t,y:e};const a=this.width,o=this.height,r=Math.max(1,a/o),n=Math.max(1,o/a),h=s?(t-s.x)*r:0,l=s?(e-s.y)*n:0,c=Math.hypot(h,l);if(!s&&"dissolve"!==this.mode)return;if(s&&c<1e-4)return;const f=.035+.11*Math.max(.1,Math.min(1,i)),d=Math.min(128,Math.max(1,Math.ceil(c/(.45*f)))),m=c?h/c:1,u=c?l/c:0,p=Math.min(1,c/(f*d)*2.2);for(let i=0;i<d;i++){const h=(i+.5)/d,l=s?s.x+(t-s.x)*h:t,c=s?s.y+(e-s.y)*h:e,g=Math.max(0,Math.floor((l-2.5*f/r)*(a-1))),M=Math.min(a-1,Math.ceil((l+2.5*f/r)*(a-1))),x=Math.max(0,Math.floor((c-2.5*f/n)*(o-1))),v=Math.min(o-1,Math.ceil((c+2.5*f/n)*(o-1)));for(let t=x;t<=v;t++)for(let e=g;e<=M;e++){const i=(e/(a-1)-l)*r/f,s=(t/(o-1)-c)*n/f,h=Math.exp(1.5*-(i*i+s*s)),d=t*a+e;if("dissolve"===this.mode)this.ink[d]=Math.max(this.ink[d],h);else{const a=(-i*u+s*m)*h*2.8,o=43758.5453*Math.sin(127.1*e+311.7*t),r=(o-Math.floor(o))*Math.PI*2,n="magnetic"===this.mode?-i*h*2.5:"scatter"===this.mode?(i+.7*Math.cos(r))*h*2:"silk"===this.mode?m*a:-s*h*2.5,l="magnetic"===this.mode?-s*h*2.5:"scatter"===this.mode?(s+.7*Math.sin(r))*h*2:"silk"===this.mode?u*a:i*h*2.5;this.targetX[d]=Math.max(-1,Math.min(1,this.targetX[d]+n*p)),this.targetY[d]=Math.max(-1,Math.min(1,this.targetY[d]+l*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),s=1-Math.exp(-22*e);let a=0;for(let t=0;t<this.ink.length;t++)if("dissolve"===this.mode){this.ink[t]*=i,a=Math.max(a,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{this.targetX[t]*=i,this.targetY[t]*=i,this.offsetX[t]+=(this.targetX[t]-this.offsetX[t])*s,this.offsetY[t]+=(this.targetY[t]-this.offsetY[t])*s,a=Math.max(a,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),o=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]=o>>>8,this.pixels[4*t+3]=255&o}this.peak=a,this.active||this.clear()}sample(t,e,i){const s=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),a=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),o=Math.floor(s),r=Math.floor(a),n=s-o,h=a-r,l=r*this.width+o,c=l+this.width,f=t=>(t[l]*(1-n)+t[l+1]*n)*(1-h)+(t[c]*(1-n)+t[c+1]*n)*h;i[0]=f(this.offsetX)*(this.edgeSafe?A(t,e,this.width/this.height):1)*.08,i[1]=f(this.offsetY)*(this.edgeSafe?A(t,e,this.width/this.height):1)*.08,i[2]="dissolve"===this.mode?6*-f(this.ink):0}},F=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 s=Math.max(1,this.width/this.height),a=Math.max(1,this.height/this.width);this.previous&&(Math.hypot((t-this.previous.x)*s,(e-this.previous.y)*a)<.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),s=Math.max(1,this.height/this.width);let a=0;for(const o of this.rings){const r=.015+o.age*(.15+.22*o.radius),n=.009+.014*o.radius,h=(Math.hypot((t-o.x)*i,(e-o.y)*s)-r)/n,l=Math.sin(Math.min(1,o.age/.07)*Math.PI/2)*Math.max(0,1-o.age/1.35)**2;a=Math.max(a,Math.exp(-h*h)*l)}return a}sample(t,e){const i=Math.max(0,Math.min(this.width-1,Math.round(t*(this.width-1)))),s=Math.max(0,Math.min(this.height-1,Math.round(e*(this.height-1))));return Math.max(this.ringSample(t,e),this.echo[s*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 s=0;for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const a=t*this.width+e;this.echo[a]=Math.max(this.ringSample(e/(this.width-1),t/(this.height-1)),this.echo[a]*i),s=Math.max(s,this.echo[a]);const o=Math.round(65535*this.echo[a]),r=4*a;this.pixels[r]=o>>>8,this.pixels[r+1]=255&o}this.echoPeak=s,this.active||(this.echo.fill(0),this.pixels.fill(0))}},I=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,s=performance.now()){if(!Number.isFinite(t+e+i+s))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 a=this.previous;if(this.previous={x:t,y:e,time:s},!a)return;const o=(t-a.x)*(this.width-1),r=(e-a.y)*(this.height-1),n=Math.hypot(o,r);if(n<.001)return;const h=Math.min(this.width,this.height),l=s>a.time?Math.max(1/240,(s-a.time)/1e3):1/60,c=Math.min(12,n/h/l),f=1-Math.exp(-c/2.2),d=h*(.022+.075*i)*(.65+.95*f),m=Math.min(128,Math.max(1,Math.ceil(n/(.4*d)))),u=n/d*(.32+.22*f)/m,p=o/n,g=r/n,M=-g,x=p,v=n*(2+18*f)/m;for(let i=0;i<m;i++){const s=(i+.5)/m,o=(a.x+(t-a.x)*s)*(this.width-1),r=(a.y+(e-a.y)*s)*(this.height-1),n=Math.max(1,Math.floor(o-3*d)),h=Math.min(this.width-2,Math.ceil(o+3*d)),l=Math.max(1,Math.floor(r-3*d)),c=Math.min(this.height-2,Math.ceil(r+3*d));for(let t=l;t<=c;t++)for(let e=n;e<=h;e++){const i=((e-o)*p+(t-r)*g)/d,s=((e-o)*M+(t-r)*x)/d,a=Math.exp(-i*i*.65-s*s*1.7),n=t*this.width+e;this.ink[n]=1-(1-this.ink[n])*Math.exp(-a*u);const h=1-s*s*.55,l=i*s*.7;this.u[n]=Math.max(-80,Math.min(80,this.u[n]+(p*h+M*l)*a*v)),this.v[n]=Math.max(-80,Math.min(80,this.v[n]+(g*h+x*l)*a*v))}}this.peak=1}read(t,e,i){const s=0|(e=Math.max(.5,Math.min(this.width-1.5,e))),a=0|(i=Math.max(.5,Math.min(this.height-1.5,i))),o=e-s,r=i-a,n=a*this.width+s;return(t[n]*(1-o)+t[n+1]*o)*(1-r)+(t[n+this.width]*(1-o)+t[n+this.width+1]*o)*r}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,s=this.height;for(;e>1e-7;){const t=Math.min(1/60,e);e-=t;const a=Math.exp(-1.9*t),o=Math.exp(-3.2*t);for(let e=1;e<s-1;e++)for(let r=1;r<i-1;r++){const n=e*i+r,h=Math.max(.5,Math.min(i-1.5,r-this.u[n]*t)),l=Math.max(.5,Math.min(s-1.5,e-this.v[n]*t)),c=0|h,f=0|l,d=h-c,m=l-f,u=f*i+c,p=(1-d)*(1-m),g=d*(1-m),M=(1-d)*m,x=d*m;this.a[n]=(this.u[u]*p+this.u[u+1]*g+this.u[u+i]*M+this.u[u+i+1]*x)*a,this.b[n]=(this.v[u]*p+this.v[u+1]*g+this.v[u+i]*M+this.v[u+i+1]*x)*a,this.c[n]=(this.ink[u]*p+this.ink[u+1]*g+this.ink[u+i]*M+this.ink[u+i+1]*x)*o}[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<s-1;t++)for(let e=1;e<i-1;e++){const s=t*i+e;this.curl[s]=.5*(this.v[s+1]-this.v[s-1]-this.u[s+i]+this.u[s-i])}for(let e=1;e<s-1;e++)for(let s=1;s<i-1;s++){const a=e*i+s,o=Math.abs(this.curl[a+1])-Math.abs(this.curl[a-1]),r=Math.abs(this.curl[a+i])-Math.abs(this.curl[a-i]),n=Math.hypot(o,r)+1e-4,h=this.curl[a]*t*10,l=Math.hypot(this.u[a],this.v[a]);this.u[a]+=r/n*h,this.v[a]-=o/n*h;const c=Math.min(1,l/(Math.hypot(this.u[a],this.v[a])+1e-6));this.u[a]*=c,this.v[a]*=c,this.divergence[a]=-.5*(this.u[a+1]-this.u[a-1]+this.v[a+i]-this.v[a-i])}this.pressure.fill(0);for(let t=0;t<4;t++){for(let t=1;t<s-1;t++)for(let e=1;e<i-1;e++){const s=t*i+e;this.pressureNext[s]=.25*(this.divergence[s]+this.pressure[s-1]+this.pressure[s+1]+this.pressure[s-i]+this.pressure[s+i])}[this.pressure,this.pressureNext]=[this.pressureNext,this.pressure]}let r=0;for(let e=1;e<s-1;e++)for(let s=1;s<i-1;s++){const a=e*i+s;this.u[a]=Math.max(-80,Math.min(80,this.u[a]-.5*(this.pressure[a+1]-this.pressure[a-1]))),this.v[a]=Math.max(-80,Math.min(80,this.v[a]-.5*(this.pressure[a+i]-this.pressure[a-i]))),this.driftX[a]+=(3.6*this.u[a]-58*this.offsetX[a]-12*this.driftX[a])*t,this.driftY[a]+=(3.6*this.v[a]-58*this.offsetY[a]-12*this.driftY[a])*t,this.offsetX[a]=Math.max(-2,Math.min(2,this.offsetX[a]+this.driftX[a]*t)),this.offsetY[a]=Math.max(-2,Math.min(2,this.offsetY[a]+this.driftY[a]*t)),this.signal[a]=1-Math.exp(.06*-Math.hypot(this.u[a],this.v[a])-.16*this.ink[a]),r=Math.max(r,this.signal[a])}this.peak=r}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 R(t,e){const i=Math.max(0,Math.min(1,e/.38));return t+(1-2*t)*(i*i*(3-2*i))}var P=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]=A(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 I(this.columns,this.rows),this.contour=new F(this.columns,this.rows),this.afterimage=new T(this.columns,this.rows),this.clear()}get invertsDensity(){return"trail"===this.mode}get densityTrail(){return["trail","contour","dissolve"].includes(this.mode)}get hasRefraction(){return this.active||this.lensStrength>15e-5}get active(){return["dissolve","silk","vortex","magnetic","scatter"].includes(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,"dissolve"!==t&&"silk"!==t&&"vortex"!==t&&"magnetic"!==t&&"scatter"!==t||this.afterimage.setMode(t),this.refraction.pixels="trail"===t?this.trail.pixels:"contour"===t?this.contour.pixels:["dissolve","silk","vortex","magnetic","scatter"].includes(t)?this.afterimage.pixels:this.waterPixels,this.refraction.strength="water"===t?30*this.amount/.55:"silk"===t?28*this.amount:"vortex"===t?38*this.amount:"magnetic"===t||"scatter"===t?32*this.amount:0)}configure(t,e=.55,i=.2,s=!1){this.setMode(t),this.refraction.edgeSafe=s,this.afterimage.edgeSafe=s,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="water"===t?30*this.amount/.55:"silk"===t?28*this.amount:"vortex"===t?38*this.amount:"magnetic"===t||"scatter"===t?32*this.amount:0,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)),["dissolve","silk","vortex","magnetic","scatter"].includes(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 s=this.previous;this.previous={x:t,y:e};const a=(t-s.x)*this.xScale,o=(e-s.y)*this.yScale,r=Math.hypot(a,o);if(r<1e-5)return;const n=.035+.1*this.radius,h=3*n,l=Math.min(192,Math.max(1,Math.ceil(r/(.5*n)))),c=95*Math.min(r,1)/l;for(let i=0;i<l;i++){const a=(i+.5)/l,o=s.x+(t-s.x)*a,r=s.y+(e-s.y)*a,f=Math.max(1,Math.floor((o-h/this.xScale)*(this.columns-1))),d=Math.min(this.columns-2,Math.ceil((o+h/this.xScale)*(this.columns-1))),m=Math.max(1,Math.floor((r-h/this.yScale)*(this.rows-1))),u=Math.min(this.rows-2,Math.ceil((r+h/this.yScale)*(this.rows-1)));for(let t=m;t<=u;t++)for(let e=f;e<=d;e++){const i=(e/(this.columns-1)-o)*this.xScale,s=(t/(this.rows-1)-r)*this.yScale,a=Math.exp(-(i*i+s*s)/(n*n))*c,h=t*this.columns+e;this.velocity[h]=Math.max(-12,this.velocity[h]-a)}}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(["dissolve","silk","vortex","magnetic","scatter"].includes(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),s=.3*Math.min(this.columns,this.rows);for(;this.remainder+1e-8>=e;){this.remainder-=e;let t=0;for(let a=1;a<this.rows-1;a++)for(let o=1;o<this.columns-1;o++){const r=a*this.columns+o,n=this.heights[r],h=this.heights[r-1]+this.heights[r+1]+this.heights[r-this.columns]+this.heights[r+this.columns]-4*n,l=Math.min(o,a,this.columns-1-o,this.rows-1-a),c=l<5?.88+.024*l:1,f=(this.velocity[r]+(h*s*s-8*n)*e)*i*c;this.velocity[r]=f,this.next[r]=(n+f*e)*c,t=Math.max(t,Math.abs(this.next[r]),.1*Math.abs(f))}this.heights.set(this.next),this.energy=t,this.pending=!1}if(!this.active)return void this.clear();const a=.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,s=(this.heights[t*this.columns+Math.max(0,e-1)]-this.heights[t*this.columns+Math.min(this.columns-1,e+1)])*a,o=(this.heights[Math.max(0,t-1)*this.columns+e]-this.heights[Math.min(this.rows-1,t+1)*this.columns+e])*a,r=Math.tanh(s)*(this.refraction.edgeSafe?this.edgeMask[i]:1),n=Math.tanh(o)*(this.refraction.edgeSafe?this.edgeMask[i]:1);this.normals[2*i]=r,this.normals[2*i+1]=n;const h=Math.round(32767*r+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),s=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)*s,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(["dissolve","silk","vortex","magnetic","scatter"].includes(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 s=Math.max(0,Math.min(this.columns-1.001,t*(this.columns-1))),a=Math.max(0,Math.min(this.rows-1.001,e*(this.rows-1))),o=Math.floor(s),r=Math.floor(a),n=s-o,h=a-r,l=2*(r*this.columns+o),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,s){const[a,o,r,n]=i.focus,h=(t-a)*Math.max(1,s)/n,l=(e-o)*Math.max(1,1/s)/n;return"light"===i.mode?Math.exp(-3*(h*h+l*l))*r:"scan"===i.mode?(1.3*Math.exp(-h*h*110)-.3*Math.exp(-h*h*12))*Math.exp(-l*l*1.8)*r:0}(t,e,this.refraction,this.xScale/this.yScale):0}};function C(t){return"videoWidth"in t?[t.videoWidth,t.videoHeight]:"naturalWidth"in t?[t.naturalWidth,t.naturalHeight]:[t.width,t.height]}var L=(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}},D=(t,e,i)=>{t.width===e&&t.height===i||(t.width=e,t.height=i)},O={blocks:" ░▒▓█",braille:" ⠁⠃⠇⡇⣇⣧⣷⣿",lines:" -═╪╬",cross:" ·+xX#",diagonal:" /╱╳",diamond:" ·◇◈◆",mixed:" .:+/◇#@"};function N(t,e={},i={}){const a=t.getContext("2d");if(!a)throw new Error("Canvas is already owned by another renderer.");const o=L(),r=L(!0),n=L(),h=L(),f=L(),d=L(),u=L(),p=L(),g=L(),M=L();let x,v=0,A=l(e),T=0,F="",I="",N=new Uint8ClampedArray(0),U=new Uint8ClampedArray(0),X=0,_=0,B=0,Y=null,z="",G=new P,W=0;const q=[0,0,0],H=[0,0,0,1],j=Math.max(64,Math.min(4096,Number.isFinite(i.maxDimension)?i.maxDimension:960)),V=Math.max(256,Math.min(1048576,Number.isFinite(i.maxCells)?i.maxCells:12e3));let $=V,K=Math.max(.1,Math.min(8,i.pixelRatio??1));return{canvas:t,render:function(e,i=0,l=960,L=540,V=i*A.motion.speed){if(Number.isFinite(i)||(i=0),!Number.isFinite(l)||!Number.isFinite(L)||l<1||L<1)throw new Error("Render dimensions must be positive finite numbers.");const[Q,J]=C(e);if(!Q||!J)return;const Z=Math.min(1,j/Math.max(l,L)),tt=Math.max(2,Math.round(l*Z)),et=Math.max(2,Math.round(L*Z));D(t,tt,et),D(o.canvas,tt,et),D(n.canvas,tt,et),D(h.canvas,tt,et),D(f.canvas,tt,et),W!==tt/et&&(W=tt/et,G=new P(W)),G.configure(A.hover.effect,A.hover.strength,A.hover.radius,A.hover.edgeSafe),G.step(Math.max(0,Math.min(.05,i-B))),B=i;const it="currentTime"in e?e.getVideoPlaybackQuality?.().totalVideoFrames??e.currentTime:0,st=[T,tt,et,it].join(":"),at="dither"===A.style,ot=m(tt,et,A,$,K),rt=ot.cell,nt=ot.rowHeight,ht=ot.columns,lt=ot.rows;if(F!==st||Y!==e||X!==ht||_!==lt){Y=e,F=st,I="",X=ht,_=lt,o.ctx.clearRect(0,0,tt,et),o.ctx.save();const t=c(Q,J,tt,et,A.crop);o.ctx.translate(t.x+t.width/2,t.y+t.height/2),o.ctx.rotate(A.crop.rotation*Math.PI/180),o.ctx.drawImage(e,-Q*t.scale/2,-J*t.scale/2,Q*t.scale,J*t.scale),o.ctx.restore(),D(r.canvas,X,_),r.ctx.clearRect(0,0,X,_),r.ctx.drawImage(o.canvas,0,0,X,_),N=r.ctx.getImageData(0,0,X,_).data;const i=A.color;for(let t=0;t<N.length;t+=4){const e=.299*N[t]+.587*N[t+1]+.114*N[t+2];for(let s=0;s<3;s++){const a=e+(N[t+s]-e)*i.saturation;N[t+s]=((a*(1-i.grayscale)+e*i.grayscale)/255-.5)*i.contrast*255+127.5+255*i.brightness}}}n.ctx.clearRect(0,0,tt,et),n.ctx.globalAlpha=1,n.ctx.globalCompositeOperation="source-over";const ct=V;if(at){const t=!G.active&&"none"===A.motion.type&&"none"===A.dither.motion;if(!t||I!==st){U.length!==N.length&&(U=new Uint8ClampedArray(N.length));const e=U;e.set(N);const a=A.motion.type;if(G.active||"none"!==a)for(let t=0;t<_;t++)for(let i=0;i<X;i++){const s=i/X,o=t/_;let r=i,n=t,h=0,l=1,c=1;G.active&&(G.sample(s,o,q),r-=q[0]*X,n-=q[1]*_,h=q[2]/3),b(a,s,o,ct,H),w(H,A.motion.amount??1),r-=H[0]/960*X,n-=H[1]/960*_,l=1+H[2],c=H[3],r=Math.max(0,Math.min(X-1,r)),n=Math.max(0,Math.min(_-1,n));const f=Math.floor(r),d=Math.floor(n),m=r-f,u=n-d,p=4*(t*X+i),g=4*(d*X+f),M=4*(d*X+Math.min(X-1,f+1)),x=4*(Math.min(_-1,d+1)*X+f),v=4*(Math.min(_-1,d+1)*X+Math.min(X-1,f+1));for(let t=0;t<3;t++){const i=((N[g+t]*(1-m)+N[M+t]*m)*(1-u)+(N[x+t]*(1-m)+N[v+t]*m)*u)/255;let s=(["trail","contour"].includes(A.hover.effect)?R(i,h):"dissolve"===A.hover.effect?i*Math.max(0,1+h):i)*l;e[p+t]=255*s}e[p+3]=N[g+3]*c}!function(t,e,i,a,o=0){const{algorithm:r,amount:n,threshold:h}=a,l=("custom"===a.palette?a.colors:s[a.palette]??s.mono).map(k),c=E[r],f=c?new Float32Array(3*e*3):null,d="drift"===a.motion?o*a.speed*3:0,m=(a.direction??45)*Math.PI/180,u=Math.round(Math.cos(m)*d),p=Math.round(Math.sin(m)*d),g=(t,e)=>(t%e+e)%e,M=l.map(t=>.299*t[0]+.587*t[1]+.114*t[2]),x="shimmer"===a.motion?.15*Math.sin(o*a.speed*2):0;for(let s=0;s<i;s++)for(let o=0;o<e;o++){const m=4*(s*e+o),v=3*(s%3*e+o);if(0===t[m+3]){f&&(f[v]=f[v+1]=f[v+2]=0);continue}let b=0;r.startsWith("bayer")?b=S(o-u&15,s-p&15,Number(r.slice(5))):"noise"===r?b=y(o-u,s-p)-.5:"lines"===r?b=g(s-p,4)/3-.5:"vertical-lines"===r?b=g(o-u,4)/3-.5:"diagonal-lines"===r?b=g(o-u+s-p,4)/3-.5:"radial"===r?b=g(Math.hypot(o-e/2,s-i/2)-d,6)/6-.5:"halftone"===r&&(b=Math.hypot(g(o-u,6)-2.5,g(s-p,6)-2.5)/3.54-.5);const w=128*(b*n+x+(.5-h)),E=t[m]+w+(f?.[v]??0),k=t[m+1]+w+(f?.[v+1]??0),A=t[m+2]+w+(f?.[v+2]??0);let T=0,F=0,I=0;if(l.length){let t=1/0;const e=.299*E+.587*k+.114*A;for(let i=0;i<l.length;i++){const s=l[i],o="luminance"===a.colorSpace?(e-M[i])**2:(E-s[0])**2*.299+(k-s[1])**2*.587+(A-s[2])**2*.114;o<t&&(t=o,[T,F,I]=s)}}else T=51*Math.round(E/51),F=51*Math.round(k/51),I=51*Math.round(A/51);if(t[m]=T,t[m+1]=F,t[m+2]=I,f&&c){f[v]=f[v+1]=f[v+2]=0;for(const[t,a,r]of c){const h=o+t;if(h<0||h>=e||s+a>=i)continue;const l=3*((s+a)%3*e+h);f[l]+=(E-T)*r*n,f[l+1]+=(k-F)*r*n,f[l+2]+=(A-I)*r*n}}}}(e,X,_,A.dither,i),r.ctx.putImageData(new ImageData(e,X,_),0,0),I=t?st:""}n.ctx.imageSmoothingEnabled=!1,n.ctx.drawImage(r.canvas,0,0,tt,et)}else{const t=Array.from(O[A.style]??A.charset),e=n.ctx,i="ascii"===A.style||!!O[A.style],s=Math.max(3,Math.round(.92*nt)),a=Math.ceil(rt+4),o=Math.ceil(nt+4),r=[t.join(""),s,a,o,A.ink,A.colorMode].join(":");if(i&&r!==z&&(z=r,D(u.canvas,a*t.length,o),u.ctx.clearRect(0,0,u.canvas.width,o),u.ctx.font=`${s}px monospace`,u.ctx.textBaseline="middle",u.ctx.textAlign="center",u.ctx.fillStyle="accent"===A.colorMode?A.ink:"#ffffff",t.forEach((t,e)=>u.ctx.fillText(t,e*a+a/2,o/2))),"lego"===A.style&&v!==rt){v=rt,D(M.canvas,Math.ceil(rt),Math.ceil(nt));const t=M.ctx;t.clearRect(0,0,M.canvas.width,M.canvas.height),t.fillStyle="rgba(255,255,255,.2)",t.strokeStyle="rgba(0,0,0,.25)",t.lineWidth=Math.max(.5,.6*K),t.beginPath(),t.arc(rt/2,nt/2,.28*rt,0,2*Math.PI),t.fill(),t.stroke()}e.font=`${s}px monospace`,e.textBaseline="middle",e.textAlign="center";for(let s=0;s<_;s++)for(let r=0;r<X;r++){let n=r,h=s,l=0;G.active&&(G.sample(r/X,s/_,q),n=Math.max(0,Math.min(X-1,r-q[0]*X)),h=Math.max(0,Math.min(_-1,s-q[1]*_)),l=q[2]/3);const c=4*(Math.floor(h)*X+Math.floor(n));if(!N[c+3])continue;const f=N[c],d=N[c+1],m=N[c+2],p=(.299*f+.587*d+.114*m)/255;let g=p;["trail","contour"].includes(A.hover.effect)&&l?g=R(g,l):"dissolve"===A.hover.effect&&(g*=Math.max(0,1+l));const x=A.motion.type;let v=r*rt,S=s*nt,E=1;b(x,r/X,s/_,ct,H),w(H,A.motion.amount??1),v+=H[0]*tt/960,S+=H[1]*et/960,g=Math.max(0,Math.min(1,g+H[2])),E=H[3],i||"accent"!==A.colorMode||"cmyk"===A.style||(E*=g),e.globalAlpha=E;const k=255*(g-p);let T="source"===A.colorMode?`rgb(${f+k},${d+k},${m+k})`:"gray"===A.colorMode?`rgb(${Math.round(255*g)},${Math.round(255*g)},${Math.round(255*g)})`:A.ink;if(e.fillStyle=T,i){const i=Math.max(0,Math.min(t.length-1,Math.round(g*(t.length-1))));"accent"===A.colorMode?e.drawImage(u.canvas,i*a,0,a,o,"none"===x||"caustics"===x?Math.round(v+(rt-a)/2):v+(rt-a)/2,"none"===x||"caustics"===x?Math.round(S+(nt-o)/2):S+(nt-o)/2,a,o):e.fillText(t[i],v+rt/2,S+nt/2)}else if("dots"===A.style)e.beginPath(),e.arc(v+rt/2,S+nt/2,.48*rt*Math.sqrt(g),0,2*Math.PI),e.fill();else if("led"===A.style)e.beginPath(),e.arc(v+rt/2,S+nt/2,.39*rt,0,2*Math.PI),e.fill(),e.globalAlpha=.35*E,e.fillStyle="#ffffff",e.beginPath(),e.arc(v+.43*rt,S+.4*nt,.11*rt,0,2*Math.PI),e.fill();else if("hex"===A.style){const t=v+rt/2,i=S+nt/2;e.beginPath();for(let s=0;s<6;s++){const a=Math.PI/3*s,o=t+Math.cos(a)*rt*.49,r=i+Math.sin(a)*nt*.49;0===s?e.moveTo(o,r):e.lineTo(o,r)}e.closePath(),e.fill()}else if("cmyk"===A.style){e.fillStyle="#ffffff",e.fillRect(v,S,rt,nt);const t=1-Math.max(f,d,m)/255,i=Math.max(.001,1-t),s=[["#00ffff",(1-f/255-t)/i,.36,.36],["#ff00ff",(1-d/255-t)/i,.64,.36],["#ffff00",(1-m/255-t)/i,.5,.66],["#000000",t,.5,.5]];e.globalCompositeOperation="multiply";for(const[t,i,a,o]of s)e.fillStyle=t,e.beginPath(),e.arc(v+rt*a,S+nt*o,.48*rt*Math.sqrt(Math.max(0,i)),0,2*Math.PI),e.fill();e.globalCompositeOperation="source-over"}else if("voxel"===A.style){const t=v+rt/2,i=S+nt/2;e.beginPath(),e.moveTo(t,S),e.lineTo(v+rt,S+.25*nt),e.lineTo(t,i),e.lineTo(v,S+.25*nt),e.closePath(),e.fill(),e.globalAlpha=.72*E,e.beginPath(),e.moveTo(v,S+.25*nt),e.lineTo(t,i),e.lineTo(t,S+nt),e.lineTo(v,S+.75*nt),e.closePath(),e.fill(),e.globalAlpha=.42*E,e.beginPath(),e.moveTo(t,i),e.lineTo(v+rt,S+.25*nt),e.lineTo(v+rt,S+.75*nt),e.lineTo(t,S+nt),e.closePath(),e.fill()}else{const t="pixel"===A.style?0:Math.max(.5,.06*rt);e.fillRect(v,S,rt-t,nt-t),"lego"===A.style&&e.drawImage(M.canvas,v,S),"disco"===A.style&&(e.fillStyle=`rgba(255,255,255,${.1+.25*y(r,s)})`,e.fillRect(v,S,rt-t,.35*nt),e.fillStyle="rgba(0,0,0,.25)",e.fillRect(v,S+.65*nt,rt-t,.35*nt-t))}}}n.ctx.globalAlpha=1,(A.color.amount||A.lights.length)&&(D(p.canvas,tt,et),p.ctx.clearRect(0,0,tt,et),p.ctx.drawImage(n.canvas,0,0)),A.color.amount&&(n.ctx.save(),n.ctx.globalCompositeOperation=A.color.blend,n.ctx.globalAlpha=A.color.amount,n.ctx.fillStyle=A.color.tint,n.ctx.fillRect(0,0,tt,et),n.ctx.restore());for(const t of A.lights){const e=t.radius*Math.max(tt,et),i=n.ctx.createRadialGradient(t.x*tt,t.y*et,0,t.x*tt,t.y*et,e);i.addColorStop(0,t.color),i.addColorStop(1,"transparent"),n.ctx.save(),n.ctx.globalCompositeOperation="screen",n.ctx.globalAlpha=t.intensity,n.ctx.fillStyle=i,n.ctx.fillRect(0,0,tt,et),n.ctx.restore()}if((A.color.amount||A.lights.length)&&(n.ctx.globalCompositeOperation="destination-in",n.ctx.drawImage(p.canvas,0,0),n.ctx.globalCompositeOperation="source-over"),A.mask.enabled&&A.mask.shapes.length){const t=f.ctx;t.clearRect(0,0,tt,et),t.fillStyle="#fff",t.strokeStyle="#fff",t.lineCap="round",t.lineJoin="round";for(const e of A.mask.shapes){if(t.beginPath(),"ellipse"===e.kind)t.ellipse((e.x+e.width/2)*tt,(e.y+e.height/2)*et,e.width*tt/2,e.height*et/2,0,0,2*Math.PI);else{if("rectangle"!==e.kind){if(t.lineWidth=(e.size??.05)*tt,1===e.points?.length){t.arc(e.points[0][0]*tt,e.points[0][1]*et,t.lineWidth/2,0,2*Math.PI),t.fill();continue}e.points?.forEach(([e,i],s)=>s?t.lineTo(e*tt,i*et):t.moveTo(e*tt,i*et)),t.stroke();continue}t.rect(e.x*tt,e.y*et,e.width*tt,e.height*et)}t.fill()}n.ctx.globalCompositeOperation=A.mask.invert?"destination-out":"destination-in",n.ctx.drawImage(f.canvas,0,0),n.ctx.globalCompositeOperation="source-over"}const ft=h.ctx;ft.clearRect(0,0,tt,et),ft.globalAlpha=A.backdrop.opacity;const dt=A.backdrop;if("solid"===dt.mode&&(ft.fillStyle=dt.color,ft.fillRect(0,0,tt,et)),"gradient"===dt.mode){const t=ft.createLinearGradient(0,0,tt,et);t.addColorStop(0,dt.color),t.addColorStop(1,dt.color2),ft.fillStyle=t,ft.fillRect(0,0,tt,et)}if("source"===dt.mode&&ft.drawImage(o.canvas,0,0),"blurred"===dt.mode){const t=Math.max(1,dt.blur);D(d.canvas,Math.max(2,Math.round(tt/t)),Math.max(2,Math.round(et/t))),d.ctx.drawImage(o.canvas,0,0,d.canvas.width,d.canvas.height),ft.imageSmoothingEnabled=!0,ft.drawImage(d.canvas,0,0,tt,et)}ft.globalAlpha=1,A.effects.characterBloom>0&&(D(g.canvas,Math.max(2,Math.round(tt/3)),Math.max(2,Math.round(et/3))),g.ctx.clearRect(0,0,g.canvas.width,g.canvas.height),g.ctx.drawImage(n.canvas,0,0,g.canvas.width,g.canvas.height),ft.save(),ft.globalAlpha=.8*A.effects.characterBloom,ft.globalCompositeOperation="screen",ft.filter=`blur(${1+4*A.effects.characterBloom}px)`,ft.drawImage(g.canvas,0,0,tt,et),ft.restore()),ft.drawImage(n.canvas,0,0);const mt=Object.entries(A.effects).some(([t,e])=>!["angle","focus","blurType","characterBloom"].includes(t)&&"number"==typeof e&&e>0);a.clearRect(0,0,tt,et),mt?(void 0===x&&(x=function(){const t=document.createElement("canvas"),e=t.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,antialias:!1,preserveDrawingBuffer:!0});if(!e)return null;const i=[],s=(t,s)=>{const a=e.createShader(t);if(i.push(a),e.shaderSource(a,s),e.compileShader(a),!e.getShaderParameter(a,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(a)||"Finish shader failed");return a},a=e.createProgram();if(e.attachShader(a,s(e.VERTEX_SHADER,"attribute vec2 p;varying vec2 uv;void main(){uv=(p+1.)*.5;gl_Position=vec4(p,0.,1.);}")),e.attachShader(a,s(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(a),!e.getProgramParameter(a,e.LINK_STATUS))throw new Error("Finish link failed");e.useProgram(a);const o=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,o),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),e.STATIC_DRAW);const r=e.getAttribLocation(a,"p");e.enableVertexAttribArray(r),e.vertexAttribPointer(r,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(a,t)])),c=e.getUniformLocation(a,"size");return{canvas:t,render(i,s,o,r=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(a),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/r,t.height/r);for(const t of h)e.uniform1f(l[t],"t"===t?o:"blurMode"===t?["gaussian","directional","radial","progressive"].indexOf(s.blurType):"angle"===t?s.angle*Math.PI/180:s[t]??0);return e.drawArrays(e.TRIANGLE_STRIP,0,4),t},destroy(){e.deleteTexture(n),e.deleteBuffer(o),e.deleteProgram(a),i.forEach(t=>e.deleteShader(t)),t.width=t.height=1,e.getExtension("WEBGL_lose_context")?.loseContext()}}}()),x?a.drawImage(x.render(h.canvas,A.effects,i,K),0,0):a.drawImage(h.canvas,0,0),t.dataset.studioFinish=x?"gpu":"unavailable"):(a.drawImage(h.canvas,0,0),t.dataset.studioFinish="none")},setPixelRatio(t){K=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1))},get pixelRatio(){return K},setBudget(t){$=Math.max(1500,Math.min(V,Math.round(t)))},get maxCells(){return $},configure(t){A=l(t),T++},pointer:(t,e,i)=>{G.configure(A.hover.effect,A.hover.strength,A.hover.radius,A.hover.edgeSafe),G.move(t,e,i)},leave(){G.leave()},get active(){return G.active},get settings(){return l(A)},get capabilities(){return{gpuFinish:null!==x}},invalidate(){F=""},destroy(){x?.destroy();for(const t of[o,r,n,h,f,d,u,p,g,M])t.canvas.width=t.canvas.height=1;Y=null,N=new Uint8ClampedArray(0)}}}function U(t,e,i){return new Promise((s,a)=>{const o=()=>{l(),s()},r=()=>{l(),a(new Error("Unable to load this media. Check its format and cross-origin permissions."))},n=()=>{l(),a(new DOMException("Cancelled","AbortError"))},h=setTimeout(r,2e4),l=()=>{clearTimeout(h),t.removeEventListener(e,o),t.removeEventListener("error",r),i?.removeEventListener("abort",n)};t.addEventListener(e,o,{once:!0}),t.addEventListener("error",r,{once:!0}),i?.addEventListener("abort",n,{once:!0}),i?.aborted&&n()})}async function X(t,e){if("string"==typeof t&&t.startsWith("blob:")){const i=await fetch(t,{signal:e}),s=await i.blob();return X(new File([s],"Imported media",{type:s.type}),e)}const i="string"!=typeof t,s=i?t.name:t;if(i?"image/gif"===t.type:/\.gif(?:[?#]|$)/i.test(s)){const s=await import("gifuct-js"),{parseGIF:a,decompressFrames:o}="function"==typeof s.parseGIF?s:s.default,r=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=a(r),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 f=o(n,!0);if(f.length*h*l*4>128e6)throw new Error("GIF exceeds the 128 MB decoded budget. Use MP4 for long animations.");const d=document.createElement("canvas");d.width=h,d.height=l;const m=d.getContext("2d"),u=document.createElement("canvas"),p=u.getContext("2d"),g=f.reduce((t,e)=>t+Math.max(20,e.delay),0)/1e3;let M=-1,x=null;const v=t=>{const e=(t%g+g)%g*1e3;let i=0,s=0;for(;s<f.length-1&&(i+=Math.max(20,f[s].delay),!(e<i));s++);s<M&&(m.clearRect(0,0,h,l),M=-1,x=null);for(let t=M+1;t<=s;t++){const e=f[t-1];2===e?.disposalType&&m.clearRect(e.dims.left,e.dims.top,e.dims.width,e.dims.height),3===e?.disposalType&&x&&m.putImageData(x,0,0);const i=f[t];x=3===i.disposalType?m.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),m.drawImage(u,i.dims.left,i.dims.top)}return M=s,d};return v(0),{source:d,width:h,height:l,duration:g,animated:!0,seek:async()=>{},frame:v,destroy(){d.width=u.width=1,f.length=0,x=null}}}const a=i?t.type.startsWith("video/"):/\.(mp4|webm|mov)(?:[?#]|$)/i.test(s),o=i?URL.createObjectURL(t):t,r=a?document.createElement("video"):new Image;r.crossOrigin="anonymous",r instanceof HTMLVideoElement&&(r.muted=!0,r.playsInline=!0,r.preload="auto");const n=()=>{r instanceof HTMLVideoElement?(r.pause(),r.removeAttribute("src"),r.load()):r.src="",i&&URL.revokeObjectURL(o)};try{const t=U(r,a?"loadeddata":"load",e);r.src=o,await t;const i=r instanceof HTMLVideoElement?r.videoWidth:r.naturalWidth,s=r instanceof HTMLVideoElement?r.videoHeight:r.naturalHeight;return{source:r,width:i,height:s,duration:r instanceof HTMLVideoElement?r.duration:0,animated:a,async seek(t,e){if(!(r instanceof HTMLVideoElement))return;if(!Number.isFinite(r.duration)||r.duration<=0)throw new Error("Video duration is unavailable.");const i=Math.max(0,Math.min(r.duration-.001,t%r.duration));if(Math.abs(r.currentTime-i)<.001&&r.readyState>=2)return;const s=U(r,"seeked",e);r.currentTime=i,await s},frame:()=>r,destroy:n}}catch(t){throw n(),t}}var _=t=>{if(t?.aborted)throw new DOMException("Export cancelled","AbortError")};function B(t,e,i={}){let s=l(i.settings),a=i.width??e.width,o=i.height??e.height;const r=N(t,s,i),n=new v;let h=0,c=!1,m=!0,u=!1,p=!0,g=0,M=0,x=0,b=-1,w=!1!==i.adaptive,y=0,S=0,E=0;const k=matchMedia("(prefers-reduced-motion: reduce)"),A=e.source instanceof HTMLVideoElement?e.source:null,T=()=>{c||h||!p||document.hidden||(h=requestAnimationFrame(R))},F=()=>!u&&!k.matches&&p&&!document.hidden,I=()=>{A&&(A.loop=!0,F()?A.play().catch(()=>{u=!0,m=!0,T()}):A.pause()),M=0,m=!0,T()};function R(t){if(h=0,c||!p||document.hidden)return;const l=F();l&&(g+=M?Math.min(.1,(t-M)/1e3):0),M=t;const d=l&&(e.animated||"none"!==s.motion.type||"none"!==s.dither.motion||s.effects.grain>0||s.effects.dust>0||s.effects.glitch>0),v=A?.getVideoPlaybackQuality?.().totalVideoFrames??-1,k="none"!==s.motion.type||"none"!==s.dither.motion||s.effects.grain>0||s.effects.dust>0||s.effects.glitch>0,I=!A||v<0||v!==b;if(m||r.active||d&&(I||k)&&t-x>=1e3/Math.max(1,Math.min(60,i.fps??60))-.5){const h=performance.now();try{e.animated&&!A&&r.invalidate();const[t,l]=f(a,o,s);r.render(e.frame(A?.currentTime??g),g,t,l,n.update(g,s.motion.type,s.motion.speed));const c=performance.now()-h;i.onFrame?.(A?.currentTime??g,c),S=S?.9*S+.1*c:c,++y>20&&w&&(d||r.active)&&(E=S>13?E+1:0,E>=12&&r.maxCells>3e3&&(r.setBudget(Math.max(3e3,.8*r.maxCells)),i.onQualityChange?.(r.maxCells),E=0,S=0))}catch(t){u=!0,i.onError?.(t instanceof Error?t:new Error(String(t)))}m=!1,x=t,b=v}l&&(d||r.active)&&T()}const P=e=>{if(!F())return;const i=t.getBoundingClientRect();r.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),T()},C=()=>{r.leave(),T()},L=new IntersectionObserver(([t])=>{p=t.isIntersecting,I()});L.observe(t),t.addEventListener("pointermove",P),t.addEventListener("pointerleave",C),t.addEventListener("pointercancel",C),document.addEventListener("visibilitychange",I),k.addEventListener("change",I);const D=()=>{c||(c=!0,cancelAnimationFrame(h),L.disconnect(),t.removeEventListener("pointermove",P),t.removeEventListener("pointerleave",C),t.removeEventListener("pointercancel",C),document.removeEventListener("visibilitychange",I),k.removeEventListener("change",I),i.signal?.removeEventListener("abort",D),r.destroy(),e.destroy())};if(i.signal?.addEventListener("abort",D,{once:!0}),i.signal?.aborted)throw D(),new DOMException("Cancelled","AbortError");return I(),{canvas:t,media:e,update(t){s=d(s,t),r.configure(s),m=!0,T()},resize(t,e,i){void 0!==i&&r.setPixelRatio(i),a=Math.max(2,t),o=Math.max(2,e),m=!0,T()},pause(t=!0){u=t,I()},async seek(t){g=Math.max(0,t),await e.seek(g),r.invalidate(),m=!0,T()},redraw(){r.invalidate(),m=!0,T()},get time(){return A?.currentTime??g},get paused(){return u||k.matches},setAdaptive(t){w=t,y=E=S=0},setBudget(t){r.setBudget(t),i.onQualityChange?.(r.maxCells),m=!0,T()},get pixelRatio(){return r.pixelRatio},get maxCells(){return r.maxCells},get capabilities(){return r.capabilities},destroy:D}}var Y={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")},z=Object.keys(Y);var G={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:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},W=G;exports.BLEND_MODES=i,exports.CHARACTER_SETS=G,exports.DEFAULT_STUDIO_SETTINGS=a,exports.DITHER_ALGORITHMS=e,exports.STUDIO_CHARACTER_SETS=W,exports.STUDIO_LOOKS=u,exports.STUDIO_MOTIONS=[{value:"none",mode:"none",label:"Off",description:"Keep the image still. Hover stays available."},{value:"caustics",mode:"caustics",label:"Caustics",description:"Soft ribbons of light travel across a stationary character grid."},{value:"current",mode:"current",label:"Slow Current",description:"A gentle flow through the image, with steady edges."},{value:"reform",mode:"reform",label:"Reveal & Reform",description:"Disperse, gather, then hold the complete image."},{value:"sheen",mode:"sheen",label:"Sheen",description:"A broad diagonal light sweep; characters stay anchored."},{value:"tidal",mode:"tidal",label:"Tidal Rings",description:"Concentric currents travel outward, with protected edges."},{value:"grain",mode:"grain",label:"Living Grain",description:"Slow, individually phased tonal changes on a stationary grid."}],exports.STUDIO_PALETTES=s,exports.STUDIO_STYLES=t,exports.STUDIO_TEXT_FONTS=z,exports.createStudioRenderer=N,exports.createStudioText=async function(t,e="Standard",i="#ffffff"){if(!Object.prototype.hasOwnProperty.call(Y,e))throw new Error("Unknown text font.");const{default:s}=await import("figlet/browser"),a=await Y[e]();s.parseFont(e,a.default),s.defaults({fetchFontIfMissing:!1});const o=s.textSync(t.slice(0,120),{font:e}),r=o.split("\n"),n=Math.max(1,...r.map(t=>t.length)),h=Math.max(1,r.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 f=c.getContext("2d");return f.fillStyle="#080808",f.fillRect(0,0,c.width,c.height),f.fillStyle=i,f.font=15*l+"px monospace",f.textBaseline="top",r.forEach((t,e)=>f.fillText(t,16,16+15*e*l)),{canvas:c,ascii:o}},exports.exportStudio=async function(t,e,i){const{format:s,signal:a}=i,o=Math.round(i.width),r=Math.round(i.height);if(!Number.isFinite(o)||!Number.isFinite(r)||o<2||r<2||o>4096||r>4096||o*r>16777216)throw new Error("Choose export dimensions between 2 and 4096 pixels.");if(!["png","jpeg","mp4","webm","gif"].includes(s))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 c="png"===s||"jpeg"===s,f=i.time??0;if(!Number.isFinite(f)||f<0)throw new Error("Image time must be a finite non-negative number.");if(!c&&o*r>8294400)throw new Error("Video exports support up to 3840 × 2160 pixels.");if("gif"===s&&(o*r>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"===s&&n>30)throw new Error("GIF exports support up to 30 fps. Choose MP4 or WebM for higher frame rates.");const d=document.createElement("canvas"),m=N(d,l(e),{maxDimension:4096,maxCells:i.maxCells??12e3,pixelRatio:o/(i.referenceWidth??Math.min(o,960))});let u;try{if(_(a),i.onProgress?.(0),c){if(m.render(await t.frame(f,a),f,o,r),"unavailable"===d.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");_(a);const e=await new Promise((t,e)=>d.toBlob(i=>i?t(i):e(new Error("Image export failed.")),"png"===s?"image/png":"image/jpeg",i.quality??.92));return i.onProgress?.(1),e}const e=Math.ceil(h*n);if("gif"===s){const s=await import("gifenc"),{GIFEncoder:l,quantize:c,applyPalette:f}="function"==typeof s.GIFEncoder?s:s.default,u=l(),p=d.getContext("2d");for(let s=0;s<e;s++){_(a);const l=s/n;if(m.invalidate(),m.render(await t.frame(l,a),l,o,r),"unavailable"===d.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");const g=p.getImageData(0,0,o,r).data,M=c(g,256),x=f(g,M);u.writeFrame(x,o,r,{palette:M,delay:10*(Math.round(100*Math.min((s+1)/n,h))-Math.round(100*s/n)),repeat:0}),i.onProgress?.((s+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:l,Mp4OutputFormat:p,WebMOutputFormat:g,BufferTarget:M,CanvasSource:x,canEncodeVideo:v}=await import("mediabunny"),b="mp4"===s?"avc":"vp9";if(!await v(b,{width:o,height:r}))throw new Error(`${s.toUpperCase()} encoding is unavailable in this browser. Try another format or a current browser with WebCodecs.`);const w=new l({format:"mp4"===s?new p({fastStart:"in-memory"}):new g,target:new M});d.width=o,d.height=r,u=()=>w.cancel();const y=new x(d,{codec:b,bitrate:Math.max(5e5,Math.round(o*r*n*.15))});w.addVideoTrack(y,{frameRate:n}),d.width=o,d.height=r,await w.start();for(let s=0;s<e;s++){_(a);const l=s/n;if(m.invalidate(),m.render(await t.frame(l,a),l,o,r),"unavailable"===d.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?.((s+1)/e*.98),s%4==0&&await new Promise(t=>setTimeout(t,0))}return y.close(),_(a),await w.finalize(),u=void 0,i.onProgress?.(1),new Blob([w.target.buffer],{type:"mp4"===s?"video/mp4":"video/webm"})}catch(t){throw await(u?.().catch(()=>{})),t}finally{m.destroy(),d.width=d.height=1}},exports.loadStudioMedia=X,exports.mountStudio=async function(t,e,i={}){const s=await X(e,i.signal);try{return B(t,s,i)}catch(t){throw s.destroy(),t}},exports.mountStudioMedia=B,exports.normalizeStudioSettings=l,exports.parseStudioSettings=function(t){if(t.length>1e5)throw new Error("Settings exceed 100 KB.");return l(JSON.parse(t))},exports.restyleStudio=function(t,e=Math.random){const i=u.filter(e=>e.settings.style!==t.style||e.settings.ink!==t.ink),s=p(i[Math.min(i.length-1,Math.max(0,Math.floor(e()*i.length)))].id);return s.aspectRatio=t.aspectRatio,s.crop={...t.crop},s.mask=l(t).mask,s},exports.serializeStudioSettings=function(t){return JSON.stringify(l(t))},exports.studioCrop=c,exports.studioDimensions=f,exports.studioGrid=m,exports.studioLook=p,exports.studioSourceSize=C,exports.updateStudioSettings=d;//# 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 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),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*r+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=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk"],l=["none","bayer2","bayer4","bayer8","bayer16","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis","halftone","lines","noise","vertical-lines","diagonal-lines","radial"],c=["source-over","multiply","screen","overlay","soft-light","hard-light","color-dodge","color-burn","hue","saturation","color","luminosity"],d={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"},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}},f=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},u=(t,e,i,a)=>"number"==typeof t&&Number.isFinite(t)?Math.min(a,Math.max(i,t)):e,g=(t,e)=>"string"==typeof t&&/^#[\da-f]{6}$/i.test(t)?t:e,p=(t,e,i)=>e.includes(t)?t:i;function M(i={}){const a=f(i),s=m;if(void 0!==a.version&&1!==a.version)throw new Error("Unsupported studio settings version. Update asciify-engine.");const r=f(a.crop),o=f(a.backdrop),n=f(a.color),M=f(a.dither),x=f(a.mask),v=f(a.effects),b=f(a.motion),w=f(a.hover),y={...s.effects};for(const t of["bloom","characterBloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","halftone"])y[t]=u(v[t],0,0,1);y.blur=u(v.blur,0,0,24),y.blurType=p(v.blurType,["gaussian","directional","radial","progressive"],s.effects.blurType),y.angle=u(v.angle,0,-180,180),y.focus=u(v.focus,.5,0,1);let S=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,h,s.style),cellSize:u(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:p(a.colorMode,["accent","source","gray"],s.colorMode),ink:g(a.ink,s.ink),crop:{x:u(r.x,.5,0,1),y:u(r.y,.5,0,1),zoom:u(r.zoom,1,1,5),rotation:90*Math.round(u(r.rotation,0,-360,360)/90)},backdrop:{mode:p(o.mode,["solid","transparent","source","blurred","gradient"],s.backdrop.mode),color:g(o.color,s.backdrop.color),color2:g(o.color2,s.backdrop.color2),blur:u(o.blur,12,0,32),opacity:u(o.opacity,1,0,1)},color:{brightness:u(n.brightness,0,-1,1),contrast:u(n.contrast,1,0,3),saturation:u(n.saturation,1,0,3),grayscale:u(n.grayscale,0,0,1),tint:g(n.tint,s.color.tint),amount:u(n.amount,0,0,1),blend:p(n.blend,c,s.color.blend)},dither:{algorithm:p(M.algorithm,l,"none"),palette:"string"==typeof M.palette&&Object.prototype.hasOwnProperty.call(d,M.palette)?M.palette:"mono",colors:Array.isArray(M.colors)&&M.colors.length>=2?M.colors.slice(0,32).map(t=>g(t,"#000000")):[...s.dither.colors],amount:u(M.amount,1,0,2),scale:Math.round(u(M.scale,2,1,12)),threshold:u(M.threshold,.5,0,1),motion:p(M.motion,["none","drift","shimmer"],"none"),speed:u(M.speed,1,.1,3),direction:u(M.direction,45,-180,180),colorSpace:p(M.colorSpace,["rgb","luminance"],"rgb")},mask:{enabled:!0===x.enabled,invert:!0===x.invert,shapes:Array.isArray(x.shapes)?x.shapes.slice(0,64).map(t=>{const e=f(t),i=p(e.kind,["rectangle","ellipse","brush"],"rectangle"),a="brush"===i&&Array.isArray(e.points)?e.points.slice(0,S).map(t=>Array.isArray(t)?[Math.round(1e4*u(t[0],0,0,1))/1e4,Math.round(1e4*u(t[1],0,0,1))/1e4]:[0,0]):[];return S-=a.length,{kind:i,x:u(e.x,0,0,1),y:u(e.y,0,0,1),width:u(e.width,.5,0,1),height:u(e.height,.5,0,1),size:u(e.size,.05,.005,.5),points:a}}):[]},lights:Array.isArray(a.lights)?a.lights.slice(0,4).map(t=>{const e=f(t);return{x:u(e.x,.5,0,1),y:u(e.y,.5,0,1),radius:u(e.radius,.3,.02,1),intensity:u(e.intensity,.5,0,1),color:g(e.color,"#ffffff")}}):[],effects:y,motion:{type:p(b.type,e.map(t=>t.mode),"none"),speed:u(b.speed,1,.1,3),amount:u(b.amount,1,0,2)},hover:{effect:p(w.effect,t.map(t=>t.value),"trail"),strength:u(w.strength,.55,0,1),radius:u(w.radius,.2,.1,1),edgeSafe:!0===w.edgeSafe}}}function x(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 v(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 b(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 M(i)}function w(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 d="dither"===i.style?i.dither.scale:i.cellSize,m=Math.max(c,d)*h;return{cell:m,rowHeight:m*l,columns:Math.ceil(r/m),rows:Math.ceil(o/(m*l)),minimum:c,limited:d<c}}var y=[["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:M(a)}));function S(t){const e=y.find(e=>e.id===t);if(!e)throw new Error("Unknown studio look.");return M(e.settings)}function k(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 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],g=h*(1-l)*t[d+3],p=(1-h)*l*t[m+3],M=h*l*t[f+3],x=u+g+p+M;for(let e=0;e<3;e++)r[e]=x?(t[c+e]*u+t[d+e]*g+t[m+e]*p+t[f+e]*M)/x:0;r[3]=x}var E=new Set(["none","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis"]);function A(t){return"dither"===t.style&&("shimmer"===t.dither.motion||"drift"===t.dither.motion&&t.dither.amount>0&&!E.has(t.dither.algorithm))}function T(t){return"none"!==t.motion.type&&(t.motion.amount??1)>0}var F=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};var I=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))])),P={"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]]},R=t=>[parseInt(t.slice(1,3),16),parseInt(t.slice(3,5),16),parseInt(t.slice(5,7),16)];function C(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 L=t=>["dissolve","silk","vortex","magnetic","scatter","etch","elastic","rake"].includes(t),D=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]=C(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 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,g=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,p=Math.max(0,Math.floor((l-2.5*d/o)*(s-1))),M=Math.min(s-1,Math.ceil((l+2.5*d/o)*(s-1))),x=Math.max(0,Math.floor((c-2.5*d/n)*(r-1))),v=Math.min(r-1,Math.ceil((c+2.5*d/n)*(r-1)));for(let t=x;t<=v;t++)for(let e=p;e<=M;e++){const i=(e/(s-1)-l)*o/d,a=(t/(r-1)-c)*n/d,h=Math.exp(1.5*-(i*i+a*a)),m=t*s+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*g*8)),this.springY[m]=Math.max(-24,Math.min(24,this.springY[m]+u*h*g*8));else{const s=(-i*u+a*f)*h*2.8,r="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*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*m+1])*h*2:"silk"===this.mode?u*s:i*h*2.5;this.targetX[m]=Math.max(-1,Math.min(1,this.targetX[m]+r*g)),this.targetY[m]=Math.max(-1,Math.min(1,this.targetY[m]+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,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?C(t,e,this.width/this.height):1)*.08,i[1]=d(this.offsetY)*(this.edgeSafe?C(t,e,this.width/this.height):1)*.08,i[2]="dissolve"===this.mode?6*-d(this.ink):0}},X=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))}},O=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),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,g=r/n,p=o/n,M=-p,x=g,v=n*(2+18*d)/f;for(let i=0;i<f;i++){const a=(i+.5)/f,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*m)),h=Math.min(this.width-2,Math.ceil(r+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-r)*g+(t-o)*p)/m,a=((e-r)*M+(t-o)*x)/m,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,d=0|l,m=h-c,f=l-d,u=d*i+c,g=(1-m)*(1-f),p=m*(1-f),M=(1-m)*f,x=m*f;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 N(t,e){const i=Math.max(0,Math.min(1,e/.38));return t+(1-2*t)*(i*i*(3-2*i))}var U=(t,e)=>"water"===t?30*e/.55:"silk"===t?28*e:"vortex"===t?38*e:["magnetic","scatter","elastic","rake"].includes(t)?32*e:0,Y=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]=C(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 O(this.columns,this.rows),this.contour=new X(this.columns,this.rows),this.afterimage=new D(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 L(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,L(t)&&this.afterimage.setMode(t),this.refraction.pixels="trail"===t?this.trail.pixels:"contour"===t?this.contour.pixels:L(t)?this.afterimage.pixels:this.waterPixels,this.refraction.strength=U(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=U(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)),L(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,d=Math.max(1,Math.floor((r-h/this.xScale)*(this.columns-1))),m=Math.min(this.columns-2,Math.ceil((r+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)-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(L(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,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 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(L(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 _(t){return"videoWidth"in t?[t.videoWidth,t.videoHeight]:"naturalWidth"in t?[t.naturalWidth,t.naturalHeight]:[t.width,t.height]}var B=(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}},z=(t,e,i)=>{t.width===e&&t.height===i||(t.width=e,t.height=i)},W={blocks:" ░▒▓█",braille:" ⠁⠃⠇⡇⣇⣧⣷⣿",lines:" -═╪╬",cross:" ·+xX#",diagonal:" /╱╳",diamond:" ·◇◈◆",mixed:" .:+/◇#@"};function G(t,e={},i={}){const a=t.getContext("2d");if(!a)throw new Error("Canvas is already owned by another renderer.");const s=B(),r=B(!0),h=B(),l=B(),c=B(),m=B(),f=B(),u=B(),g=B(),p=B();let v,b=0,y=M(e),S=0,E="",C="",L="",D=new Uint8ClampedArray(0),X=new Uint8ClampedArray(0),O=0,U=0,G=0,q=null,j="",H=new Y,V=0;const $=[0,0,0],K=[0,0,0,1],Q=[0,0,0,0],J=Math.max(64,Math.min(4096,Number.isFinite(i.maxDimension)?i.maxDimension:960)),Z=Math.max(256,Math.min(1048576,Number.isFinite(i.maxCells)?i.maxCells:12e3));let tt=Z,et=Math.max(.1,Math.min(8,i.pixelRatio??1));return{canvas:t,render:function(e,i=0,M=960,B=540,Z=i*y.motion.speed){if(Number.isFinite(i)||(i=0),!Number.isFinite(M)||!Number.isFinite(B)||M<1||B<1)throw new Error("Render dimensions must be positive finite numbers.");const[it,at]=_(e);if(!it||!at)return;const st=Math.min(1,J/Math.max(M,B)),rt=Math.max(2,Math.round(M*st)),ot=Math.max(2,Math.round(B*st));z(t,rt,ot),z(s.canvas,rt,ot),z(h.canvas,rt,ot),z(l.canvas,rt,ot),z(c.canvas,rt,ot),V!==rt/ot&&(V=rt/ot,H=new Y(V)),H.configure(y.hover.effect,y.hover.strength,y.hover.radius,y.hover.edgeSafe),H.step(Math.max(0,Math.min(.05,i-G))),G=i;const nt="currentTime"in e?e.getVideoPlaybackQuality?.().totalVideoFrames??e.currentTime:0,ht=[S,rt,ot,nt].join(":"),lt="dither"===y.style,ct=w(rt,ot,y,tt,et),dt=ct.cell,mt=ct.rowHeight,ft=ct.columns,ut=ct.rows;if(E!==ht||q!==e||O!==ft||U!==ut){q=e,E=ht,C="",L="",O=ft,U=ut,s.ctx.clearRect(0,0,rt,ot),s.ctx.save();const t=x(it,at,rt,ot,y.crop);s.ctx.translate(t.x+t.width/2,t.y+t.height/2),s.ctx.rotate(y.crop.rotation*Math.PI/180),s.ctx.drawImage(e,-it*t.scale/2,-at*t.scale/2,it*t.scale,at*t.scale),s.ctx.restore(),z(r.canvas,O,U),r.ctx.clearRect(0,0,O,U),r.ctx.drawImage(s.canvas,0,0,O,U),D=r.ctx.getImageData(0,0,O,U).data;const i=y.color;for(let t=0;t<D.length;t+=4){const e=.299*D[t]+.587*D[t+1]+.114*D[t+2];for(let a=0;a<3;a++){const s=e+(D[t+a]-e)*i.saturation;D[t+a]=((s*(1-i.grayscale)+e*i.grayscale)/255-.5)*i.contrast*255+127.5+255*i.brightness}}}const gt=T(y),pt=A(y),Mt=!H.active&&!gt&&!pt,xt=[ht,O,U,dt,mt,et].join(":");if(!Mt||L!==xt){h.ctx.clearRect(0,0,rt,ot),h.ctx.globalAlpha=1,h.ctx.globalCompositeOperation="source-over";const t=Z,e=gt?y.motion.type:"none",a=["none","caustics","sheen","grain","trace"].includes(e);if(lt){const a=Mt;if(!a||C!==ht){X.length!==D.length&&(X=new Uint8ClampedArray(D.length));const s=X;if(s.set(D),H.active||"none"!==e)for(let i=0;i<U;i++)for(let a=0;a<O;a++){const r=a/O,h=i/U;let l=a,c=i,d=0,m=1,f=1;H.active&&(H.sample(r,h,$),l-=$[0]*O,c-=$[1]*U,d=$[2]/3);const u=4*(i*O+a);o(e,r,h,t,K,(.299*D[u]+.587*D[u+1]+.114*D[u+2])/255),n(K,y.motion.amount??1),l-=K[0]/960*O,c-=K[1]/960*U,m=1+K[2],f=K[3],l=Math.max(0,Math.min(O-1,l)),c=Math.max(0,Math.min(U-1,c));const g=Math.floor(l),p=Math.floor(c),M=l-g,x=c-p,v=4*(i*O+a),b=4*(p*O+g),w=4*(p*O+Math.min(O-1,g+1)),S=4*(Math.min(U-1,p+1)*O+g),k=4*(Math.min(U-1,p+1)*O+Math.min(O-1,g+1));for(let t=0;t<3;t++){const e=((D[b+t]*(1-M)+D[w+t]*M)*(1-x)+(D[S+t]*(1-M)+D[k+t]*M)*x)/255;let i=(["trail","contour"].includes(y.hover.effect)?N(e,d):"etch"===y.hover.effect?Math.max(0,Math.min(1,e+.35*d)):"dissolve"===y.hover.effect?e*Math.max(0,1+d):e)*m;s[v+t]=255*i}s[v+3]=D[b+3]*f}!function(t,e,i,a,s=0){const{algorithm:r,amount:o,threshold:n}=a,h=r.startsWith("bayer")?Number(r.slice(5)):0,l=I.get(h),c=h-1,m="luminance"===a.colorSpace,f=("custom"===a.palette?a.colors:d[a.palette]??d.mono).map(R),u=P[r],g=u?new Float32Array(3*e*3):null,p="drift"===a.motion?s*a.speed*3:0,M=(a.direction??45)*Math.PI/180,x=Math.round(Math.cos(M)*p),v=Math.round(Math.sin(M)*p),b=(t,e)=>(t%e+e)%e,w=f.map(t=>.299*t[0]+.587*t[1]+.114*t[2]),y="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 d=4*(a*e+s),M=3*(a%3*e+s);if(0===t[d+3]){g&&(g[M]=g[M+1]=g[M+2]=0);continue}let S=0;l?S=l[(a-v&c)*h+(s-x&c)]:"noise"===r?S=F(s-x,a-v)-.5:"lines"===r?S=b(a-v,4)/3-.5:"vertical-lines"===r?S=b(s-x,4)/3-.5:"diagonal-lines"===r?S=b(s-x+a-v,4)/3-.5:"radial"===r?S=b(Math.hypot(s-e/2,a-i/2)-p,6)/6-.5:"halftone"===r&&(S=Math.hypot(b(s-x,6)-2.5,b(a-v,6)-2.5)/3.54-.5);const k=128*(S*o+y+(.5-n)),E=t[d]+k+(g?.[M]??0),A=t[d+1]+k+(g?.[M+1]??0),T=t[d+2]+k+(g?.[M+2]??0);let I=0,P=0,R=0;if(f.length){let t=1/0;const e=.299*E+.587*A+.114*T;for(let i=0;i<f.length;i++){const a=f[i],s=m?(e-w[i])**2:(E-a[0])**2*.299+(A-a[1])**2*.587+(T-a[2])**2*.114;s<t&&(t=s,[I,P,R]=a)}}else I=51*Math.round(E/51),P=51*Math.round(A/51),R=51*Math.round(T/51);if(t[d]=I,t[d+1]=P,t[d+2]=R,g&&u){g[M]=g[M+1]=g[M+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]+=(E-I)*n*o,g[l+1]+=(A-P)*n*o,g[l+2]+=(T-R)*n*o}}}}(s,O,U,y.dither,i),r.ctx.putImageData(new ImageData(s,O,U),0,0),C=a?ht:""}h.ctx.imageSmoothingEnabled=!1,h.ctx.drawImage(r.canvas,0,0,rt,ot)}else{const i=Array.from(W[y.style]??y.charset),s=h.ctx,r=R(y.ink),l="ascii"===y.style||!!W[y.style],c=Math.max(3,Math.round(.92*mt)),d=Math.ceil(dt+4),m=Math.ceil(mt+4),u=[i.join(""),c,d,m,y.ink,y.colorMode].join(":");if(l&&u!==j&&(j=u,z(f.canvas,d*i.length,m),f.ctx.clearRect(0,0,f.canvas.width,m),f.ctx.font=`${c}px monospace`,f.ctx.textBaseline="middle",f.ctx.textAlign="center",f.ctx.fillStyle="accent"===y.colorMode?y.ink:"#ffffff",i.forEach((t,e)=>f.ctx.fillText(t,e*d+d/2,m/2))),"lego"===y.style&&b!==dt){b=dt,z(p.canvas,Math.ceil(dt),Math.ceil(mt));const t=p.ctx;t.clearRect(0,0,p.canvas.width,p.canvas.height),t.fillStyle="rgba(255,255,255,.2)",t.strokeStyle="rgba(0,0,0,.25)",t.lineWidth=Math.max(.5,.6*et),t.beginPath(),t.arc(dt/2,mt/2,.28*dt,0,2*Math.PI),t.fill(),t.stroke()}s.font=`${c}px monospace`,s.textBaseline="middle",s.textAlign="center";for(let h=0;h<U;h++)for(let c=0;c<O;c++){let u=c,g=h,M=0;if(H.active&&(H.sample(c/O,h/U,$),u=Math.max(0,Math.min(O-1,c-$[0]*O)),g=Math.max(0,Math.min(U-1,h-$[1]*U)),M=$[2]/3),k(D,O,U,u,g,Q),!Q[3])continue;const x=Q[0],v=Q[1],b=Q[2],w=(.299*x+.587*v+.114*b)/255;let S=w;["trail","contour"].includes(y.hover.effect)&&M?S=N(S,M):"etch"===y.hover.effect?S=Math.max(0,Math.min(1,S+.35*M)):"dissolve"===y.hover.effect&&(S*=Math.max(0,1+M));let E=c*dt,A=h*mt,T=1;o(e,c/O,h/U,t,K,w),n(K,y.motion.amount??1),E+=K[0]*rt/960,A+=K[1]*ot/960,S=Math.max(0,Math.min(1,S+K[2])),T=K[3]*Q[3]/255,l||"accent"!==y.colorMode||"cmyk"===y.style||(T*=S),s.globalAlpha=T;const I=255*(S-w),P="source"===y.colorMode?`rgb(${x+I},${v+I},${b+I})`:"gray"===y.colorMode?`rgb(${Math.round(255*S)},${Math.round(255*S)},${Math.round(255*S)})`:y.ink;if(s.fillStyle=P,l){const t=Math.max(0,Math.min(i.length-1,Math.round(S*(i.length-1))));"accent"===y.colorMode?s.drawImage(f.canvas,t*d,0,d,m,a?Math.round(E+(dt-d)/2):E+(dt-d)/2,a?Math.round(A+(mt-m)/2):A+(mt-m)/2,d,m):s.fillText(i[t],E+dt/2,A+mt/2)}else if("dots"===y.style)s.beginPath(),s.arc(E+dt/2,A+mt/2,.48*dt*Math.sqrt(S),0,2*Math.PI),s.fill();else if("led"===y.style)s.beginPath(),s.arc(E+dt/2,A+mt/2,.39*dt,0,2*Math.PI),s.fill(),s.globalAlpha=.35*T,s.fillStyle="#ffffff",s.beginPath(),s.arc(E+.43*dt,A+.4*mt,.11*dt,0,2*Math.PI),s.fill();else if("hex"===y.style){const t=E+dt/2,e=A+mt/2;s.beginPath();for(let i=0;i<6;i++){const a=Math.PI/3*i,r=t+Math.cos(a)*dt*.49,o=e+Math.sin(a)*mt*.49;0===i?s.moveTo(r,o):s.lineTo(r,o)}s.closePath(),s.fill()}else if("cmyk"===y.style){s.fillStyle="#ffffff",s.fillRect(E,A,dt,mt);const t=(t,e)=>Math.max(0,Math.min(255,"source"===y.colorMode?t+I:"gray"===y.colorMode?255*S:e*S)),e=t(x,r[0]),i=t(v,r[1]),a=t(b,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(E+dt*i,A+mt*a,.48*dt*Math.sqrt(Math.max(0,e)),0,2*Math.PI),s.fill();s.globalCompositeOperation="source-over"}else if("voxel"===y.style){const t=E+dt/2,e=A+mt/2;s.beginPath(),s.moveTo(t,A),s.lineTo(E+dt,A+.25*mt),s.lineTo(t,e),s.lineTo(E,A+.25*mt),s.closePath(),s.fill(),s.globalAlpha=.72*T,s.beginPath(),s.moveTo(E,A+.25*mt),s.lineTo(t,e),s.lineTo(t,A+mt),s.lineTo(E,A+.75*mt),s.closePath(),s.fill(),s.globalAlpha=.42*T,s.beginPath(),s.moveTo(t,e),s.lineTo(E+dt,A+.25*mt),s.lineTo(E+dt,A+.75*mt),s.lineTo(t,A+mt),s.closePath(),s.fill()}else{const t="pixel"===y.style?0:Math.max(.5,.06*dt);s.fillRect(E,A,dt-t,mt-t),"lego"===y.style&&s.drawImage(p.canvas,E,A),"disco"===y.style&&(s.fillStyle=`rgba(255,255,255,${.1+.25*F(c,h)})`,s.fillRect(E,A,dt-t,.35*mt),s.fillStyle="rgba(0,0,0,.25)",s.fillRect(E,A+.65*mt,dt-t,.35*mt-t))}}}h.ctx.globalAlpha=1,(y.color.amount||y.lights.length)&&(z(u.canvas,rt,ot),u.ctx.clearRect(0,0,rt,ot),u.ctx.drawImage(h.canvas,0,0)),y.color.amount&&(h.ctx.save(),h.ctx.globalCompositeOperation=y.color.blend,h.ctx.globalAlpha=y.color.amount,h.ctx.fillStyle=y.color.tint,h.ctx.fillRect(0,0,rt,ot),h.ctx.restore());for(const t of y.lights){const e=t.radius*Math.max(rt,ot),i=h.ctx.createRadialGradient(t.x*rt,t.y*ot,0,t.x*rt,t.y*ot,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,rt,ot),h.ctx.restore()}if((y.color.amount||y.lights.length)&&(h.ctx.globalCompositeOperation="destination-in",h.ctx.drawImage(u.canvas,0,0),h.ctx.globalCompositeOperation="source-over"),y.mask.enabled&&y.mask.shapes.length){const t=c.ctx;t.clearRect(0,0,rt,ot),t.fillStyle="#fff",t.strokeStyle="#fff",t.lineCap="round",t.lineJoin="round";for(const e of y.mask.shapes){if(t.beginPath(),"ellipse"===e.kind)t.ellipse((e.x+e.width/2)*rt,(e.y+e.height/2)*ot,e.width*rt/2,e.height*ot/2,0,0,2*Math.PI);else{if("rectangle"!==e.kind){if(t.lineWidth=(e.size??.05)*rt,1===e.points?.length){t.arc(e.points[0][0]*rt,e.points[0][1]*ot,t.lineWidth/2,0,2*Math.PI),t.fill();continue}e.points?.forEach(([e,i],a)=>a?t.lineTo(e*rt,i*ot):t.moveTo(e*rt,i*ot)),t.stroke();continue}t.rect(e.x*rt,e.y*ot,e.width*rt,e.height*ot)}t.fill()}h.ctx.globalCompositeOperation=y.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,rt,ot),M.globalAlpha=y.backdrop.opacity;const x=y.backdrop;if("solid"===x.mode&&(M.fillStyle=x.color,M.fillRect(0,0,rt,ot)),"gradient"===x.mode){const t=M.createLinearGradient(0,0,rt,ot);t.addColorStop(0,x.color),t.addColorStop(1,x.color2),M.fillStyle=t,M.fillRect(0,0,rt,ot)}if("source"===x.mode&&M.drawImage(s.canvas,0,0),"blurred"===x.mode){const t=Math.max(1,x.blur);z(m.canvas,Math.max(2,Math.round(rt/t)),Math.max(2,Math.round(ot/t))),m.ctx.drawImage(s.canvas,0,0,m.canvas.width,m.canvas.height),M.imageSmoothingEnabled=!0,M.drawImage(m.canvas,0,0,rt,ot)}M.globalAlpha=1,y.effects.characterBloom>0&&(z(g.canvas,Math.max(2,Math.round(rt/3)),Math.max(2,Math.round(ot/3))),g.ctx.clearRect(0,0,g.canvas.width,g.canvas.height),g.ctx.drawImage(h.canvas,0,0,g.canvas.width,g.canvas.height),M.save(),M.globalAlpha=.8*y.effects.characterBloom,M.globalCompositeOperation="screen",M.filter=`blur(${1+4*y.effects.characterBloom}px)`,M.drawImage(g.canvas,0,0,rt,ot),M.restore()),M.drawImage(h.canvas,0,0),L=Mt?xt:""}const vt=Object.entries(y.effects).some(([t,e])=>!["angle","focus","blurType","characterBloom"].includes(t)&&"number"==typeof e&&e>0);a.clearRect(0,0,rt,ot),vt?(void 0===v&&(v=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()}}}()),v?a.drawImage(v.render(l.canvas,y.effects,i,et),0,0):a.drawImage(l.canvas,0,0),t.dataset.studioFinish=v?"gpu":"unavailable"):(a.drawImage(l.canvas,0,0),t.dataset.studioFinish="none")},setPixelRatio(t){et=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1))},get pixelRatio(){return et},setBudget(t){tt=Math.max(256,Math.min(Z,Number.isFinite(t)?Math.round(t):Z))},get maxCells(){return tt},configure(t){y=M(t),S++},pointer:(t,e,i)=>{H.configure(y.hover.effect,y.hover.strength,y.hover.radius,y.hover.edgeSafe),H.move(t,e,i)},leave(){H.leave()},get active(){return H.active},get settings(){return M(y)},get capabilities(){return{gpuFinish:null!==v}},invalidate(){E=""},destroy(){v?.destroy();for(const t of[s,r,h,l,c,m,f,u,g,p])t.canvas.width=t.canvas.height=1;q=null,D=new Uint8ClampedArray(0)}}}function q(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 j(t,e){if("string"==typeof t&&t.startsWith("blob:")){const i=await fetch(t,{signal:e}),a=await i.blob();return j(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 d=r(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"),g=u.getContext("2d"),p=d.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<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,g.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 v(0),{source:m,width:h,height:l,duration:p,animated:!0,seek:async()=>{},frame:v,destroy(){m.width=u.width=1,d.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=q(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=q(o,"seeked",e);o.currentTime=i,await a},frame:()=>o,destroy:n}}catch(t){throw n(),t}}var H=t=>{if(t?.aborted)throw new DOMException("Export cancelled","AbortError")};function V(t,e,i={}){let a=M(i.settings),s=i.width??e.width,o=i.height??e.height;const n=G(t,a,i),h=new r;let l=0,c=!1,d=!0,m=!1,f=!0,u=0,g=0,p=0,x=0,w=-1,y=!1!==i.adaptive,S=0,k=0,E=0;const F=matchMedia("(prefers-reduced-motion: reduce)"),I=e.source instanceof HTMLVideoElement?e.source:null,P=()=>{c||l||!f||document.hidden||(l=requestAnimationFrame(L))},R=()=>!m&&!F.matches&&f&&!document.hidden,C=()=>{I&&(I.loop=!0,R()?I.play().catch(()=>{m=!0,d=!0,P()}):I.pause()),p=0,d=!0,P()};function L(t){if(l=0,c||!f||document.hidden)return;const r=R();r&&(u+=p?Math.min(.1,(t-p)/1e3):0),p=t;const M=function(t){return T(t)||A(t)||t.effects.grain>0||t.effects.dust>0||t.effects.glitch>0}(a),b=r&&(e.animated||M),F=I?.getVideoPlaybackQuality?.().totalVideoFrames??-1,C=!I||F<0||F!==w;if(d||n.active||b&&(C||M)&&t-x>=1e3/Math.max(1,Math.min(60,i.fps??60))-.5){const r=performance.now();try{e.animated&&!I&&n.invalidate();const[t,l]=v(s,o,a);g=h.update(u,a.motion.type,a.motion.speed),n.render(e.frame(I?.currentTime??u),u,t,l,g);const c=performance.now()-r;i.onFrame?.(I?.currentTime??u,c),k=k?.9*k+.1*c:c,++S>20&&y&&(b||n.active)&&(E=k>13?E+1:0,E>=12&&n.maxCells>3e3&&(n.setBudget(Math.max(3e3,.8*n.maxCells)),i.onQualityChange?.(n.maxCells),E=0,k=0))}catch(t){m=!0,i.onError?.(t instanceof Error?t:new Error(String(t)))}d=!1,x=t,w=F}r&&(b||n.active)&&P()}const D=e=>{if(!R())return;const i=t.getBoundingClientRect();n.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),P()},X=()=>{n.leave(),P()},O=new IntersectionObserver(([t])=>{f=t.isIntersecting,C()});O.observe(t),t.addEventListener("pointermove",D),t.addEventListener("pointerleave",X),t.addEventListener("pointercancel",X),document.addEventListener("visibilitychange",C),F.addEventListener("change",C);const N=()=>{c||(c=!0,cancelAnimationFrame(l),O.disconnect(),t.removeEventListener("pointermove",D),t.removeEventListener("pointerleave",X),t.removeEventListener("pointercancel",X),document.removeEventListener("visibilitychange",C),F.removeEventListener("change",C),i.signal?.removeEventListener("abort",N),n.destroy(),e.destroy())};if(i.signal?.addEventListener("abort",N,{once:!0}),i.signal?.aborted)throw N(),new DOMException("Cancelled","AbortError");return C(),{canvas:t,media:e,update(t){a=b(a,t),n.configure(a),d=!0,P()},resize(t,e,i){void 0!==i&&n.setPixelRatio(i),s=Math.max(2,t),o=Math.max(2,e),d=!0,P()},pause(t=!0){m=t,C()},async seek(t){u=Math.max(0,t),await e.seek(u),n.invalidate(),d=!0,P()},redraw(){n.invalidate(),d=!0,P()},get time(){return I?.currentTime??u},get motionTime(){return g},get paused(){return m||F.matches},setAdaptive(t){y=t,S=E=k=0},setBudget(t){n.setBudget(t),i.onQualityChange?.(n.maxCells),d=!0,P()},get pixelRatio(){return n.pixelRatio},get maxCells(){return n.maxCells},get capabilities(){return n.capabilities},destroy:N}}var $={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")},K=Object.keys($);var Q={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:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},J=Q;exports.BLEND_MODES=c,exports.CHARACTER_SETS=Q,exports.DEFAULT_STUDIO_SETTINGS=m,exports.DITHER_ALGORITHMS=l,exports.STUDIO_CHARACTER_SETS=J,exports.STUDIO_HOVERS=t,exports.STUDIO_LOOKS=y,exports.STUDIO_MOTIONS=e,exports.STUDIO_PALETTES=d,exports.STUDIO_STYLES=h,exports.STUDIO_TEXT_FONTS=K,exports.createStudioRenderer=G,exports.createStudioText=async function(t,e="Standard",i="#ffffff"){if(!Object.prototype.hasOwnProperty.call($,e))throw new Error("Unknown text font.");const{default:a}=await import("figlet/browser"),s=await $[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 d=c.getContext("2d");return d.fillStyle="#080808",d.fillRect(0,0,c.width,c.height),d.fillStyle=i,d.font=15*l+"px monospace",d.textBaseline="top",o.forEach((t,e)=>d.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 d=document.createElement("canvas"),m=G(d,M(e),{maxDimension:4096,maxCells:i.maxCells??12e3,pixelRatio:r/(i.referenceWidth??Math.min(r,960))});let f;try{if(H(s),i.onProgress?.(0),l){if(m.render(await t.frame(c,s),c,r,o,i.motionTime),"unavailable"===d.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");H(s);const e=await new Promise((t,e)=>d.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:f}="function"==typeof a.GIFEncoder?a:a.default,u=l(),g=d.getContext("2d");for(let a=0;a<e;a++){H(s);const l=a/n;if(m.invalidate(),m.render(await t.frame(l,s),l,r,o),"unavailable"===d.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=f(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});d.width=r,d.height=o,f=()=>w.cancel();const y=new x(d,{codec:b,bitrate:Math.max(5e5,Math.round(r*o*n*.15))});w.addVideoTrack(y,{frameRate:n}),d.width=r,d.height=o,await w.start();for(let a=0;a<e;a++){H(s);const l=a/n;if(m.invalidate(),m.render(await t.frame(l,s),l,r,o),"unavailable"===d.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(),H(s),await w.finalize(),f=void 0,i.onProgress?.(1),new Blob([w.target.buffer],{type:"mp4"===a?"video/mp4":"video/webm"})}catch(t){throw await(f?.().catch(()=>{})),t}finally{m.destroy(),d.width=d.height=1}},exports.loadStudioMedia=j,exports.mountStudio=async function(t,e,i={}){const a=await j(e,i.signal);try{return V(t,a,i)}catch(t){throw a.destroy(),t}},exports.mountStudioMedia=V,exports.normalizeStudioSettings=M,exports.parseStudioSettings=function(t){if(t.length>1e5)throw new Error("Settings exceed 100 KB.");return M(JSON.parse(t))},exports.restyleStudio=function(t,e=Math.random){const i=y.filter(e=>e.settings.style!==t.style||e.settings.ink!==t.ink),a=S(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=M(t).mask,a},exports.serializeStudioSettings=function(t){return JSON.stringify(M(t))},exports.studioCrop=x,exports.studioDimensions=v,exports.studioGrid=w,exports.studioLook=S,exports.studioSourceSize=_,exports.updateStudioSettings=b;//# sourceMappingURL=studio.cjs.map
package/dist/studio.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as StudioSettings, a as StudioInput } from './model-CIiVhaQf.cjs';
2
- export { B as BLEND_MODES, C as CHARACTER_SETS, D as DEFAULT_STUDIO_SETTINGS, b as DITHER_ALGORITHMS, c as DitherAlgorithm, d as STUDIO_CHARACTER_SETS, e as STUDIO_PALETTES, f as STUDIO_STYLES, g as StudioLight, h as StudioMask, i as StudioStyle, n as normalizeStudioSettings, p as parseStudioSettings, s as serializeStudioSettings, j as studioCrop, k as studioDimensions, l as studioGrid, u as updateStudioSettings } from './model-CIiVhaQf.cjs';
1
+ import { S as StudioSettings, a as StudioInput } from './model-BOcK8oM-.cjs';
2
+ export { B as BLEND_MODES, C as CHARACTER_SETS, D as DEFAULT_STUDIO_SETTINGS, b as DITHER_ALGORITHMS, c as DitherAlgorithm, d as STUDIO_CHARACTER_SETS, e as STUDIO_PALETTES, f as STUDIO_STYLES, g as StudioLight, h as StudioMask, i as StudioStyle, n as normalizeStudioSettings, p as parseStudioSettings, s as serializeStudioSettings, j as studioCrop, k as studioDimensions, l as studioGrid, u as updateStudioSettings } from './model-BOcK8oM-.cjs';
3
3
  import * as figlet_fonts_Wavy from 'figlet/fonts/Wavy';
4
4
  import * as figlet_fonts_Univers from 'figlet/fonts/Univers';
5
5
  import * as figlet_fonts_3_D from 'figlet/fonts/3-D';
@@ -21,7 +21,7 @@ import * as figlet_fonts_Big from 'figlet/fonts/Big';
21
21
  import * as figlet_fonts_Small from 'figlet/fonts/Small';
22
22
  import * as figlet_fonts_Slant from 'figlet/fonts/Slant';
23
23
  import * as figlet_fonts_Standard from 'figlet/fonts/Standard';
24
- export { M as STUDIO_MOTIONS } from './ambient-motion-C2qG4xUI.cjs';
24
+ export { a as STUDIO_HOVERS, M as STUDIO_MOTIONS } from './hover-catalog-BeIkNwhH.cjs';
25
25
 
26
26
  declare const STUDIO_LOOKS: {
27
27
  id: string;
@@ -81,6 +81,8 @@ interface StudioExportOptions {
81
81
  duration?: number;
82
82
  /** Timeline position for a still image. Animations start at zero. */
83
83
  time?: number;
84
+ /** For still exports, use the mounted preview's motionTime after speed edits. */
85
+ motionTime?: number;
84
86
  fps?: number;
85
87
  quality?: number;
86
88
  signal?: AbortSignal;
@@ -118,6 +120,8 @@ declare function mountStudio(canvas: HTMLCanvasElement, source: File | string, o
118
120
  seek(seconds: number): Promise<void>;
119
121
  redraw(): void;
120
122
  readonly time: number;
123
+ /** Ambient phase of the last displayed frame, preserved across speed edits. */
124
+ readonly motionTime: number;
121
125
  readonly paused: boolean;
122
126
  setAdaptive(enabled: boolean): void;
123
127
  setBudget(cells: number): void;
@@ -138,6 +142,8 @@ declare function mountStudioMedia(canvas: HTMLCanvasElement, media: StudioMedia,
138
142
  seek(seconds: number): Promise<void>;
139
143
  redraw(): void;
140
144
  readonly time: number;
145
+ /** Ambient phase of the last displayed frame, preserved across speed edits. */
146
+ readonly motionTime: number;
141
147
  readonly paused: boolean;
142
148
  setAdaptive(enabled: boolean): void;
143
149
  setBudget(cells: number): void;
package/dist/studio.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as StudioSettings, a as StudioInput } from './model-S1T5tuQG.js';
2
- export { B as BLEND_MODES, C as CHARACTER_SETS, D as DEFAULT_STUDIO_SETTINGS, b as DITHER_ALGORITHMS, c as DitherAlgorithm, d as STUDIO_CHARACTER_SETS, e as STUDIO_PALETTES, f as STUDIO_STYLES, g as StudioLight, h as StudioMask, i as StudioStyle, n as normalizeStudioSettings, p as parseStudioSettings, s as serializeStudioSettings, j as studioCrop, k as studioDimensions, l as studioGrid, u as updateStudioSettings } from './model-S1T5tuQG.js';
1
+ import { S as StudioSettings, a as StudioInput } from './model-BhR1zliO.js';
2
+ export { B as BLEND_MODES, C as CHARACTER_SETS, D as DEFAULT_STUDIO_SETTINGS, b as DITHER_ALGORITHMS, c as DitherAlgorithm, d as STUDIO_CHARACTER_SETS, e as STUDIO_PALETTES, f as STUDIO_STYLES, g as StudioLight, h as StudioMask, i as StudioStyle, n as normalizeStudioSettings, p as parseStudioSettings, s as serializeStudioSettings, j as studioCrop, k as studioDimensions, l as studioGrid, u as updateStudioSettings } from './model-BhR1zliO.js';
3
3
  import * as figlet_fonts_Wavy from 'figlet/fonts/Wavy';
4
4
  import * as figlet_fonts_Univers from 'figlet/fonts/Univers';
5
5
  import * as figlet_fonts_3_D from 'figlet/fonts/3-D';
@@ -21,7 +21,7 @@ import * as figlet_fonts_Big from 'figlet/fonts/Big';
21
21
  import * as figlet_fonts_Small from 'figlet/fonts/Small';
22
22
  import * as figlet_fonts_Slant from 'figlet/fonts/Slant';
23
23
  import * as figlet_fonts_Standard from 'figlet/fonts/Standard';
24
- export { M as STUDIO_MOTIONS } from './ambient-motion-C2qG4xUI.js';
24
+ export { a as STUDIO_HOVERS, M as STUDIO_MOTIONS } from './hover-catalog-BeIkNwhH.js';
25
25
 
26
26
  declare const STUDIO_LOOKS: {
27
27
  id: string;
@@ -81,6 +81,8 @@ interface StudioExportOptions {
81
81
  duration?: number;
82
82
  /** Timeline position for a still image. Animations start at zero. */
83
83
  time?: number;
84
+ /** For still exports, use the mounted preview's motionTime after speed edits. */
85
+ motionTime?: number;
84
86
  fps?: number;
85
87
  quality?: number;
86
88
  signal?: AbortSignal;
@@ -118,6 +120,8 @@ declare function mountStudio(canvas: HTMLCanvasElement, source: File | string, o
118
120
  seek(seconds: number): Promise<void>;
119
121
  redraw(): void;
120
122
  readonly time: number;
123
+ /** Ambient phase of the last displayed frame, preserved across speed edits. */
124
+ readonly motionTime: number;
121
125
  readonly paused: boolean;
122
126
  setAdaptive(enabled: boolean): void;
123
127
  setBudget(cells: number): void;
@@ -138,6 +142,8 @@ declare function mountStudioMedia(canvas: HTMLCanvasElement, media: StudioMedia,
138
142
  seek(seconds: number): Promise<void>;
139
143
  redraw(): void;
140
144
  readonly time: number;
145
+ /** Ambient phase of the last displayed frame, preserved across speed edits. */
146
+ readonly motionTime: number;
141
147
  readonly paused: boolean;
142
148
  setAdaptive(enabled: boolean): void;
143
149
  setBudget(cells: number): void;