asciify-engine 4.2.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/{ambient-motion-CqF5-eZ2.d.cts → ambient-motion-C2qG4xUI.d.cts} +16 -1
- package/dist/{ambient-motion-CqF5-eZ2.d.ts → ambient-motion-C2qG4xUI.d.ts} +16 -1
- package/dist/core.cjs +1 -1
- package/dist/core.d.cts +4 -4
- package/dist/core.d.ts +4 -4
- package/dist/core.js +1 -1
- package/dist/hover.cjs +1 -1
- package/dist/hover.d.cts +3 -3
- package/dist/hover.d.ts +3 -3
- package/dist/hover.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/{model-CDiABFst.d.cts → model-CIiVhaQf.d.cts} +2 -2
- package/dist/{model-BbKQNvhk.d.ts → model-S1T5tuQG.d.ts} +2 -2
- package/dist/studio.cjs +1 -1
- package/dist/studio.d.cts +3 -3
- package/dist/studio.d.ts +3 -3
- package/dist/studio.js +1 -1
- package/dist/{types-BeXEm4UY.d.cts → types-CZdZg9Mw.d.cts} +1 -1
- package/dist/{types-BeXEm4UY.d.ts → types-CZdZg9Mw.d.ts} +1 -1
- package/package.json +1 -1
- package/skills/asciify-engine/SKILL.md +2 -2
- package/skills/asciify-engine/references/studio-workspace.md +18 -0
package/dist/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var t={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:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},e={dracula:{name:"Dracula",accent:"#bd93f9",bg:"#282a36",fg:"#f8f8f2"},monokai:{name:"Monokai",accent:"#a6e22e",bg:"#272822",fg:"#f8f8f2"},nord:{name:"Nord",accent:"#88c0d0",bg:"#2e3440",fg:"#eceff4"},catppuccin:{name:"Catppuccin",accent:"#cba6f7",bg:"#1e1e2e",fg:"#cdd6f4"},solarized:{name:"Solarized",accent:"#268bd2",bg:"#002b36",fg:"#839496"},gruvbox:{name:"Gruvbox",accent:"#b8bb26",bg:"#282828",fg:"#ebdbb2"}},n={fontSize:7,charSpacing:1,brightness:0,contrast:0,charset:t.standard.chars,colorMode:"grayscale",accentColor:"#d4ff00",invert:!1,renderMode:"ascii",animationStyle:"none",animationSpeed:1,dotSizeRatio:.8,ditherStrength:0,charAspect:.55,normalize:!1,hoverStrength:0,hoverRadius:.2,hoverEffect:"spotlight",hoverColor:"#ffffff",hoverShape:"circle",hoverText:"ASCIIFY",artStyle:"classic",fineDither:!1,customText:"",chromaKey:null,chromaKeyTolerance:60,chromaKeyTrimPadding:.002,chromaKeyTrimLuminanceThreshold:0,chromaKeyTrimMode:"range"},o={none:{label:"Off",options:{hoverStrength:0,hoverEffect:"spotlight",hoverRadius:.2,hoverColor:"#ffffff"}},subtle:{label:"Subtle",options:{hoverStrength:.25,hoverEffect:"glow",hoverRadius:.12,hoverColor:"#ffffff"}},flashlight:{label:"Flashlight",options:{hoverStrength:.6,hoverEffect:"spotlight",hoverRadius:.15,hoverColor:"#fffbe6"}},magnifier:{label:"Magnifier",options:{hoverStrength:.7,hoverEffect:"magnify",hoverRadius:.12,hoverColor:"#ffffff"}},forceField:{label:"Force Field",options:{hoverStrength:.7,hoverEffect:"repel",hoverRadius:.15,hoverColor:"#a0e8ff"}},neon:{label:"Neon",options:{hoverStrength:.6,hoverEffect:"colorShift",hoverRadius:.15,hoverColor:"#d946ef"}},fire:{label:"Fire",options:{hoverStrength:.7,hoverEffect:"spotlight",hoverRadius:.15,hoverColor:"#ff6b2b"}},ice:{label:"Ice",options:{hoverStrength:.5,hoverEffect:"glow",hoverRadius:.15,hoverColor:"#60d5f7"}},gravity:{label:"Gravity",options:{hoverStrength:.7,hoverEffect:"attract",hoverRadius:.18,hoverColor:"#a5d6ff"}},shatter:{label:"Shatter",options:{hoverStrength:.8,hoverEffect:"shatter",hoverRadius:.14,hoverColor:"#ff6090"}},ghost:{label:"Fluid trail",options:{hoverStrength:.55,hoverEffect:"trail",hoverRadius:.2,hoverColor:"#b39ddb"}},glitchReveal:{label:"Glitch Reveal",options:{hoverStrength:.8,hoverEffect:"glitchText",hoverRadius:.18,hoverColor:"#a3e635"}}},r=[{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."}];var i=(t,e,n)=>{const o=(t=>Math.max(0,Math.min(1,t)))((n-t)/(e-t));return o*o*(3-2*o)};function a(t,e,n,o,r){if(r[0]=r[1]=r[2]=0,r[3]=1,"none"===t)return r;const a=o*Math.PI/6,s=i(0,.12,Math.min(e,1-e,n,1-n));if("caustics"===t){const t=Math.sin(9*e+5*n+a)+Math.sin(8*n-3*e-a),o=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);r[2]=(.22*o-.045)*s}else if("current"===t)r[0]=Math.sin(9*n+a)*Math.cos(7*e-a)*10*s,r[1]=Math.cos(8*e+a)*Math.sin(6*n-a)*7*s;else if("reform"===t){const t=(o%12+12)%12,c=((t,e)=>{const n=(.06711056*t+.00583715*e)%1*52.9829189;return n-Math.floor(n)})(Math.floor(160*e),Math.floor(100*n)),l=.65*e+.2*n+.15*c+.08*Math.sin(8*e-5*n),h=i(1.8+1.2*l,3.8+1.2*l,t)*(1-i(5+1.7*l,7.2+1.7*l,t));r[0]=Math.sin(9*n+a)*h*(1-h)*24*s,r[1]=-h*(1-h)*(8+12*c)*s,r[2]=.45*-h,r[3]=1-.9*h}return r}function s(t,e){const n=document.createElement("canvas");n.width=t,n.height=e;const o=n.getContext("2d",{willReadFrequently:!0});return{canvas:n,ctx:o}}function c(t,e,n){let o=t+255*e;return o=259*(255*n+255)/(255*(259-255*n))*(o-128)+128,Math.max(0,Math.min(255,o))}function l(t,e,n,o,r,i){if((i?1-t/255:t/255)<.12)return" ";const a=[...e];return a[(o*r+n)%a.length]}var h=[[0,8,2,10],[12,4,14,6],[3,11,1,9],[15,7,13,5]];function d(t,e,n,o){if(o<=0)return t;const r=(h[n%4][e%4]/16-.5)*o*128;return Math.max(0,Math.min(255,t+r))}var f=new Array(256),m=new Array(256);for(let t=0;t<256;t++)f[t]=`rgb(${t},${t},${t})`,m[t]=`rgb(0,${t},0)`;function u(t,e,n,o,r,i=!1){switch(e){case"fullcolor":return`rgb(${t.r},${t.g},${t.b})`;case"matrix":return m[.299*t.r+.587*t.g+.114*t.b|0];case"accent":return`rgb(${n},${o},${r})`;default:{const e=.299*t.r+.587*t.g+.114*t.b|0;return f[e]}}}var g=[0,0,0];function p(t,e,n,o,r,i=!1){switch(e){case"fullcolor":g[0]=t.r,g[1]=t.g,g[2]=t.b;break;case"matrix":{const e=.299*t.r+.587*t.g+.114*t.b|0;g[0]=0,g[1]=e,g[2]=0;break}case"accent":g[0]=n,g[1]=o,g[2]=r;break;default:{const e=.299*t.r+.587*t.g+.114*t.b|0;g[0]=e,g[1]=e,g[2]=e;break}}return g}function M(t){const e=t.match(/rgba?\(\s*(\d+)\s*[,\s]\s*(\d+)\s*[,\s]\s*(\d+)(?:\s*[,/]\s*([\d.]+))?\s*\)/);return e?{r:+e[1],g:+e[2],b:+e[3],a:void 0!==e[4]?+e[4]:1}:null}function v(t){let e=t;for(;e&&e!==document.documentElement.parentElement;){const t=getComputedStyle(e).backgroundColor;if(t&&"transparent"!==t&&"rgba(0, 0, 0, 0)"!==t){const e=M(t);if(e&&e.a>.1)return e}e=e.parentElement}return null}function w(t){if(t){const e=v(t);if(e){return(.299*e.r+.587*e.g+.114*e.b)/255<.4}}if("undefined"!=typeof document){const t=document.documentElement,e=(t.getAttribute("data-theme")||"").toLowerCase();if("dark"===e)return!0;if("light"===e)return!1;if(t.classList.contains("dark"))return!0;if(document.body){const t=v(document.body);if(t){return(.299*t.r+.587*t.g+.114*t.b)/255<.4}}}return"undefined"!=typeof window&&window.matchMedia("(prefers-color-scheme: dark)").matches}function y(t){if("string"!=typeof t)return t;const e=document.createElement("canvas");e.width=1,e.height=1;const n=e.getContext("2d");n.fillStyle=t,n.fillRect(0,0,1,1);const o=n.getImageData(0,0,1,1).data;return{r:o[0],g:o[1],b:o[2]}}function x(t){return t*t*(3-2*t)}var b={scale:1,offsetX:0,offsetY:0,glow:0,colorBlend:0,proximity:0};function S(t,e,n,o,r,i,a,s,c="spotlight",l=.5,h="circle",d=[],f=1){const m=(t-n)*Math.max(1,f),u=(e-o)*Math.max(1,1/f),g=.08+.35*l+.04*i;let p,M;if("box"===h){const t=Math.abs(m),e=Math.abs(u);p=Math.max(t,e),M=g}else p=Math.sqrt(m*m+u*u),M=g;if(p>=M&&("trail"!==c||0===d.length))return b.scale=1,b.offsetX=0,b.offsetY=0,b.glow=0,b.colorBlend=0,b.proximity=0,b;const v=x(Math.max(0,1-p/M))*r;let w=1,y=0,S=0,E=0,C=0;switch(c){case"spotlight":{w=1+v*i*1.8;const t=Math.atan2(u,m),e=v*v*i*.6;y=Math.cos(t)*e*a,S=Math.sin(t)*e*s,E=v*i*.4,C=v*v*i*.25;break}case"magnify":w=1+v*i*.85,E=v*i*.15;break;case"repel":{w=1;const t=Math.atan2(u,m),e=v*v*i*1.8;y=Math.cos(t)*e*a,S=Math.sin(t)*e*s;break}case"glow":E=v*i*.8,C=v*i*.4;break;case"colorShift":w=1,E=v*i*.12,C=v*i;break;case"attract":{const t=Math.atan2(u,m),e=v*v*i*1;y=(.45*-Math.cos(t)-1.6*Math.sin(t))*e*a,S=(.45*-Math.sin(t)+1.6*Math.cos(t))*e*s,E=v*i*.3;break}case"shatter":{const t=Math.atan2(u,m),e=.5*Math.sin(43.7*m+29.3*u),n=v*i*1.4*(.7+.3*e);y=Math.cos(t+e)*n*a,S=Math.sin(t+e)*n*s,w=Math.max(.1,1-v*i*.6),E=v*i*.25;break}case"trail":{let n=v,o=-u*v,r=m*v;for(const i of d){const a=(t-i.x)*Math.max(1,f),s=(e-i.y)*Math.max(1,1/f),c=Math.hypot(a,s)/g;if(c>=1)continue;const l=x(1-c)*i.intensity;n=Math.max(n,l),o+=(.35*i.vx-2*s)*l*.35,r+=(.35*i.vy+2*a)*l*.35}y=Math.tanh(2*o)*i*a*3,S=Math.tanh(2*r)*i*s*3,C=n*i*.65,E=n*i*.35,w=1+n*i*.08,b.proximity=n;break}case"glitchText":w=1,E=v*i*.5,C=v*i*.6}return b.scale=w,b.offsetX=y,b.offsetY=S,b.glow=E,b.colorBlend=C,"trail"!==c&&(b.proximity=v),b}function E(t,e,{continuous:n=!1,interactive:o=!1}={}){const r=t.parentElement??t;let i=null,a=0,s=!1,c=!0,l=!0,h=-1/0;const d=window.matchMedia("(prefers-reduced-motion: reduce)"),f=()=>{l=!0,s||!c||document.hidden||a||(a=requestAnimationFrame(m))},m=t=>{if(a=0,s||!c||document.hidden)return;const o=!d.matches&&(n||t-h<1500);(l||o)&&(e(t,d.matches?null:i),l=!1),o&&(a=requestAnimationFrame(m))},u=e=>{if("touch"===e.pointerType)return;const n=t.getBoundingClientRect();if(!n.width||!n.height)return;const o=(e.clientX-n.left)/n.width,r=(e.clientY-n.top)/n.height;i=o>=0&&o<=1&&r>=0&&r<=1?{x:o,y:r}:null,h=performance.now(),f()},g=()=>{i=null,h=performance.now(),f()},p=()=>{document.hidden&&a?(cancelAnimationFrame(a),a=0):f()},M="undefined"==typeof IntersectionObserver?null:new IntersectionObserver(([t])=>{c=t.isIntersecting,c?f():a&&(cancelAnimationFrame(a),a=0)});return M?.observe(t),o&&(r.addEventListener("pointermove",u),r.addEventListener("pointerleave",g)),document.addEventListener("visibilitychange",p),d.addEventListener("change",f),f(),{wake:f,stop:()=>{s=!0,cancelAnimationFrame(a),M?.disconnect(),r.removeEventListener("pointermove",u),r.removeEventListener("pointerleave",g),document.removeEventListener("visibilitychange",p),d.removeEventListener("change",f)}}}var C=null,T=null;function A(t,e){if(!C||!T){const n=s(t,e);C=n.canvas,T=n.ctx}return C.width!==t&&(C.width=t),C.height!==e&&(C.height=e),T}var F=new Map,L=new Map,I=new WeakMap;function R(t){const e=Intl.Segmenter;return e?Array.from(new e(void 0,{granularity:"grapheme"}).segment(t),({segment:t})=>t):[...t]}function k(t){let e=F.get(t);return e||(e=R(t),F.set(t,e)),e}function H(t){return R(t)}function W(t,e,n){const o=n?1-t/255:t/255,r=Math.floor(o*(e.length-1));return e[Math.max(0,Math.min(e.length-1,r))]??" "}function $(t,e,n,o){const r=`${t}\0${e?1:0}\0${n}\0${o}`;let i=L.get(r);if(!i){const a=k(t);i=new Array(256);for(let t=0;t<256;t++)i[t]=W(c(t,n,o),a,e);L.set(r,i)}return i}function P(){F.clear(),L.clear(),X=new WeakMap,J=new WeakMap,_=new WeakMap,C=null,T=null}function j(t,e){return"auto"!==t?t:!w(e)}function z(t){const e=t.match(/^#([0-9a-fA-F]{3,6})$/);if(e){let t=e[1];if(3===t.length&&(t=t[0]+t[0]+t[1]+t[1]+t[2]+t[2]),6===t.length)return t}const n=t.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);return n?[n[1],n[2],n[3]].map(t=>parseInt(t).toString(16).padStart(2,"0")).join(""):null}function O(t){const e=t||"auto";if("auto"!==e)return z(e)??"ffffff";if("undefined"!=typeof document){const t=getComputedStyle(document.documentElement);for(const e of["--accent-color","--color-accent","--accent","--color-primary","--primary","--brand-color"]){const n=z(t.getPropertyValue(e).trim());if(n)return n}const e=z(getComputedStyle(document.body).accentColor??"");if(e)return e}return w("undefined"!=typeof document?document.body:null)?"faf9f7":"0d0d0d"}function q(t,e,n){return Math.max(e,Math.min(n,t))}function B(t,e,n){if(!t)return{x:0,y:0,width:e,height:n};const o=t.unit??"percent",r=!1!==t.preserveAspect,i=t=>void 0===t?void 0:"percent"===o?t*e:t,a=t=>void 0===t?void 0:"percent"===o?t*n:t,s=q(i(t.left)??0,0,e-1),c=q(i(t.right)??0,0,e-s-1),l=q(a(t.top)??0,0,n-1),h=q(a(t.bottom)??0,0,n-l-1),d=void 0!==t.left||void 0!==t.right||void 0!==t.top||void 0!==t.bottom,f=Math.max(1,e-s-c),m=Math.max(1,n-l-h),u=d?f:i(t.width),g=d?m:a(t.height);let p=u??e,M=g??n;if(r&&!d){const t=p/e,o=M/n,r=Math.min(t,o),i=void 0===u?o:void 0===g?t:r;p=e*i,M=n*i}p=q(p,1,d?f:e),M=q(M,1,d?m:n);const v=t.anchor??"center",w=i(t.x),y=a(t.y),x=d?s:0,b=d?l:0,S=d?f:e,E=d?m:n,C=v.endsWith("left")||"left"===v?0:v.endsWith("right")||"right"===v?S-p:(S-p)/2,T=v.startsWith("top")||"top"===v?0:v.startsWith("bottom")||"bottom"===v?E-M:(E-M)/2;return{x:q(w??x+C,0,Math.max(0,e-p)),y:q(y??b+T,0,Math.max(0,n-M)),width:p,height:M}}function V(t,e,n,o){const r=t instanceof HTMLVideoElement?t.videoWidth:t.width,i=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(0===r||0===i)return{frame:[],cols:0,rows:0};const a=e.charAspect,s=e.fontSize*e.charSpacing,h=e.fontSize/a*e.charSpacing,f=n||r,m=o||i,u=Math.floor(f/s),g=Math.floor(m/h);if(u<=0||g<=0)return{frame:[],cols:0,rows:0};const p=B(e.sourceCrop,r,i),M=Math.max(1,Math.min(Math.floor(2048/u),Math.floor(p.width/u))),v=Math.max(1,Math.min(Math.floor(2048/g),Math.floor(p.height/g))),w=u*M,x=g*v,b=A(w,x),S=b.globalCompositeOperation;b.globalCompositeOperation="copy";try{b.drawImage(t,p.x,p.y,p.width,p.height,0,0,w,x)}finally{b.globalCompositeOperation=S}const E=b.getImageData(0,0,w,x).data,C=e.chromaKey,T=null!=C&&!1!==C,F=!0===C,L="blue-screen"===C;let I=null,R=0;!T||F||L||(I=y(C),R=(e.chromaKeyTolerance??60)**2);let H=0,P=255;if(e.normalize){let t=255,e=0;for(let n=0;n<E.length;n+=4){if(T){const t=E[n],e=E[n+1],o=E[n+2];let r=!1;if(F)r=e>1.4*t&&e>1.4*o&&e>80;else if(L)r=o>1.4*t&&o>1.4*e&&o>80;else if(null!==I){const n=t-I.r,i=e-I.g,a=o-I.b;r=n*n+i*i+a*a<=R}if(r)continue}const o=.299*E[n]+.587*E[n+1]+.114*E[n+2];o<t&&(t=o),o>e&&(e=o)}H=t,P=e>t?e-t:255}const z=[],O=j(e.invert),q=T&&e.charset.replace(/ /g,"")||e.charset,V=k(q),D=e.customText?null:$(q,O,e.brightness,e.contrast),K=M*v;for(let t=0;t<g;t++){const n=[];for(let o=0;o<u;o++){let r=0,i=0,a=0,s=0,h=0;for(let e=0;e<v;e++){const n=(t*v+e)*w;for(let t=0;t<M;t++){const e=4*(n+o*M+t),c=E[e],l=E[e+1],d=E[e+2],f=E[e+3];if(T){let t=!1;if(F)t=l>1.4*c&&l>1.4*d&&l>80;else if(L)t=d>1.4*c&&d>1.4*l&&d>80;else if(null!==I){const e=c-I.r,n=l-I.g,o=d-I.b;t=e*e+n*n+o*o<=R}if(t){h++;continue}}r+=c,i+=l,a+=d,s+=f}}if(T&&h>K/2){n.push({char:" ",r:0,g:0,b:0,a:0});continue}const f=K-h,m=f>0?r/f:0,g=f>0?i/f:0,p=f>0?a/f:0,y=f>0?s/f:0,x=.299*m+.587*g+.114*p,b=e.normalize?(x-H)/P*255:x,S=c(b,e.brightness,e.contrast),C=e.ditherStrength>0?d(S,o,t,e.ditherStrength):S,A=e.customText?l(C,e.customText,o,t,u,O):e.ditherStrength>0?W(C,V,O):D[Math.max(0,Math.min(255,0|b))];n.push({char:A,r:m,g:g,b:p,a:y,lum:C})}z.push(n)}return{frame:z,cols:u,rows:g}}function D(t,e,n,o){const r=t instanceof HTMLVideoElement?t.videoWidth:t.width,i=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(0===r||0===i)return{rows:[],cols:0,rowCount:0};const a=e.charAspect,s=e.fontSize*e.charSpacing,l=e.fontSize/a*e.charSpacing,h=n||r,f=o||i,m=Math.floor(h/s),u=Math.floor(f/l);if(m<=0||u<=0)return{rows:[],cols:0,rowCount:0};const g=m,p=u,M=A(g,p),v=B(e.sourceCrop,r,i),w=M.globalCompositeOperation;M.globalCompositeOperation="copy";try{M.drawImage(t,v.x,v.y,v.width,v.height,0,0,g,p)}finally{M.globalCompositeOperation=w}const x=M.getImageData(0,0,g,p).data,b=e.chromaKey,S=null!=b&&!1!==b,E=!0===b,C="blue-screen"===b;let T=null,F=0;!S||E||C||(T=y(b),F=(e.chromaKeyTolerance??60)**2);let L=0,I=255;if(e.normalize){let t=255,e=0;for(let n=0;n<x.length;n+=4){if(S){const t=x[n],e=x[n+1],o=x[n+2];let r=!1;if(E)r=e>1.4*t&&e>1.4*o&&e>80;else if(C)r=o>1.4*t&&o>1.4*e&&o>80;else if(null!==T){const n=t-T.r,i=e-T.g,a=o-T.b;r=n*n+i*i+a*a<=F}if(r)continue}const o=.299*x[n]+.587*x[n+1]+.114*x[n+2];o<t&&(t=o),o>e&&(e=o)}L=t,I=e>t?e-t:255}const R=j(e.invert),H=S&&e.charset.replace(/ /g,"")||e.charset,P=k(H),z=e.customText?null:$(H,R,e.brightness,e.contrast),O=e.customText?k(e.customText):null,q="fullcolor"===e.colorMode?new Uint8ClampedArray(m*u*4):void 0,V=[];for(let t=0;t<u;t++){let n="";for(let o=0;o<m;o++){const r=4*(t*g+o),i=r,a=x[r],s=x[r+1],l=x[r+2],h=x[r+3];if(S){let t=!1;if(E)t=s>1.4*a&&s>1.4*l&&s>80;else if(C)t=l>1.4*a&&l>1.4*s&&l>80;else if(null!==T){const e=a-T.r,n=s-T.g,o=l-T.b;t=e*e+n*n+o*o<=F}if(t){n+=" ",q&&(q[i]=0,q[i+1]=0,q[i+2]=0,q[i+3]=0);continue}}q&&(q[i]=a,q[i+1]=s,q[i+2]=l,q[i+3]=h);const f=.299*a+.587*s+.114*l,u=e.normalize?(f-L)/I*255:f,p=e.ditherStrength>0||O?c(u,e.brightness,e.contrast):u,M=e.ditherStrength>0?d(p,o,t,e.ditherStrength):p;if(O){n+=(R?1-M/255:M/255)<.12?" ":O[(t*m+o)%O.length]}else e.ditherStrength<=0?n+=z[Math.max(0,Math.min(255,0|u))]:n+=W(M,P,R)}V.push(n)}return{rows:V,cols:m,rowCount:u,colors:q}}function K(t,e,n,o,r){if(0===e.rows.length)return;const i=t.canvas,a=Boolean(n.chromaKey)||e.rows.some(t=>t.includes(" "));a||(I.delete(t),t.clearRect(0,0,o,r),t.fillStyle=w(i)?"#0a0a0a":"#faf9f7",t.fillRect(0,0,o,r));const s=O(n.accentColor),c=parseInt(s.substring(0,2),16),l=parseInt(s.substring(2,4),16),h=parseInt(s.substring(4,6),16),d=o/e.cols,f=r/e.rowCount,m=.9*Math.min(d/.55,f),u=e.colors;if("fullcolor"===n.colorMode&&u){I.delete(t),t.clearRect(0,0,o,r),t.font=`${m}px "JetBrains Mono", monospace`,t.textAlign="left",t.textBaseline="middle",t.globalAlpha=1;let n="";for(let o=0;o<e.rows.length;o++){const r=H(e.rows[o]);let i=0;for(;i<e.cols;){for(;i<e.cols&&" "===r[i];)i++;if(i>=e.cols)break;const a=i,s=4*(o*e.cols+i),c=240&u[s],l=240&u[s+1],h=240&u[s+2];for(i++;i<e.cols&&" "!==r[i];){const t=4*(o*e.cols+i);if((240&u[t])!==c||(240&u[t+1])!==l||(240&u[t+2])!==h)break;i++}const m=`rgb(${c},${l},${h})`;m!==n&&(t.fillStyle=m,n=m),t.fillText(r.slice(a,i).join(""),a*d+.5*d,o*f+.5*f)}}return void(t.globalAlpha=1)}t.font=`${m}px "JetBrains Mono", monospace`,t.textAlign="left",t.textBaseline="middle";const g="matrix"===n.colorMode?"rgb(0,255,0)":"grayscale"===n.colorMode?w(i)?"rgb(230,230,230)":"rgb(24,24,24)":`rgb(${c},${l},${h})`;t.fillStyle=g,t.globalAlpha=1;const p=I.get(t),M=a&&p&&p.cols===e.cols&&p.rowCount===e.rowCount&&p.canvasWidth===o&&p.canvasHeight===r&&p.fillStyle===g;M||t.clearRect(0,0,o,r);for(let n=0;n<e.rows.length;n++){const r=e.rows[n];M&&p.rows[n]===r||(M&&t.clearRect(0,n*f,o,f+1),0!==r.trim().length&&t.fillText(r,.5*d,n*f+.5*f))}I.set(t,{rows:e.rows.slice(),cols:e.cols,rowCount:e.rowCount,canvasWidth:o,canvasHeight:r,fillStyle:g}),t.globalAlpha=1}async function N(t,e,n,o,r=12,i=10,a,s=0){const c=Math.min(t.duration-s,i),l=Math.ceil(c*r),h=[];let d=0,f=0;for(let i=0;i<l;i++){const m=s+i/r;if(m>s+c)break;t.currentTime=m,await new Promise(e=>{const n=()=>{t.removeEventListener("seeked",n),e()};t.addEventListener("seeked",n)});const u=V(t,e,n,o);h.push(u.frame),d=u.cols,f=u.rows,a?.((i+1)/l)}return{frames:h,cols:d,rows:f,fps:r}}async function U(t,e,n,o,r=12,i=10,a,s=0){const c=Math.min(t.duration-s,i),l=Math.ceil(c*r),h=[];let d=0,f=0;for(let i=0;i<l;i++){const m=s+i/r;if(m>s+c)break;t.currentTime=m,await new Promise(e=>{const n=()=>{t.removeEventListener("seeked",n),e()};t.addEventListener("seeked",n)});const u=D(t,e,n,o);h.push(u),d=u.cols,f=u.rowCount,a?.((i+1)/l)}return{frames:h,cols:d,rows:f,fps:r}}async function Y(t,e,n,o,r){const{parseGIF:i,decompressFrames:a}=await import("gifuct-js"),s=i(t),c=a(s,!0);if(0===c.length)return{frames:[],cols:0,rows:0,fps:10};const l=c[0].dims.width,h=c[0].dims.height,d=s.lsd?.width||l,f=s.lsd?.height||h,m=document.createElement("canvas");m.width=d,m.height=f;const u=m.getContext("2d"),g=document.createElement("canvas");g.width=d,g.height=f;const p=g.getContext("2d"),M=document.createElement("canvas"),v=M.getContext("2d"),w=[];let y=0,x=0,b=0;for(const t of c)b+=t.delay||100;const S=b/c.length,E=Math.round(Math.min(30,Math.max(5,1e3/S))),C=Math.min(c.length,300);for(let t=0;t<C;t++){const i=c[t],{dims:a,patch:s,disposalType:l}=i;3===l&&(p.clearRect(0,0,d,f),p.drawImage(m,0,0)),M.width!==a.width&&(M.width=a.width),M.height!==a.height&&(M.height=a.height);const h=new ImageData(new Uint8ClampedArray(s.buffer),a.width,a.height);v.putImageData(h,0,0),u.drawImage(M,a.left||0,a.top||0);const b=V(m,e,n,o);w.push(b.frame),y=b.cols,x=b.rows,2===l?u.clearRect(a.left||0,a.top||0,a.width,a.height):3===l&&(u.clearRect(0,0,d,f),u.drawImage(g,0,0)),r?.((t+1)/C)}return{frames:w,cols:y,rows:x,fps:E}}async function G(t,e,n,o,r){const{parseGIF:i,decompressFrames:a}=await import("gifuct-js"),s=i(t),c=a(s,!0);if(0===c.length)return{frames:[],cols:0,rows:0,fps:10};const l=c[0].dims.width,h=c[0].dims.height,d=s.lsd?.width||l,f=s.lsd?.height||h,m=document.createElement("canvas");m.width=d,m.height=f;const u=m.getContext("2d"),g=document.createElement("canvas");g.width=d,g.height=f;const p=g.getContext("2d"),M=document.createElement("canvas"),v=M.getContext("2d"),w=[];let y=0,x=0,b=0;for(const t of c)b+=t.delay||100;const S=b/c.length,E=Math.round(Math.min(30,Math.max(5,1e3/S))),C=Math.min(c.length,300);for(let t=0;t<C;t++){const i=c[t],{dims:a,patch:s,disposalType:l}=i;3===l&&(p.clearRect(0,0,d,f),p.drawImage(m,0,0)),M.width!==a.width&&(M.width=a.width),M.height!==a.height&&(M.height=a.height);const h=new ImageData(new Uint8ClampedArray(s.buffer),a.width,a.height);v.putImageData(h,0,0),u.drawImage(M,a.left||0,a.top||0);const b=D(m,e,n,o);w.push(b),y=b.cols,x=b.rowCount,2===l?u.clearRect(a.left||0,a.top||0,a.width,a.height):3===l&&(u.clearRect(0,0,d,f),u.drawImage(g,0,0)),r?.((t+1)/C)}return{frames:w,cols:y,rows:x,fps:E}}var X=new WeakMap,_=new WeakMap,J=new WeakMap;function Q(t,e,n,o,r,i=0,a){if(!e.length||!e[0].length||o<=0||r<=0)return;let s=null;if(n.hoverStrength>0){let e=X.get(t);e||(e={x:.5,y:.5,intensity:0,time:-1,emittedAt:-1,points:[]},X.set(t,e)),s=function(t,e,n){const o=t.time<0?1/60:Math.max(0,Math.min(.1,(n-t.time)/1e3));t.time=n;const r=t.intensity<.003,i=t.x,a=t.y;if(e){r&&(t.x=e.x,t.y=e.y);const n=1-Math.exp(-o/.055);t.x+=(e.x-t.x)*n,t.y+=(e.y-t.y)*n}t.intensity+=((e?.intensity??(e?1:0))-t.intensity)*(1-Math.exp(-o/(e?.09:.18)));const s=Math.exp(-o/.22);for(const e of t.points)e.intensity*=s;for(;t.points.length&&t.points[0].intensity<.01;)t.points.shift();return e&&!r&&n-t.emittedAt>=24&&Math.hypot(t.x-i,t.y-a)>5e-4&&(t.points.push({x:t.x,y:t.y,intensity:t.intensity,vx:Math.max(-1,Math.min(1,(t.x-i)/Math.max(o,.001))),vy:Math.max(-1,Math.min(1,(t.y-a)/Math.max(o,.001)))}),t.points.length>12&&t.points.shift(),t.emittedAt=n),!e&&t.intensity<.003&&!t.points.length?(t.intensity=0,null):{x:t.x,y:t.y,intensity:t.intensity,trail:t.points}}(e,a??null,performance.now())}else X.delete(t);if("none"!==n.animationStyle||n.charsetFrames?.length||n.hoverStrength<=0)return J.delete(t),void Z(t,e,n,o,r,i,s);const c=_.get(t);if(c?.frame!==e)return _.set(t,{frame:e,since:performance.now()}),J.delete(t),void Z(t,e,n,o,r,i,s);if(performance.now()-c.since<100)return void Z(t,e,n,o,r,i,s);const l=t.getTransform();if(l.b||l.c||l.a<=0||l.d<=0)return void Z(t,e,n,o,r,i,s);if(!s||(s.intensity??0)<.003)return void Z(t,e,n,o,r,i,null);const h=w(t.canvas),d={...n,accentColor:"#"+O(n.accentColor)},f=JSON.stringify([d,o,r,l.a,l.d,h,void 0!==document.fonts?document.fonts.status:"loaded"]);let m=J.get(t);if(!m||m.frame!==e||m.key!==f){const n=m?.canvas??document.createElement("canvas");n.width=Math.ceil(o*l.a),n.height=Math.ceil(r*l.d);const i=n.getContext("2d");i.setTransform(l.a,0,0,l.d,0,0),Z(i,e,d,o,r,0,null,void 0,h),m={frame:e,key:f,canvas:n},J.set(t,m)}if(t.clearRect(0,0,o,r),t.drawImage(m.canvas,0,0,o,r),!s||(s.intensity??0)<.003)return;const u=e.length,g=e[0].length,p=.08+.35*n.hoverRadius+.04*n.hoverStrength,M="trail"===n.hoverEffect?[s,...s.trail??[]]:[s];let v=1,y=1,x=0,b=0;for(const t of M)v=Math.min(v,t.x-p),x=Math.max(x,t.x+p),y=Math.min(y,t.y-p),b=Math.max(b,t.y+p);if("glitchText"===n.hoverEffect){const t=n.hoverText,e=Math.max(1,...(Array.isArray(t)?t:[t]).map(t=>t.length));v=Math.min(v,s.x-e/g),x=Math.max(x,s.x+e/g)}const S=Math.ceil(5+4*n.hoverStrength),E={x:Math.max(0,Math.floor(v*g)-S),y:Math.max(0,Math.floor(y*u)-S),right:Math.min(g,Math.ceil(x*g)+S),bottom:Math.min(u,Math.ceil(b*u)+S)};t.save(),t.beginPath(),t.rect(E.x*o/g,E.y*r/u,(E.right-E.x)*o/g,(E.bottom-E.y)*r/u),t.clip(),Z(t,e,d,o,r,i,s,E,h),t.restore()}function Z(t,e,n,o,i,s=0,c,l,h){const d=e.length;if(0===d)return;const f=e[0].length;t.clearRect(0,0,o,i);let m=!1;const g=Math.max(1,d>>2),M=Math.max(1,f>>2);t:for(let t=0;t<d;t+=g){const n=e[t];for(let t=0;t<f;t+=M)if(n[t].a<200){m=!0;break t}}const v=t.canvas,y=h??w(v);m||(t.fillStyle=y?"#0a0a0a":"#faf9f7",t.fillRect(0,0,o,i));const x=o/f,b=i/d,E=c?.intensity??1,C=!!(c&&n.hoverStrength>0&&E>.005),T="#"+(z(n.hoverColor||"#ffffff")??"ffffff"),A=parseInt(T.slice(1,3),16),F=parseInt(T.slice(3,5),16),L=parseInt(T.slice(5,7),16),I=O(n.accentColor),R=parseInt(I.substring(0,2),16),H=parseInt(I.substring(2,4),16),$=parseInt(I.substring(4,6),16),P=n.hoverRadius;let q=0,B=f,V=0,D=d,K=0,N=0;if(C&&c){K=c.x,N=c.y;const t=.08+.35*P+.04*n.hoverStrength;q=Math.max(0,Math.floor((K-t)*f)-1),B=Math.min(f,Math.ceil((K+t)*f)+1),V=Math.max(0,Math.floor((N-t)*d)-1),D=Math.min(d,Math.ceil((N+t)*d)+1)}if(C&&"trail"===n.hoverEffect)for(const t of c?.trail??[]){const e=.08+.35*P+.04*n.hoverStrength;q=Math.min(q,Math.max(0,Math.floor((t.x-e)*f)-1)),B=Math.max(B,Math.min(f,Math.ceil((t.x+e)*f)+1)),V=Math.min(V,Math.max(0,Math.floor((t.y-e)*d)-1)),D=Math.max(D,Math.min(d,Math.ceil((t.y+e)*d)+1))}const U=n.animationStyle,Y=n.animationSpeed,G=(X=U,r.find(t=>t.value===X||t.mode===X)?.mode??"none");var X;const _="none"===G,J=[0,0,0,1],Q=n.hoverStrength,Z=n.hoverEffect,tt=P,et=n.hoverShape||"circle",nt=j(n.invert,v),ot=n.colorMode,rt=2*Math.PI,it=1/f,at=1/d;let st="",ct=-1;if("dots"===n.renderMode){const r=.5*Math.min(x,b)*n.dotSizeRatio;for(let n=l?.y??0;n<(l?.bottom??d);n++){const h=e[n];for(let e=l?.x??0;e<(l?.right??f);e++){const l=h[e];if(l.a<10)continue;const m=.00392156863*(.299*l.r+.587*l.g+.114*l.b),g=nt?1-m:m;if(g<.02)continue;_||a(G,e/f,n/d,s*Y,J);const M=Math.max(0,Math.min(1,(1+J[2])*J[3]));let v=1,w=0,y=0,T=0,I=0;if(C&&e>=q&&e<=B&&n>=V&&n<=D){const t=S(e*it,n*at,K,N,E,Q,x,b,Z,tt,et,c?.trail,o/i);v=t.scale,w=t.offsetX,y=t.offsetY,T=t.glow,I=t.colorBlend}const k=r*g*M*v;if(k<.3)continue;const W=e*x+.5*x+w+J[0],P=n*b+.5*b+y+J[1];let j;if(I>0){const t=p(l,ot,R,H,$,nt);j=`rgb(${Math.min(255,t[0]+(A-t[0])*I|0)},${Math.min(255,t[1]+(F-t[1])*I|0)},${Math.min(255,t[2]+(L-t[2])*I|0)})`}else j=u(l,ot,R,H,$,nt);const z=Math.min(1,.00392156863*l.a*M*(1+T));if(z!==ct&&(t.globalAlpha=z,ct=z),j!==st&&(t.fillStyle=j,st=j),k<=3){const e=2*k;t.fillRect(W-k,P-k,e,e)}else t.beginPath(),t.arc(W,P,k,0,rt),t.fill()}}}else{const r=.55,h=.9*Math.min(x/r,b);{const e=/\p{Extended_Pictographic}/u.test(n.customText||n.charset);t.font=e?`${h}px "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla", sans-serif`:`${h}px "JetBrains Mono", monospace`,t.textAlign="center",t.textBaseline="middle"}const m=n.charsetFrames,g=!!m?.length,M=g?m[Math.floor(Math.max(0,s)*(n.charsetFps??2))%m.length]:n.charset,v=t.getTransform();if(!C&&_&&!g&&"accent"===ot&&!l&&n.hoverStrength<=0&&!/\p{Extended_Pictographic}/u.test(n.customText||n.charset)&&"letterSpacing"in t&&/^[\x20-\x7e]*$/.test(n.customText||n.charset)&&e.every(t=>t.every(t=>t.a<10||255===t.a&&1===t.char.length&&/^[\x20-\x7e]$/.test(t.char)))){const n=t.letterSpacing;t.letterSpacing="0px";const o=t.measureText("M").width;t.letterSpacing=x-o+"px",t.fillStyle=`rgb(${R},${H},${$})`,t.globalAlpha=1,t.textAlign="left";for(let n=0;n<d;n++){const r=e[n];let i="";for(let t=0;t<f;t++){const e=r[t];i+=e.a<10?" ":e.char}0!==i.trim().length&&t.fillText(i,.5*(x-o),n*b+.5*b)}return t.letterSpacing=n,t.textAlign="center",void(t.globalAlpha=1)}const w="glitchText"===Z&&C,y="!@#$%^&*<>{}[]|/\\~`0123456789",T=y.length;let I="",j=0,z=0,O=0,U=0,X=0,rt=0;if(w){const t=n.hoverText??"ASCIIFY";if(z=Math.round(K*f),O=Math.round(N*d),Array.isArray(t)){const e=t.filter(t=>t.length>0);0===e.length&&e.push("ASCIIFY");I=e[((7*Math.floor(z/Math.max(1,Math.ceil(f/5)))+13*Math.floor(O/Math.max(1,Math.ceil(d/3))))%e.length+e.length)%e.length]}else I=t||"ASCIIFY";j=I.length,U=Math.max(3,Math.min(12,Math.round(d*P*.6)));const e=Math.floor(U/2);X=Math.max(0,O-e),X+U>d&&(X=Math.max(0,d-U)),rt=z-Math.floor(j/2)}for(let n=l?.y??0;n<(l?.bottom??d);n++){const r=e[n];for(let h=l?.x??0;h<(l?.right??f);h++){const l=r[h];if(l.a<10)continue;let m=g&&null!=l.lum?W(l.lum,k(M),nt):l.char;if(" "===m)continue;_||a(G,h/f,n/d,s*Y,J);const P=Math.max(0,Math.min(1,(1+J[2])*J[3]));if(P<.05)continue;let lt=1,ht=0,dt=0,ft=0,mt=0;if(C&&!w&&h>=q&&h<=B&&n>=V&&n<=D){const t=S(h*it,n*at,K,N,E,Q,x,b,Z,tt,et,c?.trail,o/i);if(lt=t.scale,ht=t.offsetX,dt=t.offsetY,ft=t.glow,mt=t.colorBlend,"trail"===Z&&t.proximity>0){const o=Math.max(0,Math.min(f-1,Math.round(h-t.offsetX/x))),r=e[Math.max(0,Math.min(d-1,Math.round(n-t.offsetY/b)))][o],i=r.lum??.299*r.r+.587*r.g+.114*r.b;m=W(Math.min(255,i+t.proximity*Q*65),k(M),nt)}}if(w&&n>=X&&n<X+U){const t=h-rt;if(t>=0&&t<j){const e=I[t],o=Math.abs(n-O)/Math.max(1,.5*U),r=Math.abs(h-z)/Math.max(1,j),i=Math.max(o,r),a=Math.max(0,Math.min(1,1-.9*i)),c=43758.5453*Math.sin(127.1*h+311.7*n+43758.5453*Math.floor(12*s));m=Math.abs(c-Math.floor(c))<a?e:y[Math.abs(Math.floor(97*c))%T],ft=.3+.7*a,mt=.3+.65*a}}const ut=h*x+.5*x+ht+J[0],gt=n*b+.5*b+dt+J[1];let pt;if(mt>0){const t=p(l,ot,R,H,$,nt);pt=`rgb(${Math.min(255,t[0]+(A-t[0])*mt|0)},${Math.min(255,t[1]+(F-t[1])*mt|0)},${Math.min(255,t[2]+(L-t[2])*mt|0)})`}else pt=u(l,ot,R,H,$,nt);const Mt=Math.min(1,.00392156863*l.a*P*(1+ft));Mt!==ct&&(t.globalAlpha=Mt,ct=Mt),pt!==st&&(t.fillStyle=pt,st=pt),1!==lt?(t.translate(ut,gt),t.scale(lt,lt),t.fillText(m,0,0),t.setTransform(v)):t.fillText(m,ut,gt)}}}t.globalAlpha=1}function tt(t="classic"){if("classic"!==t)throw new RangeError(`Art preset "${String(t)}" was removed in 4.1. Use a StudioStyle with asciify-engine/studio, or supply options.charset directly.`);return{artStyle:"classic"}}function et(t){return Math.max(0,Math.min(1,t))}function nt(t){return"string"==typeof t?document.querySelector(t):t instanceof HTMLElement?t:null}function ot(t){return"ascii"===t.renderMode&&"none"===t.animationStyle&&t.hoverStrength<=0&&!t.charsetFrames?.length}function rt(t,e={}){const n=et(t),o=et(n*(void 0===e.speed?1:Math.max(.001,e.speed)));return et(e.ease?e.ease(o):o)}function it(t,e,n={}){if(!Number.isFinite(t.duration)||t.duration<=0)return;const o=n.from??0,r=n.to??t.duration,i=Math.max(o,Math.min(r,t.duration)),a=rt(e,n),s=o+(i-o)*a;t.currentTime=Math.min(Math.max(o,s),Math.max(o,i-.04)),n.onUpdate?.(a,t)}function at(t,e){return Math.abs(t.currentTime-e)<1/240?st(t):new Promise(n=>{const o=()=>{t.removeEventListener("seeked",o),n()};t.addEventListener("seeked",o,{once:!0});const r=t.fastSeek;r?r.call(t,e):t.currentTime=e})}function st(t){const e=t.requestVideoFrameCallback;return new Promise(e?n=>{let o=!1;const r=()=>{o||(o=!0,n())};e.call(t,r),window.setTimeout(r,32)}:t=>requestAnimationFrame(()=>t()))}function ct(t,e={}){const n=nt(e.trigger)??t;t.pause();const o=e.gsap,r=e.ScrollTrigger??o?.ScrollTrigger;if(o&&r?.create){o.registerPlugin?.(r);const i=r.create({trigger:n,start:e.start??"top bottom",end:e.end??"bottom top",scrub:e.scrub??!0,onUpdate:n=>it(t,n.progress,e)});return()=>i.kill?.()}return function(t,e,n){let o=0;const r=()=>{o=0;const r=e.getBoundingClientRect(),i=window.innerHeight||document.documentElement.clientHeight,a=r.height+i,s=a>0?et((i-r.top)/a):0;it(t,s,n)},i=()=>{o||(o=requestAnimationFrame(r))};return window.addEventListener("scroll",i,{passive:!0}),window.addEventListener("resize",i),i(),()=>{window.removeEventListener("scroll",i),window.removeEventListener("resize",i),o&&cancelAnimationFrame(o)}}(t,n,e)}function lt(t,e,n){const o=e.gsap,r=e.ScrollTrigger??o?.ScrollTrigger;if(o&&r?.create){o.registerPlugin?.(r);const i=r.create({trigger:t,start:e.start??"top bottom",end:e.end??"bottom top",scrub:e.scrub??!0,onUpdate:t=>n(t.progress)});return()=>i.kill?.()}return function(t,e){let n=0;const o=()=>{n=0;const o=t.getBoundingClientRect(),r=window.innerHeight||document.documentElement.clientHeight,i=o.height+r,a=i>0?et((r-o.top)/i):0;e(a)},r=()=>{n||(n=requestAnimationFrame(o))};return window.addEventListener("scroll",r,{passive:!0}),window.addEventListener("resize",r),r(),()=>{window.removeEventListener("scroll",r),window.removeEventListener("resize",r),n&&cancelAnimationFrame(n)}}(t,n)}function ht(t,e,n){if(!t||!e||!n.sourceCrop)return{w:t,h:e};const o=B(n.sourceCrop,t,e);return{w:Math.max(1,Math.round(o.width)),h:Math.max(1,Math.round(o.height))}}function dt(t,e,n,o){const r=o.chromaKey;if(null==r||!1===r)return!1;if(!0===r)return e>1.4*t&&e>1.4*n&&e>80;if("blue-screen"===r)return n>1.4*t&&n>1.4*e&&n>80;const i=y(r),a=(o.chromaKeyTolerance??60)**2,s=t-i.r,c=e-i.g,l=n-i.b;return s*s+c*c+l*l<=a}function ft(t,e,n){if(!e.chromaKey||!e.sourceCrop||"off"===e.chromaKeyTrimMode)return e;const o=t instanceof HTMLVideoElement?t.videoWidth:t.width,r=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(!o||!r)return e;const i=B(e.sourceCrop,o,r),a=Math.min(360,Math.max(1,Math.round(i.width))),c=Math.max(1,Math.round(a*(i.height/i.width))),{ctx:l}=s(a,c);l.drawImage(t,i.x,i.y,i.width,i.height,0,0,a,c);const h=l.getImageData(0,0,a,c).data,d=Math.max(0,Math.min(255,e.chromaKeyTrimLuminanceThreshold??0));let f=a,m=c,u=-1,g=-1;for(let t=0;t<c;t++)for(let n=0;n<a;n++){const o=4*(t*a+n),r=h[o+3],i=h[o],s=h[o+1],c=h[o+2];r<=8||.2126*i+.7152*s+.0722*c<=d||dt(i,s,c,e)||(n<f&&(f=n),t<m&&(m=t),n>u&&(u=n),t>g&&(g=t))}if(u<f||g<m)return e;const p=Math.max(0,Math.min(.25,e.chromaKeyTrimPadding??.002)),M=Math.round(a*p),v=Math.round(c*p);f=Math.max(0,f-M),m=Math.max(0,m-v),u=Math.min(a-1,u+M),g=Math.min(c-1,g+v);const w=function(t,e,n,o,r){const i=r&&Number.isFinite(r)&&r>0?r:null;if(!i)return t;const a=e.x,s=e.y,c=e.x+e.width,l=e.y+e.height,h=Math.max(a,t.left),d=Math.max(s,t.top),f=Math.min(c,n-t.right),m=Math.min(l,o-t.bottom),u=Math.max(1,f-h),g=Math.max(1,m-d),p=h+u/2,M=d+g/2;let v=u,w=g;v/w<i?v=w*i:w=v/i;v>e.width&&(v=e.width,w=Math.max(g,Math.min(e.height,v/i)));w>e.height&&(w=e.height,v=Math.max(u,Math.min(e.width,w*i)));let y=p-v/2,x=M-w/2;return y=Math.max(a,Math.min(c-v,y)),x=Math.max(s,Math.min(l-w,x)),{left:y,top:x,right:n-(y+v),bottom:o-(x+w)}}({left:i.x+f/a*i.width,top:i.y+m/c*i.height,right:o-(i.x+(u+1)/a*i.width),bottom:r-(i.y+(g+1)/c*i.height)},{x:i.x,y:i.y,width:i.width,height:i.height},o,r,n);return{...e,sourceCrop:{unit:"pixel",...w,preserveAspect:!1}}}function mt(t){const e=t.sourceCrop;return e&&"pixel"===e.unit?void 0===e.left||void 0===e.top||void 0===e.right||void 0===e.bottom?null:{left:e.left,top:e.top,right:e.right,bottom:e.bottom}:null}async function ut(t,e,n,o,r){if(!e.chromaKey||!e.sourceCrop||"range"!==e.chromaKeyTrimMode)return e;const i=t.currentTime,a=function(t,e,n,o){const r=!0===o?{}:o||{},i=Math.max(0,r.from??e),a=r.to??n??(Number.isFinite(t.duration)?t.duration:i),s=Math.max(i,a-.04),c=Math.max(0,s-i),l=c>.1?[i,i+.25*c,i+.5*c,i+.75*c,s]:[i];return Array.from(new Set(l.map(t=>Math.max(0,Number(t.toFixed(3))))))}(t,n,o,r);let s=null;for(const n of a){await at(t,n),await st(t);const o=mt(ft(t,e));o&&(s=s?{left:Math.min(s.left,o.left),top:Math.min(s.top,o.top),right:Math.min(s.right,o.right),bottom:Math.min(s.bottom,o.bottom)}:o)}return await at(t,i),await st(t),s?{...e,sourceCrop:{unit:"pixel",...s,preserveAspect:!0}}:e}function gt(t,e,n=2048){return pt({sourceWidth:t,sourceHeight:e,maxRenderDimension:n})}function pt({sourceWidth:t,sourceHeight:e,cssWidth:n=0,cssHeight:o=0,maxRenderDimension:r=2048}){const i=Math.max(1,t),a=Math.max(1,e),s=i/a,c=Math.max(1,r),l=Math.min(1,c/Math.max(i,a)),h=Math.max(i,a)*l,d=Math.max(0,n,o),f=Math.min(c,Math.max(h,d));return s>=1?{renderW:Math.round(f),renderH:Math.round(f/s)}:{renderW:Math.round(f*s),renderH:Math.round(f)}}function Mt(t,e,n,o){if(void 0===t)return;if("number"==typeof t)return t;const r=t.trim();if(r.endsWith("%")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?e*t:void 0}if(r.endsWith("px")){const t=Number.parseFloat(r);return Number.isFinite(t)?t:void 0}if(r.endsWith("vw")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?n*t:void 0}if(r.endsWith("vh")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?o*t:void 0}}function vt(t,e,n,o,r,i=2048,a={}){const{width:s,height:c}=e.getBoundingClientRect();if(!s||!c)return{renderW:0,renderH:0,dpr:1};const l="undefined"!=typeof window?window.innerWidth:s,h="undefined"!=typeof window?window.innerHeight:c,d=Mt(a.width,s,l,h)??s,f=Mt(a.height,c,l,h)??c,m=function(t,e,n,o,r){const i=t=>{const n=Mt(t,e,o,r);return n&&n>0?n:0},a=t=>{const e=Mt(t,n,o,r);return e&&e>0?e:0};return void 0===t?{x:0,y:0}:"number"==typeof t||"string"==typeof t?{x:i(t),y:a(t)}:{x:i(t.x),y:a(t.y)}}(a.bleed,s,c,l,h),u=d+2*m.x,g=f+2*m.y,{cssW:p,cssH:M}=function(t,e,n,o="contain"){if("fill"===o)return{cssW:t,cssH:e};let r=t,i=r/n;const a="cover"===o,s=i>e;return(a&&!s||!a&&s)&&(i=e,r=i*n),"scale-down"===o&&(r=Math.min(r,t),i=Math.min(i,e)),{cssW:Math.round(r),cssH:Math.round(i)}}(u,g,n,a.objectFit??"contain"),v="undefined"!=typeof window&&window.devicePixelRatio||1;let w,y;o&&r?({renderW:w,renderH:y}=pt({sourceWidth:o,sourceHeight:r,cssWidth:p,cssHeight:M,maxRenderDimension:i})):(w=p,y=M);const x=8e6,b=w*v*y*v>x?Math.sqrt(x/(w*y)):v;return t.width=Math.round(w*b),t.height=Math.round(y*b),t.style.width=`${p}px`,t.style.height=`${M}px`,{renderW:w,renderH:y,dpr:b}}async function wt(t,e,{fontSize:o,artStyle:r="classic",options:i={}}={}){let a;if("string"==typeof t){const e=new Image;e.crossOrigin="anonymous",await new Promise((n,o)=>{e.onload=()=>n(),e.onerror=()=>o(new Error(`Failed to load image: ${t}`)),e.src=t}),a=e}else t instanceof HTMLImageElement&&!t.complete?(await new Promise((e,n)=>{t.onload=()=>e(),t.onerror=()=>n(new Error("Image failed to load"))}),a=t):a=t;const s=tt(r),c=o??i.fontSize??10,l={...n,...s,artStyle:r,...i,fontSize:c},h=e.getContext("2d");if(!h)throw new Error("Could not get 2d context from canvas");const{w:d,h:f}=function(t){return t instanceof HTMLVideoElement?{w:t.videoWidth,h:t.videoHeight}:t instanceof HTMLImageElement?{w:t.naturalWidth||t.width,h:t.naturalHeight||t.height}:{w:t.width,h:t.height}}(a),{renderW:m,renderH:u}=gt(d,f),g="undefined"!=typeof window&&window.devicePixelRatio||1,p=8e6,M=m*g*u*g>p?Math.sqrt(p/(m*u)):g;e.width===Math.round(m*M)&&e.height===Math.round(u*M)||(e.width=Math.round(m*M),e.height=Math.round(u*M));const{frame:v}=V(a,l,m,u),w=(t,e)=>{h.save(),h.setTransform(M,0,0,M,0,0),Q(h,v,l,m,u,t/1e3,e),h.restore()};w(0,null);return E(e,w,{continuous:"none"!==l.animationStyle||!!l.charsetFrames?.length,interactive:l.hoverStrength>0}).stop}async function yt(t,e,{fontSize:o,artStyle:r="classic",options:i={}}={}){const a="string"==typeof t?await fetch(t).then(t=>t.arrayBuffer()):t,s=o??i.fontSize??10;let c={...n,...tt(r),artStyle:r,...i,fontSize:s};const l=e.getContext("2d");if(!l)throw new Error("Could not get 2d context from canvas");const{frames:h,fps:d}=await Y(a,c,e.width,e.height);if(!h.length)throw new Error("asciifyGif: the GIF contains no renderable frames.");const f=performance.now();let m=-1;return E(e,(t,n)=>{const o=Math.floor((t-f)*d/1e3)%h.length;o===m&&!n&&c.hoverStrength<=0&&"none"===c.animationStyle&&!c.charsetFrames?.length||(Q(l,h[o],c,e.width,e.height,(t-f)/1e3,n),m=o)},{continuous:!0,interactive:c.hoverStrength>0}).stop}async function xt(t,e,{fontSize:o,artStyle:r="classic",options:i={},fitTo:a,objectFit:s,objectPosition:c,scale:l,width:h,height:d,bleed:f,preExtract:m=!1,fps:u,maxRenderDimension:g=2048,trim:p,scroll:M,maxCachedFrames:v=90,onReady:w,onFrame:y}={}){const x=p?.start??0,b=p?.end,S=o??i.fontSize??10;let C={...n,...tt(r),artStyle:r,...i,fontSize:S};const T=e.getContext("2d");if(!T)throw new Error("asciifyVideo: could not get 2d context from canvas.");const A="string"==typeof a?document.querySelector(a):a instanceof HTMLElement?a:null,F={objectFit:s,objectPosition:c,scale:l,width:h,height:d,bleed:f},L=function(t,e){var n;if(!function(t){return void 0!==t.objectFit||void 0!==t.objectPosition||void 0!==t.scale||void 0!==t.width||void 0!==t.height||void 0!==t.bleed}(e))return()=>{};const o={width:t.style.width,height:t.style.height,objectFit:t.style.objectFit,objectPosition:t.style.objectPosition,maxWidth:t.style.maxWidth,maxHeight:t.style.maxHeight,transformOrigin:t.style.transformOrigin,scale:t.style.getPropertyValue("scale")};if(e.objectFit&&(t.style.objectFit=e.objectFit),e.objectPosition&&(t.style.objectPosition=e.objectPosition,t.style.transformOrigin=e.objectPosition),void 0===e.scale&&void 0===e.bleed||(t.style.maxWidth="none",t.style.maxHeight="none"),void 0!==e.scale){const o=Number.isFinite(e.scale)&&e.scale>0?e.scale:1;t.style.setProperty("scale",String(o)),(n=t.style).transformOrigin||(n.transformOrigin=e.objectPosition??"center center")}return()=>{t.style.width=o.width,t.style.height=o.height,t.style.objectFit=o.objectFit,t.style.objectPosition=o.objectPosition,t.style.maxWidth=o.maxWidth,t.style.maxHeight=o.maxHeight,t.style.transformOrigin=o.transformOrigin,o.scale?t.style.setProperty("scale",o.scale):t.style.removeProperty("scale")}}(e,F),I=t=>()=>{t(),L()};if(m){let n;"string"==typeof t?(n=document.createElement("video"),n.crossOrigin="anonymous",n.src=t,n.readyState<2&&await new Promise((e,o)=>{n.onloadeddata=()=>e(),n.onerror=()=>o(new Error(`asciifyVideo: failed to load "${t}"`))})):n=t,C=await ut(n,C,x,b,M);const o=ht(n.videoWidth,n.videoHeight,C);A&&vt(e,A,o.w/o.h,o.w,o.h,g,F);const{renderW:r,renderH:i}=gt(o.w,o.h,g),a="undefined"!=typeof window&&window.devicePixelRatio||1,s=8e6,c=r*a*i*a>s?Math.sqrt(s/(r*i)):a;e.width===Math.round(r*c)&&e.height===Math.round(i*c)||(e.width=Math.round(r*c),e.height=Math.round(i*c));const l=void 0!==b?b-x:10,h=u??(M?18:void 0);if(ot(C)){const{frames:t,fps:o}=await U(n,C,r,i,h,l,void 0,x),a=e=>{const n=t[e];n&&(T.save(),T.setTransform(c,0,0,c,0,0),K(T,n,C,r,i),T.restore(),y?.())};if(M){let o=!1,r=-1;const i=!0===M?{}:M,s=lt(nt(i.trigger)??A??e,i,e=>{const s=rt(e,i),c=Math.max(0,Math.min(t.length-1,Math.round(s*(t.length-1))));c!==r&&(r=c,a(c),o||(o=!0,w?.(n)),i.onUpdate?.(s,n))});return a(0),o=!0,w?.(n),I(s)}let s,d=!1,f=0,m=performance.now(),u=!0;const g=1e3/o,p=e=>{d||(e-m>=g&&(a(f),f=(f+1)%t.length,m=e,u&&(u=!1,w?.(n))),s=requestAnimationFrame(p))};return s=requestAnimationFrame(p),I(()=>{d=!0,cancelAnimationFrame(s)})}const{frames:d,fps:f}=await N(n,C,r,i,h,l,void 0,x);if(!d.length)throw new Error("asciifyVideo: no frames were decoded.");let m=0;const p=performance.now(),v=E(e,(t,e)=>{M||(m=Math.floor((t-p)*f/1e3)%d.length),T.save(),T.setTransform(c,0,0,c,0,0),Q(T,d[m],C,r,i,(t-p)/1e3,e),T.restore(),y?.()},{continuous:!M||"none"!==C.animationStyle||!!C.charsetFrames?.length,interactive:C.hoverStrength>0});let S;if(M){const t=!0===M?{}:M;S=lt(nt(t.trigger)??A??e,t,e=>{m=Math.max(0,Math.min(d.length-1,Math.round(rt(e,t)*(d.length-1)))),v.wake(),t.onUpdate?.(e,n)})}return w?.(n),I(()=>{v.stop(),S?.()})}let R,k=!1;"string"==typeof t?(R=document.createElement("video"),R.crossOrigin="anonymous",R.src=t,R.muted=!0,R.loop=!0,R.playsInline=!0,R.setAttribute("playsinline",""),Object.assign(R.style,{position:"fixed",top:"0",left:"0",width:"1px",height:"1px",opacity:"0",pointerEvents:"none",zIndex:"-1"}),document.body.appendChild(R),k=!0,await new Promise((e,n)=>{R.onloadedmetadata=()=>e(),R.onerror=()=>n(new Error(`asciifyVideo: failed to load "${t}"`))}),await R.play().catch(()=>{})):(R=t,R.readyState<HTMLMediaElement.HAVE_METADATA&&await new Promise((t,e)=>{const n=()=>{R.removeEventListener("loadedmetadata",o),R.removeEventListener("error",r)},o=()=>{n(),t()},r=()=>{n(),e(new Error("asciifyVideo: provided video element failed to load metadata."))};R.addEventListener("loadedmetadata",o),R.addEventListener("error",r),R.load()}),R.paused&&await R.play().catch(()=>{})),x>0&&(R.currentTime=x,await new Promise(t=>{const e=()=>{R.removeEventListener("seeked",e),t()};R.addEventListener("seeked",e)}),await st(R));let H=null;(x>0||void 0!==b)&&(H=()=>{(void 0!==b&&R.currentTime>=b||x>0&&R.currentTime<x)&&(R.currentTime=x)},R.addEventListener("timeupdate",H)),C=await ut(R,C,x,b,M);let W=null;const $=ht(R.videoWidth,R.videoHeight,C);let{renderW:P,renderH:j}=gt($.w,$.h,g);const z=t=>"frame"===C.chromaKeyTrimMode?ft(t,C,P/j):C;if(A){const t=$.w/$.h,n=$.w,o=$.h,r=vt(e,A,t,n,o,g,F);P=r.renderW,j=r.renderH;const i=e.getContext("2d");i&&i.setTransform(r.dpr,0,0,r.dpr,0,0),W=new ResizeObserver(()=>{const r=vt(e,A,t,n,o,g,F);P=r.renderW,j=r.renderH;const i=e.getContext("2d");i&&i.setTransform(r.dpr,0,0,r.dpr,0,0)}),W.observe(A)}else{const t="undefined"!=typeof window&&window.devicePixelRatio||1,n=8e6,o=P*t*j*t>n?Math.sqrt(n/(P*j)):t;e.width===Math.round(P*o)&&e.height===Math.round(j*o)||(e.width=Math.round(P*o),e.height=Math.round(j*o)),T.setTransform(o,0,0,o,0,0)}let O=!0,q=null;const B=M&&!m,Y=u&&u>0?1e3/u:0;let G=0;const X=!B&&ot(C);if(B&&"ascii"===C.renderMode&&"none"===C.animationStyle&&C.hoverStrength<=0&&!C.charsetFrames?.length){const t=!0===M?{}:M,n=nt(t.trigger)??A??e,o=t.from??x,r=t.to??b??R.duration,i=Math.max(o,Math.min(r,R.duration)),a=Math.max(.001,i-o),s=Math.min(60,Math.max(12,u??30)),c=Math.max(2,Math.ceil(a*s)+1),l=new Array(c),h=[],d=Math.max(2,Math.min(c,Math.floor(v))),f=()=>{for(;h.length>d;){const t=h.findIndex(t=>t!==g&&Math.abs(t-g)>2),e=t>=0?t:0,n=h.splice(e,1)[0];void 0!==n&&(l[n]=void 0)}},m=t=>{const e=h.indexOf(t);e>=0&&h.splice(e,1),h.push(t),f()};let g=0,p=0,S=-1,E=0,F=!1,L=!1,$=!1;const O=new Set,B=document.createElement("video");B.muted=!0,B.playsInline=!0,B.preload="auto",B.crossOrigin=R.crossOrigin||"anonymous",B.src=R.currentSrc||R.src,Object.assign(B.style,{position:"fixed",top:"0",left:"0",width:"1px",height:"1px",opacity:"0",pointerEvents:"none",zIndex:"-1"}),document.body.appendChild(B),B.readyState<HTMLMediaElement.HAVE_METADATA&&await new Promise((t,e)=>{const n=()=>{B.removeEventListener("loadedmetadata",o),B.removeEventListener("error",r)},o=()=>{n(),t()},r=()=>{n(),e(new Error("asciifyVideo: cache video failed to load metadata."))};B.addEventListener("loadedmetadata",o),B.addEventListener("error",r),B.load()}),B.pause(),R.paused&&await R.play().catch(()=>{});const V=t=>o+a*t/Math.max(1,c-1),N=t=>Math.max(0,Math.min(c-1,Math.round(t*(c-1)))),U=z(R),X=D(R,U,P,j);X.rows.length>0&&(l[0]=X,m(0),K(T,X,U,P,j),$=!0,w?.(R),y?.());const _=t=>{if(l[t])return t;for(let e=1;e<c;e++){const n=t-e,o=t+e;if(n>=0&&l[n])return n;if(o<c&&l[o])return o}return-1},J=()=>{if(!l[g])return g;for(const t of O)if(!l[t])return t;for(let t=1;t<c;t++){const e=g-t,n=g+t;if(e>=0&&!l[e])return e;if(n<c&&!l[n])return n}return-1},Q=t=>{t<0||t>=c||l[t]||(O.add(t),Z())},Z=async()=>{if(F||L)return;const t=J();if(!(t<0)){O.delete(t),L=!0;try{if(await at(B,V(t)),!F){const e=z(B),n=D(B,e,P,j);n.rows.length>0&&(l[t]=n,m(t))}}finally{L=!1,F||requestAnimationFrame(()=>{Z()})}}},tt=()=>{if(F)return;const t=_(g);if(t>=0&&t!==S){const e=l[t];e&&(K(T,e,C,P,j),S=t,$||($=!0,w?.(R)),y?.())}else if(t<0||S<0){const t=performance.now();if(Y<=0||t-G>=Y){const e=z(R),n=D(R,e,P,j);n.rows.length>0&&(K(T,n,e,P,j),G=t,$||($=!0,w?.(R)),y?.())}}Q(g),E=requestAnimationFrame(tt)};return q=lt(n,t,e=>{const n=function(t,e,n={}){if(!Number.isFinite(t.duration)||t.duration<=0)return null;const o=n.from??0,r=n.to??t.duration,i=Math.max(o,Math.min(r,t.duration)),a=rt(e,n),s=o+(i-o)*a;return{progress:a,time:Math.min(Math.max(o,s),Math.max(o,i-.04))}}(R,e,{...t,from:o,to:i});p=n?.progress??et(e),g=N(p),Q(g),Q(g-1),Q(g+1),Q(g-2),Q(g+2),Q(g-3),Q(g+3),t.onUpdate?.(p,R)}),Q(0),Q(1),E=requestAnimationFrame(tt),I(()=>{F=!0,cancelAnimationFrame(E),q?.(),W?.disconnect(),O.clear(),h.length=0,l.fill(void 0),B.pause(),B.src="",B.removeAttribute("src"),B.load(),B.isConnected&&B.remove(),H&&R.removeEventListener("timeupdate",H),k&&(R.pause(),R.src="",R.removeAttribute("src"),R.load(),R.isConnected&&R.remove())})}if(B){const t=!0===M?{}:M;q=ct(R,{...t,trigger:t.trigger??A??e,from:t.from??x,to:t.to??b})}let _=-1,J=0,Z=-1,it=0;const dt="function"==typeof R.requestVideoFrameCallback,mt=()=>{it=R.requestVideoFrameCallback(()=>{J++,mt()})};dt&&mt();let pt=0,Mt=0,wt=null;const yt=E(e,(t,n)=>{if(R.readyState<2||0===e.width||0===e.height)return;if(Y>0&&t-G<Y&&!n)return;if(x>0&&R.currentTime<x)return;if(void 0!==b&&R.currentTime>=b)return;const o=(dt?J!==Z:R.currentTime!==_)||pt!==P||Mt!==j;if(o||!(C.hoverStrength<=0)||"none"!==C.animationStyle||C.charsetFrames?.length){if(X){const t=z(R),e=D(R,t,P,j);K(T,e,t,P,j)}else!o&&wt||(wt=V(R,z(R),P,j).frame),Q(T,wt,C,P,j,t/1e3,n);_=R.currentTime,Z=J,pt=P,Mt=j,G=t,O&&(O=!1,w?.(R)),y?.()}},{continuous:!0,interactive:C.hoverStrength>0});return I(()=>{yt.stop(),it&&R.cancelVideoFrameCallback(it),q?.(),W?.disconnect(),H&&R.removeEventListener("timeupdate",H),k&&(R.pause(),R.src="",R.removeAttribute("src"),R.load(),R.isConnected&&R.remove())})}function bt(t,e,n){return xt(t,e,n)}function St(t,e={},o,r){const i={...n,...e},{frame:a,cols:s}=V(t,i,o,r);if(!a.length||0===s)return"";const c=[];for(const t of a)c.push(t.map(t=>t.char).join(""));return c.join("\n")}function Et(t,e={},o,r){const i={...n,...e},{frame:a,cols:s}=V(t,i,o,r);if(!a.length||0===s)return"";const c=[];for(const t of a){let e="";for(const n of t)" "===n.char||n.a<10?e+=" ":e+=`[38;2;${n.r};${n.g};${n.b}m${n.char}[0m`;c.push(e)}return c.join("\n")}function Ct(t,e,n,o="#505050",r=100){if(!t||e<=0||n<=0)return[];const i=function(t){const e=t.match(/^#([0-9a-f]{3,8})$/i)?.[1];if(e){const t=e.length<=4?e.split("").map(t=>parseInt(t+t,16)):[parseInt(e.slice(0,2),16),parseInt(e.slice(2,4),16),parseInt(e.slice(4,6),16)];return{r:t[0],g:t[1],b:t[2]}}const n=t.match(/rgba?\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)/i);return n?{r:+n[1],g:+n[2],b:+n[3]}:null}(o)??{r:80,g:80,b:80},a=t,s=a.length;return Array.from({length:n},(t,n)=>Array.from({length:e},(t,o)=>({char:a[(n*e+o)%s],r:i.r,g:i.g,b:i.b,a:r})))}var Tt=new WeakMap;function At(t,e,o,r,i={},a){const{fontSize:s=10,lineHeight:c=1.6,color:l="#505050",opacity:h=100,hoverEffect:d="spotlight",hoverStrength:f=.85,hoverRadius:m=.18,hoverColor:u="#d4ff00"}=i,g=Math.max(1,Math.floor(e/s)),p=Math.max(1,Math.floor(o/(s*c))),M=JSON.stringify([r,g,p,l,h]);let v=Tt.get(t);v&&v.key===M||(v={key:M,frame:Ct(r,g,p,l,h)},Tt.set(t,v));Q(t,v.frame,{...n,fontSize:s,hoverEffect:d,hoverStrength:f,hoverRadius:m,hoverColor:u},e,o,0,a??null)}function Ft(t,{format:e="png",quality:n=.92,scale:o=1}={}){return new Promise((r,i)=>{let a=t;if(1!==o){const e=document.createElement("canvas");e.width=Math.round(t.width*o),e.height=Math.round(t.height*o);const n=e.getContext("2d");if(!n)return void i(new Error("captureSnapshot: could not get 2d context"));n.drawImage(t,0,0,e.width,e.height),a=e}a.toBlob(t=>t?r(t):i(new Error("captureSnapshot: toBlob returned null")),`image/${e}`,n)})}async function Lt(t,e={}){const{filename:n="asciify-snapshot",format:o="png",...r}=e,i=await Ft(t,{format:o,...r}),a="jpeg"===o?"jpg":o,s=document.createElement("a");s.href=URL.createObjectURL(i),s.download=`${n}.${a}`,s.click(),setTimeout(()=>URL.revokeObjectURL(s.href),1e4)}async function It(t,{fontSize:e=10,style:o="classic",options:r={},liveOptions:i,mirror:a=!0,constraints:s={facingMode:"user"},dpr:c}={}){if(!navigator.mediaDevices?.getUserMedia)throw new Error("asciifyWebcam: getUserMedia is not supported in this browser.");const l=tt(o),h=await navigator.mediaDevices.getUserMedia({video:s}),d=document.createElement("video");d.srcObject=h,d.muted=!0,d.playsInline=!0,await new Promise((t,e)=>{d.onloadedmetadata=()=>t(),d.onerror=()=>e(new Error("asciifyWebcam: video stream failed to load.")),d.play().catch(e)});const f={...n,...l,...r,fontSize:e},m=t.getContext("2d");if(!m)throw new Error("asciifyWebcam: could not get 2d context from canvas.");const u=c??("undefined"!=typeof window?window.devicePixelRatio:1)??1;1!==u&&m.scale(u,u);let g=null;const p=e=>{const n=t.getBoundingClientRect();g={x:(e.clientX-n.left)/n.width,y:(e.clientY-n.top)/n.height}},M=()=>{g=null};f.hoverStrength>0&&(t.addEventListener("mousemove",p),t.addEventListener("mouseleave",M));let v,w=!1;const y=performance.now(),x=e=>{if(!w){if(d.readyState>=d.HAVE_CURRENT_DATA){const n=t.width/u,o=t.height/u,r=(e-y)/1e3,s=i?{...f,...i()}:f;s.hoverStrength>0?(t.addEventListener("mousemove",p),t.addEventListener("mouseleave",M)):(t.removeEventListener("mousemove",p),t.removeEventListener("mouseleave",M));const{frame:c}=V(d,s,n,o),l=g&&a?{x:1-g.x,y:g.y}:g;a?(m.save(),m.scale(-1,1),m.translate(-n,0),Q(m,c,s,n,o,r,l),m.restore()):Q(m,c,s,n,o,r,l)}v=requestAnimationFrame(x)}};return v=requestAnimationFrame(x),()=>{w=!0,cancelAnimationFrame(v),t.removeEventListener("mousemove",p),t.removeEventListener("mouseleave",M),h.getTracks().forEach(t=>t.stop()),d.srcObject=null}}var Rt={A:[28,54,99,127,99,99,99],B:[126,99,99,126,99,99,126],C:[62,99,96,96,96,99,62],D:[124,102,99,99,99,102,124],E:[127,96,96,124,96,96,127],F:[127,96,96,124,96,96,96],G:[62,99,96,111,99,99,62],H:[99,99,99,127,99,99,99],I:[127,8,8,8,8,8,127],J:[63,6,6,6,102,102,60],K:[99,102,108,120,108,102,99],L:[96,96,96,96,96,96,127],M:[99,119,107,107,99,99,99],N:[99,115,107,103,99,99,99],O:[62,99,99,99,99,99,62],P:[126,99,99,126,96,96,96],Q:[62,99,99,99,107,102,61],R:[126,99,99,126,108,102,99],S:[62,99,96,62,3,99,62],T:[127,8,8,8,8,8,8],U:[99,99,99,99,99,99,62],V:[99,99,99,99,54,28,8],W:[99,99,99,107,107,54,20],X:[99,54,28,8,28,54,99],Y:[99,99,54,28,8,8,8],Z:[127,3,6,12,24,48,127],a:[0,0,60,3,62,99,61],b:[96,96,124,99,99,99,124],c:[0,0,62,96,96,96,62],d:[3,3,31,99,99,99,31],e:[0,0,62,99,127,96,62],f:[30,48,48,126,48,48,48],g:[0,0,63,99,63,3,62],h:[96,96,124,99,99,99,99],i:[8,0,24,8,8,8,28],j:[4,0,12,4,4,36,24],k:[96,96,102,108,120,108,102],l:[24,8,8,8,8,8,28],m:[0,0,92,107,107,99,99],n:[0,0,94,99,99,99,99],o:[0,0,62,99,99,99,62],p:[0,0,126,99,126,96,96],q:[0,0,63,99,63,3,3],r:[0,0,94,99,96,96,96],s:[0,0,62,96,62,3,124],t:[48,48,126,48,48,48,30],u:[0,0,99,99,99,103,59],v:[0,0,99,99,54,28,8],w:[0,0,99,99,107,54,20],x:[0,0,99,54,28,54,99],y:[0,0,99,99,63,3,62],z:[0,0,127,6,12,24,127],0:[62,99,103,107,115,99,62],1:[8,24,56,8,8,8,62],2:[62,99,3,6,24,48,127],3:[62,99,3,30,3,99,62],4:[6,14,22,38,127,6,6],5:[127,96,126,3,3,99,62],6:[62,99,96,126,99,99,62],7:[127,3,6,12,24,24,24],8:[62,99,99,62,99,99,62],9:[62,99,99,63,3,99,62]," ":[0,0,0,0,0,0,0],"!":[24,24,24,24,24,0,24],"?":[62,99,3,14,8,0,8],".":[0,0,0,0,0,24,24],",":[0,0,0,0,0,24,48],";":[0,24,24,0,24,24,48],":":[0,24,24,0,24,24,0],"-":[0,0,0,62,0,0,0],_:[0,0,0,0,0,0,127],"'":[24,24,32,0,0,0,0],'"':[54,54,36,0,0,0,0],"`":[24,8,0,0,0,0,0],")":[24,12,6,6,6,12,24],"(":[12,24,48,48,48,24,12],"[":[60,48,48,48,48,48,60],"]":[30,6,6,6,6,6,30],"{":[14,24,24,48,24,24,14],"}":[56,12,12,6,12,12,56],"/":[3,6,12,24,48,96,0],"\\":[96,48,24,12,6,3,0],"|":[8,8,8,8,8,8,8],"+":[0,8,8,62,8,8,0],"=":[0,0,62,0,62,0,0],"*":[0,42,28,127,28,42,0],"#":[36,36,127,36,127,36,36],"@":[62,99,111,107,111,96,62],"&":[24,36,24,60,74,68,58],"%":[99,38,4,8,16,50,99],$:[8,62,72,62,9,62,8],"^":[8,20,34,0,0,0,0],"~":[0,0,50,76,0,0,0],"<":[6,12,24,48,24,12,6],">":[48,24,12,6,12,24,48]},kt=[127,65,65,65,65,65,127];function Ht(t){return Rt[t]??Rt[t.toUpperCase()]??kt}function Wt(t,e={}){if(!t)return"";const{char:n="█",scale:o=1}=e,r=[...n][0]??"█",i=Math.max(1,Math.floor(o)),a=7*i,s=i,c=Array.from({length:a},()=>"");for(let e=0;e<t.length;e++){const n=Ht(t[e]);for(let t=0;t<7;t++){const e=n[t];let o="";for(let t=6;t>=0;t--)o+=(e>>t&1?r:" ").repeat(i);for(let e=0;e<i;e++)c[t*i+e]+=o}if(e<t.length-1)for(let t=0;t<a;t++)c[t]+=" ".repeat(s)}return c.join("\n")}function $t(t,e,n={}){const{color:o="#d4ff00",bgColor:r,fontSize:i=10}=n,a=Wt(e,n);if(!a)return;const s=a.split("\n"),c=Math.max(...s.map(t=>[...t].length));t.width=Math.ceil(c*i*.6),t.height=Math.ceil(s.length*i);const l=t.getContext("2d");r&&"transparent"!==r?(l.fillStyle=r,l.fillRect(0,0,t.width,t.height)):l.clearRect(0,0,t.width,t.height),l.fillStyle=o,l.font=`${i}px monospace`,l.textBaseline="top",s.forEach((t,e)=>l.fillText(t,0,e*i))}var Pt=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk"];export{t as CHARACTER_SETS,n as DEFAULT_OPTIONS,o as HOVER_PRESETS,e as PALETTE_THEMES,Pt as STUDIO_STYLES,St as asciiText,Et as asciiTextAnsi,wt as asciify,yt as asciifyGif,bt as asciifyLiveVideo,Wt as asciifyText,xt as asciifyVideo,It as asciifyWebcam,Ct as buildTextFrame,Ft as captureSnapshot,P as clearAsciifyCaches,pt as computeCanvasRenderSize,ct as createVideoScrollScrub,Y as gifToAsciiFrames,G as gifToAsciiTextFrames,V as imageToAsciiFrame,D as imageToAsciiTextFrame,Q as renderFrameToCanvas,At as renderTextBackground,K as renderTextFrameToCanvas,$t as renderTextToCanvas,Lt as snapshotAndDownload,N as videoToAsciiFrames,U as videoToAsciiTextFrames};//# sourceMappingURL=core.js.map
|
|
1
|
+
var t={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:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},e={dracula:{name:"Dracula",accent:"#bd93f9",bg:"#282a36",fg:"#f8f8f2"},monokai:{name:"Monokai",accent:"#a6e22e",bg:"#272822",fg:"#f8f8f2"},nord:{name:"Nord",accent:"#88c0d0",bg:"#2e3440",fg:"#eceff4"},catppuccin:{name:"Catppuccin",accent:"#cba6f7",bg:"#1e1e2e",fg:"#cdd6f4"},solarized:{name:"Solarized",accent:"#268bd2",bg:"#002b36",fg:"#839496"},gruvbox:{name:"Gruvbox",accent:"#b8bb26",bg:"#282828",fg:"#ebdbb2"}},n={fontSize:7,charSpacing:1,brightness:0,contrast:0,charset:t.standard.chars,colorMode:"grayscale",accentColor:"#d4ff00",invert:!1,renderMode:"ascii",animationStyle:"none",animationSpeed:1,dotSizeRatio:.8,ditherStrength:0,charAspect:.55,normalize:!1,hoverStrength:0,hoverRadius:.2,hoverEffect:"spotlight",hoverColor:"#ffffff",hoverShape:"circle",hoverText:"ASCIIFY",artStyle:"classic",fineDither:!1,customText:"",chromaKey:null,chromaKeyTolerance:60,chromaKeyTrimPadding:.002,chromaKeyTrimLuminanceThreshold:0,chromaKeyTrimMode:"range"},o={none:{label:"Off",options:{hoverStrength:0,hoverEffect:"spotlight",hoverRadius:.2,hoverColor:"#ffffff"}},subtle:{label:"Subtle",options:{hoverStrength:.25,hoverEffect:"glow",hoverRadius:.12,hoverColor:"#ffffff"}},flashlight:{label:"Flashlight",options:{hoverStrength:.6,hoverEffect:"spotlight",hoverRadius:.15,hoverColor:"#fffbe6"}},magnifier:{label:"Magnifier",options:{hoverStrength:.7,hoverEffect:"magnify",hoverRadius:.12,hoverColor:"#ffffff"}},forceField:{label:"Force Field",options:{hoverStrength:.7,hoverEffect:"repel",hoverRadius:.15,hoverColor:"#a0e8ff"}},neon:{label:"Neon",options:{hoverStrength:.6,hoverEffect:"colorShift",hoverRadius:.15,hoverColor:"#d946ef"}},fire:{label:"Fire",options:{hoverStrength:.7,hoverEffect:"spotlight",hoverRadius:.15,hoverColor:"#ff6b2b"}},ice:{label:"Ice",options:{hoverStrength:.5,hoverEffect:"glow",hoverRadius:.15,hoverColor:"#60d5f7"}},gravity:{label:"Gravity",options:{hoverStrength:.7,hoverEffect:"attract",hoverRadius:.18,hoverColor:"#a5d6ff"}},shatter:{label:"Shatter",options:{hoverStrength:.8,hoverEffect:"shatter",hoverRadius:.14,hoverColor:"#ff6090"}},ghost:{label:"Fluid trail",options:{hoverStrength:.55,hoverEffect:"trail",hoverRadius:.2,hoverColor:"#b39ddb"}},glitchReveal:{label:"Glitch Reveal",options:{hoverStrength:.8,hoverEffect:"glitchText",hoverRadius:.18,hoverColor:"#a3e635"}}},r=[{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."}];var i=(t,e,n)=>{const o=(t=>Math.max(0,Math.min(1,t)))((n-t)/(e-t));return o*o*(3-2*o)},a=(t,e)=>{const n=(.06711056*t+.00583715*e)%1*52.9829189;return n-Math.floor(n)};function s(t,e,n,o,r){if(r[0]=r[1]=r[2]=0,r[3]=1,"none"===t)return r;const s=o*Math.PI/6,c=i(0,.12,Math.min(e,1-e,n,1-n));if("caustics"===t){const t=Math.sin(9*e+5*n+s)+Math.sin(8*n-3*e-s),o=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);r[2]=(.22*o-.045)*c}else if("current"===t)r[0]=Math.sin(9*n+s)*Math.cos(7*e-s)*10*c,r[1]=Math.cos(8*e+s)*Math.sin(6*n-s)*7*c;else if("sheen"===t)r[2]=.2*Math.pow(.5+.5*Math.cos(5*e+3*n-s),8)-.025;else if("tidal"===t){const t=e-.5,o=n-.5,i=Math.hypot(t,o),a=Math.sin(22*i-s)*c;r[0]=t*a*9,r[1]=o*a*9,r[2]=.035*a}else if("grain"===t){const t=a(Math.floor(160*e),Math.floor(100*n))*Math.PI*2;r[2]=.07*Math.sin(s+t)}else if("reform"===t){const t=(o%12+12)%12,l=a(Math.floor(160*e),Math.floor(100*n)),h=.65*e+.2*n+.15*l+.08*Math.sin(8*e-5*n),d=i(1.8+1.2*h,3.8+1.2*h,t)*(1-i(5+1.7*h,7.2+1.7*h,t));r[0]=Math.sin(9*n+s)*d*(1-d)*24*c,r[1]=-d*(1-d)*(8+12*l)*c,r[2]=.45*-d,r[3]=1-.9*d}return r}function c(t,e){const n=document.createElement("canvas");n.width=t,n.height=e;const o=n.getContext("2d",{willReadFrequently:!0});return{canvas:n,ctx:o}}function l(t,e,n){let o=t+255*e;return o=259*(255*n+255)/(255*(259-255*n))*(o-128)+128,Math.max(0,Math.min(255,o))}function h(t,e,n,o,r,i){if((i?1-t/255:t/255)<.12)return" ";const a=[...e];return a[(o*r+n)%a.length]}var d=[[0,8,2,10],[12,4,14,6],[3,11,1,9],[15,7,13,5]];function f(t,e,n,o){if(o<=0)return t;const r=(d[n%4][e%4]/16-.5)*o*128;return Math.max(0,Math.min(255,t+r))}var m=new Array(256),u=new Array(256);for(let t=0;t<256;t++)m[t]=`rgb(${t},${t},${t})`,u[t]=`rgb(0,${t},0)`;function g(t,e,n,o,r,i=!1){switch(e){case"fullcolor":return`rgb(${t.r},${t.g},${t.b})`;case"matrix":return u[.299*t.r+.587*t.g+.114*t.b|0];case"accent":return`rgb(${n},${o},${r})`;default:{const e=.299*t.r+.587*t.g+.114*t.b|0;return m[e]}}}var p=[0,0,0];function M(t,e,n,o,r,i=!1){switch(e){case"fullcolor":p[0]=t.r,p[1]=t.g,p[2]=t.b;break;case"matrix":{const e=.299*t.r+.587*t.g+.114*t.b|0;p[0]=0,p[1]=e,p[2]=0;break}case"accent":p[0]=n,p[1]=o,p[2]=r;break;default:{const e=.299*t.r+.587*t.g+.114*t.b|0;p[0]=e,p[1]=e,p[2]=e;break}}return p}function v(t){const e=t.match(/rgba?\(\s*(\d+)\s*[,\s]\s*(\d+)\s*[,\s]\s*(\d+)(?:\s*[,/]\s*([\d.]+))?\s*\)/);return e?{r:+e[1],g:+e[2],b:+e[3],a:void 0!==e[4]?+e[4]:1}:null}function w(t){let e=t;for(;e&&e!==document.documentElement.parentElement;){const t=getComputedStyle(e).backgroundColor;if(t&&"transparent"!==t&&"rgba(0, 0, 0, 0)"!==t){const e=v(t);if(e&&e.a>.1)return e}e=e.parentElement}return null}function y(t){if(t){const e=w(t);if(e){return(.299*e.r+.587*e.g+.114*e.b)/255<.4}}if("undefined"!=typeof document){const t=document.documentElement,e=(t.getAttribute("data-theme")||"").toLowerCase();if("dark"===e)return!0;if("light"===e)return!1;if(t.classList.contains("dark"))return!0;if(document.body){const t=w(document.body);if(t){return(.299*t.r+.587*t.g+.114*t.b)/255<.4}}}return"undefined"!=typeof window&&window.matchMedia("(prefers-color-scheme: dark)").matches}function x(t){if("string"!=typeof t)return t;const e=document.createElement("canvas");e.width=1,e.height=1;const n=e.getContext("2d");n.fillStyle=t,n.fillRect(0,0,1,1);const o=n.getImageData(0,0,1,1).data;return{r:o[0],g:o[1],b:o[2]}}function b(t){return t*t*(3-2*t)}var S={scale:1,offsetX:0,offsetY:0,glow:0,colorBlend:0,proximity:0};function E(t,e,n,o,r,i,a,s,c="spotlight",l=.5,h="circle",d=[],f=1){const m=(t-n)*Math.max(1,f),u=(e-o)*Math.max(1,1/f),g=.08+.35*l+.04*i;let p,M;if("box"===h){const t=Math.abs(m),e=Math.abs(u);p=Math.max(t,e),M=g}else p=Math.sqrt(m*m+u*u),M=g;if(p>=M&&("trail"!==c||0===d.length))return S.scale=1,S.offsetX=0,S.offsetY=0,S.glow=0,S.colorBlend=0,S.proximity=0,S;const v=b(Math.max(0,1-p/M))*r;let w=1,y=0,x=0,E=0,C=0;switch(c){case"spotlight":{w=1+v*i*1.8;const t=Math.atan2(u,m),e=v*v*i*.6;y=Math.cos(t)*e*a,x=Math.sin(t)*e*s,E=v*i*.4,C=v*v*i*.25;break}case"magnify":w=1+v*i*.85,E=v*i*.15;break;case"repel":{w=1;const t=Math.atan2(u,m),e=v*v*i*1.8;y=Math.cos(t)*e*a,x=Math.sin(t)*e*s;break}case"glow":E=v*i*.8,C=v*i*.4;break;case"colorShift":w=1,E=v*i*.12,C=v*i;break;case"attract":{const t=Math.atan2(u,m),e=v*v*i*1;y=(.45*-Math.cos(t)-1.6*Math.sin(t))*e*a,x=(.45*-Math.sin(t)+1.6*Math.cos(t))*e*s,E=v*i*.3;break}case"shatter":{const t=Math.atan2(u,m),e=.5*Math.sin(43.7*m+29.3*u),n=v*i*1.4*(.7+.3*e);y=Math.cos(t+e)*n*a,x=Math.sin(t+e)*n*s,w=Math.max(.1,1-v*i*.6),E=v*i*.25;break}case"trail":{let n=v,o=-u*v,r=m*v;for(const i of d){const a=(t-i.x)*Math.max(1,f),s=(e-i.y)*Math.max(1,1/f),c=Math.hypot(a,s)/g;if(c>=1)continue;const l=b(1-c)*i.intensity;n=Math.max(n,l),o+=(.35*i.vx-2*s)*l*.35,r+=(.35*i.vy+2*a)*l*.35}y=Math.tanh(2*o)*i*a*3,x=Math.tanh(2*r)*i*s*3,C=n*i*.65,E=n*i*.35,w=1+n*i*.08,S.proximity=n;break}case"glitchText":w=1,E=v*i*.5,C=v*i*.6}return S.scale=w,S.offsetX=y,S.offsetY=x,S.glow=E,S.colorBlend=C,"trail"!==c&&(S.proximity=v),S}function C(t,e,{continuous:n=!1,interactive:o=!1}={}){const r=t.parentElement??t;let i=null,a=0,s=!1,c=!0,l=!0,h=-1/0;const d=window.matchMedia("(prefers-reduced-motion: reduce)"),f=()=>{l=!0,s||!c||document.hidden||a||(a=requestAnimationFrame(m))},m=t=>{if(a=0,s||!c||document.hidden)return;const o=!d.matches&&(n||t-h<1500);(l||o)&&(e(t,d.matches?null:i),l=!1),o&&(a=requestAnimationFrame(m))},u=e=>{if("touch"===e.pointerType)return;const n=t.getBoundingClientRect();if(!n.width||!n.height)return;const o=(e.clientX-n.left)/n.width,r=(e.clientY-n.top)/n.height;i=o>=0&&o<=1&&r>=0&&r<=1?{x:o,y:r}:null,h=performance.now(),f()},g=()=>{i=null,h=performance.now(),f()},p=()=>{document.hidden&&a?(cancelAnimationFrame(a),a=0):f()},M="undefined"==typeof IntersectionObserver?null:new IntersectionObserver(([t])=>{c=t.isIntersecting,c?f():a&&(cancelAnimationFrame(a),a=0)});return M?.observe(t),o&&(r.addEventListener("pointermove",u),r.addEventListener("pointerleave",g)),document.addEventListener("visibilitychange",p),d.addEventListener("change",f),f(),{wake:f,stop:()=>{s=!0,cancelAnimationFrame(a),M?.disconnect(),r.removeEventListener("pointermove",u),r.removeEventListener("pointerleave",g),document.removeEventListener("visibilitychange",p),d.removeEventListener("change",f)}}}var T=null,A=null;function F(t,e){if(!T||!A){const n=c(t,e);T=n.canvas,A=n.ctx}return T.width!==t&&(T.width=t),T.height!==e&&(T.height=e),A}var L=new Map,I=new Map,R=new WeakMap;function k(t){const e=Intl.Segmenter;return e?Array.from(new e(void 0,{granularity:"grapheme"}).segment(t),({segment:t})=>t):[...t]}function H(t){let e=L.get(t);return e||(e=k(t),L.set(t,e)),e}function W(t){return k(t)}function $(t,e,n){const o=n?1-t/255:t/255,r=Math.floor(o*(e.length-1));return e[Math.max(0,Math.min(e.length-1,r))]??" "}function P(t,e,n,o){const r=`${t}\0${e?1:0}\0${n}\0${o}`;let i=I.get(r);if(!i){const a=H(t);i=new Array(256);for(let t=0;t<256;t++)i[t]=$(l(t,n,o),a,e);I.set(r,i)}return i}function j(){L.clear(),I.clear(),_=new WeakMap,Q=new WeakMap,J=new WeakMap,T=null,A=null}function z(t,e){return"auto"!==t?t:!y(e)}function O(t){const e=t.match(/^#([0-9a-fA-F]{3,6})$/);if(e){let t=e[1];if(3===t.length&&(t=t[0]+t[0]+t[1]+t[1]+t[2]+t[2]),6===t.length)return t}const n=t.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);return n?[n[1],n[2],n[3]].map(t=>parseInt(t).toString(16).padStart(2,"0")).join(""):null}function q(t){const e=t||"auto";if("auto"!==e)return O(e)??"ffffff";if("undefined"!=typeof document){const t=getComputedStyle(document.documentElement);for(const e of["--accent-color","--color-accent","--accent","--color-primary","--primary","--brand-color"]){const n=O(t.getPropertyValue(e).trim());if(n)return n}const e=O(getComputedStyle(document.body).accentColor??"");if(e)return e}return y("undefined"!=typeof document?document.body:null)?"faf9f7":"0d0d0d"}function B(t,e,n){return Math.max(e,Math.min(n,t))}function V(t,e,n){if(!t)return{x:0,y:0,width:e,height:n};const o=t.unit??"percent",r=!1!==t.preserveAspect,i=t=>void 0===t?void 0:"percent"===o?t*e:t,a=t=>void 0===t?void 0:"percent"===o?t*n:t,s=B(i(t.left)??0,0,e-1),c=B(i(t.right)??0,0,e-s-1),l=B(a(t.top)??0,0,n-1),h=B(a(t.bottom)??0,0,n-l-1),d=void 0!==t.left||void 0!==t.right||void 0!==t.top||void 0!==t.bottom,f=Math.max(1,e-s-c),m=Math.max(1,n-l-h),u=d?f:i(t.width),g=d?m:a(t.height);let p=u??e,M=g??n;if(r&&!d){const t=p/e,o=M/n,r=Math.min(t,o),i=void 0===u?o:void 0===g?t:r;p=e*i,M=n*i}p=B(p,1,d?f:e),M=B(M,1,d?m:n);const v=t.anchor??"center",w=i(t.x),y=a(t.y),x=d?s:0,b=d?l:0,S=d?f:e,E=d?m:n,C=v.endsWith("left")||"left"===v?0:v.endsWith("right")||"right"===v?S-p:(S-p)/2,T=v.startsWith("top")||"top"===v?0:v.startsWith("bottom")||"bottom"===v?E-M:(E-M)/2;return{x:B(w??x+C,0,Math.max(0,e-p)),y:B(y??b+T,0,Math.max(0,n-M)),width:p,height:M}}function D(t,e,n,o){const r=t instanceof HTMLVideoElement?t.videoWidth:t.width,i=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(0===r||0===i)return{frame:[],cols:0,rows:0};const a=e.charAspect,s=e.fontSize*e.charSpacing,c=e.fontSize/a*e.charSpacing,d=n||r,m=o||i,u=Math.floor(d/s),g=Math.floor(m/c);if(u<=0||g<=0)return{frame:[],cols:0,rows:0};const p=V(e.sourceCrop,r,i),M=Math.max(1,Math.min(Math.floor(2048/u),Math.floor(p.width/u))),v=Math.max(1,Math.min(Math.floor(2048/g),Math.floor(p.height/g))),w=u*M,y=g*v,b=F(w,y),S=b.globalCompositeOperation;b.globalCompositeOperation="copy";try{b.drawImage(t,p.x,p.y,p.width,p.height,0,0,w,y)}finally{b.globalCompositeOperation=S}const E=b.getImageData(0,0,w,y).data,C=e.chromaKey,T=null!=C&&!1!==C,A=!0===C,L="blue-screen"===C;let I=null,R=0;!T||A||L||(I=x(C),R=(e.chromaKeyTolerance??60)**2);let k=0,W=255;if(e.normalize){let t=255,e=0;for(let n=0;n<E.length;n+=4){if(T){const t=E[n],e=E[n+1],o=E[n+2];let r=!1;if(A)r=e>1.4*t&&e>1.4*o&&e>80;else if(L)r=o>1.4*t&&o>1.4*e&&o>80;else if(null!==I){const n=t-I.r,i=e-I.g,a=o-I.b;r=n*n+i*i+a*a<=R}if(r)continue}const o=.299*E[n]+.587*E[n+1]+.114*E[n+2];o<t&&(t=o),o>e&&(e=o)}k=t,W=e>t?e-t:255}const j=[],O=z(e.invert),q=T&&e.charset.replace(/ /g,"")||e.charset,B=H(q),D=e.customText?null:P(q,O,e.brightness,e.contrast),K=M*v;for(let t=0;t<g;t++){const n=[];for(let o=0;o<u;o++){let r=0,i=0,a=0,s=0,c=0;for(let e=0;e<v;e++){const n=(t*v+e)*w;for(let t=0;t<M;t++){const e=4*(n+o*M+t),l=E[e],h=E[e+1],d=E[e+2],f=E[e+3];if(T){let t=!1;if(A)t=h>1.4*l&&h>1.4*d&&h>80;else if(L)t=d>1.4*l&&d>1.4*h&&d>80;else if(null!==I){const e=l-I.r,n=h-I.g,o=d-I.b;t=e*e+n*n+o*o<=R}if(t){c++;continue}}r+=l,i+=h,a+=d,s+=f}}if(T&&c>K/2){n.push({char:" ",r:0,g:0,b:0,a:0});continue}const d=K-c,m=d>0?r/d:0,g=d>0?i/d:0,p=d>0?a/d:0,y=d>0?s/d:0,x=.299*m+.587*g+.114*p,b=e.normalize?(x-k)/W*255:x,S=l(b,e.brightness,e.contrast),C=e.ditherStrength>0?f(S,o,t,e.ditherStrength):S,F=e.customText?h(C,e.customText,o,t,u,O):e.ditherStrength>0?$(C,B,O):D[Math.max(0,Math.min(255,0|b))];n.push({char:F,r:m,g:g,b:p,a:y,lum:C})}j.push(n)}return{frame:j,cols:u,rows:g}}function K(t,e,n,o){const r=t instanceof HTMLVideoElement?t.videoWidth:t.width,i=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(0===r||0===i)return{rows:[],cols:0,rowCount:0};const a=e.charAspect,s=e.fontSize*e.charSpacing,c=e.fontSize/a*e.charSpacing,h=n||r,d=o||i,m=Math.floor(h/s),u=Math.floor(d/c);if(m<=0||u<=0)return{rows:[],cols:0,rowCount:0};const g=m,p=u,M=F(g,p),v=V(e.sourceCrop,r,i),w=M.globalCompositeOperation;M.globalCompositeOperation="copy";try{M.drawImage(t,v.x,v.y,v.width,v.height,0,0,g,p)}finally{M.globalCompositeOperation=w}const y=M.getImageData(0,0,g,p).data,b=e.chromaKey,S=null!=b&&!1!==b,E=!0===b,C="blue-screen"===b;let T=null,A=0;!S||E||C||(T=x(b),A=(e.chromaKeyTolerance??60)**2);let L=0,I=255;if(e.normalize){let t=255,e=0;for(let n=0;n<y.length;n+=4){if(S){const t=y[n],e=y[n+1],o=y[n+2];let r=!1;if(E)r=e>1.4*t&&e>1.4*o&&e>80;else if(C)r=o>1.4*t&&o>1.4*e&&o>80;else if(null!==T){const n=t-T.r,i=e-T.g,a=o-T.b;r=n*n+i*i+a*a<=A}if(r)continue}const o=.299*y[n]+.587*y[n+1]+.114*y[n+2];o<t&&(t=o),o>e&&(e=o)}L=t,I=e>t?e-t:255}const R=z(e.invert),k=S&&e.charset.replace(/ /g,"")||e.charset,W=H(k),j=e.customText?null:P(k,R,e.brightness,e.contrast),O=e.customText?H(e.customText):null,q="fullcolor"===e.colorMode?new Uint8ClampedArray(m*u*4):void 0,B=[];for(let t=0;t<u;t++){let n="";for(let o=0;o<m;o++){const r=4*(t*g+o),i=r,a=y[r],s=y[r+1],c=y[r+2],h=y[r+3];if(S){let t=!1;if(E)t=s>1.4*a&&s>1.4*c&&s>80;else if(C)t=c>1.4*a&&c>1.4*s&&c>80;else if(null!==T){const e=a-T.r,n=s-T.g,o=c-T.b;t=e*e+n*n+o*o<=A}if(t){n+=" ",q&&(q[i]=0,q[i+1]=0,q[i+2]=0,q[i+3]=0);continue}}q&&(q[i]=a,q[i+1]=s,q[i+2]=c,q[i+3]=h);const d=.299*a+.587*s+.114*c,u=e.normalize?(d-L)/I*255:d,p=e.ditherStrength>0||O?l(u,e.brightness,e.contrast):u,M=e.ditherStrength>0?f(p,o,t,e.ditherStrength):p;if(O){n+=(R?1-M/255:M/255)<.12?" ":O[(t*m+o)%O.length]}else e.ditherStrength<=0?n+=j[Math.max(0,Math.min(255,0|u))]:n+=$(M,W,R)}B.push(n)}return{rows:B,cols:m,rowCount:u,colors:q}}function N(t,e,n,o,r){if(0===e.rows.length)return;const i=t.canvas,a=Boolean(n.chromaKey)||e.rows.some(t=>t.includes(" "));a||(R.delete(t),t.clearRect(0,0,o,r),t.fillStyle=y(i)?"#0a0a0a":"#faf9f7",t.fillRect(0,0,o,r));const s=q(n.accentColor),c=parseInt(s.substring(0,2),16),l=parseInt(s.substring(2,4),16),h=parseInt(s.substring(4,6),16),d=o/e.cols,f=r/e.rowCount,m=.9*Math.min(d/.55,f),u=e.colors;if("fullcolor"===n.colorMode&&u){R.delete(t),t.clearRect(0,0,o,r),t.font=`${m}px "JetBrains Mono", monospace`,t.textAlign="left",t.textBaseline="middle",t.globalAlpha=1;let n="";for(let o=0;o<e.rows.length;o++){const r=W(e.rows[o]);let i=0;for(;i<e.cols;){for(;i<e.cols&&" "===r[i];)i++;if(i>=e.cols)break;const a=i,s=4*(o*e.cols+i),c=240&u[s],l=240&u[s+1],h=240&u[s+2];for(i++;i<e.cols&&" "!==r[i];){const t=4*(o*e.cols+i);if((240&u[t])!==c||(240&u[t+1])!==l||(240&u[t+2])!==h)break;i++}const m=`rgb(${c},${l},${h})`;m!==n&&(t.fillStyle=m,n=m),t.fillText(r.slice(a,i).join(""),a*d+.5*d,o*f+.5*f)}}return void(t.globalAlpha=1)}t.font=`${m}px "JetBrains Mono", monospace`,t.textAlign="left",t.textBaseline="middle";const g="matrix"===n.colorMode?"rgb(0,255,0)":"grayscale"===n.colorMode?y(i)?"rgb(230,230,230)":"rgb(24,24,24)":`rgb(${c},${l},${h})`;t.fillStyle=g,t.globalAlpha=1;const p=R.get(t),M=a&&p&&p.cols===e.cols&&p.rowCount===e.rowCount&&p.canvasWidth===o&&p.canvasHeight===r&&p.fillStyle===g;M||t.clearRect(0,0,o,r);for(let n=0;n<e.rows.length;n++){const r=e.rows[n];M&&p.rows[n]===r||(M&&t.clearRect(0,n*f,o,f+1),0!==r.trim().length&&t.fillText(r,.5*d,n*f+.5*f))}R.set(t,{rows:e.rows.slice(),cols:e.cols,rowCount:e.rowCount,canvasWidth:o,canvasHeight:r,fillStyle:g}),t.globalAlpha=1}async function U(t,e,n,o,r=12,i=10,a,s=0){const c=Math.min(t.duration-s,i),l=Math.ceil(c*r),h=[];let d=0,f=0;for(let i=0;i<l;i++){const m=s+i/r;if(m>s+c)break;t.currentTime=m,await new Promise(e=>{const n=()=>{t.removeEventListener("seeked",n),e()};t.addEventListener("seeked",n)});const u=D(t,e,n,o);h.push(u.frame),d=u.cols,f=u.rows,a?.((i+1)/l)}return{frames:h,cols:d,rows:f,fps:r}}async function Y(t,e,n,o,r=12,i=10,a,s=0){const c=Math.min(t.duration-s,i),l=Math.ceil(c*r),h=[];let d=0,f=0;for(let i=0;i<l;i++){const m=s+i/r;if(m>s+c)break;t.currentTime=m,await new Promise(e=>{const n=()=>{t.removeEventListener("seeked",n),e()};t.addEventListener("seeked",n)});const u=K(t,e,n,o);h.push(u),d=u.cols,f=u.rowCount,a?.((i+1)/l)}return{frames:h,cols:d,rows:f,fps:r}}async function G(t,e,n,o,r){const{parseGIF:i,decompressFrames:a}=await import("gifuct-js"),s=i(t),c=a(s,!0);if(0===c.length)return{frames:[],cols:0,rows:0,fps:10};const l=c[0].dims.width,h=c[0].dims.height,d=s.lsd?.width||l,f=s.lsd?.height||h,m=document.createElement("canvas");m.width=d,m.height=f;const u=m.getContext("2d"),g=document.createElement("canvas");g.width=d,g.height=f;const p=g.getContext("2d"),M=document.createElement("canvas"),v=M.getContext("2d"),w=[];let y=0,x=0,b=0;for(const t of c)b+=t.delay||100;const S=b/c.length,E=Math.round(Math.min(30,Math.max(5,1e3/S))),C=Math.min(c.length,300);for(let t=0;t<C;t++){const i=c[t],{dims:a,patch:s,disposalType:l}=i;3===l&&(p.clearRect(0,0,d,f),p.drawImage(m,0,0)),M.width!==a.width&&(M.width=a.width),M.height!==a.height&&(M.height=a.height);const h=new ImageData(new Uint8ClampedArray(s.buffer),a.width,a.height);v.putImageData(h,0,0),u.drawImage(M,a.left||0,a.top||0);const b=D(m,e,n,o);w.push(b.frame),y=b.cols,x=b.rows,2===l?u.clearRect(a.left||0,a.top||0,a.width,a.height):3===l&&(u.clearRect(0,0,d,f),u.drawImage(g,0,0)),r?.((t+1)/C)}return{frames:w,cols:y,rows:x,fps:E}}async function X(t,e,n,o,r){const{parseGIF:i,decompressFrames:a}=await import("gifuct-js"),s=i(t),c=a(s,!0);if(0===c.length)return{frames:[],cols:0,rows:0,fps:10};const l=c[0].dims.width,h=c[0].dims.height,d=s.lsd?.width||l,f=s.lsd?.height||h,m=document.createElement("canvas");m.width=d,m.height=f;const u=m.getContext("2d"),g=document.createElement("canvas");g.width=d,g.height=f;const p=g.getContext("2d"),M=document.createElement("canvas"),v=M.getContext("2d"),w=[];let y=0,x=0,b=0;for(const t of c)b+=t.delay||100;const S=b/c.length,E=Math.round(Math.min(30,Math.max(5,1e3/S))),C=Math.min(c.length,300);for(let t=0;t<C;t++){const i=c[t],{dims:a,patch:s,disposalType:l}=i;3===l&&(p.clearRect(0,0,d,f),p.drawImage(m,0,0)),M.width!==a.width&&(M.width=a.width),M.height!==a.height&&(M.height=a.height);const h=new ImageData(new Uint8ClampedArray(s.buffer),a.width,a.height);v.putImageData(h,0,0),u.drawImage(M,a.left||0,a.top||0);const b=K(m,e,n,o);w.push(b),y=b.cols,x=b.rowCount,2===l?u.clearRect(a.left||0,a.top||0,a.width,a.height):3===l&&(u.clearRect(0,0,d,f),u.drawImage(g,0,0)),r?.((t+1)/C)}return{frames:w,cols:y,rows:x,fps:E}}var _=new WeakMap,J=new WeakMap,Q=new WeakMap;function Z(t,e,n,o,r,i=0,a){if(!e.length||!e[0].length||o<=0||r<=0)return;let s=null;if(n.hoverStrength>0){let e=_.get(t);e||(e={x:.5,y:.5,intensity:0,time:-1,emittedAt:-1,points:[]},_.set(t,e)),s=function(t,e,n){const o=t.time<0?1/60:Math.max(0,Math.min(.1,(n-t.time)/1e3));t.time=n;const r=t.intensity<.003,i=t.x,a=t.y;if(e){r&&(t.x=e.x,t.y=e.y);const n=1-Math.exp(-o/.055);t.x+=(e.x-t.x)*n,t.y+=(e.y-t.y)*n}t.intensity+=((e?.intensity??(e?1:0))-t.intensity)*(1-Math.exp(-o/(e?.09:.18)));const s=Math.exp(-o/.22);for(const e of t.points)e.intensity*=s;for(;t.points.length&&t.points[0].intensity<.01;)t.points.shift();return e&&!r&&n-t.emittedAt>=24&&Math.hypot(t.x-i,t.y-a)>5e-4&&(t.points.push({x:t.x,y:t.y,intensity:t.intensity,vx:Math.max(-1,Math.min(1,(t.x-i)/Math.max(o,.001))),vy:Math.max(-1,Math.min(1,(t.y-a)/Math.max(o,.001)))}),t.points.length>12&&t.points.shift(),t.emittedAt=n),!e&&t.intensity<.003&&!t.points.length?(t.intensity=0,null):{x:t.x,y:t.y,intensity:t.intensity,trail:t.points}}(e,a??null,performance.now())}else _.delete(t);if("none"!==n.animationStyle||n.charsetFrames?.length||n.hoverStrength<=0)return Q.delete(t),void tt(t,e,n,o,r,i,s);const c=J.get(t);if(c?.frame!==e)return J.set(t,{frame:e,since:performance.now()}),Q.delete(t),void tt(t,e,n,o,r,i,s);if(performance.now()-c.since<100)return void tt(t,e,n,o,r,i,s);const l=t.getTransform();if(l.b||l.c||l.a<=0||l.d<=0)return void tt(t,e,n,o,r,i,s);if(!s||(s.intensity??0)<.003)return void tt(t,e,n,o,r,i,null);const h=y(t.canvas),d={...n,accentColor:"#"+q(n.accentColor)},f=JSON.stringify([d,o,r,l.a,l.d,h,void 0!==document.fonts?document.fonts.status:"loaded"]);let m=Q.get(t);if(!m||m.frame!==e||m.key!==f){const n=m?.canvas??document.createElement("canvas");n.width=Math.ceil(o*l.a),n.height=Math.ceil(r*l.d);const i=n.getContext("2d");i.setTransform(l.a,0,0,l.d,0,0),tt(i,e,d,o,r,0,null,void 0,h),m={frame:e,key:f,canvas:n},Q.set(t,m)}if(t.clearRect(0,0,o,r),t.drawImage(m.canvas,0,0,o,r),!s||(s.intensity??0)<.003)return;const u=e.length,g=e[0].length,p=.08+.35*n.hoverRadius+.04*n.hoverStrength,M="trail"===n.hoverEffect?[s,...s.trail??[]]:[s];let v=1,w=1,x=0,b=0;for(const t of M)v=Math.min(v,t.x-p),x=Math.max(x,t.x+p),w=Math.min(w,t.y-p),b=Math.max(b,t.y+p);if("glitchText"===n.hoverEffect){const t=n.hoverText,e=Math.max(1,...(Array.isArray(t)?t:[t]).map(t=>t.length));v=Math.min(v,s.x-e/g),x=Math.max(x,s.x+e/g)}const S=Math.ceil(5+4*n.hoverStrength),E={x:Math.max(0,Math.floor(v*g)-S),y:Math.max(0,Math.floor(w*u)-S),right:Math.min(g,Math.ceil(x*g)+S),bottom:Math.min(u,Math.ceil(b*u)+S)};t.save(),t.beginPath(),t.rect(E.x*o/g,E.y*r/u,(E.right-E.x)*o/g,(E.bottom-E.y)*r/u),t.clip(),tt(t,e,d,o,r,i,s,E,h),t.restore()}function tt(t,e,n,o,i,a=0,c,l,h){const d=e.length;if(0===d)return;const f=e[0].length;t.clearRect(0,0,o,i);let m=!1;const u=Math.max(1,d>>2),p=Math.max(1,f>>2);t:for(let t=0;t<d;t+=u){const n=e[t];for(let t=0;t<f;t+=p)if(n[t].a<200){m=!0;break t}}const v=t.canvas,w=h??y(v);m||(t.fillStyle=w?"#0a0a0a":"#faf9f7",t.fillRect(0,0,o,i));const x=o/f,b=i/d,S=c?.intensity??1,C=!!(c&&n.hoverStrength>0&&S>.005),T="#"+(O(n.hoverColor||"#ffffff")??"ffffff"),A=parseInt(T.slice(1,3),16),F=parseInt(T.slice(3,5),16),L=parseInt(T.slice(5,7),16),I=q(n.accentColor),R=parseInt(I.substring(0,2),16),k=parseInt(I.substring(2,4),16),W=parseInt(I.substring(4,6),16),P=n.hoverRadius;let j=0,B=f,V=0,D=d,K=0,N=0;if(C&&c){K=c.x,N=c.y;const t=.08+.35*P+.04*n.hoverStrength;j=Math.max(0,Math.floor((K-t)*f)-1),B=Math.min(f,Math.ceil((K+t)*f)+1),V=Math.max(0,Math.floor((N-t)*d)-1),D=Math.min(d,Math.ceil((N+t)*d)+1)}if(C&&"trail"===n.hoverEffect)for(const t of c?.trail??[]){const e=.08+.35*P+.04*n.hoverStrength;j=Math.min(j,Math.max(0,Math.floor((t.x-e)*f)-1)),B=Math.max(B,Math.min(f,Math.ceil((t.x+e)*f)+1)),V=Math.min(V,Math.max(0,Math.floor((t.y-e)*d)-1)),D=Math.max(D,Math.min(d,Math.ceil((t.y+e)*d)+1))}const U=n.animationStyle,Y=n.animationSpeed,G=(X=U,r.find(t=>t.value===X||t.mode===X)?.mode??"none");var X;const _="none"===G,J=[0,0,0,1],Q=n.hoverStrength,Z=n.hoverEffect,tt=P,et=n.hoverShape||"circle",nt=z(n.invert,v),ot=n.colorMode,rt=2*Math.PI,it=1/f,at=1/d;let st="",ct=-1;if("dots"===n.renderMode){const r=.5*Math.min(x,b)*n.dotSizeRatio;for(let n=l?.y??0;n<(l?.bottom??d);n++){const h=e[n];for(let e=l?.x??0;e<(l?.right??f);e++){const l=h[e];if(l.a<10)continue;const m=.00392156863*(.299*l.r+.587*l.g+.114*l.b),u=nt?1-m:m;if(u<.02)continue;_||s(G,e/f,n/d,a*Y,J);const p=Math.max(0,Math.min(1,(1+J[2])*J[3]));let v=1,w=0,y=0,T=0,I=0;if(C&&e>=j&&e<=B&&n>=V&&n<=D){const t=E(e*it,n*at,K,N,S,Q,x,b,Z,tt,et,c?.trail,o/i);v=t.scale,w=t.offsetX,y=t.offsetY,T=t.glow,I=t.colorBlend}const H=r*u*p*v;if(H<.3)continue;const $=e*x+.5*x+w+J[0],P=n*b+.5*b+y+J[1];let z;if(I>0){const t=M(l,ot,R,k,W,nt);z=`rgb(${Math.min(255,t[0]+(A-t[0])*I|0)},${Math.min(255,t[1]+(F-t[1])*I|0)},${Math.min(255,t[2]+(L-t[2])*I|0)})`}else z=g(l,ot,R,k,W,nt);const O=Math.min(1,.00392156863*l.a*p*(1+T));if(O!==ct&&(t.globalAlpha=O,ct=O),z!==st&&(t.fillStyle=z,st=z),H<=3){const e=2*H;t.fillRect($-H,P-H,e,e)}else t.beginPath(),t.arc($,P,H,0,rt),t.fill()}}}else{const r=.55,h=.9*Math.min(x/r,b);{const e=/\p{Extended_Pictographic}/u.test(n.customText||n.charset);t.font=e?`${h}px "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla", sans-serif`:`${h}px "JetBrains Mono", monospace`,t.textAlign="center",t.textBaseline="middle"}const m=n.charsetFrames,u=!!m?.length,p=u?m[Math.floor(Math.max(0,a)*(n.charsetFps??2))%m.length]:n.charset,v=t.getTransform();if(!C&&_&&!u&&"accent"===ot&&!l&&n.hoverStrength<=0&&!/\p{Extended_Pictographic}/u.test(n.customText||n.charset)&&"letterSpacing"in t&&/^[\x20-\x7e]*$/.test(n.customText||n.charset)&&e.every(t=>t.every(t=>t.a<10||255===t.a&&1===t.char.length&&/^[\x20-\x7e]$/.test(t.char)))){const n=t.letterSpacing;t.letterSpacing="0px";const o=t.measureText("M").width;t.letterSpacing=x-o+"px",t.fillStyle=`rgb(${R},${k},${W})`,t.globalAlpha=1,t.textAlign="left";for(let n=0;n<d;n++){const r=e[n];let i="";for(let t=0;t<f;t++){const e=r[t];i+=e.a<10?" ":e.char}0!==i.trim().length&&t.fillText(i,.5*(x-o),n*b+.5*b)}return t.letterSpacing=n,t.textAlign="center",void(t.globalAlpha=1)}const w="glitchText"===Z&&C,y="!@#$%^&*<>{}[]|/\\~`0123456789",T=y.length;let I="",z=0,O=0,q=0,U=0,X=0,rt=0;if(w){const t=n.hoverText??"ASCIIFY";if(O=Math.round(K*f),q=Math.round(N*d),Array.isArray(t)){const e=t.filter(t=>t.length>0);0===e.length&&e.push("ASCIIFY");I=e[((7*Math.floor(O/Math.max(1,Math.ceil(f/5)))+13*Math.floor(q/Math.max(1,Math.ceil(d/3))))%e.length+e.length)%e.length]}else I=t||"ASCIIFY";z=I.length,U=Math.max(3,Math.min(12,Math.round(d*P*.6)));const e=Math.floor(U/2);X=Math.max(0,q-e),X+U>d&&(X=Math.max(0,d-U)),rt=O-Math.floor(z/2)}for(let n=l?.y??0;n<(l?.bottom??d);n++){const r=e[n];for(let h=l?.x??0;h<(l?.right??f);h++){const l=r[h];if(l.a<10)continue;let m=u&&null!=l.lum?$(l.lum,H(p),nt):l.char;if(" "===m)continue;_||s(G,h/f,n/d,a*Y,J);const P=Math.max(0,Math.min(1,(1+J[2])*J[3]));if(P<.05)continue;let lt=1,ht=0,dt=0,ft=0,mt=0;if(C&&!w&&h>=j&&h<=B&&n>=V&&n<=D){const t=E(h*it,n*at,K,N,S,Q,x,b,Z,tt,et,c?.trail,o/i);if(lt=t.scale,ht=t.offsetX,dt=t.offsetY,ft=t.glow,mt=t.colorBlend,"trail"===Z&&t.proximity>0){const o=Math.max(0,Math.min(f-1,Math.round(h-t.offsetX/x))),r=e[Math.max(0,Math.min(d-1,Math.round(n-t.offsetY/b)))][o],i=r.lum??.299*r.r+.587*r.g+.114*r.b;m=$(Math.min(255,i+t.proximity*Q*65),H(p),nt)}}if(w&&n>=X&&n<X+U){const t=h-rt;if(t>=0&&t<z){const e=I[t],o=Math.abs(n-q)/Math.max(1,.5*U),r=Math.abs(h-O)/Math.max(1,z),i=Math.max(o,r),s=Math.max(0,Math.min(1,1-.9*i)),c=43758.5453*Math.sin(127.1*h+311.7*n+43758.5453*Math.floor(12*a));m=Math.abs(c-Math.floor(c))<s?e:y[Math.abs(Math.floor(97*c))%T],ft=.3+.7*s,mt=.3+.65*s}}const ut=h*x+.5*x+ht+J[0],gt=n*b+.5*b+dt+J[1];let pt;if(mt>0){const t=M(l,ot,R,k,W,nt);pt=`rgb(${Math.min(255,t[0]+(A-t[0])*mt|0)},${Math.min(255,t[1]+(F-t[1])*mt|0)},${Math.min(255,t[2]+(L-t[2])*mt|0)})`}else pt=g(l,ot,R,k,W,nt);const Mt=Math.min(1,.00392156863*l.a*P*(1+ft));Mt!==ct&&(t.globalAlpha=Mt,ct=Mt),pt!==st&&(t.fillStyle=pt,st=pt),1!==lt?(t.translate(ut,gt),t.scale(lt,lt),t.fillText(m,0,0),t.setTransform(v)):t.fillText(m,ut,gt)}}}t.globalAlpha=1}function et(t="classic"){if("classic"!==t)throw new RangeError(`Art preset "${String(t)}" was removed in 4.1. Use a StudioStyle with asciify-engine/studio, or supply options.charset directly.`);return{artStyle:"classic"}}function nt(t){return Math.max(0,Math.min(1,t))}function ot(t){return"string"==typeof t?document.querySelector(t):t instanceof HTMLElement?t:null}function rt(t){return"ascii"===t.renderMode&&"none"===t.animationStyle&&t.hoverStrength<=0&&!t.charsetFrames?.length}function it(t,e={}){const n=nt(t),o=nt(n*(void 0===e.speed?1:Math.max(.001,e.speed)));return nt(e.ease?e.ease(o):o)}function at(t,e,n={}){if(!Number.isFinite(t.duration)||t.duration<=0)return;const o=n.from??0,r=n.to??t.duration,i=Math.max(o,Math.min(r,t.duration)),a=it(e,n),s=o+(i-o)*a;t.currentTime=Math.min(Math.max(o,s),Math.max(o,i-.04)),n.onUpdate?.(a,t)}function st(t,e){return Math.abs(t.currentTime-e)<1/240?ct(t):new Promise(n=>{const o=()=>{t.removeEventListener("seeked",o),n()};t.addEventListener("seeked",o,{once:!0});const r=t.fastSeek;r?r.call(t,e):t.currentTime=e})}function ct(t){const e=t.requestVideoFrameCallback;return new Promise(e?n=>{let o=!1;const r=()=>{o||(o=!0,n())};e.call(t,r),window.setTimeout(r,32)}:t=>requestAnimationFrame(()=>t()))}function lt(t,e={}){const n=ot(e.trigger)??t;t.pause();const o=e.gsap,r=e.ScrollTrigger??o?.ScrollTrigger;if(o&&r?.create){o.registerPlugin?.(r);const i=r.create({trigger:n,start:e.start??"top bottom",end:e.end??"bottom top",scrub:e.scrub??!0,onUpdate:n=>at(t,n.progress,e)});return()=>i.kill?.()}return function(t,e,n){let o=0;const r=()=>{o=0;const r=e.getBoundingClientRect(),i=window.innerHeight||document.documentElement.clientHeight,a=r.height+i,s=a>0?nt((i-r.top)/a):0;at(t,s,n)},i=()=>{o||(o=requestAnimationFrame(r))};return window.addEventListener("scroll",i,{passive:!0}),window.addEventListener("resize",i),i(),()=>{window.removeEventListener("scroll",i),window.removeEventListener("resize",i),o&&cancelAnimationFrame(o)}}(t,n,e)}function ht(t,e,n){const o=e.gsap,r=e.ScrollTrigger??o?.ScrollTrigger;if(o&&r?.create){o.registerPlugin?.(r);const i=r.create({trigger:t,start:e.start??"top bottom",end:e.end??"bottom top",scrub:e.scrub??!0,onUpdate:t=>n(t.progress)});return()=>i.kill?.()}return function(t,e){let n=0;const o=()=>{n=0;const o=t.getBoundingClientRect(),r=window.innerHeight||document.documentElement.clientHeight,i=o.height+r,a=i>0?nt((r-o.top)/i):0;e(a)},r=()=>{n||(n=requestAnimationFrame(o))};return window.addEventListener("scroll",r,{passive:!0}),window.addEventListener("resize",r),r(),()=>{window.removeEventListener("scroll",r),window.removeEventListener("resize",r),n&&cancelAnimationFrame(n)}}(t,n)}function dt(t,e,n){if(!t||!e||!n.sourceCrop)return{w:t,h:e};const o=V(n.sourceCrop,t,e);return{w:Math.max(1,Math.round(o.width)),h:Math.max(1,Math.round(o.height))}}function ft(t,e,n,o){const r=o.chromaKey;if(null==r||!1===r)return!1;if(!0===r)return e>1.4*t&&e>1.4*n&&e>80;if("blue-screen"===r)return n>1.4*t&&n>1.4*e&&n>80;const i=x(r),a=(o.chromaKeyTolerance??60)**2,s=t-i.r,c=e-i.g,l=n-i.b;return s*s+c*c+l*l<=a}function mt(t,e,n){if(!e.chromaKey||!e.sourceCrop||"off"===e.chromaKeyTrimMode)return e;const o=t instanceof HTMLVideoElement?t.videoWidth:t.width,r=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(!o||!r)return e;const i=V(e.sourceCrop,o,r),a=Math.min(360,Math.max(1,Math.round(i.width))),s=Math.max(1,Math.round(a*(i.height/i.width))),{ctx:l}=c(a,s);l.drawImage(t,i.x,i.y,i.width,i.height,0,0,a,s);const h=l.getImageData(0,0,a,s).data,d=Math.max(0,Math.min(255,e.chromaKeyTrimLuminanceThreshold??0));let f=a,m=s,u=-1,g=-1;for(let t=0;t<s;t++)for(let n=0;n<a;n++){const o=4*(t*a+n),r=h[o+3],i=h[o],s=h[o+1],c=h[o+2];r<=8||.2126*i+.7152*s+.0722*c<=d||ft(i,s,c,e)||(n<f&&(f=n),t<m&&(m=t),n>u&&(u=n),t>g&&(g=t))}if(u<f||g<m)return e;const p=Math.max(0,Math.min(.25,e.chromaKeyTrimPadding??.002)),M=Math.round(a*p),v=Math.round(s*p);f=Math.max(0,f-M),m=Math.max(0,m-v),u=Math.min(a-1,u+M),g=Math.min(s-1,g+v);const w=function(t,e,n,o,r){const i=r&&Number.isFinite(r)&&r>0?r:null;if(!i)return t;const a=e.x,s=e.y,c=e.x+e.width,l=e.y+e.height,h=Math.max(a,t.left),d=Math.max(s,t.top),f=Math.min(c,n-t.right),m=Math.min(l,o-t.bottom),u=Math.max(1,f-h),g=Math.max(1,m-d),p=h+u/2,M=d+g/2;let v=u,w=g;v/w<i?v=w*i:w=v/i;v>e.width&&(v=e.width,w=Math.max(g,Math.min(e.height,v/i)));w>e.height&&(w=e.height,v=Math.max(u,Math.min(e.width,w*i)));let y=p-v/2,x=M-w/2;return y=Math.max(a,Math.min(c-v,y)),x=Math.max(s,Math.min(l-w,x)),{left:y,top:x,right:n-(y+v),bottom:o-(x+w)}}({left:i.x+f/a*i.width,top:i.y+m/s*i.height,right:o-(i.x+(u+1)/a*i.width),bottom:r-(i.y+(g+1)/s*i.height)},{x:i.x,y:i.y,width:i.width,height:i.height},o,r,n);return{...e,sourceCrop:{unit:"pixel",...w,preserveAspect:!1}}}function ut(t){const e=t.sourceCrop;return e&&"pixel"===e.unit?void 0===e.left||void 0===e.top||void 0===e.right||void 0===e.bottom?null:{left:e.left,top:e.top,right:e.right,bottom:e.bottom}:null}async function gt(t,e,n,o,r){if(!e.chromaKey||!e.sourceCrop||"range"!==e.chromaKeyTrimMode)return e;const i=t.currentTime,a=function(t,e,n,o){const r=!0===o?{}:o||{},i=Math.max(0,r.from??e),a=r.to??n??(Number.isFinite(t.duration)?t.duration:i),s=Math.max(i,a-.04),c=Math.max(0,s-i),l=c>.1?[i,i+.25*c,i+.5*c,i+.75*c,s]:[i];return Array.from(new Set(l.map(t=>Math.max(0,Number(t.toFixed(3))))))}(t,n,o,r);let s=null;for(const n of a){await st(t,n),await ct(t);const o=ut(mt(t,e));o&&(s=s?{left:Math.min(s.left,o.left),top:Math.min(s.top,o.top),right:Math.min(s.right,o.right),bottom:Math.min(s.bottom,o.bottom)}:o)}return await st(t,i),await ct(t),s?{...e,sourceCrop:{unit:"pixel",...s,preserveAspect:!0}}:e}function pt(t,e,n=2048){return Mt({sourceWidth:t,sourceHeight:e,maxRenderDimension:n})}function Mt({sourceWidth:t,sourceHeight:e,cssWidth:n=0,cssHeight:o=0,maxRenderDimension:r=2048}){const i=Math.max(1,t),a=Math.max(1,e),s=i/a,c=Math.max(1,r),l=Math.min(1,c/Math.max(i,a)),h=Math.max(i,a)*l,d=Math.max(0,n,o),f=Math.min(c,Math.max(h,d));return s>=1?{renderW:Math.round(f),renderH:Math.round(f/s)}:{renderW:Math.round(f*s),renderH:Math.round(f)}}function vt(t,e,n,o){if(void 0===t)return;if("number"==typeof t)return t;const r=t.trim();if(r.endsWith("%")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?e*t:void 0}if(r.endsWith("px")){const t=Number.parseFloat(r);return Number.isFinite(t)?t:void 0}if(r.endsWith("vw")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?n*t:void 0}if(r.endsWith("vh")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?o*t:void 0}}function wt(t,e,n,o,r,i=2048,a={}){const{width:s,height:c}=e.getBoundingClientRect();if(!s||!c)return{renderW:0,renderH:0,dpr:1};const l="undefined"!=typeof window?window.innerWidth:s,h="undefined"!=typeof window?window.innerHeight:c,d=vt(a.width,s,l,h)??s,f=vt(a.height,c,l,h)??c,m=function(t,e,n,o,r){const i=t=>{const n=vt(t,e,o,r);return n&&n>0?n:0},a=t=>{const e=vt(t,n,o,r);return e&&e>0?e:0};return void 0===t?{x:0,y:0}:"number"==typeof t||"string"==typeof t?{x:i(t),y:a(t)}:{x:i(t.x),y:a(t.y)}}(a.bleed,s,c,l,h),u=d+2*m.x,g=f+2*m.y,{cssW:p,cssH:M}=function(t,e,n,o="contain"){if("fill"===o)return{cssW:t,cssH:e};let r=t,i=r/n;const a="cover"===o,s=i>e;return(a&&!s||!a&&s)&&(i=e,r=i*n),"scale-down"===o&&(r=Math.min(r,t),i=Math.min(i,e)),{cssW:Math.round(r),cssH:Math.round(i)}}(u,g,n,a.objectFit??"contain"),v="undefined"!=typeof window&&window.devicePixelRatio||1;let w,y;o&&r?({renderW:w,renderH:y}=Mt({sourceWidth:o,sourceHeight:r,cssWidth:p,cssHeight:M,maxRenderDimension:i})):(w=p,y=M);const x=8e6,b=w*v*y*v>x?Math.sqrt(x/(w*y)):v;return t.width=Math.round(w*b),t.height=Math.round(y*b),t.style.width=`${p}px`,t.style.height=`${M}px`,{renderW:w,renderH:y,dpr:b}}async function yt(t,e,{fontSize:o,artStyle:r="classic",options:i={}}={}){let a;if("string"==typeof t){const e=new Image;e.crossOrigin="anonymous",await new Promise((n,o)=>{e.onload=()=>n(),e.onerror=()=>o(new Error(`Failed to load image: ${t}`)),e.src=t}),a=e}else t instanceof HTMLImageElement&&!t.complete?(await new Promise((e,n)=>{t.onload=()=>e(),t.onerror=()=>n(new Error("Image failed to load"))}),a=t):a=t;const s=et(r),c=o??i.fontSize??10,l={...n,...s,artStyle:r,...i,fontSize:c},h=e.getContext("2d");if(!h)throw new Error("Could not get 2d context from canvas");const{w:d,h:f}=function(t){return t instanceof HTMLVideoElement?{w:t.videoWidth,h:t.videoHeight}:t instanceof HTMLImageElement?{w:t.naturalWidth||t.width,h:t.naturalHeight||t.height}:{w:t.width,h:t.height}}(a),{renderW:m,renderH:u}=pt(d,f),g="undefined"!=typeof window&&window.devicePixelRatio||1,p=8e6,M=m*g*u*g>p?Math.sqrt(p/(m*u)):g;e.width===Math.round(m*M)&&e.height===Math.round(u*M)||(e.width=Math.round(m*M),e.height=Math.round(u*M));const{frame:v}=D(a,l,m,u),w=(t,e)=>{h.save(),h.setTransform(M,0,0,M,0,0),Z(h,v,l,m,u,t/1e3,e),h.restore()};w(0,null);return C(e,w,{continuous:"none"!==l.animationStyle||!!l.charsetFrames?.length,interactive:l.hoverStrength>0}).stop}async function xt(t,e,{fontSize:o,artStyle:r="classic",options:i={}}={}){const a="string"==typeof t?await fetch(t).then(t=>t.arrayBuffer()):t,s=o??i.fontSize??10;let c={...n,...et(r),artStyle:r,...i,fontSize:s};const l=e.getContext("2d");if(!l)throw new Error("Could not get 2d context from canvas");const{frames:h,fps:d}=await G(a,c,e.width,e.height);if(!h.length)throw new Error("asciifyGif: the GIF contains no renderable frames.");const f=performance.now();let m=-1;return C(e,(t,n)=>{const o=Math.floor((t-f)*d/1e3)%h.length;o===m&&!n&&c.hoverStrength<=0&&"none"===c.animationStyle&&!c.charsetFrames?.length||(Z(l,h[o],c,e.width,e.height,(t-f)/1e3,n),m=o)},{continuous:!0,interactive:c.hoverStrength>0}).stop}async function bt(t,e,{fontSize:o,artStyle:r="classic",options:i={},fitTo:a,objectFit:s,objectPosition:c,scale:l,width:h,height:d,bleed:f,preExtract:m=!1,fps:u,maxRenderDimension:g=2048,trim:p,scroll:M,maxCachedFrames:v=90,onReady:w,onFrame:y}={}){const x=p?.start??0,b=p?.end,S=o??i.fontSize??10;let E={...n,...et(r),artStyle:r,...i,fontSize:S};const T=e.getContext("2d");if(!T)throw new Error("asciifyVideo: could not get 2d context from canvas.");const A="string"==typeof a?document.querySelector(a):a instanceof HTMLElement?a:null,F={objectFit:s,objectPosition:c,scale:l,width:h,height:d,bleed:f},L=function(t,e){var n;if(!function(t){return void 0!==t.objectFit||void 0!==t.objectPosition||void 0!==t.scale||void 0!==t.width||void 0!==t.height||void 0!==t.bleed}(e))return()=>{};const o={width:t.style.width,height:t.style.height,objectFit:t.style.objectFit,objectPosition:t.style.objectPosition,maxWidth:t.style.maxWidth,maxHeight:t.style.maxHeight,transformOrigin:t.style.transformOrigin,scale:t.style.getPropertyValue("scale")};if(e.objectFit&&(t.style.objectFit=e.objectFit),e.objectPosition&&(t.style.objectPosition=e.objectPosition,t.style.transformOrigin=e.objectPosition),void 0===e.scale&&void 0===e.bleed||(t.style.maxWidth="none",t.style.maxHeight="none"),void 0!==e.scale){const o=Number.isFinite(e.scale)&&e.scale>0?e.scale:1;t.style.setProperty("scale",String(o)),(n=t.style).transformOrigin||(n.transformOrigin=e.objectPosition??"center center")}return()=>{t.style.width=o.width,t.style.height=o.height,t.style.objectFit=o.objectFit,t.style.objectPosition=o.objectPosition,t.style.maxWidth=o.maxWidth,t.style.maxHeight=o.maxHeight,t.style.transformOrigin=o.transformOrigin,o.scale?t.style.setProperty("scale",o.scale):t.style.removeProperty("scale")}}(e,F),I=t=>()=>{t(),L()};if(m){let n;"string"==typeof t?(n=document.createElement("video"),n.crossOrigin="anonymous",n.src=t,n.readyState<2&&await new Promise((e,o)=>{n.onloadeddata=()=>e(),n.onerror=()=>o(new Error(`asciifyVideo: failed to load "${t}"`))})):n=t,E=await gt(n,E,x,b,M);const o=dt(n.videoWidth,n.videoHeight,E);A&&wt(e,A,o.w/o.h,o.w,o.h,g,F);const{renderW:r,renderH:i}=pt(o.w,o.h,g),a="undefined"!=typeof window&&window.devicePixelRatio||1,s=8e6,c=r*a*i*a>s?Math.sqrt(s/(r*i)):a;e.width===Math.round(r*c)&&e.height===Math.round(i*c)||(e.width=Math.round(r*c),e.height=Math.round(i*c));const l=void 0!==b?b-x:10,h=u??(M?18:void 0);if(rt(E)){const{frames:t,fps:o}=await Y(n,E,r,i,h,l,void 0,x),a=e=>{const n=t[e];n&&(T.save(),T.setTransform(c,0,0,c,0,0),N(T,n,E,r,i),T.restore(),y?.())};if(M){let o=!1,r=-1;const i=!0===M?{}:M,s=ht(ot(i.trigger)??A??e,i,e=>{const s=it(e,i),c=Math.max(0,Math.min(t.length-1,Math.round(s*(t.length-1))));c!==r&&(r=c,a(c),o||(o=!0,w?.(n)),i.onUpdate?.(s,n))});return a(0),o=!0,w?.(n),I(s)}let s,d=!1,f=0,m=performance.now(),u=!0;const g=1e3/o,p=e=>{d||(e-m>=g&&(a(f),f=(f+1)%t.length,m=e,u&&(u=!1,w?.(n))),s=requestAnimationFrame(p))};return s=requestAnimationFrame(p),I(()=>{d=!0,cancelAnimationFrame(s)})}const{frames:d,fps:f}=await U(n,E,r,i,h,l,void 0,x);if(!d.length)throw new Error("asciifyVideo: no frames were decoded.");let m=0;const p=performance.now(),v=C(e,(t,e)=>{M||(m=Math.floor((t-p)*f/1e3)%d.length),T.save(),T.setTransform(c,0,0,c,0,0),Z(T,d[m],E,r,i,(t-p)/1e3,e),T.restore(),y?.()},{continuous:!M||"none"!==E.animationStyle||!!E.charsetFrames?.length,interactive:E.hoverStrength>0});let S;if(M){const t=!0===M?{}:M;S=ht(ot(t.trigger)??A??e,t,e=>{m=Math.max(0,Math.min(d.length-1,Math.round(it(e,t)*(d.length-1)))),v.wake(),t.onUpdate?.(e,n)})}return w?.(n),I(()=>{v.stop(),S?.()})}let R,k=!1;"string"==typeof t?(R=document.createElement("video"),R.crossOrigin="anonymous",R.src=t,R.muted=!0,R.loop=!0,R.playsInline=!0,R.setAttribute("playsinline",""),Object.assign(R.style,{position:"fixed",top:"0",left:"0",width:"1px",height:"1px",opacity:"0",pointerEvents:"none",zIndex:"-1"}),document.body.appendChild(R),k=!0,await new Promise((e,n)=>{R.onloadedmetadata=()=>e(),R.onerror=()=>n(new Error(`asciifyVideo: failed to load "${t}"`))}),await R.play().catch(()=>{})):(R=t,R.readyState<HTMLMediaElement.HAVE_METADATA&&await new Promise((t,e)=>{const n=()=>{R.removeEventListener("loadedmetadata",o),R.removeEventListener("error",r)},o=()=>{n(),t()},r=()=>{n(),e(new Error("asciifyVideo: provided video element failed to load metadata."))};R.addEventListener("loadedmetadata",o),R.addEventListener("error",r),R.load()}),R.paused&&await R.play().catch(()=>{})),x>0&&(R.currentTime=x,await new Promise(t=>{const e=()=>{R.removeEventListener("seeked",e),t()};R.addEventListener("seeked",e)}),await ct(R));let H=null;(x>0||void 0!==b)&&(H=()=>{(void 0!==b&&R.currentTime>=b||x>0&&R.currentTime<x)&&(R.currentTime=x)},R.addEventListener("timeupdate",H)),E=await gt(R,E,x,b,M);let W=null;const $=dt(R.videoWidth,R.videoHeight,E);let{renderW:P,renderH:j}=pt($.w,$.h,g);const z=t=>"frame"===E.chromaKeyTrimMode?mt(t,E,P/j):E;if(A){const t=$.w/$.h,n=$.w,o=$.h,r=wt(e,A,t,n,o,g,F);P=r.renderW,j=r.renderH;const i=e.getContext("2d");i&&i.setTransform(r.dpr,0,0,r.dpr,0,0),W=new ResizeObserver(()=>{const r=wt(e,A,t,n,o,g,F);P=r.renderW,j=r.renderH;const i=e.getContext("2d");i&&i.setTransform(r.dpr,0,0,r.dpr,0,0)}),W.observe(A)}else{const t="undefined"!=typeof window&&window.devicePixelRatio||1,n=8e6,o=P*t*j*t>n?Math.sqrt(n/(P*j)):t;e.width===Math.round(P*o)&&e.height===Math.round(j*o)||(e.width=Math.round(P*o),e.height=Math.round(j*o)),T.setTransform(o,0,0,o,0,0)}let O=!0,q=null;const B=M&&!m,V=u&&u>0?1e3/u:0;let G=0;const X=!B&&rt(E);if(B&&"ascii"===E.renderMode&&"none"===E.animationStyle&&E.hoverStrength<=0&&!E.charsetFrames?.length){const t=!0===M?{}:M,n=ot(t.trigger)??A??e,o=t.from??x,r=t.to??b??R.duration,i=Math.max(o,Math.min(r,R.duration)),a=Math.max(.001,i-o),s=Math.min(60,Math.max(12,u??30)),c=Math.max(2,Math.ceil(a*s)+1),l=new Array(c),h=[],d=Math.max(2,Math.min(c,Math.floor(v))),f=()=>{for(;h.length>d;){const t=h.findIndex(t=>t!==g&&Math.abs(t-g)>2),e=t>=0?t:0,n=h.splice(e,1)[0];void 0!==n&&(l[n]=void 0)}},m=t=>{const e=h.indexOf(t);e>=0&&h.splice(e,1),h.push(t),f()};let g=0,p=0,S=-1,C=0,F=!1,L=!1,$=!1;const O=new Set,B=document.createElement("video");B.muted=!0,B.playsInline=!0,B.preload="auto",B.crossOrigin=R.crossOrigin||"anonymous",B.src=R.currentSrc||R.src,Object.assign(B.style,{position:"fixed",top:"0",left:"0",width:"1px",height:"1px",opacity:"0",pointerEvents:"none",zIndex:"-1"}),document.body.appendChild(B),B.readyState<HTMLMediaElement.HAVE_METADATA&&await new Promise((t,e)=>{const n=()=>{B.removeEventListener("loadedmetadata",o),B.removeEventListener("error",r)},o=()=>{n(),t()},r=()=>{n(),e(new Error("asciifyVideo: cache video failed to load metadata."))};B.addEventListener("loadedmetadata",o),B.addEventListener("error",r),B.load()}),B.pause(),R.paused&&await R.play().catch(()=>{});const D=t=>o+a*t/Math.max(1,c-1),U=t=>Math.max(0,Math.min(c-1,Math.round(t*(c-1)))),Y=z(R),X=K(R,Y,P,j);X.rows.length>0&&(l[0]=X,m(0),N(T,X,Y,P,j),$=!0,w?.(R),y?.());const _=t=>{if(l[t])return t;for(let e=1;e<c;e++){const n=t-e,o=t+e;if(n>=0&&l[n])return n;if(o<c&&l[o])return o}return-1},J=()=>{if(!l[g])return g;for(const t of O)if(!l[t])return t;for(let t=1;t<c;t++){const e=g-t,n=g+t;if(e>=0&&!l[e])return e;if(n<c&&!l[n])return n}return-1},Q=t=>{t<0||t>=c||l[t]||(O.add(t),Z())},Z=async()=>{if(F||L)return;const t=J();if(!(t<0)){O.delete(t),L=!0;try{if(await st(B,D(t)),!F){const e=z(B),n=K(B,e,P,j);n.rows.length>0&&(l[t]=n,m(t))}}finally{L=!1,F||requestAnimationFrame(()=>{Z()})}}},tt=()=>{if(F)return;const t=_(g);if(t>=0&&t!==S){const e=l[t];e&&(N(T,e,E,P,j),S=t,$||($=!0,w?.(R)),y?.())}else if(t<0||S<0){const t=performance.now();if(V<=0||t-G>=V){const e=z(R),n=K(R,e,P,j);n.rows.length>0&&(N(T,n,e,P,j),G=t,$||($=!0,w?.(R)),y?.())}}Q(g),C=requestAnimationFrame(tt)};return q=ht(n,t,e=>{const n=function(t,e,n={}){if(!Number.isFinite(t.duration)||t.duration<=0)return null;const o=n.from??0,r=n.to??t.duration,i=Math.max(o,Math.min(r,t.duration)),a=it(e,n),s=o+(i-o)*a;return{progress:a,time:Math.min(Math.max(o,s),Math.max(o,i-.04))}}(R,e,{...t,from:o,to:i});p=n?.progress??nt(e),g=U(p),Q(g),Q(g-1),Q(g+1),Q(g-2),Q(g+2),Q(g-3),Q(g+3),t.onUpdate?.(p,R)}),Q(0),Q(1),C=requestAnimationFrame(tt),I(()=>{F=!0,cancelAnimationFrame(C),q?.(),W?.disconnect(),O.clear(),h.length=0,l.fill(void 0),B.pause(),B.src="",B.removeAttribute("src"),B.load(),B.isConnected&&B.remove(),H&&R.removeEventListener("timeupdate",H),k&&(R.pause(),R.src="",R.removeAttribute("src"),R.load(),R.isConnected&&R.remove())})}if(B){const t=!0===M?{}:M;q=lt(R,{...t,trigger:t.trigger??A??e,from:t.from??x,to:t.to??b})}let _=-1,J=0,Q=-1,tt=0;const at="function"==typeof R.requestVideoFrameCallback,ft=()=>{tt=R.requestVideoFrameCallback(()=>{J++,ft()})};at&&ft();let ut=0,Mt=0,vt=null;const yt=C(e,(t,n)=>{if(R.readyState<2||0===e.width||0===e.height)return;if(V>0&&t-G<V&&!n)return;if(x>0&&R.currentTime<x)return;if(void 0!==b&&R.currentTime>=b)return;const o=(at?J!==Q:R.currentTime!==_)||ut!==P||Mt!==j;if(o||!(E.hoverStrength<=0)||"none"!==E.animationStyle||E.charsetFrames?.length){if(X){const t=z(R),e=K(R,t,P,j);N(T,e,t,P,j)}else!o&&vt||(vt=D(R,z(R),P,j).frame),Z(T,vt,E,P,j,t/1e3,n);_=R.currentTime,Q=J,ut=P,Mt=j,G=t,O&&(O=!1,w?.(R)),y?.()}},{continuous:!0,interactive:E.hoverStrength>0});return I(()=>{yt.stop(),tt&&R.cancelVideoFrameCallback(tt),q?.(),W?.disconnect(),H&&R.removeEventListener("timeupdate",H),k&&(R.pause(),R.src="",R.removeAttribute("src"),R.load(),R.isConnected&&R.remove())})}function St(t,e,n){return bt(t,e,n)}function Et(t,e={},o,r){const i={...n,...e},{frame:a,cols:s}=D(t,i,o,r);if(!a.length||0===s)return"";const c=[];for(const t of a)c.push(t.map(t=>t.char).join(""));return c.join("\n")}function Ct(t,e={},o,r){const i={...n,...e},{frame:a,cols:s}=D(t,i,o,r);if(!a.length||0===s)return"";const c=[];for(const t of a){let e="";for(const n of t)" "===n.char||n.a<10?e+=" ":e+=`[38;2;${n.r};${n.g};${n.b}m${n.char}[0m`;c.push(e)}return c.join("\n")}function Tt(t,e,n,o="#505050",r=100){if(!t||e<=0||n<=0)return[];const i=function(t){const e=t.match(/^#([0-9a-f]{3,8})$/i)?.[1];if(e){const t=e.length<=4?e.split("").map(t=>parseInt(t+t,16)):[parseInt(e.slice(0,2),16),parseInt(e.slice(2,4),16),parseInt(e.slice(4,6),16)];return{r:t[0],g:t[1],b:t[2]}}const n=t.match(/rgba?\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)/i);return n?{r:+n[1],g:+n[2],b:+n[3]}:null}(o)??{r:80,g:80,b:80},a=t,s=a.length;return Array.from({length:n},(t,n)=>Array.from({length:e},(t,o)=>({char:a[(n*e+o)%s],r:i.r,g:i.g,b:i.b,a:r})))}var At=new WeakMap;function Ft(t,e,o,r,i={},a){const{fontSize:s=10,lineHeight:c=1.6,color:l="#505050",opacity:h=100,hoverEffect:d="spotlight",hoverStrength:f=.85,hoverRadius:m=.18,hoverColor:u="#d4ff00"}=i,g=Math.max(1,Math.floor(e/s)),p=Math.max(1,Math.floor(o/(s*c))),M=JSON.stringify([r,g,p,l,h]);let v=At.get(t);v&&v.key===M||(v={key:M,frame:Tt(r,g,p,l,h)},At.set(t,v));Z(t,v.frame,{...n,fontSize:s,hoverEffect:d,hoverStrength:f,hoverRadius:m,hoverColor:u},e,o,0,a??null)}function Lt(t,{format:e="png",quality:n=.92,scale:o=1}={}){return new Promise((r,i)=>{let a=t;if(1!==o){const e=document.createElement("canvas");e.width=Math.round(t.width*o),e.height=Math.round(t.height*o);const n=e.getContext("2d");if(!n)return void i(new Error("captureSnapshot: could not get 2d context"));n.drawImage(t,0,0,e.width,e.height),a=e}a.toBlob(t=>t?r(t):i(new Error("captureSnapshot: toBlob returned null")),`image/${e}`,n)})}async function It(t,e={}){const{filename:n="asciify-snapshot",format:o="png",...r}=e,i=await Lt(t,{format:o,...r}),a="jpeg"===o?"jpg":o,s=document.createElement("a");s.href=URL.createObjectURL(i),s.download=`${n}.${a}`,s.click(),setTimeout(()=>URL.revokeObjectURL(s.href),1e4)}async function Rt(t,{fontSize:e=10,style:o="classic",options:r={},liveOptions:i,mirror:a=!0,constraints:s={facingMode:"user"},dpr:c}={}){if(!navigator.mediaDevices?.getUserMedia)throw new Error("asciifyWebcam: getUserMedia is not supported in this browser.");const l=et(o),h=await navigator.mediaDevices.getUserMedia({video:s}),d=document.createElement("video");d.srcObject=h,d.muted=!0,d.playsInline=!0,await new Promise((t,e)=>{d.onloadedmetadata=()=>t(),d.onerror=()=>e(new Error("asciifyWebcam: video stream failed to load.")),d.play().catch(e)});const f={...n,...l,...r,fontSize:e},m=t.getContext("2d");if(!m)throw new Error("asciifyWebcam: could not get 2d context from canvas.");const u=c??("undefined"!=typeof window?window.devicePixelRatio:1)??1;1!==u&&m.scale(u,u);let g=null;const p=e=>{const n=t.getBoundingClientRect();g={x:(e.clientX-n.left)/n.width,y:(e.clientY-n.top)/n.height}},M=()=>{g=null};f.hoverStrength>0&&(t.addEventListener("mousemove",p),t.addEventListener("mouseleave",M));let v,w=!1;const y=performance.now(),x=e=>{if(!w){if(d.readyState>=d.HAVE_CURRENT_DATA){const n=t.width/u,o=t.height/u,r=(e-y)/1e3,s=i?{...f,...i()}:f;s.hoverStrength>0?(t.addEventListener("mousemove",p),t.addEventListener("mouseleave",M)):(t.removeEventListener("mousemove",p),t.removeEventListener("mouseleave",M));const{frame:c}=D(d,s,n,o),l=g&&a?{x:1-g.x,y:g.y}:g;a?(m.save(),m.scale(-1,1),m.translate(-n,0),Z(m,c,s,n,o,r,l),m.restore()):Z(m,c,s,n,o,r,l)}v=requestAnimationFrame(x)}};return v=requestAnimationFrame(x),()=>{w=!0,cancelAnimationFrame(v),t.removeEventListener("mousemove",p),t.removeEventListener("mouseleave",M),h.getTracks().forEach(t=>t.stop()),d.srcObject=null}}var kt={A:[28,54,99,127,99,99,99],B:[126,99,99,126,99,99,126],C:[62,99,96,96,96,99,62],D:[124,102,99,99,99,102,124],E:[127,96,96,124,96,96,127],F:[127,96,96,124,96,96,96],G:[62,99,96,111,99,99,62],H:[99,99,99,127,99,99,99],I:[127,8,8,8,8,8,127],J:[63,6,6,6,102,102,60],K:[99,102,108,120,108,102,99],L:[96,96,96,96,96,96,127],M:[99,119,107,107,99,99,99],N:[99,115,107,103,99,99,99],O:[62,99,99,99,99,99,62],P:[126,99,99,126,96,96,96],Q:[62,99,99,99,107,102,61],R:[126,99,99,126,108,102,99],S:[62,99,96,62,3,99,62],T:[127,8,8,8,8,8,8],U:[99,99,99,99,99,99,62],V:[99,99,99,99,54,28,8],W:[99,99,99,107,107,54,20],X:[99,54,28,8,28,54,99],Y:[99,99,54,28,8,8,8],Z:[127,3,6,12,24,48,127],a:[0,0,60,3,62,99,61],b:[96,96,124,99,99,99,124],c:[0,0,62,96,96,96,62],d:[3,3,31,99,99,99,31],e:[0,0,62,99,127,96,62],f:[30,48,48,126,48,48,48],g:[0,0,63,99,63,3,62],h:[96,96,124,99,99,99,99],i:[8,0,24,8,8,8,28],j:[4,0,12,4,4,36,24],k:[96,96,102,108,120,108,102],l:[24,8,8,8,8,8,28],m:[0,0,92,107,107,99,99],n:[0,0,94,99,99,99,99],o:[0,0,62,99,99,99,62],p:[0,0,126,99,126,96,96],q:[0,0,63,99,63,3,3],r:[0,0,94,99,96,96,96],s:[0,0,62,96,62,3,124],t:[48,48,126,48,48,48,30],u:[0,0,99,99,99,103,59],v:[0,0,99,99,54,28,8],w:[0,0,99,99,107,54,20],x:[0,0,99,54,28,54,99],y:[0,0,99,99,63,3,62],z:[0,0,127,6,12,24,127],0:[62,99,103,107,115,99,62],1:[8,24,56,8,8,8,62],2:[62,99,3,6,24,48,127],3:[62,99,3,30,3,99,62],4:[6,14,22,38,127,6,6],5:[127,96,126,3,3,99,62],6:[62,99,96,126,99,99,62],7:[127,3,6,12,24,24,24],8:[62,99,99,62,99,99,62],9:[62,99,99,63,3,99,62]," ":[0,0,0,0,0,0,0],"!":[24,24,24,24,24,0,24],"?":[62,99,3,14,8,0,8],".":[0,0,0,0,0,24,24],",":[0,0,0,0,0,24,48],";":[0,24,24,0,24,24,48],":":[0,24,24,0,24,24,0],"-":[0,0,0,62,0,0,0],_:[0,0,0,0,0,0,127],"'":[24,24,32,0,0,0,0],'"':[54,54,36,0,0,0,0],"`":[24,8,0,0,0,0,0],")":[24,12,6,6,6,12,24],"(":[12,24,48,48,48,24,12],"[":[60,48,48,48,48,48,60],"]":[30,6,6,6,6,6,30],"{":[14,24,24,48,24,24,14],"}":[56,12,12,6,12,12,56],"/":[3,6,12,24,48,96,0],"\\":[96,48,24,12,6,3,0],"|":[8,8,8,8,8,8,8],"+":[0,8,8,62,8,8,0],"=":[0,0,62,0,62,0,0],"*":[0,42,28,127,28,42,0],"#":[36,36,127,36,127,36,36],"@":[62,99,111,107,111,96,62],"&":[24,36,24,60,74,68,58],"%":[99,38,4,8,16,50,99],$:[8,62,72,62,9,62,8],"^":[8,20,34,0,0,0,0],"~":[0,0,50,76,0,0,0],"<":[6,12,24,48,24,12,6],">":[48,24,12,6,12,24,48]},Ht=[127,65,65,65,65,65,127];function Wt(t){return kt[t]??kt[t.toUpperCase()]??Ht}function $t(t,e={}){if(!t)return"";const{char:n="█",scale:o=1}=e,r=[...n][0]??"█",i=Math.max(1,Math.floor(o)),a=7*i,s=i,c=Array.from({length:a},()=>"");for(let e=0;e<t.length;e++){const n=Wt(t[e]);for(let t=0;t<7;t++){const e=n[t];let o="";for(let t=6;t>=0;t--)o+=(e>>t&1?r:" ").repeat(i);for(let e=0;e<i;e++)c[t*i+e]+=o}if(e<t.length-1)for(let t=0;t<a;t++)c[t]+=" ".repeat(s)}return c.join("\n")}function Pt(t,e,n={}){const{color:o="#d4ff00",bgColor:r,fontSize:i=10}=n,a=$t(e,n);if(!a)return;const s=a.split("\n"),c=Math.max(...s.map(t=>[...t].length));t.width=Math.ceil(c*i*.6),t.height=Math.ceil(s.length*i);const l=t.getContext("2d");r&&"transparent"!==r?(l.fillStyle=r,l.fillRect(0,0,t.width,t.height)):l.clearRect(0,0,t.width,t.height),l.fillStyle=o,l.font=`${i}px monospace`,l.textBaseline="top",s.forEach((t,e)=>l.fillText(t,0,e*i))}var jt=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk"];export{t as CHARACTER_SETS,n as DEFAULT_OPTIONS,o as HOVER_PRESETS,e as PALETTE_THEMES,jt as STUDIO_STYLES,Et as asciiText,Ct as asciiTextAnsi,yt as asciify,xt as asciifyGif,St as asciifyLiveVideo,$t as asciifyText,bt as asciifyVideo,Rt as asciifyWebcam,Tt as buildTextFrame,Lt as captureSnapshot,j as clearAsciifyCaches,Mt as computeCanvasRenderSize,lt as createVideoScrollScrub,G as gifToAsciiFrames,X as gifToAsciiTextFrames,D as imageToAsciiFrame,K as imageToAsciiTextFrame,Z as renderFrameToCanvas,Ft as renderTextBackground,N as renderTextFrameToCanvas,Pt as renderTextToCanvas,It as snapshotAndDownload,U as videoToAsciiFrames,Y as videoToAsciiTextFrames};//# sourceMappingURL=core.js.map
|
package/dist/hover.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";function t(t,e,i=()=>{}){const s=Array.isArray(e)?e:[e],n=document.createElement("canvas"),a=n.getContext("2d");let o,r=!0,h=!1,l=0;const c=()=>{h||(r=!0,i())},d=new ResizeObserver(c);d.observe(t),s.forEach(t=>d.observe(t));const f=new MutationObserver(c);return s.forEach(t=>f.observe(t,{subtree:!0,childList:!0,characterData:!0,attributes:!0})),document.fonts?.addEventListener("loadingdone",c),document.fonts?.ready.then(c),window.addEventListener("resize",c),{invalidate:c,read(){if(h)return;if(!r)return o;r=!1;const e=t.getBoundingClientRect(),i=Math.min(devicePixelRatio||1,1.5,Math.sqrt(4e6/Math.max(1,e.width*e.height)));n.width=Math.max(1,Math.round(e.width*i)),n.height=Math.max(1,Math.round(e.height*i)),a.setTransform(i,0,0,i,0,0),a.fillStyle="#fff",a.textBaseline="alphabetic";for(const t of s){const i=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(let t=i.nextNode();t;t=i.nextNode()){const i=t.parentElement;if(!i)continue;const s=getComputedStyle(i);if("hidden"===s.visibility||"none"===s.display)continue;a.font=`${s.fontStyle} ${s.fontWeight} ${s.fontSize} ${s.fontFamily}`;const n=a.measureText("Hg"),o=n.fontBoundingBoxAscent??.8*parseFloat(s.fontSize),r=n.fontBoundingBoxDescent??.2*parseFloat(s.fontSize),h=t.textContent??"",l=document.createRange();let c=0;for(const i of h){if(l.setStart(t,c),c+=i.length,l.setEnd(t,c),/\s/.test(i))continue;const s=l.getBoundingClientRect();s.width&&s.height&&a.fillText(i,s.left-e.left,s.top-e.top+(s.height-o-r)/2+o)}}}return o={canvas:n,revision:++l},o},destroy(){h=!0,d.disconnect(),f.disconnect(),document.fonts?.removeEventListener("loadingdone",c),window.removeEventListener("resize",c),n.width=n.height=1,o=void 0}}}var e=[{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."}];function i(t){return e.find(e=>e.value===t||e.mode===t)?.mode??"none"}var s=(t,e,i)=>{const s=(t=>Math.max(0,Math.min(1,t)))((i-t)/(e-t));return s*s*(3-2*s)},n=(t,e)=>{const i=(.06711056*t+.00583715*e)%1*52.9829189;return i-Math.floor(i)},a=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,i,a,o){if(o[0]=o[1]=o[2]=0,o[3]=1,"none"===t)return o;const r=a*Math.PI/6,h=s(0,.12,Math.min(e,1-e,i,1-i));if("caustics"===t){const t=Math.sin(9*e+5*i+r)+Math.sin(8*i-3*e-r),s=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);o[2]=(.22*s-.045)*h}else if("current"===t)o[0]=Math.sin(9*i+r)*Math.cos(7*e-r)*10*h,o[1]=Math.cos(8*e+r)*Math.sin(6*i-r)*7*h;else if("reform"===t){const t=(a%12+12)%12,l=n(Math.floor(160*e),Math.floor(100*i)),c=.65*e+.2*i+.15*l+.08*Math.sin(8*e-5*i),d=s(1.8+1.2*c,3.8+1.2*c,t)*(1-s(5+1.7*c,7.2+1.7*c,t));o[0]=Math.sin(9*i+r)*d*(1-d)*24*h,o[1]=-d*(1-d)*(8+12*l)*h,o[2]=.45*-d,o[3]=1-.9*d}return o}function r(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)),n=Math.max(0,Math.min(1,(s-.035)/.105));return n*n*n*(n*(6*n-15)+10)}var h=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]=r(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 n=this.width,a=this.height,o=Math.max(1,n/a),r=Math.max(1,a/n),h=s?(t-s.x)*o:0,l=s?(e-s.y)*r:0,c=Math.hypot(h,l);if(!s&&"dissolve"!==this.mode)return;if(s&&c<1e-4)return;const d=.035+.11*Math.max(.1,Math.min(1,i)),f=Math.min(128,Math.max(1,Math.ceil(c/(.45*d)))),m=c?h/c:1,u=c?l/c:0,g=Math.min(1,c/(d*f)*2.2);for(let i=0;i<f;i++){const h=(i+.5)/f,l=s?s.x+(t-s.x)*h:t,c=s?s.y+(e-s.y)*h:e,p=Math.max(0,Math.floor((l-2.5*d/o)*(n-1))),x=Math.min(n-1,Math.ceil((l+2.5*d/o)*(n-1))),v=Math.max(0,Math.floor((c-2.5*d/r)*(a-1))),M=Math.min(a-1,Math.ceil((c+2.5*d/r)*(a-1)));for(let t=v;t<=M;t++)for(let e=p;e<=x;e++){const i=(e/(n-1)-l)*o/d,s=(t/(a-1)-c)*r/d,h=Math.exp(1.5*-(i*i+s*s)),f=t*n+e;if("dissolve"===this.mode)this.ink[f]=Math.max(this.ink[f],h);else{const t=(-i*u+s*m)*h*2.8,e="silk"===this.mode?m*t:-s*h*2.5,n="silk"===this.mode?u*t:i*h*2.5;this.targetX[f]=Math.max(-1,Math.min(1,this.targetX[f]+e*g)),this.targetY[f]=Math.max(-1,Math.min(1,this.targetY[f]+n*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),s=1-Math.exp(-22*e);let n=0;for(let t=0;t<this.ink.length;t++)if("dissolve"===this.mode){this.ink[t]*=i,n=Math.max(n,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,n=Math.max(n,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),a=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]=a>>>8,this.pixels[4*t+3]=255&a}this.peak=n,this.active||this.clear()}sample(t,e,i){const s=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),n=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),a=Math.floor(s),o=Math.floor(n),h=s-a,l=n-o,c=o*this.width+a,d=c+this.width,f=t=>(t[c]*(1-h)+t[c+1]*h)*(1-l)+(t[d]*(1-h)+t[d+1]*h)*l;i[0]=f(this.offsetX)*(this.edgeSafe?r(t,e,this.width/this.height):1)*.08,i[1]=f(this.offsetY)*(this.edgeSafe?r(t,e,this.width/this.height):1)*.08,i[2]="dissolve"===this.mode?6*-f(this.ink):0}},l=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),n=Math.max(1,this.height/this.width);this.previous&&(Math.hypot((t-this.previous.x)*s,(e-this.previous.y)*n)<.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 n=0;for(const a of this.rings){const o=.015+a.age*(.15+.22*a.radius),r=.009+.014*a.radius,h=(Math.hypot((t-a.x)*i,(e-a.y)*s)-o)/r,l=Math.sin(Math.min(1,a.age/.07)*Math.PI/2)*Math.max(0,1-a.age/1.35)**2;n=Math.max(n,Math.exp(-h*h)*l)}return n}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 n=t*this.width+e;this.echo[n]=Math.max(this.ringSample(e/(this.width-1),t/(this.height-1)),this.echo[n]*i),s=Math.max(s,this.echo[n]);const a=Math.round(65535*this.echo[n]),o=4*n;this.pixels[o]=a>>>8,this.pixels[o+1]=255&a}this.echoPeak=s,this.active||(this.echo.fill(0),this.pixels.fill(0))}},c=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 n=this.previous;if(this.previous={x:t,y:e,time:s},!n)return;const a=(t-n.x)*(this.width-1),o=(e-n.y)*(this.height-1),r=Math.hypot(a,o);if(r<.001)return;const h=Math.min(this.width,this.height),l=s>n.time?Math.max(1/240,(s-n.time)/1e3):1/60,c=Math.min(12,r/h/l),d=1-Math.exp(-c/2.2),f=h*(.022+.075*i)*(.65+.95*d),m=Math.min(128,Math.max(1,Math.ceil(r/(.4*f)))),u=r/f*(.32+.22*d)/m,g=a/r,p=o/r,x=-p,v=g,M=r*(2+18*d)/m;for(let i=0;i<m;i++){const s=(i+.5)/m,a=(n.x+(t-n.x)*s)*(this.width-1),o=(n.y+(e-n.y)*s)*(this.height-1),r=Math.max(1,Math.floor(a-3*f)),h=Math.min(this.width-2,Math.ceil(a+3*f)),l=Math.max(1,Math.floor(o-3*f)),c=Math.min(this.height-2,Math.ceil(o+3*f));for(let t=l;t<=c;t++)for(let e=r;e<=h;e++){const i=((e-a)*g+(t-o)*p)/f,s=((e-a)*x+(t-o)*v)/f,n=Math.exp(-i*i*.65-s*s*1.7),r=t*this.width+e;this.ink[r]=1-(1-this.ink[r])*Math.exp(-n*u);const h=1-s*s*.55,l=i*s*.7;this.u[r]=Math.max(-80,Math.min(80,this.u[r]+(g*h+x*l)*n*M)),this.v[r]=Math.max(-80,Math.min(80,this.v[r]+(p*h+v*l)*n*M))}}this.peak=1}read(t,e,i){const s=0|(e=Math.max(.5,Math.min(this.width-1.5,e))),n=0|(i=Math.max(.5,Math.min(this.height-1.5,i))),a=e-s,o=i-n,r=n*this.width+s;return(t[r]*(1-a)+t[r+1]*a)*(1-o)+(t[r+this.width]*(1-a)+t[r+this.width+1]*a)*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,s=this.height;for(;e>1e-7;){const t=Math.min(1/60,e);e-=t;const n=Math.exp(-1.9*t),a=Math.exp(-3.2*t);for(let e=1;e<s-1;e++)for(let o=1;o<i-1;o++){const r=e*i+o,h=Math.max(.5,Math.min(i-1.5,o-this.u[r]*t)),l=Math.max(.5,Math.min(s-1.5,e-this.v[r]*t)),c=0|h,d=0|l,f=h-c,m=l-d,u=d*i+c,g=(1-f)*(1-m),p=f*(1-m),x=(1-f)*m,v=f*m;this.a[r]=(this.u[u]*g+this.u[u+1]*p+this.u[u+i]*x+this.u[u+i+1]*v)*n,this.b[r]=(this.v[u]*g+this.v[u+1]*p+this.v[u+i]*x+this.v[u+i+1]*v)*n,this.c[r]=(this.ink[u]*g+this.ink[u+1]*p+this.ink[u+i]*x+this.ink[u+i+1]*v)*a}[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 n=e*i+s,a=Math.abs(this.curl[n+1])-Math.abs(this.curl[n-1]),o=Math.abs(this.curl[n+i])-Math.abs(this.curl[n-i]),r=Math.hypot(a,o)+1e-4,h=this.curl[n]*t*10,l=Math.hypot(this.u[n],this.v[n]);this.u[n]+=o/r*h,this.v[n]-=a/r*h;const c=Math.min(1,l/(Math.hypot(this.u[n],this.v[n])+1e-6));this.u[n]*=c,this.v[n]*=c,this.divergence[n]=-.5*(this.u[n+1]-this.u[n-1]+this.v[n+i]-this.v[n-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 o=0;for(let e=1;e<s-1;e++)for(let s=1;s<i-1;s++){const n=e*i+s;this.u[n]=Math.max(-80,Math.min(80,this.u[n]-.5*(this.pressure[n+1]-this.pressure[n-1]))),this.v[n]=Math.max(-80,Math.min(80,this.v[n]-.5*(this.pressure[n+i]-this.pressure[n-i]))),this.driftX[n]+=(3.6*this.u[n]-58*this.offsetX[n]-12*this.driftX[n])*t,this.driftY[n]+=(3.6*this.v[n]-58*this.offsetY[n]-12*this.driftY[n])*t,this.offsetX[n]=Math.max(-2,Math.min(2,this.offsetX[n]+this.driftX[n]*t)),this.offsetY[n]=Math.max(-2,Math.min(2,this.offsetY[n]+this.driftY[n]*t)),this.signal[n]=1-Math.exp(.06*-Math.hypot(this.u[n],this.v[n])-.16*this.ink[n]),o=Math.max(o,this.signal[n])}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()}},d=t=>["trail","contour","dissolve"].includes(t);function f(t,e,i){const s=Math.max(0,e-1),n=1-Math.exp(3.5*-Math.max(0,i));return Math.max(0,s-Math.abs(s-(t+n*s*2.1)))}function m(t,e,i,s,n,a,o,r,h,l,c,d=!1){const m=Math.min(n,a,i-1-n,s-1-a),u=Math.max(0,Math.min(1,(m-1)/4)),g=d?u*u*(3-2*u):1;o*=g;const p=1-Math.exp(3.5*-Math.max(0,o)),x=Math.max(0,Math.min(i-1,n-r*p*.026*i*g)),v=Math.max(0,Math.min(s-1,a-h*p*.026*s*g)),M=Math.floor(x),y=Math.floor(v),w=x-M,S=v-y;c.fill(0);for(let n=0;n<2;n++)for(let a=0;a<2;a++){const o=4*(Math.min(s-1,y+n)*i+Math.min(i-1,M+a)),r=(a?w:1-w)*(n?S:1-S);c[0]+=(t[o]+256*t[o+1])*r,c[1]+=t[o+2]/255*r;for(let t=0;t<4;t++)c[t+2]+=e[o+t]*r}const b=43758.5453*Math.sin(127.1*n+311.7*a),E=b-Math.floor(b);c[0]=Math.max(0,f(c[0],l,o)-p*(1-p)*E*3)}var u=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]=r(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 c(this.columns,this.rows),this.contour=new l(this.columns,this.rows),this.afterimage=new h(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"].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||this.afterimage.setMode(t),this.refraction.pixels="trail"===t?this.trail.pixels:"contour"===t?this.contour.pixels:["dissolve","silk","vortex"].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: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: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"].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 n=(t-s.x)*this.xScale,a=(e-s.y)*this.yScale,o=Math.hypot(n,a);if(o<1e-5)return;const r=.035+.1*this.radius,h=3*r,l=Math.min(192,Math.max(1,Math.ceil(o/(.5*r)))),c=95*Math.min(o,1)/l;for(let i=0;i<l;i++){const n=(i+.5)/l,a=s.x+(t-s.x)*n,o=s.y+(e-s.y)*n,d=Math.max(1,Math.floor((a-h/this.xScale)*(this.columns-1))),f=Math.min(this.columns-2,Math.ceil((a+h/this.xScale)*(this.columns-1))),m=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=m;t<=u;t++)for(let e=d;e<=f;e++){const i=(e/(this.columns-1)-a)*this.xScale,s=(t/(this.rows-1)-o)*this.yScale,n=Math.exp(-(i*i+s*s)/(r*r))*c,h=t*this.columns+e;this.velocity[h]=Math.max(-12,this.velocity[h]-n)}}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"].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 n=1;n<this.rows-1;n++)for(let a=1;a<this.columns-1;a++){const o=n*this.columns+a,r=this.heights[o],h=this.heights[o-1]+this.heights[o+1]+this.heights[o-this.columns]+this.heights[o+this.columns]-4*r,l=Math.min(a,n,this.columns-1-a,this.rows-1-n),c=l<5?.88+.024*l:1,d=(this.velocity[o]+(h*s*s-8*r)*e)*i*c;this.velocity[o]=d,this.next[o]=(r+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 n=.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)])*n,a=(this.heights[Math.max(0,t-1)*this.columns+e]-this.heights[Math.min(this.rows-1,t+1)*this.columns+e])*n,o=Math.tanh(s)*(this.refraction.edgeSafe?this.edgeMask[i]:1),r=Math.tanh(a)*(this.refraction.edgeSafe?this.edgeMask[i]:1);this.normals[2*i]=o,this.normals[2*i+1]=r;const h=Math.round(32767*o+32768),l=Math.round(32767*r+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"].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))),n=Math.max(0,Math.min(this.rows-1.001,e*(this.rows-1))),a=Math.floor(s),o=Math.floor(n),r=s-a,h=n-o,l=2*(o*this.columns+a),c=l+2*this.columns;for(let t=0;t<2;t++)i[t]=.08*((this.normals[l+t]*(1-r)+this.normals[l+2+t]*r)*(1-h)+(this.normals[c+t]*(1-r)+this.normals[c+2+t]*r)*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[n,a,o,r]=i.focus,h=(t-n)*Math.max(1,s)/r,l=(e-a)*Math.max(1,1/s)/r;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}};var g=[{value:"clean",label:"Clean",description:"Crisp characters with no optical texture."},{value:"signal",label:"Signal",description:"Broken scanlines at the edges, with a clear center."},{value:"prism",label:"Prism",description:"Soft red/cyan separation at the edges, with a crisp center."},{value:"etch",label:"Etch",description:"A fine engraved texture, keeping the ink monochrome."}];function p(t){const e=Intl.Segmenter;return e?Array.from(new e(void 0,{granularity:"grapheme"}).segment(t),t=>t.segment):Array.from(t)}function x(){const t=document.createElement("canvas"),e=document.createElement("canvas"),i=t.getContext("2d"),s=e.getContext("2d",{willReadFrequently:!0}),n=function(){const t=new WeakMap;return(e,i,s="")=>{if(!e)return i;let n=t.get(e);if(!n){const i=new Set;for(const t of e)for(const e of t)e.char&&i.add(e.char);n=[...i].sort(),t.set(e,n)}const a=i+s;return i+n.filter(t=>!a.includes(t)).join("")}}();let a,o=null;return{update(r,h,l,c,d,f,m,u){const g=m?.[0]?.length??Math.max(1,Math.round(h/c)),x=m?.length??Math.max(1,Math.round(l/d)),v=u??{charset:" .:-=+*#%@",customText:"",colorMode:"fullcolor"},M=n(m,v.charset+(v.charsetFrames?.join("")??""),v.customText),y=function(t,e,i,s,n,a,o,r=4096,h=0,l=1){if(![i,s,n,a,o,r].every(t=>Number.isFinite(t)&&t>0))throw new Error("Glyph atlas dimensions must be positive and finite.");const c=JSON.stringify([e.charset,e.customText,i,s,n,a,o,r,h,l]);if(t?.key===c)return t;const d=[...new Set([" ",...p(e.charset),...p(e.customText??"")])];if(d.length>65536)throw new Error("This character set exceeds the glyph texture capacity.");const f=i/a,m=s/o,u=.9*Math.min(f/.55,m)*l,g=Math.ceil(f*n)+6,x=Math.ceil(m*n)+6,v=Math.min(d.length,Math.floor(r/g));if(v<1||Math.ceil(d.length/v)*x>r)throw new Error("The glyph atlas exceeds the available GPU texture size.");return{key:c,glyphs:d,indices:new Map(d.map((t,e)=>[t,e])),cellWidth:f,cellHeight:m,fontSize:u,padding:3,tileWidth:g,tileHeight:x,atlasColumns:v,atlasWidth:v*g,atlasHeight:Math.ceil(d.length/v)*x}}(o,{...v,charset:M},h,l,f,g,x);if(y!==o&&(t.width=y.atlasWidth,t.height=y.atlasHeight,i.font=y.fontSize*f+'px "JetBrains Mono", monospace',i.textAlign="center",i.textBaseline="middle",i.fillStyle="#fff",y.glyphs.forEach((t,e)=>i.fillText(t,e%y.atlasColumns*y.tileWidth+y.padding+y.cellWidth*f*.5,Math.floor(e/y.atlasColumns)*y.tileHeight+y.padding+y.cellHeight*f*.5))),o=y,m)a=function(t,e,i,s,n=!1){const a=t.length,o=t[0]?.length??0,r=s?.cols===o&&s.rows===a?s:{cols:o,rows:a,indices:new Uint8Array(o*a*4),colors:new Uint8ClampedArray(o*a*4)};r.indices.fill(0),r.colors.fill(0);const h="accent"===i.colorMode?[1,3,5].map(t=>parseInt(i.accentColor.slice(t,t+2),16)):null;for(let s=0;s<a;s++){if(t[s].length!==o)throw new Error("Glyph frames must have a rectangular cell grid.");for(let a=0;a<o;a++){const l=t[s][a];if(!l.char||!n&&" "===l.char||l.a<10)continue;const c=e.get(l.char);if(void 0===c)throw new Error(`Glyph is absent from the configured character set: ${l.char}`);const d=4*(s*o+a);let f=l.r,m=l.g,u=l.b;if(h)[f,m,u]=h;else if("fullcolor"!==i.colorMode){const t=.299*f+.587*m+.114*u|0;f="matrix"===i.colorMode?0:t,m=t,u=f}(n||0!==f||0!==m||0!==u)&&(r.indices[d]=255&c,r.indices[d+1]=c>>>8,r.indices[d+2]=Math.round(.299*l.r+.587*l.g+.114*l.b),r.colors[d]=f,r.colors[d+1]=m,r.colors[d+2]=u,r.colors[d+3]=l.a)}}return r}(m,o.indices,v,a,!0);else{e.width=g,e.height=x,s.drawImage(r,0,0,g,x);const t=s.getImageData(0,0,g,x).data;a={cols:g,rows:x,indices:new Uint8Array(g*x*4),colors:new Uint8ClampedArray(t)};for(let e=0;e<t.length;e+=4){const i=Math.min(1,(.299*t[e]+.587*t[e+1]+.114*t[e+2])/255*(t[e+3]/255)*3);a.indices[e+2]=Math.round(255*i),a.indices[e]=Math.min(o.glyphs.length-1,Math.floor(i*o.glyphs.length))}}return{plan:o,packed:a,atlas:t,dots:"dots"===v.renderMode,dotSize:v.dotSizeRatio??.72}},reset(){o=null},destroy(){t.width=t.height=e.width=e.height=1,a=void 0,o=null}}}function v(t){return!!t&&"ascii"===t.renderMode&&!/\p{Extended_Pictographic}/u.test(t.customText||t.charset)&&!t.charsetFrames?.length&&["fullcolor","grayscale","matrix","accent"].includes(t.colorMode)&&("accent"!==t.colorMode||/^#[\da-f]{6}$/i.test(t.accentColor))}function M(t){for(let e=t;e;e=e.parentElement){const t=getComputedStyle(e).backgroundColor.match(/[\d.]+/g)?.map(Number);if(t&&t.length>=3&&(t[3]??1)>.5)return(.299*t[0]+.587*t[1]+.114*t[2])/255<.4?[10/255,10/255,10/255,1]:[250/255,249/255,247/255,1]}const e=document.documentElement.dataset.theme;if("dark"!==e&&"light"!==e&&!t.isConnected&&document.body)return M(document.body);return"dark"===e||"light"!==e&&(document.documentElement.classList.contains("dark")||matchMedia("(prefers-color-scheme: dark)").matches)?[10/255,10/255,10/255,1]:[250/255,249/255,247/255,1]}function y(t,e,s){const r=e.style.visibility;let h=document.createElement("canvas"),l=null,c=null,u=null,p=null;const y=[],w=[];let S=!1,b=!1,E=4096,T=null,A=0,k=0,z=0,R=0,D=!1;const C=function(){const t=document.createElement("canvas"),e=t.getContext("2d");return{paint(i,s,n,a){s&&(t.width===i.canvas.width&&t.height===i.canvas.height||(t.width=i.canvas.width,t.height=i.canvas.height),e.globalCompositeOperation="copy",e.drawImage(i.canvas,0,0),e.globalCompositeOperation="destination-in",e.drawImage(s.canvas,0,0,t.width,t.height),e.globalCompositeOperation="source-in",e.fillStyle="#090909",e.fillRect(0,0,t.width,t.height),e.globalCompositeOperation="source-over",i.drawImage(t,0,0,n,a))},destroy(){t.width=t.height=1}}}();let F;const _=document.createElement("canvas"),I=document.createElement("canvas"),X=_.getContext("2d"),P=I.getContext("2d");let L=!1;const U=new a,N=x();let G=null,Y={};const B=()=>{h.className="ascii-hover-surface",h.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none",h.setAttribute("role","img"),h.setAttribute("aria-label","ASCII artwork preview"),h.dataset.renderer=l?"surface-gpu":"surface-canvas",t.prepend(h),e.style.visibility="hidden"},H=()=>{l&&(y.forEach(t=>l.deleteTexture(t)),w.forEach(t=>l.deleteShader(t)),u&&l.deleteProgram(u),p&&l.deleteBuffer(p))},W=()=>{S||c||(h.removeEventListener("webglcontextlost",W),H(),h.remove(),l=null,h=document.createElement("canvas"),c=h.getContext("2d"),B(),s())};try{if(l=h.getContext("webgl",{alpha:!0,antialias:!1,depth:!1,stencil:!1,premultipliedAlpha:!0,preserveDrawingBuffer:!0}),!l)throw new Error("WebGL unavailable");E=l.getParameter(l.MAX_TEXTURE_SIZE);const t=(t,e)=>{const i=l.createShader(t);if(w.push(i),l.shaderSource(i,e),l.compileShader(i),!l.getShaderParameter(i,l.COMPILE_STATUS))throw new Error(l.getShaderInfoLog(i)||"Shader compilation failed");return i};if(u=l.createProgram(),l.attachShader(u,t(l.VERTEX_SHADER,"attribute vec2 position; void main(){gl_Position=vec4(position,0.,1.);}")),l.attachShader(u,t(l.FRAGMENT_SHADER,"\n precision highp float;\n uniform sampler2D artwork; uniform sampler2D surface;\n uniform vec2 resolution; uniform vec2 sceneSize; uniform vec2 cellSize;\n uniform vec2 surfaceSize; uniform float strength;\n \nuniform float hoverMode;\nuniform vec4 hoverFocus;\nfloat surfaceLight(vec2 uv, vec2 size) {\n vec2 delta = (uv - hoverFocus.xy) * size / min(size.x, size.y) / hoverFocus.w;\n float light = exp(-3.0 * dot(delta, delta));\n if (hoverMode > 1.5) light = (exp(-delta.x * delta.x * 110.0) * 1.3 - exp(-delta.x * delta.x * 12.0) * .3) * exp(-delta.y * delta.y * 1.8);\n return hoverMode > .5 ? light * hoverFocus.z : 0.0;\n}\nvec3 illuminate(vec3 ink, float light) {\n return mix(ink, vec3(1.0), max(0.0, light) * .82) * (1.0 + min(0.0, light));\n}\n\n uniform sampler2D codes; uniform sampler2D cellColors; uniform sampler2D glyphAtlas;\n uniform vec2 gridSize; uniform vec2 atlasSize; uniform vec2 tileSize;\n uniform float atlasColumns; uniform float padding; uniform float glyphCount;\n uniform float dots; uniform float dotSize; uniform float directGlyphs; uniform vec4 backdrop;\n uniform float edgeEffect; uniform sampler2D textMask; uniform float hasTextMask;\n \nuniform float finishMode;\nuniform float finishPixelRatio;\nuniform float finishSoftness;\nvec3 edgeCoverage(sampler2D sheet, vec2 uv, vec2 atlas, vec2 pixel, vec2 viewport, float amount) {\n float a=texture2D(sheet,uv).a;\n if(amount<=0.0 || finishMode<.5) return vec3(a);\n vec2 radial=(pixel/viewport-.5)*2.0;\n float edge=smoothstep(.3,1.05,length(radial));\n float strength=clamp(amount,0.0,1.0)*edge;\n if(strength<=0.0) return vec3(a);\n vec2 cssPixel=pixel/max(1.0,finishPixelRatio);\n // Etch is a single texture sample: linework, not an opacity wash.\n if(finishMode>1.5 && finishMode<2.5) {\n float hatch=step(.68,fract((cssPixel.y+cssPixel.x*.22)*.5));\n return vec3(a*(1.0-hatch*strength*.64));\n }\n // Samples remain inside the current atlas tile's three-pixel padding.\n if(finishMode>2.5) {\n float band=floor(cssPixel.y/3.0);\n float phase=fract(sin(band*12.9898)*43758.5453);\n float tear=(phase-.5)*3.6*strength;\n float displaced=texture2D(sheet,uv+vec2(tear,0.0)/atlas).a;\n float cut=step(.72,fract(cssPixel.y*.5));\n return vec3(mix(a,displaced,strength)*(1.0-cut*.55*strength));\n }\n // A five-tap lens: opposed red/cyan edges with a short soft shoulder.\n // The center remains untouched; all offsets stay within three atlas texels.\n vec2 direction=normalize(vec2(radial.x-radial.y*.3,radial.y+radial.x*.3)+vec2(.00001));\n vec2 shift=direction*(2.35+.45*finishSoftness)*strength/atlas;\n float left=texture2D(sheet,uv-shift).a,right=texture2D(sheet,uv+shift).a;\n float softLeft=texture2D(sheet,uv-shift*.45).a,softRight=texture2D(sheet,uv+shift*.45).a;\n float red=left*.7+softLeft*.22+a*.08;\n float cyan=right*.7+softRight*.22+a*.08;\n // Reuse the same taps for a short optical blur and peripheral fade.\n // No whole-canvas blur, extra pass or softened HTML controls.\n float soft=a*.4+(left+right+softLeft+softRight)*.15;\n vec3 fringe=mix(vec3(red,cyan,cyan),vec3(soft),finishSoftness*.45);\n return mix(vec3(a),fringe,strength)*(1.-finishSoftness*strength*.32);\n\n}\n\n \nuniform float edgeSafe;\nuniform float trailAmount;\nuniform float trailKind;\nvec4 trailField(vec2 address) {\n return texture2D(surface,(address*(surfaceSize-1.0)+.5)/surfaceSize);\n}\nfloat trailFieldDensity(vec4 field) {\n return (field.r*65280.0+field.g*255.0)/65535.0*trailAmount;\n}\nfloat trailDensity(vec2 address) { return trailFieldDensity(trailField(address)); }\nfloat trailPin(vec2 cell, vec2 grid) {\n vec2 edge=min(cell,grid-1.0-cell);\n return mix(1.,smoothstep(1.0,5.0,min(edge.x,edge.y)),edgeSafe);\n}\nvec2 trailSource(vec2 cell, vec2 grid, vec4 field) {\n vec2 home=(cell+.5)/grid;\n if(trailKind>.5 || trailAmount<=0.) return home;\n float pin=trailPin(cell,grid);\n float response=1.-exp(-trailFieldDensity(field)*pin*3.5);\n vec2 drift=(field.ba*255.-128.)/127.;\n return clamp(home-drift*response*.026*pin,.5/grid,1.-.5/grid);\n}\nvec2 decodedGlyph(vec4 code) {\n return vec2(floor(code.r*255.+.5)+floor(code.g*255.+.5)*256.,code.b);\n}\n// Bilinear interpolation happens before glyph selection, never between bitmap\n// letters. Four small metadata reads replace the old four full-glyph gathers.\nvec2 flowGlyph(sampler2D codes,vec2 uv,vec2 grid) {\n vec2 p=uv*grid-.5,b=floor(p),f=fract(p);\n return mix(mix(decodedGlyph(texture2D(codes,(b+.5)/grid)),decodedGlyph(texture2D(codes,(b+vec2(1.5,.5))/grid)),f.x),\n mix(decodedGlyph(texture2D(codes,(b+vec2(.5,1.5))/grid)),decodedGlyph(texture2D(codes,(b+1.5)/grid)),f.x),f.y);\n}\nvec3 trailInk(vec3 ink, float density) {\n if (trailKind < .5) return ink;\n float peak=max(ink.r,max(ink.g,ink.b));\n float raised=trailKind>1.5?peak:max(peak,min(.44,density*.75));\n return peak>.001 ? ink*(raised/peak) : vec3(raised);\n}\nfloat flowIndex(float index,float count,float density) {\n float last=max(0.,count-1.);\n float response=1.-exp(-max(0.,density)*3.5);\n return max(0.,last-abs(last-(index+response*last*2.1)));\n}\nfloat trailTone(float tone, float density) {\n if (trailKind < .5) return flowIndex(tone,2.,density);\n return clamp(tone + (trailKind > 1.5 ? -density : density) * .65, 0.0, 1.0);\n}\nfloat trailIndex(float index, float count, float density, vec2 cell) {\n float grain=fract((cell.x*cell.x*17.0+cell.y*cell.y*23.0+cell.x*cell.y*19.0)*.0137);\n if(trailKind>1.5) return max(0.0,index-floor(density*count*(1.35+grain*.9)));\n if(trailKind<.5) {\n float seed=fract(sin(dot(cell,vec2(127.1,311.7)))*43758.5453);\n float response=1.-exp(-max(0.,density)*3.5);\n return floor(max(0.,flowIndex(index,count,density)-response*(1.-response)*seed*3.)+.5);\n }\n return min(count-1.0,index+floor(density*count*.85));\n}\n\n \n uniform float motionMode; uniform float motionTime; uniform float fineDither; uniform float ditherAmount;\n float printGrain(vec2 p) { return fract(52.9829189*fract(dot(p,vec2(.06711056,.00583715)))); }\n vec4 ambientAt(vec2 uv) {\n float p=motionTime*.5235987756;\n float edge=smoothstep(0.,.12,min(min(uv.x,1.-uv.x),min(uv.y,1.-uv.y)));\n if(motionMode<.5) return vec4(0.,0.,0.,1.);\n if(motionMode<1.5) {\n float fold=sin(uv.x*9.+uv.y*5.+p)+sin(uv.y*8.-uv.x*3.-p);\n float light=pow(max(0.,1.-abs(fold)*.72),3.);\n return vec4(0.,0.,(light*.22-.045)*edge,1.);\n }\n if(motionMode<2.5) return vec4(sin(uv.y*9.+p)*cos(uv.x*7.-p)*10.*edge,cos(uv.x*8.+p)*sin(uv.y*6.-p)*7.*edge,0.,1.);\n float cycle=mod(motionTime,12.);\n float grain=printGrain(floor(uv*vec2(160.,100.)));\n float order=uv.x*.65+uv.y*.2+grain*.15+sin(uv.x*8.-uv.y*5.)*.08;\n float gone=smoothstep(1.8+order*1.2,3.8+order*1.2,cycle)*(1.-smoothstep(5.+order*1.7,7.2+order*1.7,cycle));\n return vec4(sin(uv.y*9.+p)*gone*(1.-gone)*24.*edge,-gone*(1.-gone)*(8.+grain*12.)*edge,-gone*.45,1.-gone*.9);\n }\n\n float toneAt(vec2 uv) {\n vec2 p=uv*gridSize-.5, b=floor(p), f=fract(p);\n return mix(mix(texture2D(codes,(b+.5)/gridSize).b,texture2D(codes,(b+vec2(1.5,.5))/gridSize).b,f.x),mix(texture2D(codes,(b+vec2(.5,1.5))/gridSize).b,texture2D(codes,(b+1.5)/gridSize).b,f.x),f.y);\n }\n vec4 flowingCharacter(vec2 pixel, vec2 cell, vec4 ambient) {\n if(cell.x<0. || cell.y<0. || cell.x>=gridSize.x || cell.y>=gridSize.y) return vec4(0.);\n vec2 address=(cell+.5)/gridSize;\n vec4 field=trailField(address);\n vec2 local=pixel-cell*cellSize;\n if(local.x<0. || local.y<0. || local.x>=cellSize.x || local.y>=cellSize.y) return vec4(0.);\n vec2 source=trailSource(cell,gridSize,field);\n vec2 encoded=flowGlyph(codes,source,gridSize);\n vec4 color=texture2D(cellColors,source);\n float original=encoded.x;\n float density=trailFieldDensity(field)*trailPin(cell,gridSize),index=trailIndex(original,glyphCount,density,cell);\n if(original>.5) index=clamp(floor(index+ambient.z*(glyphCount-1.)+printGrain(cell)),0.,glyphCount-1.);\n if(index<.5 || color.a<.01) return vec4(0.);\n vec2 slot=vec2(mod(index,atlasColumns),floor(index/atlasColumns));\n float alpha=texture2D(glyphAtlas,(slot*tileSize+padding+local*resolution/sceneSize)/atlasSize).a;\n if(dots>.5) {\n vec2 d=(local-cellSize*.5)/min(cellSize.x,cellSize.y);\n float r=min(.48,(index/(glyphCount-1.))*.5*dotSize);\n alpha=1.-smoothstep(r-.06,r+.02,length(d));\n }\n vec3 coverage=dots>.5?vec3(alpha):edgeCoverage(glyphAtlas,(slot*tileSize+padding+local*resolution/sceneSize)/atlasSize,atlasSize,pixel,sceneSize,edgeEffect);\n coverage*=color.a;alpha=max(coverage.r,max(coverage.g,coverage.b));\n return vec4(trailInk(color.rgb,density)*coverage,alpha);\n }\n void main(){\n vec2 uv = vec2(gl_FragCoord.x, resolution.y - gl_FragCoord.y) / resolution;\n vec2 pixel = uv * sceneSize;\n if (strength > 0.) {\n vec4 normal = texture2D(surface, (uv * (surfaceSize - 1.) + .5) / surfaceSize) * 255.;\n vec2 slope = (vec2(normal.r * 256. + normal.g, normal.b * 256. + normal.a) - 32768.) / 32767.;\n vec2 edge = min(pixel, sceneSize - pixel) / cellSize;\n uv -= slope * strength * mix(1.,smoothstep(2.,8.,min(edge.x,edge.y)),edgeSafe) / sceneSize;\n }\n vec4 ambient=ambientAt(uv);\n uv -= ambient.xy/sceneSize;\n pixel=uv*sceneSize;\n vec4 ink = vec4(0.);\n if (directGlyphs > .5) {\n vec2 cell=floor(pixel/cellSize), address=(cell+.5)/gridSize;\n vec4 encoded=texture2D(codes,address), color=texture2D(cellColors,address);\n float index=floor(encoded.r*255.+.5)+floor(encoded.g*255.+.5)*256.;\n if(index>.5 && color.a>.01) {\n vec2 local=(pixel-cell*cellSize)*resolution/sceneSize;\n vec2 slot=vec2(mod(index,atlasColumns),floor(index/atlasColumns));\n float alpha=texture2D(glyphAtlas,(slot*tileSize+padding+local)/atlasSize).a*color.a;\n vec3 coverage=edgeCoverage(glyphAtlas,(slot*tileSize+padding+local)/atlasSize,atlasSize,pixel,sceneSize,edgeEffect)*color.a;\n ink=vec4(color.rgb*coverage,max(coverage.r,max(coverage.g,coverage.b)));\n }\n } else ink = texture2D(artwork, uv);\n if (fineDither > .5) {\n vec2 cell=floor(pixel/cellSize),address=(cell+.5)/gridSize;\n vec4 color=texture2D(cellColors,address);\n float density=trailAmount>0.?trailDensity(address):0.;\n vec2 source=trailAmount>0. && trailKind<.5?trailSource(cell,gridSize,trailField(address)):uv;\n float tone=trailTone(clamp(toneAt(source)+ambient.z,0.,1.),density*(trailKind<.5?trailPin(cell,gridSize):1.));\n float pitch=max(1.,min(cellSize.x,cellSize.y)*.32);\n float grain=.5+(printGrain(floor(pixel/pitch))-.5)*ditherAmount;\n float alpha=(tone<.001?0.:tone>.999?1.:smoothstep(grain-.035,grain+.035,tone))*color.a*ambient.w;\n // Preserve hue; tone is carried by mark coverage rather than muddy ink.\n vec3 hue=color.rgb/max(.001,max(color.r,max(color.g,color.b)));\n if(hasTextMask>.5) hue=mix(hue,vec3(.035),texture2D(textMask,vec2(gl_FragCoord.x,resolution.y-gl_FragCoord.y)/resolution).a);\n gl_FragColor=vec4(hue*alpha,alpha); return;\n }\n if ((trailAmount > 0. && trailKind > .5) || motionMode > .5) {\n vec2 cell=floor(pixel/cellSize), address=(cell+.5)/gridSize;\n float density=trailAmount>0.?trailDensity(address):0.;\n vec4 encoded=texture2D(codes,address);\n float original=floor(encoded.r*255.+.5)+floor(encoded.g*255.+.5)*256.;\n float index=trailIndex(original,glyphCount,density,cell);\n if(original>.5) index=clamp(floor(index+ambient.z*(glyphCount-1.)+printGrain(cell)),0.,glyphCount-1.);\n vec4 color=texture2D(cellColors,address);\n if((index!=original || motionMode>.5) && color.a>.01) {\n vec2 local=(pixel-cell*cellSize)*resolution/sceneSize;\n vec2 slot=vec2(mod(index,atlasColumns),floor(index/atlasColumns));\n float alpha=texture2D(glyphAtlas,(slot*tileSize+padding+local)/atlasSize).a;\n if(dots>.5) {\n vec2 d=(pixel-(cell+.5)*cellSize)/min(cellSize.x,cellSize.y);\n float r=min(.48,(index/(glyphCount-1.))*.5*dotSize);\n alpha=1.-smoothstep(r-.06,r+.02,length(d));\n }\n // Replace the cell, rather than blending two glyphs into a ghost.\n vec3 rgb=trailInk(color.rgb,density);\n ink=vec4(rgb*alpha*color.a,alpha*color.a);\n }\n }\n if(trailAmount>0. && trailKind<.5 && trailDensity((floor(pixel/cellSize)+.5)/gridSize)>.001) {\n ink=flowingCharacter(pixel,floor(pixel/cellSize),ambient);\n }\n vec3 straightInk = ink.a > .0 ? ink.rgb / ink.a : vec3(.0);\n float value = max(straightInk.r, max(straightInk.g, straightInk.b));\n // Lighting belongs to character ink; black/transparent gaps stay empty.\n float light = surfaceLight((floor(pixel / cellSize) + .5) * cellSize / sceneSize, sceneSize);\n vec3 lit = illuminate(straightInk, light * smoothstep(0., .22, value)) * ink.a;\n if(hasTextMask>.5) lit=mix(lit,vec3(.035)*ink.a,texture2D(textMask,vec2(gl_FragCoord.x,resolution.y-gl_FragCoord.y)/resolution).a);\n vec4 result = vec4(lit, ink.a)*ambient.w;\n gl_FragColor = directGlyphs > .5 ? result + backdrop*(1.-result.a) : result;\n }")),l.linkProgram(u),!l.getProgramParameter(u,l.LINK_STATUS))throw new Error("Surface shader link failed");l.useProgram(u),p=l.createBuffer(),l.bindBuffer(l.ARRAY_BUFFER,p),l.bufferData(l.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),l.STATIC_DRAW);const e=l.getAttribLocation(u,"position");l.enableVertexAttribArray(e),l.vertexAttribPointer(e,2,l.FLOAT,!1,0,0),Y=Object.fromEntries(["finishSoftness","finishMode","finishPixelRatio","edgeEffect","textMask","hasTextMask","artwork","surface","resolution","sceneSize","cellSize","surfaceSize","strength","hoverMode","hoverFocus","codes","cellColors","glyphAtlas","gridSize","atlasSize","tileSize","atlasColumns","padding","glyphCount","dots","dotSize","directGlyphs","backdrop","trailKind","edgeSafe","trailAmount","motionMode","motionTime","fineDither","ditherAmount"].map(t=>[t,l.getUniformLocation(u,t)]));for(let t=0;t<6;t++){const e=l.createTexture();y.push(e),l.activeTexture(l.TEXTURE0+t),l.bindTexture(l.TEXTURE_2D,e),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.LINEAR),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.LINEAR),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,1,1,0,l.RGBA,l.UNSIGNED_BYTE,new Uint8Array(4)),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE)}l.uniform1i(Y.textMask,5),l.uniform1i(Y.codes,2),l.uniform1i(Y.cellColors,3),l.uniform1i(Y.glyphAtlas,4),l.uniform1i(Y.artwork,0),l.uniform1i(Y.surface,1),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),l.disable(l.BLEND),l.disable(l.DEPTH_TEST),h.addEventListener("webglcontextlost",W),B()}catch{W()}const O=()=>{S||(N.reset(),G=null,b=!1,s())};return document.fonts?.addEventListener("loadingdone",O),document.fonts?.ready.then(O),{get canvas(){return h},canRenderGlyphs:t=>!!l&&!S&&v(t),render(t,s,a,r,u,p,x,w,B=0,H={}){const O=i(w?.animationStyle),K=U.update(B,O,w?.animationSpeed),$=(t=>!0===t?.fineDither&&!t.customText&&!t.charsetFrames?.length&&!/[A-Za-z]/.test(t.charset??""))(w),q=!!l&&!!x&&v(w);if(q!==D&&(b=!1,D=q),S||!a||!r||!e.width||!e.height)return;const j=Math.min(e.width/a,1.5,Math.sqrt(4e6/(a*r))),J=Math.max(1,Math.round(a*j)),V=Math.max(1,Math.round(r*j));if(h.width===J&&h.height===V||(h.width=J,h.height=V,b=!1),l&&(e.width>E||e.height>E)&&W(),(q||d(s.mode)||"none"!==O||$)&&(t||!b||!G)&&(G=N.update(e,a,r,u,p,j,x,w),l)){const{plan:t,packed:e,atlas:i}=G;for(const[t,i]of[[2,e.indices],[3,e.colors]])l.activeTexture(l.TEXTURE0+t),l.bindTexture(l.TEXTURE_2D,y[t]),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,3===t?l.LINEAR:l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,3===t?l.LINEAR:l.NEAREST),A!==e.cols||k!==e.rows?l.texImage2D(l.TEXTURE_2D,0,l.RGBA,e.cols,e.rows,0,l.RGBA,l.UNSIGNED_BYTE,i):l.texSubImage2D(l.TEXTURE_2D,0,0,0,e.cols,e.rows,l.RGBA,l.UNSIGNED_BYTE,i);A=e.cols,k=e.rows,T!==t&&(l.activeTexture(l.TEXTURE4),l.bindTexture(l.TEXTURE_2D,y[4]),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,l.RGBA,l.UNSIGNED_BYTE,i),T=t),l.uniform2f(Y.gridSize,e.cols,e.rows),l.uniform2f(Y.atlasSize,t.atlasWidth,t.atlasHeight),l.uniform2f(Y.tileSize,t.tileWidth,t.tileHeight),l.uniform1f(Y.atlasColumns,t.atlasColumns),l.uniform1f(Y.padding,t.padding),l.uniform1f(Y.glyphCount,t.glyphs.length),l.uniform1f(Y.dots,G.dots?1:0),l.uniform1f(Y.dotSize,G.dotSize)}if(l){l.uniform1f(Y.motionMode,(t=>["none","caustics","current","reform"].indexOf(t))(O)),l.uniform1f(Y.motionTime,K),l.uniform1f(Y.fineDither,$?1:0),l.uniform1f(Y.ditherAmount,Math.max(0,Math.min(2,w?.ditherStrength??1))),l.uniform1f(Y.trailKind,"dissolve"===s.mode?2:"contour"===s.mode?1:0),l.uniform1f(Y.edgeSafe,s.edgeSafe?1:0),l.uniform1f(Y.trailAmount,d(s.mode)?s.focus[2]:0),l.viewport(0,0,J,V),q||!t&&b||(l.activeTexture(l.TEXTURE0),l.bindTexture(l.TEXTURE_2D,y[0]),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,l.RGBA,l.UNSIGNED_BYTE,e),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1)),l.uniform1f(Y.directGlyphs,q?1:0),!q||!t&&b||l.uniform4fv(Y.backdrop,H.textMask||function(t){const e=t.length,i=t[0]?.length??0;for(let s=0;s<e;s+=Math.max(1,e>>2))for(let e=0;e<i;e+=Math.max(1,i>>2))if(t[s][e].a<200)return!0;return!1}(x)?[0,0,0,0]:M(e)),b=!0,l.activeTexture(l.TEXTURE1),l.bindTexture(l.TEXTURE_2D,y[1]),z!==s.width||R!==s.height?(l.texImage2D(l.TEXTURE_2D,0,l.RGBA,s.width,s.height,0,l.RGBA,l.UNSIGNED_BYTE,s.pixels),z=s.width,R=s.height):l.texSubImage2D(l.TEXTURE_2D,0,0,0,s.width,s.height,l.RGBA,l.UNSIGNED_BYTE,s.pixels),l.uniform2f(Y.resolution,J,V),l.uniform2f(Y.sceneSize,a,r),l.uniform2f(Y.cellSize,u,p),l.uniform2f(Y.surfaceSize,s.width,s.height),l.uniform1f(Y.strength,s.strength),l.uniform1f(Y.hoverMode,"light"===s.mode?1:"scan"===s.mode?2:0),l.uniform4fv(Y.hoverFocus,s.focus),H.textMask&&H.textMask!==F&&(l.activeTexture(l.TEXTURE5),l.bindTexture(l.TEXTURE_2D,y[5]),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,l.RGBA,l.UNSIGNED_BYTE,H.textMask.canvas),F=H.textMask),l.uniform1f(Y.hasTextMask,H.textMask?1:0);const i=function(t={}){const e=g.some(e=>e.value===t.filter)?t.filter:"prism",i=Number.isFinite(t.edgeEffect)?Math.max(0,Math.min(1,t.edgeEffect)):t.filter?1:0,s=Number.isFinite(t.edgeSoftness)?Math.max(0,Math.min(1,t.edgeSoftness)):0;return{mode:["clean","prism","etch","signal"].indexOf(e),amount:"clean"===e?0:i,softness:"prism"===e?s:0}}(H);l.uniform1f(Y.edgeEffect,i.amount),l.uniform1f(Y.finishMode,i.mode),l.uniform1f(Y.finishSoftness,i.softness),l.uniform1f(Y.finishPixelRatio,1),l.drawArrays(l.TRIANGLE_STRIP,0,4)}else if(c){if(c.setTransform(j,0,0,j,0,0),c.clearRect(0,0,a,r),c.drawImage(e,0,0,a,r),("none"!==O||$)&&G){c.clearRect(0,0,a,r);const{plan:t,packed:e,atlas:i}=G,h=[0,0,0,1],l=[0,0,0,0,0,0],g=Math.max(1,.32*Math.min(u,p));for(let a=0;a<e.rows;a++)for(let r=0;r<e.cols;r++){const x=(r+.5)/e.cols,v=(a+.5)/e.rows,M=4*(a*e.cols+r);if(e.colors[M+3]<10)continue;o(O,x,v,K,h);const y=4*(Math.min(s.height-1,Math.round(v*(s.height-1)))*s.width+Math.min(s.width-1,Math.round(x*(s.width-1)))),S=d(s.mode)?(256*s.pixels[y]+s.pixels[y+1])/65535*s.focus[2]:0,b=e.indices[M]+256*e.indices[M+1];"trail"===s.mode&&m(e.indices,e.colors,e.cols,e.rows,r,a,S,(s.pixels[y+2]-128)/127,(s.pixels[y+3]-128)/127,t.glyphs.length,l,s.edgeSafe);let E="trail"===s.mode?l[0]:"dissolve"===s.mode?b-Math.floor(S*t.glyphs.length*1.8):b+Math.floor(S*t.glyphs.length*.85);b>0&&(E+=h[2]*(t.glyphs.length-1)),E=Math.max(0,Math.min(t.glyphs.length-1,Math.floor(E+n(r,a))));let T=h[0],A=h[1];s.strength>0&&(T+=(256*s.pixels[y]+s.pixels[y+1]-32768)/32767*s.strength,A+=(256*s.pixels[y+2]+s.pixels[y+3]-32768)/32767*s.strength);const k=r*u+T,z=a*p+A,R=("trail"===s.mode?l[5]:e.colors[M+3])/255*h[3],D="trail"===s.mode?l[2]:e.colors[M],C="trail"===s.mode?l[3]:e.colors[M+1],F="trail"===s.mode?l[4]:e.colors[M+2],_=$?Math.max(1,D,C,F):255,I=`rgb(${D/_*255},${C/_*255},${F/_*255})`;if(c.fillStyle=I,$){const t="trail"===s.mode?f(Math.max(0,Math.min(1,l[1]+h[2])),2,S):Math.max(0,Math.min(1,e.indices[M+2]/255+h[2]+.65*("dissolve"===s.mode?-S:S)));c.globalAlpha=R;for(let e=0;e<p;e+=g)for(let i=0;i<u;i+=g)t>.5+(n(Math.floor((k+i)/g),Math.floor((z+e)/g))-.5)*Math.max(0,Math.min(2,w?.ditherStrength??1))&&c.fillRect(k+i,z+e,Math.min(g,u-i),Math.min(g,p-e))}else if(E>0)if(c.globalAlpha=R,G.dots){const e=Math.min(.48,E/(t.glyphs.length-1)*.5*G.dotSize)*Math.min(u,p);c.beginPath(),c.arc(k+.5*u,z+.5*p,e,0,2*Math.PI),c.fill()}else c.drawImage(i,E%t.atlasColumns*t.tileWidth+t.padding,Math.floor(E/t.atlasColumns)*t.tileHeight+t.padding,t.cellWidth*j,t.cellHeight*j,k,z,u,p),c.globalAlpha=1,c.globalCompositeOperation="source-atop",c.fillRect(k,z,u,p),c.globalCompositeOperation="source-over"}c.globalAlpha=1}else if(d(s.mode)&&G){const{plan:t,packed:e,atlas:i}=G,n=[0,0,0,0,0,0];for(let a=0;a<e.rows;a++)for(let o=0;o<e.cols;o++){const r=4*(Math.min(s.height-1,Math.round((a+.5)/e.rows*(s.height-1)))*s.width+Math.min(s.width-1,Math.round((o+.5)/e.cols*(s.width-1)))),h=(256*s.pixels[r]+s.pixels[r+1])/65535*s.focus[2],l=4*(a*e.cols+o),d=.0137*(o*o*17+a*a*23+o*a*19),f=d-Math.floor(d);"trail"===s.mode&&m(e.indices,e.colors,e.cols,e.rows,o,a,h,(s.pixels[r+2]-128)/127,(s.pixels[r+3]-128)/127,t.glyphs.length,n,s.edgeSafe);const g=e.indices[l]+256*e.indices[l+1],x="trail"===s.mode?Math.round(n[0]):"dissolve"===s.mode?Math.max(0,g-Math.floor(h*t.glyphs.length*(1.35+.9*f))):Math.min(t.glyphs.length-1,g+Math.floor(h*t.glyphs.length*.85));if(x===g&&("trail"!==s.mode||h<1e-4)||e.colors[l+3]<10)continue;const v=o*u,M=a*p;if(c.clearRect(v,M,u,p),c.globalAlpha=("trail"===s.mode?n[5]:e.colors[l+3])/255,G.dots){const e=Math.min(.48,x/(t.glyphs.length-1)*.5*G.dotSize)*Math.min(u,p);c.fillStyle="#fff",c.beginPath(),c.arc(v+.5*u,M+.5*p,e,0,2*Math.PI),c.fill()}else c.drawImage(i,x%t.atlasColumns*t.tileWidth+t.padding,Math.floor(x/t.atlasColumns)*t.tileHeight+t.padding,t.cellWidth*j,t.cellHeight*j,v,M,u,p);c.globalAlpha=1,c.globalCompositeOperation="source-atop";const y="trail"===s.mode?n[2]:e.colors[l],w="trail"===s.mode?n[3]:e.colors[l+1],S="trail"===s.mode?n[4]:e.colors[l+2],b=Math.max(y,w,S),E="dissolve"===s.mode||"trail"===s.mode?b:Math.max(b,Math.min(112,191*h)),T=b?E/b:0;c.fillStyle=`rgb(${b?y*T:E},${b?w*T:E},${b?S*T:E})`,c.fillRect(v,M,u,p),c.globalCompositeOperation="source-over"}}else if("light"===s.mode||"scan"===s.mode){!t&&L&&_.width===J&&_.height===V||(_.width=J,_.height=V,I.width=J,I.height=V,X.filter="brightness(3)",X.drawImage(e,0,0,J,V),X.filter="none",L=!0);const[i,n,o,h]=s.focus;if(o>.001){P.setTransform(1,0,0,1,0,0),P.clearRect(0,0,J,V),P.drawImage(_,0,0),P.globalCompositeOperation="destination-in",P.save(),P.translate(i*J,n*V),P.scale("scan"===s.mode?.13:1,1);const t=h*Math.min(J,V),e=P.createRadialGradient(0,0,0,0,0,t);e.addColorStop(0,`rgba(255,255,255,${o})`),e.addColorStop(.5,`rgba(255,255,255,${.4*o})`),e.addColorStop(1,"rgba(255,255,255,0)"),P.fillStyle=e,P.fillRect(10*-J,10*-V,20*J,20*V),P.restore(),P.globalCompositeOperation="source-over",c.globalCompositeOperation="source-atop",c.drawImage(I,0,0,a,r),c.globalCompositeOperation="source-over"}}else if(s.strength>0){const t=32,i=18,n=a/t,o=r/i;for(let h=0;h<i;h++)for(let l=0;l<t;l++){const d=(l+.5)/t,f=(h+.5)/i,m=Math.min(s.width-1,Math.round(d*(s.width-1))),g=4*(Math.min(s.height-1,Math.round(f*(s.height-1)))*s.width+m),x=s.pixels,v=Math.min(l*n/u,(a-(l+1)*n)/u,h*o/p,(r-(h+1)*o)/p),M=Math.max(0,Math.min(1,(v-2)/6)),y=s.edgeSafe?M*M*(3-2*M):1,w=(256*x[g]+x[g+1]-32768)/32767*s.strength*y,S=(256*x[g+2]+x[g+3]-32768)/32767*s.strength*y;Math.abs(w)+Math.abs(S)<.02||(c.clearRect(l*n,h*o,n,o),c.drawImage(e,Math.max(0,Math.min(a-n,l*n-w))*e.width/a,Math.max(0,Math.min(r-o,h*o-S))*e.height/r,n*e.width/a,o*e.height/r,l*n,h*o,n,o))}}C.paint(c,H.textMask,a,r)}},destroy(){S=!0,C.destroy(),document.fonts?.removeEventListener("loadingdone",O),N.destroy(),h.removeEventListener("webglcontextlost",W),H(),h.remove(),_.width=_.height=I.width=I.height=1,e.style.visibility=r,l?.getExtension("WEBGL_lose_context")?.loseContext()}}}function w(e,s,n={}){let a,o,r={effect:"trail",strength:.55,radius:n.effect&&"trail"!==n.effect?.2:.45,animated:!1,fps:30,fontSize:7,charAspect:.58,charSpacing:1,paused:!1,charset:" .:-=+*#%@",customText:"",renderMode:"ascii",dotSizeRatio:.72,...n},h=new u(s.clientWidth/Math.max(1,s.clientHeight)),l=!1,c=!1,d=!0,f=0,m=0,g=-1/0,p=0,x=null,v=!1,M=[];const w=matchMedia("(prefers-reduced-motion: reduce)"),S=()=>{l||!c||document.hidden||f||(f=requestAnimationFrame(E))},b=y(e,s,()=>queueMicrotask(()=>{d=!0,S()}));function E(t){if(f=0,l||!c||document.hidden)return;const e=s.clientWidth,n=s.clientHeight;if(!e||!n)return;const u=w.matches||r.paused;h.configure(r.effect,r.strength,r.radius,r.edgeSafe);const y=h.active;if(!u){if(p+=m?Math.min(.1,(t-m)/1e3):0,v){const t=s.getBoundingClientRect();if(t.width&&t.height)for(const e of M)h.move((e.x-t.left)/t.width,(e.y-t.top)/t.height,e.time);M=[],x||h.leave(),v=!1}h.step(m?(t-m)/1e3:1/60)}const E=d||r.animated&&!u&&t-g>=1e3/Math.max(1,Math.min(60,r.fps))-.5;(E||y||h.active||!u&&"none"!==i(r.motion))&&(E&&(a=r.getFrame?.()),b.render(E,h.refraction,e,n,r.fontSize*r.charSpacing,r.fontSize/r.charAspect*r.charSpacing,a,{charset:r.charset,customText:r.customText,renderMode:r.renderMode,dotSizeRatio:r.dotSizeRatio,colorMode:r.colorMode??"fullcolor",accentColor:r.accentColor??"#888888",animationStyle:r.motion,animationSpeed:r.motionSpeed??1,artStyle:"classic",fineDither:r.fineDither,ditherStrength:r.ditherStrength??1},p,{filter:r.filter,edgeEffect:r.edgeEffect,edgeSoftness:r.edgeSoftness,textMask:o?.read()}),E&&(g=t),d=!1),m=t,u||!r.animated&&!h.active&&"none"===i(r.motion)||S()}r.textMask&&(o=t(e,r.textMask,()=>{d=!0,S()}));const T=()=>{h.clear(),x=null,M=[],v=!1,m=0,d=!0,cancelAnimationFrame(f),f=0,S()},A=t=>{if("touch"===t.pointerType||r.paused||w.matches)return;if(t.target instanceof Element&&t.target.closest("button,a,input,summary,select"))return void k();const e=s.getBoundingClientRect();t.clientX<e.left||t.clientX>e.right||t.clientY<e.top||t.clientY>e.bottom?k():(x={x:t.clientX,y:t.clientY,time:t.timeStamp},M.push(x),M.length>6&&M.shift(),v=!0,S())},k=()=>{x=null,v=!0,S()},z=new IntersectionObserver(([t])=>{c=t.isIntersecting,T()});z.observe(e);const R=new ResizeObserver(()=>{h=new u(s.clientWidth/Math.max(1,s.clientHeight)),T()});return R.observe(s),e.addEventListener("pointermove",A),e.addEventListener("pointerleave",k),e.addEventListener("pointercancel",k),document.addEventListener("visibilitychange",T),w.addEventListener("change",T),{get canvas(){return b.canvas},invalidate(){o?.invalidate(),d=!0,S()},update(i){"textMask"in i&&(o?.destroy(),o=i.textMask?t(e,i.textMask,()=>{d=!0,S()}):void 0),r={...r,...i},T()},destroy(){l||(l=!0,cancelAnimationFrame(f),z.disconnect(),R.disconnect(),b.destroy(),o?.destroy(),e.removeEventListener("pointermove",A),e.removeEventListener("pointerleave",k),e.removeEventListener("pointercancel",k),document.removeEventListener("visibilitychange",T),w.removeEventListener("change",T))}}}exports.createTextMask=t,exports.mountHover=w,exports.mountStudioHover=w;//# sourceMappingURL=hover.cjs.map
|
|
1
|
+
"use strict";function t(t,e,i=()=>{}){const s=Array.isArray(e)?e:[e],n=document.createElement("canvas"),a=n.getContext("2d");let o,r=!0,h=!1,l=0;const c=()=>{h||(r=!0,i())},d=new ResizeObserver(c);d.observe(t),s.forEach(t=>d.observe(t));const f=new MutationObserver(c);return s.forEach(t=>f.observe(t,{subtree:!0,childList:!0,characterData:!0,attributes:!0})),document.fonts?.addEventListener("loadingdone",c),document.fonts?.ready.then(c),window.addEventListener("resize",c),{invalidate:c,read(){if(h)return;if(!r)return o;r=!1;const e=t.getBoundingClientRect(),i=Math.min(devicePixelRatio||1,1.5,Math.sqrt(4e6/Math.max(1,e.width*e.height)));n.width=Math.max(1,Math.round(e.width*i)),n.height=Math.max(1,Math.round(e.height*i)),a.setTransform(i,0,0,i,0,0),a.fillStyle="#fff",a.textBaseline="alphabetic";for(const t of s){const i=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(let t=i.nextNode();t;t=i.nextNode()){const i=t.parentElement;if(!i)continue;const s=getComputedStyle(i);if("hidden"===s.visibility||"none"===s.display)continue;a.font=`${s.fontStyle} ${s.fontWeight} ${s.fontSize} ${s.fontFamily}`;const n=a.measureText("Hg"),o=n.fontBoundingBoxAscent??.8*parseFloat(s.fontSize),r=n.fontBoundingBoxDescent??.2*parseFloat(s.fontSize),h=t.textContent??"",l=document.createRange();let c=0;for(const i of h){if(l.setStart(t,c),c+=i.length,l.setEnd(t,c),/\s/.test(i))continue;const s=l.getBoundingClientRect();s.width&&s.height&&a.fillText(i,s.left-e.left,s.top-e.top+(s.height-o-r)/2+o)}}}return o={canvas:n,revision:++l},o},destroy(){h=!0,d.disconnect(),f.disconnect(),document.fonts?.removeEventListener("loadingdone",c),window.removeEventListener("resize",c),n.width=n.height=1,o=void 0}}}var e=[{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."}];function i(t){return e.find(e=>e.value===t||e.mode===t)?.mode??"none"}var s=(t,e,i)=>{const s=(t=>Math.max(0,Math.min(1,t)))((i-t)/(e-t));return s*s*(3-2*s)},n=(t,e)=>{const i=(.06711056*t+.00583715*e)%1*52.9829189;return i-Math.floor(i)},a=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,i,a,o){if(o[0]=o[1]=o[2]=0,o[3]=1,"none"===t)return o;const r=a*Math.PI/6,h=s(0,.12,Math.min(e,1-e,i,1-i));if("caustics"===t){const t=Math.sin(9*e+5*i+r)+Math.sin(8*i-3*e-r),s=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);o[2]=(.22*s-.045)*h}else if("current"===t)o[0]=Math.sin(9*i+r)*Math.cos(7*e-r)*10*h,o[1]=Math.cos(8*e+r)*Math.sin(6*i-r)*7*h;else if("sheen"===t)o[2]=.2*Math.pow(.5+.5*Math.cos(5*e+3*i-r),8)-.025;else if("tidal"===t){const t=e-.5,s=i-.5,n=Math.hypot(t,s),a=Math.sin(22*n-r)*h;o[0]=t*a*9,o[1]=s*a*9,o[2]=.035*a}else if("grain"===t){const t=n(Math.floor(160*e),Math.floor(100*i))*Math.PI*2;o[2]=.07*Math.sin(r+t)}else if("reform"===t){const t=(a%12+12)%12,l=n(Math.floor(160*e),Math.floor(100*i)),c=.65*e+.2*i+.15*l+.08*Math.sin(8*e-5*i),d=s(1.8+1.2*c,3.8+1.2*c,t)*(1-s(5+1.7*c,7.2+1.7*c,t));o[0]=Math.sin(9*i+r)*d*(1-d)*24*h,o[1]=-d*(1-d)*(8+12*l)*h,o[2]=.45*-d,o[3]=1-.9*d}return o}function r(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)),n=Math.max(0,Math.min(1,(s-.035)/.105));return n*n*n*(n*(6*n-15)+10)}var h=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]=r(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 n=this.width,a=this.height,o=Math.max(1,n/a),r=Math.max(1,a/n),h=s?(t-s.x)*o:0,l=s?(e-s.y)*r:0,c=Math.hypot(h,l);if(!s&&"dissolve"!==this.mode)return;if(s&&c<1e-4)return;const d=.035+.11*Math.max(.1,Math.min(1,i)),f=Math.min(128,Math.max(1,Math.ceil(c/(.45*d)))),m=c?h/c:1,u=c?l/c:0,g=Math.min(1,c/(d*f)*2.2);for(let i=0;i<f;i++){const h=(i+.5)/f,l=s?s.x+(t-s.x)*h:t,c=s?s.y+(e-s.y)*h:e,p=Math.max(0,Math.floor((l-2.5*d/o)*(n-1))),x=Math.min(n-1,Math.ceil((l+2.5*d/o)*(n-1))),v=Math.max(0,Math.floor((c-2.5*d/r)*(a-1))),M=Math.min(a-1,Math.ceil((c+2.5*d/r)*(a-1)));for(let t=v;t<=M;t++)for(let e=p;e<=x;e++){const i=(e/(n-1)-l)*o/d,s=(t/(a-1)-c)*r/d,h=Math.exp(1.5*-(i*i+s*s)),f=t*n+e;if("dissolve"===this.mode)this.ink[f]=Math.max(this.ink[f],h);else{const n=(-i*u+s*m)*h*2.8,a=43758.5453*Math.sin(127.1*e+311.7*t),o=(a-Math.floor(a))*Math.PI*2,r="magnetic"===this.mode?-i*h*2.5:"scatter"===this.mode?(i+.7*Math.cos(o))*h*2:"silk"===this.mode?m*n:-s*h*2.5,l="magnetic"===this.mode?-s*h*2.5:"scatter"===this.mode?(s+.7*Math.sin(o))*h*2:"silk"===this.mode?u*n:i*h*2.5;this.targetX[f]=Math.max(-1,Math.min(1,this.targetX[f]+r*g)),this.targetY[f]=Math.max(-1,Math.min(1,this.targetY[f]+l*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),s=1-Math.exp(-22*e);let n=0;for(let t=0;t<this.ink.length;t++)if("dissolve"===this.mode){this.ink[t]*=i,n=Math.max(n,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,n=Math.max(n,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),a=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]=a>>>8,this.pixels[4*t+3]=255&a}this.peak=n,this.active||this.clear()}sample(t,e,i){const s=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),n=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),a=Math.floor(s),o=Math.floor(n),h=s-a,l=n-o,c=o*this.width+a,d=c+this.width,f=t=>(t[c]*(1-h)+t[c+1]*h)*(1-l)+(t[d]*(1-h)+t[d+1]*h)*l;i[0]=f(this.offsetX)*(this.edgeSafe?r(t,e,this.width/this.height):1)*.08,i[1]=f(this.offsetY)*(this.edgeSafe?r(t,e,this.width/this.height):1)*.08,i[2]="dissolve"===this.mode?6*-f(this.ink):0}},l=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),n=Math.max(1,this.height/this.width);this.previous&&(Math.hypot((t-this.previous.x)*s,(e-this.previous.y)*n)<.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 n=0;for(const a of this.rings){const o=.015+a.age*(.15+.22*a.radius),r=.009+.014*a.radius,h=(Math.hypot((t-a.x)*i,(e-a.y)*s)-o)/r,l=Math.sin(Math.min(1,a.age/.07)*Math.PI/2)*Math.max(0,1-a.age/1.35)**2;n=Math.max(n,Math.exp(-h*h)*l)}return n}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 n=t*this.width+e;this.echo[n]=Math.max(this.ringSample(e/(this.width-1),t/(this.height-1)),this.echo[n]*i),s=Math.max(s,this.echo[n]);const a=Math.round(65535*this.echo[n]),o=4*n;this.pixels[o]=a>>>8,this.pixels[o+1]=255&a}this.echoPeak=s,this.active||(this.echo.fill(0),this.pixels.fill(0))}},c=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 n=this.previous;if(this.previous={x:t,y:e,time:s},!n)return;const a=(t-n.x)*(this.width-1),o=(e-n.y)*(this.height-1),r=Math.hypot(a,o);if(r<.001)return;const h=Math.min(this.width,this.height),l=s>n.time?Math.max(1/240,(s-n.time)/1e3):1/60,c=Math.min(12,r/h/l),d=1-Math.exp(-c/2.2),f=h*(.022+.075*i)*(.65+.95*d),m=Math.min(128,Math.max(1,Math.ceil(r/(.4*f)))),u=r/f*(.32+.22*d)/m,g=a/r,p=o/r,x=-p,v=g,M=r*(2+18*d)/m;for(let i=0;i<m;i++){const s=(i+.5)/m,a=(n.x+(t-n.x)*s)*(this.width-1),o=(n.y+(e-n.y)*s)*(this.height-1),r=Math.max(1,Math.floor(a-3*f)),h=Math.min(this.width-2,Math.ceil(a+3*f)),l=Math.max(1,Math.floor(o-3*f)),c=Math.min(this.height-2,Math.ceil(o+3*f));for(let t=l;t<=c;t++)for(let e=r;e<=h;e++){const i=((e-a)*g+(t-o)*p)/f,s=((e-a)*x+(t-o)*v)/f,n=Math.exp(-i*i*.65-s*s*1.7),r=t*this.width+e;this.ink[r]=1-(1-this.ink[r])*Math.exp(-n*u);const h=1-s*s*.55,l=i*s*.7;this.u[r]=Math.max(-80,Math.min(80,this.u[r]+(g*h+x*l)*n*M)),this.v[r]=Math.max(-80,Math.min(80,this.v[r]+(p*h+v*l)*n*M))}}this.peak=1}read(t,e,i){const s=0|(e=Math.max(.5,Math.min(this.width-1.5,e))),n=0|(i=Math.max(.5,Math.min(this.height-1.5,i))),a=e-s,o=i-n,r=n*this.width+s;return(t[r]*(1-a)+t[r+1]*a)*(1-o)+(t[r+this.width]*(1-a)+t[r+this.width+1]*a)*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,s=this.height;for(;e>1e-7;){const t=Math.min(1/60,e);e-=t;const n=Math.exp(-1.9*t),a=Math.exp(-3.2*t);for(let e=1;e<s-1;e++)for(let o=1;o<i-1;o++){const r=e*i+o,h=Math.max(.5,Math.min(i-1.5,o-this.u[r]*t)),l=Math.max(.5,Math.min(s-1.5,e-this.v[r]*t)),c=0|h,d=0|l,f=h-c,m=l-d,u=d*i+c,g=(1-f)*(1-m),p=f*(1-m),x=(1-f)*m,v=f*m;this.a[r]=(this.u[u]*g+this.u[u+1]*p+this.u[u+i]*x+this.u[u+i+1]*v)*n,this.b[r]=(this.v[u]*g+this.v[u+1]*p+this.v[u+i]*x+this.v[u+i+1]*v)*n,this.c[r]=(this.ink[u]*g+this.ink[u+1]*p+this.ink[u+i]*x+this.ink[u+i+1]*v)*a}[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 n=e*i+s,a=Math.abs(this.curl[n+1])-Math.abs(this.curl[n-1]),o=Math.abs(this.curl[n+i])-Math.abs(this.curl[n-i]),r=Math.hypot(a,o)+1e-4,h=this.curl[n]*t*10,l=Math.hypot(this.u[n],this.v[n]);this.u[n]+=o/r*h,this.v[n]-=a/r*h;const c=Math.min(1,l/(Math.hypot(this.u[n],this.v[n])+1e-6));this.u[n]*=c,this.v[n]*=c,this.divergence[n]=-.5*(this.u[n+1]-this.u[n-1]+this.v[n+i]-this.v[n-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 o=0;for(let e=1;e<s-1;e++)for(let s=1;s<i-1;s++){const n=e*i+s;this.u[n]=Math.max(-80,Math.min(80,this.u[n]-.5*(this.pressure[n+1]-this.pressure[n-1]))),this.v[n]=Math.max(-80,Math.min(80,this.v[n]-.5*(this.pressure[n+i]-this.pressure[n-i]))),this.driftX[n]+=(3.6*this.u[n]-58*this.offsetX[n]-12*this.driftX[n])*t,this.driftY[n]+=(3.6*this.v[n]-58*this.offsetY[n]-12*this.driftY[n])*t,this.offsetX[n]=Math.max(-2,Math.min(2,this.offsetX[n]+this.driftX[n]*t)),this.offsetY[n]=Math.max(-2,Math.min(2,this.offsetY[n]+this.driftY[n]*t)),this.signal[n]=1-Math.exp(.06*-Math.hypot(this.u[n],this.v[n])-.16*this.ink[n]),o=Math.max(o,this.signal[n])}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()}},d=t=>["trail","contour","dissolve"].includes(t);function f(t,e,i){const s=Math.max(0,e-1),n=1-Math.exp(3.5*-Math.max(0,i));return Math.max(0,s-Math.abs(s-(t+n*s*2.1)))}function m(t,e,i,s,n,a,o,r,h,l,c,d=!1){const m=Math.min(n,a,i-1-n,s-1-a),u=Math.max(0,Math.min(1,(m-1)/4)),g=d?u*u*(3-2*u):1;o*=g;const p=1-Math.exp(3.5*-Math.max(0,o)),x=Math.max(0,Math.min(i-1,n-r*p*.026*i*g)),v=Math.max(0,Math.min(s-1,a-h*p*.026*s*g)),M=Math.floor(x),y=Math.floor(v),w=x-M,S=v-y;c.fill(0);for(let n=0;n<2;n++)for(let a=0;a<2;a++){const o=4*(Math.min(s-1,y+n)*i+Math.min(i-1,M+a)),r=(a?w:1-w)*(n?S:1-S);c[0]+=(t[o]+256*t[o+1])*r,c[1]+=t[o+2]/255*r;for(let t=0;t<4;t++)c[t+2]+=e[o+t]*r}const b=43758.5453*Math.sin(127.1*n+311.7*a),E=b-Math.floor(b);c[0]=Math.max(0,f(c[0],l,o)-p*(1-p)*E*3)}var u=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]=r(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 c(this.columns,this.rows),this.contour=new l(this.columns,this.rows),this.afterimage=new h(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 n=(t-s.x)*this.xScale,a=(e-s.y)*this.yScale,o=Math.hypot(n,a);if(o<1e-5)return;const r=.035+.1*this.radius,h=3*r,l=Math.min(192,Math.max(1,Math.ceil(o/(.5*r)))),c=95*Math.min(o,1)/l;for(let i=0;i<l;i++){const n=(i+.5)/l,a=s.x+(t-s.x)*n,o=s.y+(e-s.y)*n,d=Math.max(1,Math.floor((a-h/this.xScale)*(this.columns-1))),f=Math.min(this.columns-2,Math.ceil((a+h/this.xScale)*(this.columns-1))),m=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=m;t<=u;t++)for(let e=d;e<=f;e++){const i=(e/(this.columns-1)-a)*this.xScale,s=(t/(this.rows-1)-o)*this.yScale,n=Math.exp(-(i*i+s*s)/(r*r))*c,h=t*this.columns+e;this.velocity[h]=Math.max(-12,this.velocity[h]-n)}}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 n=1;n<this.rows-1;n++)for(let a=1;a<this.columns-1;a++){const o=n*this.columns+a,r=this.heights[o],h=this.heights[o-1]+this.heights[o+1]+this.heights[o-this.columns]+this.heights[o+this.columns]-4*r,l=Math.min(a,n,this.columns-1-a,this.rows-1-n),c=l<5?.88+.024*l:1,d=(this.velocity[o]+(h*s*s-8*r)*e)*i*c;this.velocity[o]=d,this.next[o]=(r+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 n=.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)])*n,a=(this.heights[Math.max(0,t-1)*this.columns+e]-this.heights[Math.min(this.rows-1,t+1)*this.columns+e])*n,o=Math.tanh(s)*(this.refraction.edgeSafe?this.edgeMask[i]:1),r=Math.tanh(a)*(this.refraction.edgeSafe?this.edgeMask[i]:1);this.normals[2*i]=o,this.normals[2*i+1]=r;const h=Math.round(32767*o+32768),l=Math.round(32767*r+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))),n=Math.max(0,Math.min(this.rows-1.001,e*(this.rows-1))),a=Math.floor(s),o=Math.floor(n),r=s-a,h=n-o,l=2*(o*this.columns+a),c=l+2*this.columns;for(let t=0;t<2;t++)i[t]=.08*((this.normals[l+t]*(1-r)+this.normals[l+2+t]*r)*(1-h)+(this.normals[c+t]*(1-r)+this.normals[c+2+t]*r)*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[n,a,o,r]=i.focus,h=(t-n)*Math.max(1,s)/r,l=(e-a)*Math.max(1,1/s)/r;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}};var g=[{value:"clean",label:"Clean",description:"Crisp characters with no optical texture."},{value:"signal",label:"Signal",description:"Broken scanlines at the edges, with a clear center."},{value:"prism",label:"Prism",description:"Soft red/cyan separation at the edges, with a crisp center."},{value:"etch",label:"Etch",description:"A fine engraved texture, keeping the ink monochrome."}];function p(t){const e=Intl.Segmenter;return e?Array.from(new e(void 0,{granularity:"grapheme"}).segment(t),t=>t.segment):Array.from(t)}function x(){const t=document.createElement("canvas"),e=document.createElement("canvas"),i=t.getContext("2d"),s=e.getContext("2d",{willReadFrequently:!0}),n=function(){const t=new WeakMap;return(e,i,s="")=>{if(!e)return i;let n=t.get(e);if(!n){const i=new Set;for(const t of e)for(const e of t)e.char&&i.add(e.char);n=[...i].sort(),t.set(e,n)}const a=i+s;return i+n.filter(t=>!a.includes(t)).join("")}}();let a,o=null;return{update(r,h,l,c,d,f,m,u){const g=m?.[0]?.length??Math.max(1,Math.round(h/c)),x=m?.length??Math.max(1,Math.round(l/d)),v=u??{charset:" .:-=+*#%@",customText:"",colorMode:"fullcolor"},M=n(m,v.charset+(v.charsetFrames?.join("")??""),v.customText),y=function(t,e,i,s,n,a,o,r=4096,h=0,l=1){if(![i,s,n,a,o,r].every(t=>Number.isFinite(t)&&t>0))throw new Error("Glyph atlas dimensions must be positive and finite.");const c=JSON.stringify([e.charset,e.customText,i,s,n,a,o,r,h,l]);if(t?.key===c)return t;const d=[...new Set([" ",...p(e.charset),...p(e.customText??"")])];if(d.length>65536)throw new Error("This character set exceeds the glyph texture capacity.");const f=i/a,m=s/o,u=.9*Math.min(f/.55,m)*l,g=Math.ceil(f*n)+6,x=Math.ceil(m*n)+6,v=Math.min(d.length,Math.floor(r/g));if(v<1||Math.ceil(d.length/v)*x>r)throw new Error("The glyph atlas exceeds the available GPU texture size.");return{key:c,glyphs:d,indices:new Map(d.map((t,e)=>[t,e])),cellWidth:f,cellHeight:m,fontSize:u,padding:3,tileWidth:g,tileHeight:x,atlasColumns:v,atlasWidth:v*g,atlasHeight:Math.ceil(d.length/v)*x}}(o,{...v,charset:M},h,l,f,g,x);if(y!==o&&(t.width=y.atlasWidth,t.height=y.atlasHeight,i.font=y.fontSize*f+'px "JetBrains Mono", monospace',i.textAlign="center",i.textBaseline="middle",i.fillStyle="#fff",y.glyphs.forEach((t,e)=>i.fillText(t,e%y.atlasColumns*y.tileWidth+y.padding+y.cellWidth*f*.5,Math.floor(e/y.atlasColumns)*y.tileHeight+y.padding+y.cellHeight*f*.5))),o=y,m)a=function(t,e,i,s,n=!1){const a=t.length,o=t[0]?.length??0,r=s?.cols===o&&s.rows===a?s:{cols:o,rows:a,indices:new Uint8Array(o*a*4),colors:new Uint8ClampedArray(o*a*4)};r.indices.fill(0),r.colors.fill(0);const h="accent"===i.colorMode?[1,3,5].map(t=>parseInt(i.accentColor.slice(t,t+2),16)):null;for(let s=0;s<a;s++){if(t[s].length!==o)throw new Error("Glyph frames must have a rectangular cell grid.");for(let a=0;a<o;a++){const l=t[s][a];if(!l.char||!n&&" "===l.char||l.a<10)continue;const c=e.get(l.char);if(void 0===c)throw new Error(`Glyph is absent from the configured character set: ${l.char}`);const d=4*(s*o+a);let f=l.r,m=l.g,u=l.b;if(h)[f,m,u]=h;else if("fullcolor"!==i.colorMode){const t=.299*f+.587*m+.114*u|0;f="matrix"===i.colorMode?0:t,m=t,u=f}(n||0!==f||0!==m||0!==u)&&(r.indices[d]=255&c,r.indices[d+1]=c>>>8,r.indices[d+2]=Math.round(.299*l.r+.587*l.g+.114*l.b),r.colors[d]=f,r.colors[d+1]=m,r.colors[d+2]=u,r.colors[d+3]=l.a)}}return r}(m,o.indices,v,a,!0);else{e.width=g,e.height=x,s.drawImage(r,0,0,g,x);const t=s.getImageData(0,0,g,x).data;a={cols:g,rows:x,indices:new Uint8Array(g*x*4),colors:new Uint8ClampedArray(t)};for(let e=0;e<t.length;e+=4){const i=Math.min(1,(.299*t[e]+.587*t[e+1]+.114*t[e+2])/255*(t[e+3]/255)*3);a.indices[e+2]=Math.round(255*i),a.indices[e]=Math.min(o.glyphs.length-1,Math.floor(i*o.glyphs.length))}}return{plan:o,packed:a,atlas:t,dots:"dots"===v.renderMode,dotSize:v.dotSizeRatio??.72}},reset(){o=null},destroy(){t.width=t.height=e.width=e.height=1,a=void 0,o=null}}}function v(t){return!!t&&"ascii"===t.renderMode&&!/\p{Extended_Pictographic}/u.test(t.customText||t.charset)&&!t.charsetFrames?.length&&["fullcolor","grayscale","matrix","accent"].includes(t.colorMode)&&("accent"!==t.colorMode||/^#[\da-f]{6}$/i.test(t.accentColor))}function M(t){for(let e=t;e;e=e.parentElement){const t=getComputedStyle(e).backgroundColor.match(/[\d.]+/g)?.map(Number);if(t&&t.length>=3&&(t[3]??1)>.5)return(.299*t[0]+.587*t[1]+.114*t[2])/255<.4?[10/255,10/255,10/255,1]:[250/255,249/255,247/255,1]}const e=document.documentElement.dataset.theme;if("dark"!==e&&"light"!==e&&!t.isConnected&&document.body)return M(document.body);return"dark"===e||"light"!==e&&(document.documentElement.classList.contains("dark")||matchMedia("(prefers-color-scheme: dark)").matches)?[10/255,10/255,10/255,1]:[250/255,249/255,247/255,1]}function y(t,e,s){const r=e.style.visibility;let h=document.createElement("canvas"),l=null,c=null,u=null,p=null;const y=[],w=[];let S=!1,b=!1,E=4096,T=null,A=0,k=0,z=0,R=0,D=!1;const C=function(){const t=document.createElement("canvas"),e=t.getContext("2d");return{paint(i,s,n,a){s&&(t.width===i.canvas.width&&t.height===i.canvas.height||(t.width=i.canvas.width,t.height=i.canvas.height),e.globalCompositeOperation="copy",e.drawImage(i.canvas,0,0),e.globalCompositeOperation="destination-in",e.drawImage(s.canvas,0,0,t.width,t.height),e.globalCompositeOperation="source-in",e.fillStyle="#090909",e.fillRect(0,0,t.width,t.height),e.globalCompositeOperation="source-over",i.drawImage(t,0,0,n,a))},destroy(){t.width=t.height=1}}}();let F;const _=document.createElement("canvas"),I=document.createElement("canvas"),P=_.getContext("2d"),X=I.getContext("2d");let L=!1;const U=new a,G=x();let N=null,Y={};const B=()=>{h.className="ascii-hover-surface",h.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none",h.setAttribute("role","img"),h.setAttribute("aria-label","ASCII artwork preview"),h.dataset.renderer=l?"surface-gpu":"surface-canvas",t.prepend(h),e.style.visibility="hidden"},H=()=>{l&&(y.forEach(t=>l.deleteTexture(t)),w.forEach(t=>l.deleteShader(t)),u&&l.deleteProgram(u),p&&l.deleteBuffer(p))},W=()=>{S||c||(h.removeEventListener("webglcontextlost",W),H(),h.remove(),l=null,h=document.createElement("canvas"),c=h.getContext("2d"),B(),s())};try{if(l=h.getContext("webgl",{alpha:!0,antialias:!1,depth:!1,stencil:!1,premultipliedAlpha:!0,preserveDrawingBuffer:!0}),!l)throw new Error("WebGL unavailable");E=l.getParameter(l.MAX_TEXTURE_SIZE);const t=(t,e)=>{const i=l.createShader(t);if(w.push(i),l.shaderSource(i,e),l.compileShader(i),!l.getShaderParameter(i,l.COMPILE_STATUS))throw new Error(l.getShaderInfoLog(i)||"Shader compilation failed");return i};if(u=l.createProgram(),l.attachShader(u,t(l.VERTEX_SHADER,"attribute vec2 position; void main(){gl_Position=vec4(position,0.,1.);}")),l.attachShader(u,t(l.FRAGMENT_SHADER,"\n precision highp float;\n uniform sampler2D artwork; uniform sampler2D surface;\n uniform vec2 resolution; uniform vec2 sceneSize; uniform vec2 cellSize;\n uniform vec2 surfaceSize; uniform float strength;\n \nuniform float hoverMode;\nuniform vec4 hoverFocus;\nfloat surfaceLight(vec2 uv, vec2 size) {\n vec2 delta = (uv - hoverFocus.xy) * size / min(size.x, size.y) / hoverFocus.w;\n float light = exp(-3.0 * dot(delta, delta));\n if (hoverMode > 1.5) light = (exp(-delta.x * delta.x * 110.0) * 1.3 - exp(-delta.x * delta.x * 12.0) * .3) * exp(-delta.y * delta.y * 1.8);\n return hoverMode > .5 ? light * hoverFocus.z : 0.0;\n}\nvec3 illuminate(vec3 ink, float light) {\n return mix(ink, vec3(1.0), max(0.0, light) * .82) * (1.0 + min(0.0, light));\n}\n\n uniform sampler2D codes; uniform sampler2D cellColors; uniform sampler2D glyphAtlas;\n uniform vec2 gridSize; uniform vec2 atlasSize; uniform vec2 tileSize;\n uniform float atlasColumns; uniform float padding; uniform float glyphCount;\n uniform float dots; uniform float dotSize; uniform float directGlyphs; uniform vec4 backdrop;\n uniform float edgeEffect; uniform sampler2D textMask; uniform float hasTextMask;\n \nuniform float finishMode;\nuniform float finishPixelRatio;\nuniform float finishSoftness;\nvec3 edgeCoverage(sampler2D sheet, vec2 uv, vec2 atlas, vec2 pixel, vec2 viewport, float amount) {\n float a=texture2D(sheet,uv).a;\n if(amount<=0.0 || finishMode<.5) return vec3(a);\n vec2 radial=(pixel/viewport-.5)*2.0;\n float edge=smoothstep(.3,1.05,length(radial));\n float strength=clamp(amount,0.0,1.0)*edge;\n if(strength<=0.0) return vec3(a);\n vec2 cssPixel=pixel/max(1.0,finishPixelRatio);\n // Etch is a single texture sample: linework, not an opacity wash.\n if(finishMode>1.5 && finishMode<2.5) {\n float hatch=step(.68,fract((cssPixel.y+cssPixel.x*.22)*.5));\n return vec3(a*(1.0-hatch*strength*.64));\n }\n // Samples remain inside the current atlas tile's three-pixel padding.\n if(finishMode>2.5) {\n float band=floor(cssPixel.y/3.0);\n float phase=fract(sin(band*12.9898)*43758.5453);\n float tear=(phase-.5)*3.6*strength;\n float displaced=texture2D(sheet,uv+vec2(tear,0.0)/atlas).a;\n float cut=step(.72,fract(cssPixel.y*.5));\n return vec3(mix(a,displaced,strength)*(1.0-cut*.55*strength));\n }\n // A five-tap lens: opposed red/cyan edges with a short soft shoulder.\n // The center remains untouched; all offsets stay within three atlas texels.\n vec2 direction=normalize(vec2(radial.x-radial.y*.3,radial.y+radial.x*.3)+vec2(.00001));\n vec2 shift=direction*(2.35+.45*finishSoftness)*strength/atlas;\n float left=texture2D(sheet,uv-shift).a,right=texture2D(sheet,uv+shift).a;\n float softLeft=texture2D(sheet,uv-shift*.45).a,softRight=texture2D(sheet,uv+shift*.45).a;\n float red=left*.7+softLeft*.22+a*.08;\n float cyan=right*.7+softRight*.22+a*.08;\n // Reuse the same taps for a short optical blur and peripheral fade.\n // No whole-canvas blur, extra pass or softened HTML controls.\n float soft=a*.4+(left+right+softLeft+softRight)*.15;\n vec3 fringe=mix(vec3(red,cyan,cyan),vec3(soft),finishSoftness*.45);\n return mix(vec3(a),fringe,strength)*(1.-finishSoftness*strength*.32);\n\n}\n\n \nuniform float edgeSafe;\nuniform float trailAmount;\nuniform float trailKind;\nvec4 trailField(vec2 address) {\n return texture2D(surface,(address*(surfaceSize-1.0)+.5)/surfaceSize);\n}\nfloat trailFieldDensity(vec4 field) {\n return (field.r*65280.0+field.g*255.0)/65535.0*trailAmount;\n}\nfloat trailDensity(vec2 address) { return trailFieldDensity(trailField(address)); }\nfloat trailPin(vec2 cell, vec2 grid) {\n vec2 edge=min(cell,grid-1.0-cell);\n return mix(1.,smoothstep(1.0,5.0,min(edge.x,edge.y)),edgeSafe);\n}\nvec2 trailSource(vec2 cell, vec2 grid, vec4 field) {\n vec2 home=(cell+.5)/grid;\n if(trailKind>.5 || trailAmount<=0.) return home;\n float pin=trailPin(cell,grid);\n float response=1.-exp(-trailFieldDensity(field)*pin*3.5);\n vec2 drift=(field.ba*255.-128.)/127.;\n return clamp(home-drift*response*.026*pin,.5/grid,1.-.5/grid);\n}\nvec2 decodedGlyph(vec4 code) {\n return vec2(floor(code.r*255.+.5)+floor(code.g*255.+.5)*256.,code.b);\n}\n// Bilinear interpolation happens before glyph selection, never between bitmap\n// letters. Four small metadata reads replace the old four full-glyph gathers.\nvec2 flowGlyph(sampler2D codes,vec2 uv,vec2 grid) {\n vec2 p=uv*grid-.5,b=floor(p),f=fract(p);\n return mix(mix(decodedGlyph(texture2D(codes,(b+.5)/grid)),decodedGlyph(texture2D(codes,(b+vec2(1.5,.5))/grid)),f.x),\n mix(decodedGlyph(texture2D(codes,(b+vec2(.5,1.5))/grid)),decodedGlyph(texture2D(codes,(b+1.5)/grid)),f.x),f.y);\n}\nvec3 trailInk(vec3 ink, float density) {\n if (trailKind < .5) return ink;\n float peak=max(ink.r,max(ink.g,ink.b));\n float raised=trailKind>1.5?peak:max(peak,min(.44,density*.75));\n return peak>.001 ? ink*(raised/peak) : vec3(raised);\n}\nfloat flowIndex(float index,float count,float density) {\n float last=max(0.,count-1.);\n float response=1.-exp(-max(0.,density)*3.5);\n return max(0.,last-abs(last-(index+response*last*2.1)));\n}\nfloat trailTone(float tone, float density) {\n if (trailKind < .5) return flowIndex(tone,2.,density);\n return clamp(tone + (trailKind > 1.5 ? -density : density) * .65, 0.0, 1.0);\n}\nfloat trailIndex(float index, float count, float density, vec2 cell) {\n float grain=fract((cell.x*cell.x*17.0+cell.y*cell.y*23.0+cell.x*cell.y*19.0)*.0137);\n if(trailKind>1.5) return max(0.0,index-floor(density*count*(1.35+grain*.9)));\n if(trailKind<.5) {\n float seed=fract(sin(dot(cell,vec2(127.1,311.7)))*43758.5453);\n float response=1.-exp(-max(0.,density)*3.5);\n return floor(max(0.,flowIndex(index,count,density)-response*(1.-response)*seed*3.)+.5);\n }\n return min(count-1.0,index+floor(density*count*.85));\n}\n\n \n uniform float motionMode; uniform float motionTime; uniform float fineDither; uniform float ditherAmount;\n float printGrain(vec2 p) { return fract(52.9829189*fract(dot(p,vec2(.06711056,.00583715)))); }\n vec4 ambientAt(vec2 uv) {\n float p=motionTime*.5235987756;\n float edge=smoothstep(0.,.12,min(min(uv.x,1.-uv.x),min(uv.y,1.-uv.y)));\n if(motionMode<.5) return vec4(0.,0.,0.,1.);\n if(motionMode<1.5) {\n float fold=sin(uv.x*9.+uv.y*5.+p)+sin(uv.y*8.-uv.x*3.-p);\n float light=pow(max(0.,1.-abs(fold)*.72),3.);\n return vec4(0.,0.,(light*.22-.045)*edge,1.);\n }\n if(motionMode<2.5) return vec4(sin(uv.y*9.+p)*cos(uv.x*7.-p)*10.*edge,cos(uv.x*8.+p)*sin(uv.y*6.-p)*7.*edge,0.,1.);\n if(motionMode>5.5) return vec4(0.,0.,sin(p+printGrain(floor(uv*vec2(160.,100.)))*6.28318530718)*.07,1.);\n if(motionMode>4.5) {\n vec2 delta=uv-.5; float wave=sin(length(delta)*22.-p)*edge;\n return vec4(delta*wave*9.,wave*.035,1.);\n }\n if(motionMode>3.5) return vec4(0.,0.,pow(.5+.5*cos(uv.x*5.+uv.y*3.-p),8.)*.2-.025,1.);\n float cycle=mod(motionTime,12.);\n float grain=printGrain(floor(uv*vec2(160.,100.)));\n float order=uv.x*.65+uv.y*.2+grain*.15+sin(uv.x*8.-uv.y*5.)*.08;\n float gone=smoothstep(1.8+order*1.2,3.8+order*1.2,cycle)*(1.-smoothstep(5.+order*1.7,7.2+order*1.7,cycle));\n return vec4(sin(uv.y*9.+p)*gone*(1.-gone)*24.*edge,-gone*(1.-gone)*(8.+grain*12.)*edge,-gone*.45,1.-gone*.9);\n }\n\n float toneAt(vec2 uv) {\n vec2 p=uv*gridSize-.5, b=floor(p), f=fract(p);\n return mix(mix(texture2D(codes,(b+.5)/gridSize).b,texture2D(codes,(b+vec2(1.5,.5))/gridSize).b,f.x),mix(texture2D(codes,(b+vec2(.5,1.5))/gridSize).b,texture2D(codes,(b+1.5)/gridSize).b,f.x),f.y);\n }\n vec4 flowingCharacter(vec2 pixel, vec2 cell, vec4 ambient) {\n if(cell.x<0. || cell.y<0. || cell.x>=gridSize.x || cell.y>=gridSize.y) return vec4(0.);\n vec2 address=(cell+.5)/gridSize;\n vec4 field=trailField(address);\n vec2 local=pixel-cell*cellSize;\n if(local.x<0. || local.y<0. || local.x>=cellSize.x || local.y>=cellSize.y) return vec4(0.);\n vec2 source=trailSource(cell,gridSize,field);\n vec2 encoded=flowGlyph(codes,source,gridSize);\n vec4 color=texture2D(cellColors,source);\n float original=encoded.x;\n float density=trailFieldDensity(field)*trailPin(cell,gridSize),index=trailIndex(original,glyphCount,density,cell);\n if(original>.5) index=clamp(floor(index+ambient.z*(glyphCount-1.)+printGrain(cell)),0.,glyphCount-1.);\n if(index<.5 || color.a<.01) return vec4(0.);\n vec2 slot=vec2(mod(index,atlasColumns),floor(index/atlasColumns));\n float alpha=texture2D(glyphAtlas,(slot*tileSize+padding+local*resolution/sceneSize)/atlasSize).a;\n if(dots>.5) {\n vec2 d=(local-cellSize*.5)/min(cellSize.x,cellSize.y);\n float r=min(.48,(index/(glyphCount-1.))*.5*dotSize);\n alpha=1.-smoothstep(r-.06,r+.02,length(d));\n }\n vec3 coverage=dots>.5?vec3(alpha):edgeCoverage(glyphAtlas,(slot*tileSize+padding+local*resolution/sceneSize)/atlasSize,atlasSize,pixel,sceneSize,edgeEffect);\n coverage*=color.a;alpha=max(coverage.r,max(coverage.g,coverage.b));\n return vec4(trailInk(color.rgb,density)*coverage,alpha);\n }\n void main(){\n vec2 uv = vec2(gl_FragCoord.x, resolution.y - gl_FragCoord.y) / resolution;\n vec2 pixel = uv * sceneSize;\n if (strength > 0.) {\n vec4 normal = texture2D(surface, (uv * (surfaceSize - 1.) + .5) / surfaceSize) * 255.;\n vec2 slope = (vec2(normal.r * 256. + normal.g, normal.b * 256. + normal.a) - 32768.) / 32767.;\n vec2 edge = min(pixel, sceneSize - pixel) / cellSize;\n uv -= slope * strength * mix(1.,smoothstep(2.,8.,min(edge.x,edge.y)),edgeSafe) / sceneSize;\n }\n vec4 ambient=ambientAt(uv);\n uv -= ambient.xy/sceneSize;\n pixel=uv*sceneSize;\n vec4 ink = vec4(0.);\n if (directGlyphs > .5) {\n vec2 cell=floor(pixel/cellSize), address=(cell+.5)/gridSize;\n vec4 encoded=texture2D(codes,address), color=texture2D(cellColors,address);\n float index=floor(encoded.r*255.+.5)+floor(encoded.g*255.+.5)*256.;\n if(index>.5 && color.a>.01) {\n vec2 local=(pixel-cell*cellSize)*resolution/sceneSize;\n vec2 slot=vec2(mod(index,atlasColumns),floor(index/atlasColumns));\n float alpha=texture2D(glyphAtlas,(slot*tileSize+padding+local)/atlasSize).a*color.a;\n vec3 coverage=edgeCoverage(glyphAtlas,(slot*tileSize+padding+local)/atlasSize,atlasSize,pixel,sceneSize,edgeEffect)*color.a;\n ink=vec4(color.rgb*coverage,max(coverage.r,max(coverage.g,coverage.b)));\n }\n } else ink = texture2D(artwork, uv);\n if (fineDither > .5) {\n vec2 cell=floor(pixel/cellSize),address=(cell+.5)/gridSize;\n vec4 color=texture2D(cellColors,address);\n float density=trailAmount>0.?trailDensity(address):0.;\n vec2 source=trailAmount>0. && trailKind<.5?trailSource(cell,gridSize,trailField(address)):uv;\n float tone=trailTone(clamp(toneAt(source)+ambient.z,0.,1.),density*(trailKind<.5?trailPin(cell,gridSize):1.));\n float pitch=max(1.,min(cellSize.x,cellSize.y)*.32);\n float grain=.5+(printGrain(floor(pixel/pitch))-.5)*ditherAmount;\n float alpha=(tone<.001?0.:tone>.999?1.:smoothstep(grain-.035,grain+.035,tone))*color.a*ambient.w;\n // Preserve hue; tone is carried by mark coverage rather than muddy ink.\n vec3 hue=color.rgb/max(.001,max(color.r,max(color.g,color.b)));\n if(hasTextMask>.5) hue=mix(hue,vec3(.035),texture2D(textMask,vec2(gl_FragCoord.x,resolution.y-gl_FragCoord.y)/resolution).a);\n gl_FragColor=vec4(hue*alpha,alpha); return;\n }\n if ((trailAmount > 0. && trailKind > .5) || motionMode > .5) {\n vec2 cell=floor(pixel/cellSize), address=(cell+.5)/gridSize;\n float density=trailAmount>0.?trailDensity(address):0.;\n vec4 encoded=texture2D(codes,address);\n float original=floor(encoded.r*255.+.5)+floor(encoded.g*255.+.5)*256.;\n float index=trailIndex(original,glyphCount,density,cell);\n if(original>.5) index=clamp(floor(index+ambient.z*(glyphCount-1.)+printGrain(cell)),0.,glyphCount-1.);\n vec4 color=texture2D(cellColors,address);\n if((index!=original || motionMode>.5) && color.a>.01) {\n vec2 local=(pixel-cell*cellSize)*resolution/sceneSize;\n vec2 slot=vec2(mod(index,atlasColumns),floor(index/atlasColumns));\n float alpha=texture2D(glyphAtlas,(slot*tileSize+padding+local)/atlasSize).a;\n if(dots>.5) {\n vec2 d=(pixel-(cell+.5)*cellSize)/min(cellSize.x,cellSize.y);\n float r=min(.48,(index/(glyphCount-1.))*.5*dotSize);\n alpha=1.-smoothstep(r-.06,r+.02,length(d));\n }\n // Replace the cell, rather than blending two glyphs into a ghost.\n vec3 rgb=trailInk(color.rgb,density);\n ink=vec4(rgb*alpha*color.a,alpha*color.a);\n }\n }\n if(trailAmount>0. && trailKind<.5 && trailDensity((floor(pixel/cellSize)+.5)/gridSize)>.001) {\n ink=flowingCharacter(pixel,floor(pixel/cellSize),ambient);\n }\n vec3 straightInk = ink.a > .0 ? ink.rgb / ink.a : vec3(.0);\n float value = max(straightInk.r, max(straightInk.g, straightInk.b));\n // Lighting belongs to character ink; black/transparent gaps stay empty.\n float light = surfaceLight((floor(pixel / cellSize) + .5) * cellSize / sceneSize, sceneSize);\n vec3 lit = illuminate(straightInk, light * smoothstep(0., .22, value)) * ink.a;\n if(hasTextMask>.5) lit=mix(lit,vec3(.035)*ink.a,texture2D(textMask,vec2(gl_FragCoord.x,resolution.y-gl_FragCoord.y)/resolution).a);\n vec4 result = vec4(lit, ink.a)*ambient.w;\n gl_FragColor = directGlyphs > .5 ? result + backdrop*(1.-result.a) : result;\n }")),l.linkProgram(u),!l.getProgramParameter(u,l.LINK_STATUS))throw new Error("Surface shader link failed");l.useProgram(u),p=l.createBuffer(),l.bindBuffer(l.ARRAY_BUFFER,p),l.bufferData(l.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),l.STATIC_DRAW);const e=l.getAttribLocation(u,"position");l.enableVertexAttribArray(e),l.vertexAttribPointer(e,2,l.FLOAT,!1,0,0),Y=Object.fromEntries(["finishSoftness","finishMode","finishPixelRatio","edgeEffect","textMask","hasTextMask","artwork","surface","resolution","sceneSize","cellSize","surfaceSize","strength","hoverMode","hoverFocus","codes","cellColors","glyphAtlas","gridSize","atlasSize","tileSize","atlasColumns","padding","glyphCount","dots","dotSize","directGlyphs","backdrop","trailKind","edgeSafe","trailAmount","motionMode","motionTime","fineDither","ditherAmount"].map(t=>[t,l.getUniformLocation(u,t)]));for(let t=0;t<6;t++){const e=l.createTexture();y.push(e),l.activeTexture(l.TEXTURE0+t),l.bindTexture(l.TEXTURE_2D,e),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.LINEAR),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.LINEAR),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,1,1,0,l.RGBA,l.UNSIGNED_BYTE,new Uint8Array(4)),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE)}l.uniform1i(Y.textMask,5),l.uniform1i(Y.codes,2),l.uniform1i(Y.cellColors,3),l.uniform1i(Y.glyphAtlas,4),l.uniform1i(Y.artwork,0),l.uniform1i(Y.surface,1),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),l.disable(l.BLEND),l.disable(l.DEPTH_TEST),h.addEventListener("webglcontextlost",W),B()}catch{W()}const O=()=>{S||(G.reset(),N=null,b=!1,s())};return document.fonts?.addEventListener("loadingdone",O),document.fonts?.ready.then(O),{get canvas(){return h},canRenderGlyphs:t=>!!l&&!S&&v(t),render(t,s,a,r,u,p,x,w,B=0,H={}){const O=i(w?.animationStyle),K=U.update(B,O,w?.animationSpeed),$=(t=>!0===t?.fineDither&&!t.customText&&!t.charsetFrames?.length&&!/[A-Za-z]/.test(t.charset??""))(w),q=!!l&&!!x&&v(w);if(q!==D&&(b=!1,D=q),S||!a||!r||!e.width||!e.height)return;const j=Math.min(e.width/a,1.5,Math.sqrt(4e6/(a*r))),J=Math.max(1,Math.round(a*j)),V=Math.max(1,Math.round(r*j));if(h.width===J&&h.height===V||(h.width=J,h.height=V,b=!1),l&&(e.width>E||e.height>E)&&W(),(q||d(s.mode)||"none"!==O||$)&&(t||!b||!N)&&(N=G.update(e,a,r,u,p,j,x,w),l)){const{plan:t,packed:e,atlas:i}=N;for(const[t,i]of[[2,e.indices],[3,e.colors]])l.activeTexture(l.TEXTURE0+t),l.bindTexture(l.TEXTURE_2D,y[t]),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,3===t?l.LINEAR:l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,3===t?l.LINEAR:l.NEAREST),A!==e.cols||k!==e.rows?l.texImage2D(l.TEXTURE_2D,0,l.RGBA,e.cols,e.rows,0,l.RGBA,l.UNSIGNED_BYTE,i):l.texSubImage2D(l.TEXTURE_2D,0,0,0,e.cols,e.rows,l.RGBA,l.UNSIGNED_BYTE,i);A=e.cols,k=e.rows,T!==t&&(l.activeTexture(l.TEXTURE4),l.bindTexture(l.TEXTURE_2D,y[4]),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,l.RGBA,l.UNSIGNED_BYTE,i),T=t),l.uniform2f(Y.gridSize,e.cols,e.rows),l.uniform2f(Y.atlasSize,t.atlasWidth,t.atlasHeight),l.uniform2f(Y.tileSize,t.tileWidth,t.tileHeight),l.uniform1f(Y.atlasColumns,t.atlasColumns),l.uniform1f(Y.padding,t.padding),l.uniform1f(Y.glyphCount,t.glyphs.length),l.uniform1f(Y.dots,N.dots?1:0),l.uniform1f(Y.dotSize,N.dotSize)}if(l){l.uniform1f(Y.motionMode,(t=>["none","caustics","current","reform","sheen","tidal","grain"].indexOf(t))(O)),l.uniform1f(Y.motionTime,K),l.uniform1f(Y.fineDither,$?1:0),l.uniform1f(Y.ditherAmount,Math.max(0,Math.min(2,w?.ditherStrength??1))),l.uniform1f(Y.trailKind,"dissolve"===s.mode?2:"contour"===s.mode?1:0),l.uniform1f(Y.edgeSafe,s.edgeSafe?1:0),l.uniform1f(Y.trailAmount,d(s.mode)?s.focus[2]:0),l.viewport(0,0,J,V),q||!t&&b||(l.activeTexture(l.TEXTURE0),l.bindTexture(l.TEXTURE_2D,y[0]),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,l.RGBA,l.UNSIGNED_BYTE,e),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1)),l.uniform1f(Y.directGlyphs,q?1:0),!q||!t&&b||l.uniform4fv(Y.backdrop,H.textMask||function(t){const e=t.length,i=t[0]?.length??0;for(let s=0;s<e;s+=Math.max(1,e>>2))for(let e=0;e<i;e+=Math.max(1,i>>2))if(t[s][e].a<200)return!0;return!1}(x)?[0,0,0,0]:M(e)),b=!0,l.activeTexture(l.TEXTURE1),l.bindTexture(l.TEXTURE_2D,y[1]),z!==s.width||R!==s.height?(l.texImage2D(l.TEXTURE_2D,0,l.RGBA,s.width,s.height,0,l.RGBA,l.UNSIGNED_BYTE,s.pixels),z=s.width,R=s.height):l.texSubImage2D(l.TEXTURE_2D,0,0,0,s.width,s.height,l.RGBA,l.UNSIGNED_BYTE,s.pixels),l.uniform2f(Y.resolution,J,V),l.uniform2f(Y.sceneSize,a,r),l.uniform2f(Y.cellSize,u,p),l.uniform2f(Y.surfaceSize,s.width,s.height),l.uniform1f(Y.strength,s.strength),l.uniform1f(Y.hoverMode,"light"===s.mode?1:"scan"===s.mode?2:0),l.uniform4fv(Y.hoverFocus,s.focus),H.textMask&&H.textMask!==F&&(l.activeTexture(l.TEXTURE5),l.bindTexture(l.TEXTURE_2D,y[5]),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,l.RGBA,l.UNSIGNED_BYTE,H.textMask.canvas),F=H.textMask),l.uniform1f(Y.hasTextMask,H.textMask?1:0);const i=function(t={}){const e=g.some(e=>e.value===t.filter)?t.filter:"prism",i=Number.isFinite(t.edgeEffect)?Math.max(0,Math.min(1,t.edgeEffect)):t.filter?1:0,s=Number.isFinite(t.edgeSoftness)?Math.max(0,Math.min(1,t.edgeSoftness)):0;return{mode:["clean","prism","etch","signal"].indexOf(e),amount:"clean"===e?0:i,softness:"prism"===e?s:0}}(H);l.uniform1f(Y.edgeEffect,i.amount),l.uniform1f(Y.finishMode,i.mode),l.uniform1f(Y.finishSoftness,i.softness),l.uniform1f(Y.finishPixelRatio,1),l.drawArrays(l.TRIANGLE_STRIP,0,4)}else if(c){if(c.setTransform(j,0,0,j,0,0),c.clearRect(0,0,a,r),c.drawImage(e,0,0,a,r),("none"!==O||$)&&N){c.clearRect(0,0,a,r);const{plan:t,packed:e,atlas:i}=N,h=[0,0,0,1],l=[0,0,0,0,0,0],g=Math.max(1,.32*Math.min(u,p));for(let a=0;a<e.rows;a++)for(let r=0;r<e.cols;r++){const x=(r+.5)/e.cols,v=(a+.5)/e.rows,M=4*(a*e.cols+r);if(e.colors[M+3]<10)continue;o(O,x,v,K,h);const y=4*(Math.min(s.height-1,Math.round(v*(s.height-1)))*s.width+Math.min(s.width-1,Math.round(x*(s.width-1)))),S=d(s.mode)?(256*s.pixels[y]+s.pixels[y+1])/65535*s.focus[2]:0,b=e.indices[M]+256*e.indices[M+1];"trail"===s.mode&&m(e.indices,e.colors,e.cols,e.rows,r,a,S,(s.pixels[y+2]-128)/127,(s.pixels[y+3]-128)/127,t.glyphs.length,l,s.edgeSafe);let E="trail"===s.mode?l[0]:"dissolve"===s.mode?b-Math.floor(S*t.glyphs.length*1.8):b+Math.floor(S*t.glyphs.length*.85);b>0&&(E+=h[2]*(t.glyphs.length-1)),E=Math.max(0,Math.min(t.glyphs.length-1,Math.floor(E+n(r,a))));let T=h[0],A=h[1];s.strength>0&&(T+=(256*s.pixels[y]+s.pixels[y+1]-32768)/32767*s.strength,A+=(256*s.pixels[y+2]+s.pixels[y+3]-32768)/32767*s.strength);const k=r*u+T,z=a*p+A,R=("trail"===s.mode?l[5]:e.colors[M+3])/255*h[3],D="trail"===s.mode?l[2]:e.colors[M],C="trail"===s.mode?l[3]:e.colors[M+1],F="trail"===s.mode?l[4]:e.colors[M+2],_=$?Math.max(1,D,C,F):255,I=`rgb(${D/_*255},${C/_*255},${F/_*255})`;if(c.fillStyle=I,$){const t="trail"===s.mode?f(Math.max(0,Math.min(1,l[1]+h[2])),2,S):Math.max(0,Math.min(1,e.indices[M+2]/255+h[2]+.65*("dissolve"===s.mode?-S:S)));c.globalAlpha=R;for(let e=0;e<p;e+=g)for(let i=0;i<u;i+=g)t>.5+(n(Math.floor((k+i)/g),Math.floor((z+e)/g))-.5)*Math.max(0,Math.min(2,w?.ditherStrength??1))&&c.fillRect(k+i,z+e,Math.min(g,u-i),Math.min(g,p-e))}else if(E>0)if(c.globalAlpha=R,N.dots){const e=Math.min(.48,E/(t.glyphs.length-1)*.5*N.dotSize)*Math.min(u,p);c.beginPath(),c.arc(k+.5*u,z+.5*p,e,0,2*Math.PI),c.fill()}else c.drawImage(i,E%t.atlasColumns*t.tileWidth+t.padding,Math.floor(E/t.atlasColumns)*t.tileHeight+t.padding,t.cellWidth*j,t.cellHeight*j,k,z,u,p),c.globalAlpha=1,c.globalCompositeOperation="source-atop",c.fillRect(k,z,u,p),c.globalCompositeOperation="source-over"}c.globalAlpha=1}else if(d(s.mode)&&N){const{plan:t,packed:e,atlas:i}=N,n=[0,0,0,0,0,0];for(let a=0;a<e.rows;a++)for(let o=0;o<e.cols;o++){const r=4*(Math.min(s.height-1,Math.round((a+.5)/e.rows*(s.height-1)))*s.width+Math.min(s.width-1,Math.round((o+.5)/e.cols*(s.width-1)))),h=(256*s.pixels[r]+s.pixels[r+1])/65535*s.focus[2],l=4*(a*e.cols+o),d=.0137*(o*o*17+a*a*23+o*a*19),f=d-Math.floor(d);"trail"===s.mode&&m(e.indices,e.colors,e.cols,e.rows,o,a,h,(s.pixels[r+2]-128)/127,(s.pixels[r+3]-128)/127,t.glyphs.length,n,s.edgeSafe);const g=e.indices[l]+256*e.indices[l+1],x="trail"===s.mode?Math.round(n[0]):"dissolve"===s.mode?Math.max(0,g-Math.floor(h*t.glyphs.length*(1.35+.9*f))):Math.min(t.glyphs.length-1,g+Math.floor(h*t.glyphs.length*.85));if(x===g&&("trail"!==s.mode||h<1e-4)||e.colors[l+3]<10)continue;const v=o*u,M=a*p;if(c.clearRect(v,M,u,p),c.globalAlpha=("trail"===s.mode?n[5]:e.colors[l+3])/255,N.dots){const e=Math.min(.48,x/(t.glyphs.length-1)*.5*N.dotSize)*Math.min(u,p);c.fillStyle="#fff",c.beginPath(),c.arc(v+.5*u,M+.5*p,e,0,2*Math.PI),c.fill()}else c.drawImage(i,x%t.atlasColumns*t.tileWidth+t.padding,Math.floor(x/t.atlasColumns)*t.tileHeight+t.padding,t.cellWidth*j,t.cellHeight*j,v,M,u,p);c.globalAlpha=1,c.globalCompositeOperation="source-atop";const y="trail"===s.mode?n[2]:e.colors[l],w="trail"===s.mode?n[3]:e.colors[l+1],S="trail"===s.mode?n[4]:e.colors[l+2],b=Math.max(y,w,S),E="dissolve"===s.mode||"trail"===s.mode?b:Math.max(b,Math.min(112,191*h)),T=b?E/b:0;c.fillStyle=`rgb(${b?y*T:E},${b?w*T:E},${b?S*T:E})`,c.fillRect(v,M,u,p),c.globalCompositeOperation="source-over"}}else if("light"===s.mode||"scan"===s.mode){!t&&L&&_.width===J&&_.height===V||(_.width=J,_.height=V,I.width=J,I.height=V,P.filter="brightness(3)",P.drawImage(e,0,0,J,V),P.filter="none",L=!0);const[i,n,o,h]=s.focus;if(o>.001){X.setTransform(1,0,0,1,0,0),X.clearRect(0,0,J,V),X.drawImage(_,0,0),X.globalCompositeOperation="destination-in",X.save(),X.translate(i*J,n*V),X.scale("scan"===s.mode?.13:1,1);const t=h*Math.min(J,V),e=X.createRadialGradient(0,0,0,0,0,t);e.addColorStop(0,`rgba(255,255,255,${o})`),e.addColorStop(.5,`rgba(255,255,255,${.4*o})`),e.addColorStop(1,"rgba(255,255,255,0)"),X.fillStyle=e,X.fillRect(10*-J,10*-V,20*J,20*V),X.restore(),X.globalCompositeOperation="source-over",c.globalCompositeOperation="source-atop",c.drawImage(I,0,0,a,r),c.globalCompositeOperation="source-over"}}else if(s.strength>0){const t=32,i=18,n=a/t,o=r/i;for(let h=0;h<i;h++)for(let l=0;l<t;l++){const d=(l+.5)/t,f=(h+.5)/i,m=Math.min(s.width-1,Math.round(d*(s.width-1))),g=4*(Math.min(s.height-1,Math.round(f*(s.height-1)))*s.width+m),x=s.pixels,v=Math.min(l*n/u,(a-(l+1)*n)/u,h*o/p,(r-(h+1)*o)/p),M=Math.max(0,Math.min(1,(v-2)/6)),y=s.edgeSafe?M*M*(3-2*M):1,w=(256*x[g]+x[g+1]-32768)/32767*s.strength*y,S=(256*x[g+2]+x[g+3]-32768)/32767*s.strength*y;Math.abs(w)+Math.abs(S)<.02||(c.clearRect(l*n,h*o,n,o),c.drawImage(e,Math.max(0,Math.min(a-n,l*n-w))*e.width/a,Math.max(0,Math.min(r-o,h*o-S))*e.height/r,n*e.width/a,o*e.height/r,l*n,h*o,n,o))}}C.paint(c,H.textMask,a,r)}},destroy(){S=!0,C.destroy(),document.fonts?.removeEventListener("loadingdone",O),G.destroy(),h.removeEventListener("webglcontextlost",W),H(),h.remove(),_.width=_.height=I.width=I.height=1,e.style.visibility=r,l?.getExtension("WEBGL_lose_context")?.loseContext()}}}function w(e,s,n={}){let a,o,r={effect:"trail",strength:.55,radius:n.effect&&"trail"!==n.effect?.2:.45,animated:!1,fps:30,fontSize:7,charAspect:.58,charSpacing:1,paused:!1,charset:" .:-=+*#%@",customText:"",renderMode:"ascii",dotSizeRatio:.72,...n},h=new u(s.clientWidth/Math.max(1,s.clientHeight)),l=!1,c=!1,d=!0,f=0,m=0,g=-1/0,p=0,x=null,v=!1,M=[];const w=matchMedia("(prefers-reduced-motion: reduce)"),S=()=>{l||!c||document.hidden||f||(f=requestAnimationFrame(E))},b=y(e,s,()=>queueMicrotask(()=>{d=!0,S()}));function E(t){if(f=0,l||!c||document.hidden)return;const e=s.clientWidth,n=s.clientHeight;if(!e||!n)return;const u=w.matches||r.paused;h.configure(r.effect,r.strength,r.radius,r.edgeSafe);const y=h.active;if(!u){if(p+=m?Math.min(.1,(t-m)/1e3):0,v){const t=s.getBoundingClientRect();if(t.width&&t.height)for(const e of M)h.move((e.x-t.left)/t.width,(e.y-t.top)/t.height,e.time);M=[],x||h.leave(),v=!1}h.step(m?(t-m)/1e3:1/60)}const E=d||r.animated&&!u&&t-g>=1e3/Math.max(1,Math.min(60,r.fps))-.5;(E||y||h.active||!u&&"none"!==i(r.motion))&&(E&&(a=r.getFrame?.()),b.render(E,h.refraction,e,n,r.fontSize*r.charSpacing,r.fontSize/r.charAspect*r.charSpacing,a,{charset:r.charset,customText:r.customText,renderMode:r.renderMode,dotSizeRatio:r.dotSizeRatio,colorMode:r.colorMode??"fullcolor",accentColor:r.accentColor??"#888888",animationStyle:r.motion,animationSpeed:r.motionSpeed??1,artStyle:"classic",fineDither:r.fineDither,ditherStrength:r.ditherStrength??1},p,{filter:r.filter,edgeEffect:r.edgeEffect,edgeSoftness:r.edgeSoftness,textMask:o?.read()}),E&&(g=t),d=!1),m=t,u||!r.animated&&!h.active&&"none"===i(r.motion)||S()}r.textMask&&(o=t(e,r.textMask,()=>{d=!0,S()}));const T=()=>{h.clear(),x=null,M=[],v=!1,m=0,d=!0,cancelAnimationFrame(f),f=0,S()},A=t=>{if("touch"===t.pointerType||r.paused||w.matches)return;if(t.target instanceof Element&&t.target.closest("button,a,input,summary,select"))return void k();const e=s.getBoundingClientRect();t.clientX<e.left||t.clientX>e.right||t.clientY<e.top||t.clientY>e.bottom?k():(x={x:t.clientX,y:t.clientY,time:t.timeStamp},M.push(x),M.length>6&&M.shift(),v=!0,S())},k=()=>{x=null,v=!0,S()},z=new IntersectionObserver(([t])=>{c=t.isIntersecting,T()});z.observe(e);const R=new ResizeObserver(()=>{h=new u(s.clientWidth/Math.max(1,s.clientHeight)),T()});return R.observe(s),e.addEventListener("pointermove",A),e.addEventListener("pointerleave",k),e.addEventListener("pointercancel",k),document.addEventListener("visibilitychange",T),w.addEventListener("change",T),{get canvas(){return b.canvas},invalidate(){o?.invalidate(),d=!0,S()},update(i){"textMask"in i&&(o?.destroy(),o=i.textMask?t(e,i.textMask,()=>{d=!0,S()}):void 0),r={...r,...i},T()},destroy(){l||(l=!0,cancelAnimationFrame(f),z.disconnect(),R.disconnect(),b.destroy(),o?.destroy(),e.removeEventListener("pointermove",A),e.removeEventListener("pointerleave",k),e.removeEventListener("pointercancel",k),document.removeEventListener("visibilitychange",T),w.removeEventListener("change",T))}}}exports.createTextMask=t,exports.mountHover=w,exports.mountStudioHover=w;//# sourceMappingURL=hover.cjs.map
|