@liiift-studio/threadtext 0.2.0 → 0.2.2

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 CHANGED
@@ -75,8 +75,9 @@ import { ThreadText } from '@liiift-studio/threadtext'
75
75
  ```
76
76
 
77
77
  Thread colour, `fill` (size — the word re-fits to the container width on load/resize),
78
- `weight`, `font`, `sewStyle` (`'machine'` satin rows or `'hand'` — a single thread that
79
- wanders stitch by stitch), `sewRate`, `sheen`, `animate`, and `editable` (type straight on
78
+ `weight`, `font`, `sewStyle` (`'machine'` satin rows in parallel, or `'hand'` — one letter at a
79
+ time, entering at the top and working down, edges last), `sewRate`, `sheen`, `animate`, and
80
+ `editable` (type straight on
80
81
  the artwork — backed by a real input, so touch keyboards and IME work) with an `onTextChange`
81
82
  callback are all options — see `ThreadTextOptions`. Change any of them live with
82
83
  `instance.update(...)` — it redraws instantly, never re-running the sew-in. `react`/`react-dom`
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Q=require("react"),Fe=require("react/jsx-runtime"),Et={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function ot(y,o){let r=Math.imul(y|0,374761393)+Math.imul(o|0,668265263)|0;return r=Math.imul(r^r>>>13,1274126177),((r^r>>>16)>>>0)/4294967295}function ne(y,o){const r=Math.floor(y),l=Math.floor(o),c=y-r,s=o-l,h=c*c*(3-2*c),R=s*s*(3-2*s),E=ot(r,l),P=ot(r+1,l),f=ot(r,l+1),m=ot(r+1,l+1);return E+(P-E)*h+(f-E)*R+(E-P-f+m)*h*R}const At=1e20;function oe(y,o,r,l,c){let s=0;l[0]=0,c[0]=-At,c[1]=At;for(let h=1;h<o;h++){let R=(y[h]+h*h-(y[l[s]]+l[s]*l[s]))/(2*h-2*l[s]);for(;R<=c[s];)s--,R=(y[h]+h*h-(y[l[s]]+l[s]*l[s]))/(2*h-2*l[s]);s++,l[s]=h,c[s]=R,c[s+1]=At}s=0;for(let h=0;h<o;h++){for(;c[s+1]<h;)s++;r[h]=(h-l[s])*(h-l[s])+y[l[s]]}}function Re(y,o,r){const l=new Float64Array(o*r);for(let f=0;f<o*r;f++)l[f]=y[f]?At:0;const c=Math.max(o,r),s=new Float64Array(c),h=new Float64Array(c),R=new Int32Array(c),E=new Float64Array(c+1);for(let f=0;f<o;f++){for(let m=0;m<r;m++)s[m]=l[m*o+f];oe(s,r,h,R,E);for(let m=0;m<r;m++)l[m*o+f]=h[m]}for(let f=0;f<r;f++){for(let m=0;m<o;m++)s[m]=l[f*o+m];oe(s,o,h,R,E);for(let m=0;m<o;m++)l[f*o+m]=h[m]}const P=new Float32Array(o*r);for(let f=0;f<o*r;f++)P[f]=Math.sqrt(l[f]);return P}function re(y,o,r,l,c){let s=Float32Array.from(y);const h=new Float32Array(o*r),R=1/(2*l+1),E=(P,f)=>P<0?0:P>f?f:P;for(let P=0;P<c;P++){for(let f=0;f<r;f++){const m=f*o;let O=0;for(let z=-l;z<=l;z++)O+=s[m+E(z,o-1)];for(let z=0;z<o;z++)h[m+z]=O*R,O+=s[m+E(z+l+1,o-1)]-s[m+E(z-l,o-1)]}for(let f=0;f<o;f++){let m=0;for(let O=-l;O<=l;O++)m+=h[E(O,r-1)*o+f];for(let O=0;O<r;O++)s[O*o+f]=m*R,m+=h[E(O+l+1,r-1)*o+f]-h[E(O-l,r-1)*o+f]}}return s}function ie(y,o){if(!y)return o;const r=y.trim();if(r[0]==="#"){let c=r.slice(1);if(c.length===3&&(c=c[0]+c[0]+c[1]+c[1]+c[2]+c[2]),c.length>=6){const s=parseInt(c.slice(0,2),16),h=parseInt(c.slice(2,4),16),R=parseInt(c.slice(4,6),16);if(!Number.isNaN(s)&&!Number.isNaN(h)&&!Number.isNaN(R))return[s,h,R]}return o}const l=r.match(/rgba?\(([^)]+)\)/i);if(l){const c=l[1].split(",").map(s=>parseFloat(s));if(c.length>=3&&c.slice(0,3).every(s=>!Number.isNaN(s)))return[Math.round(c[0]),Math.round(c[1]),Math.round(c[2])]}return o}function J(y){return y<0?0:y>255?255:Math.round(y)}function St(y,o,r){return y<o?o:y>r?r:y}function ae(y){return(y.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function le(y,o){if(typeof window>"u"||typeof document>"u"||!y)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return o.text??""}};let r=o.text??"",l=o.font??"Georgia, serif",c=St(o.weight??680,1,1e3),s=St(o.fill??.9,.05,1),h=Math.max(1,o.sewRate??110),R=o.sewStyle==="hand"?"hand":"machine",E=o.sheen??!0,P=o.animate??!0,f=o.editable??!1,m=o.pitch,O=o.onTextChange,z=ae(l);const pt=o.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let B=ie(o.threadColor??"#fffbf3",[255,251,243]),ut=[0,0,0],G=[0,0,0];function dt(t){B=ie(t,[255,251,243]),ut=[B[0]*.585,B[1]*.585,B[2]*.585],G=[B[0]*.47,B[1]*.47,B[2]*.47]}dt(o.threadColor??"#fffbf3");const Y=[];let N,k;y instanceof HTMLCanvasElement?(N=y,k=y.parentElement??y):(k=y,N=document.createElement("canvas"),Y.push(N),k.appendChild(N)),N.classList.add(Et.bg);const U=document.createElement("canvas");Y.push(U),U.classList.add(Et.fx),k.appendChild(U),getComputedStyle(k).position==="static"&&(k.style.position="relative"),N.style.display="block",N.style.width="100%",Object.assign(U.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let w=null,F=null,tt=!1,u=0,g=0,rt=0,Ft=0,it=4,at=[],ht=0,mt=0,zt=-1,_t="",Xt=-1,Gt=-1,Rt=new Uint8Array(0),Lt=new Float32Array(0),wt=new Float32Array(0),Mt=new Float32Array(0),Z=null,lt=null,Ct=null,ct=[],et=3;const I={rows:[],idx:0,acc:0,rate:0,on:!1},H={x:0,y:0,set:!1};let nt=!0,It=0,xt=!1,yt=0,K=!1,W=!1;function fe(){const t=k.getBoundingClientRect(),e=Math.max(1,Math.round(t.width||Math.min(window.innerWidth*.95,1240))),i=r||"Ag",d=N.getContext("2d");d&&(d.textBaseline="middle");let b=100;d&&(d.font=`${c} 100px ${l}`,b=d.measureText(i).width||100);const C=Math.max(8,100*(e*s)/b);let T=C*.62,A=C*.62,S=e*s;if(d){d.font=`${c} ${C}px ${l}`;const a=d.measureText(i);S=a.width||S,a.actualBoundingBoxAscent>0&&(T=a.actualBoundingBoxAscent),a.actualBoundingBoxDescent>0&&(A=a.actualBoundingBoxDescent)}const M=Math.max(1,Math.round(2*Math.max(T,A)*1.1));let n=Math.min(window.devicePixelRatio||1,1.7);for(;e*n*M*n>9e5&&n>.4;)n-=.1;u=Math.max(1,Math.round(e*n)),g=Math.max(1,Math.round(M*n)),rt=Math.max(4,Math.round(C*n)),Ft=Math.round(u/2-S*n/2);for(const a of[N,U])a.width=u,a.height=g,a.style.height=M+"px";k.style.height=M+"px",it=m??Math.max(3,g*.0095)}function ue(){lt&&Xt===u&&Gt===g||(lt=document.createElement("canvas"),lt.width=u,lt.height=g,Ct=lt.getContext("2d",{willReadFrequently:!0}),Xt=u,Gt=g)}function Ut(){const t=Math.max(7,it*2.5),e=Math.max(3.2,it*1.3);ht=Math.ceil(t)+2,mt=Math.ceil(e)+2,at=[];for(let i=0;i<20;i++){const d=.34+i/19*.82,b=document.createElement("canvas");b.width=ht,b.height=mt;const C=b.getContext("2d");if(!C){at.push(b);continue}const T=ht/2,A=mt/2,S=C.createLinearGradient(0,A-e/2,0,A+e/2),M=(L,$)=>`rgba(${J(L[0]*d)},${J(L[1]*d)},${J(L[2]*d)},${$})`;S.addColorStop(0,M(G,0)),S.addColorStop(.16,M(ut,1)),S.addColorStop(.5,M(B,1)),S.addColorStop(.84,M(ut,1)),S.addColorStop(1,M(G,0)),C.fillStyle=S,C.beginPath();const n=e/2;C.moveTo(T-t/2+n,A-n),C.lineTo(T+t/2-n,A-n),C.arc(T+t/2-n,A,n,-Math.PI/2,Math.PI/2),C.lineTo(T-t/2+n,A+n),C.arc(T-t/2+n,A,n,Math.PI/2,-Math.PI/2),C.closePath(),C.fill(),C.globalCompositeOperation="destination-in";const a=C.createLinearGradient(T-t/2,0,T+t/2,0);a.addColorStop(0,"rgba(0,0,0,0)"),a.addColorStop(.22,"rgba(0,0,0,1)"),a.addColorStop(.78,"rgba(0,0,0,1)"),a.addColorStop(1,"rgba(0,0,0,0)"),C.fillStyle=a,C.fillRect(0,0,ht,mt),at.push(b)}zt=it,_t=B.join(",")}function de(){at.length&&zt===it&&_t===B.join(",")||Ut()}function he(){if(!Ct)return;const t=Ct;t.clearRect(0,0,u,g),t.fillStyle="#fff",t.textAlign="left",t.textBaseline="middle",t.font=`${c} ${rt}px ${l}`,t.fillText(r,Ft,g*.5);const e=t.getImageData(0,0,u,g).data,i=new Uint8Array(u*g);for(let x=0;x<g;x++)for(let p=0;p<u;p++){const v=x*u+p,_=e[v*4+3]/255,q=ne(p*.5,x*.5)*.22+ne(p*1.8,x*1.8)*.1;i[v]=_>.5+(q-.16)?1:0}Rt=i;const d=Re(i,u,g),b=new Float32Array(u*g);for(let x=1;x<g-1;x++)for(let p=1;p<u-1;p++){const v=x*u+p;b[v]=(d[v]*4+d[v-1]+d[v+1]+d[v-u]+d[v+u])/8}const C=new Float32Array(u*g),T=new Float32Array(u*g),A=new Float32Array(u*g),S=new Float32Array(u*g);for(let x=1;x<g-1;x++)for(let p=1;p<u-1;p++){const v=x*u+p;if(!i[v])continue;const _=(b[v+1]-b[v-1])*.5,q=(b[v+u]-b[v-u])*.5;A[v]=_,S[v]=q,C[v]=_*_-q*q,T[v]=2*_*q}const M=Math.max(7,Math.round(g*.05)),n=re(C,u,g,M,2),a=re(T,u,g,M,2);wt=new Float32Array(u*g),Mt=new Float32Array(u*g);for(let x=0;x<u*g;x++){if(!i[x])continue;const p=.5*Math.atan2(a[x],n[x]);wt[x]=Math.cos(p),Mt[x]=Math.sin(p)}const L=Math.max(9,g*.04),$=new Float32Array(u*g),X=-.45,V=-.62,D=.64;for(let x=1;x<g-1;x++)for(let p=1;p<u-1;p++){const v=x*u+p;if(!i[v])continue;let _=A[v],q=S[v];const gt=Math.hypot(_,q)||1;_/=gt,q/=gt;const Wt=b[v],te=(1-Math.min(Wt/L,1))*1.25;let Nt=-_*te,Dt=-q*te;const ee=1.5,jt=Math.hypot(Nt,Dt,ee);Nt/=jt,Dt/=jt;let qt=Nt*X+Dt*V+ee/jt*D;qt<0&&(qt=0);const Ae=Math.min(1,.45+.55*Math.min(Wt/(L*.7),1));$[v]=Math.min(1.12,(.5+.75*qt)*Ae)}Lt=$,Z=document.createElement("canvas"),Z.width=u,Z.height=g;const j=Z.getContext("2d");if(j){const x=j.createImageData(u,g);for(let p=0;p<u*g;p++)i[p]&&(x.data[p*4]=255,x.data[p*4+1]=255,x.data[p*4+2]=255,x.data[p*4+3]=255);j.putImageData(x,0,0)}}function me(){const t=Math.max(1.6,it*.6);et=t;const e=[];for(let i=0;i<g;i+=t)for(let d=0;d<u;d+=t){const b=(ot(Math.floor(d),Math.floor(i))-.5)*t*.9,C=(ot(Math.floor(i),Math.floor(d))-.5)*t*.9,T=Math.round(d+b),A=Math.round(i+C);if(T<1||A<1||T>=u-1||A>=g-1)continue;const S=A*u+T;if(!Rt[S])continue;const M=Math.atan2(Mt[S],wt[S]),n=.86+ot(T*7,A*13)*.18;let a=Lt[S]*n;a=a<0?0:a>1.12?1.12:a,e.push({x:T,y:A,ang:M,idx:Math.min(19,Math.max(0,Math.round(a/1.12*19)))})}ct=e}function Kt(t,e){t.save(),t.translate(e.x,e.y),t.rotate(e.ang),t.drawImage(at[e.idx],-ht/2,-mt/2),t.restore()}function $t(){const t=N.getContext("2d");if(t)for(const e of ct)Kt(t,e)}function kt(){const t=N.getContext("2d");t&&t.clearRect(0,0,u,g)}function xe(t){if(!t.length)return[];const e=Math.max(4,et*1.5),i=new Map,d=(M,n)=>M+","+n;t.forEach((M,n)=>{const a=d(Math.floor(M.x/e),Math.floor(M.y/e));let L=i.get(a);L||i.set(a,L=[]),L.push(n)});const b=et*1.8*(et*1.8);function C(M){const n=t[M],a=Math.floor(n.x/e),L=Math.floor(n.y/e),$=[];for(let X=-1;X<=1;X++)for(let V=-1;V<=1;V++){const D=i.get(d(a+X,L+V));if(D)for(const j of D){if(j===M)continue;const x=t[j].x-n.x,p=t[j].y-n.y;x*x+p*p<=b&&$.push(j)}}return $}const T=new Uint8Array(t.length),A=[],S=t.map((M,n)=>n).sort((M,n)=>t[M].x+t[M].y-(t[n].x+t[n].y));for(const M of S){if(T[M])continue;let n=[M];for(T[M]=1;n.length;){A.push(n.map(L=>t[L]));const a=[];for(const L of n)for(const $ of C(L))T[$]||(T[$]=1,a.push($));n=a}}return A}function ye(t){if(!t.length)return[];const e=Math.max(4,et*1.5),i=new Map,d=(n,a)=>n+","+a;t.forEach((n,a)=>{const L=d(Math.floor(n.x/e),Math.floor(n.y/e));let $=i.get(L);$||i.set(L,$=[]),$.push(a)});const b=et*1.8*(et*1.8),C=n=>{const a=t[n],L=d(Math.floor(a.x/e),Math.floor(a.y/e)),$=i.get(L);if(!$)return;const X=$.indexOf(n);X>=0&&$.splice(X,1),$.length||i.delete(L)};function T(n){const a=t[n],L=Math.floor(a.x/e),$=Math.floor(a.y/e);let X=-1,V=1/0;for(let D=-1;D<=1;D++)for(let j=-1;j<=1;j++){const x=i.get(d(L+D,$+j));if(x)for(const p of x){const v=t[p].x-a.x,_=t[p].y-a.y,q=v*v+_*_;q<=b&&q<V&&(V=q,X=p)}}return X}function A(n){const a=t[n],L=Math.floor(a.x/e),$=Math.floor(a.y/e);let X=-1,V=1/0;for(let D=1;D<512;D++){for(let j=-D;j<=D;j++)for(let x=-D;x<=D;x++){if(Math.max(Math.abs(j),Math.abs(x))!==D)continue;const p=i.get(d(L+j,$+x));if(p)for(const v of p){const _=t[v].x-a.x,q=t[v].y-a.y,gt=_*_+q*q;gt<V&&(V=gt,X=v)}}if(X>=0&&D>Math.ceil(Math.sqrt(V)/e)+1)break}return X}let S=0;for(let n=1;n<t.length;n++)t[n].x+t[n].y<t[S].x+t[S].y&&(S=n);const M=[t[S]];C(S);for(let n=1;n<t.length;n++){let a=T(S);if(a<0&&(a=A(S)),a<0)break;M.push(t[a]),C(a),S=a}return M}function ge(){if(kt(),pt||!P){$t(),I.on=!1;return}R==="hand"?(I.rows=ye(ct).map(t=>[t]),I.rate=Math.max(h,ct.length/3.2)):(I.rows=xe(ct),I.rate=h),I.idx=0,I.acc=0,I.on=I.rows.length>0}function pe(t){const e=N.getContext("2d");if(e)for(t>I.rows.length&&(t=I.rows.length);I.idx<t;){const i=I.rows[I.idx++];for(const d of i)Kt(e,d)}}function we(t,e){const i=U.getContext("2d");if(!i||(i.clearRect(0,0,u,g),!E||!Z))return;const d=u*.32,b=i.createRadialGradient(t,e,0,t,e,d);b.addColorStop(0,"rgba(255,250,238,0.18)"),b.addColorStop(.5,"rgba(255,250,238,0.055)"),b.addColorStop(1,"rgba(255,250,238,0)"),i.fillStyle=b,i.fillRect(0,0,u,g),i.globalCompositeOperation="destination-in",i.drawImage(Z,0,0),i.globalCompositeOperation="source-over"}function Me(){F||!f||(F=document.createElement("span"),F.className=Et.caret,F.setAttribute("aria-hidden","true"),Object.assign(F.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${J(B[0])},${J(B[1])},${J(B[2])})`}),k.appendChild(F),Y.push(F))}function Pt(){if(!f||!F)return;const t=N.getContext("2d");if(!t)return;t.font=`${c} ${rt}px ${l}`;const e=t.measureText(r).width,i=(N.clientWidth||u)/u,d=rt*.7;F.style.left=(Ft+e+rt*.05)*i+"px",F.style.top=.5*(N.clientHeight||g)-d*i/2+"px",F.style.height=d*i+"px",F.style.width=Math.max(2,Math.round(rt*.02*i))+"px",F.style.background=`rgb(${J(B[0])},${J(B[1])},${J(B[2])})`}function st(){K||xt||(xt=!0,yt=0,It=requestAnimationFrame(Vt))}function Vt(t){if(K){xt=!1;return}yt||(yt=t);const e=Math.min(.25,(t-yt)/1e3);yt=t,I.on&&(I.acc+=I.rate*e,pe(I.acc),I.idx>=I.rows.length&&(I.on=!1)),nt&&Z&&(we(H.set?H.x:u*.5,H.set?H.y:g*.45),nt=!1);const i=f&&tt;if(F&&(F.style.opacity=i&&Math.floor(t/530)%2===0?"1":"0"),!I.on&&!nt&&!i){xt=!1;return}It=requestAnimationFrame(Vt)}function vt(t){const e=k.getBoundingClientRect();H.x=(t.clientX-e.left)/(e.width||1)*u,H.y=(t.clientY-e.top)/(e.height||1)*g,H.set=!0,nt=!0,st()}function Tt(){H.set=!1,nt=!0,st()}function Ce(){w&&Ht(w.value,!0)}function ve(t){t.key==="Enter"&&(t.preventDefault(),Bt.replay())}function Te(){tt=!0,st()}function be(){tt=!1,F&&(F.style.opacity="0")}function Yt(t){t===f&&w||(f=t,t?(w||(w=document.createElement("input"),w.type="text",w.value=r,w.maxLength=64,w.setAttribute("aria-label","Embroidered text — type to change it"),w.setAttribute("autocomplete","off"),w.setAttribute("autocapitalize","off"),w.spellcheck=!1,Object.assign(w.style,{position:"absolute",inset:"0",width:"100%",height:"100%",margin:"0",padding:"0",border:"0",outline:"none",background:"transparent",color:"transparent",caretColor:"transparent",font:"inherit",textAlign:"center",cursor:"text"}),w.addEventListener("input",Ce),w.addEventListener("keydown",ve),w.addEventListener("focus",Te),w.addEventListener("blur",be),k.appendChild(w),Y.push(w)),Me(),Pt()):(w&&(w.remove(),w=null),tt=!1,F&&(F.style.opacity="0")))}function Se(t){if(t!==E)if(E=t,t)k.addEventListener("pointermove",vt,{passive:!0}),k.addEventListener("pointerleave",Tt,{passive:!0}),H.set=!1,nt=!0,st();else{k.removeEventListener("pointermove",vt),k.removeEventListener("pointerleave",Tt);const e=U.getContext("2d");e&&e.clearRect(0,0,u,g)}}function ft(t){fe(),ue(),de(),he(),me(),t?ge():(kt(),$t(),I.on=!1),w&&w.value!==r&&(w.value=r),Pt(),nt=!0,st()}function Ht(t,e){t=t??"",!(t===r&&W)&&(r=t,W&&(ft(!1),e&&O&&O(r)))}const bt=new Set;function Jt(t,e,i){const d=`${e} 200px ${t}`;let b=!1;try{b=!!document.fonts&&document.fonts.check(d)}catch{b=!0}if(!document.fonts||b){i();return}let C=!1,T;const A=()=>{C||(C=!0,clearTimeout(T),bt.delete(T),K||i())};document.fonts.load(d,r).then(()=>document.fonts.ready).then(A,A),T=setTimeout(A,1500),bt.add(T)}function Ee(){K||(ft(!0),W=!0)}f&&(f=!1,Yt(!0)),E&&(k.addEventListener("pointermove",vt,{passive:!0}),k.addEventListener("pointerleave",Tt,{passive:!0})),Jt(z,c,Ee);let Ot,Qt=-1;function Zt(){clearTimeout(Ot),Ot=setTimeout(()=>{if(K||!W)return;const t=Math.round(k.getBoundingClientRect().width);t!==Qt&&(Qt=t,ft(!1))},200)}window.addEventListener("resize",Zt);const Bt={get text(){return r},setText(t){if(!K){if(!W){r=t??"",w&&(w.value=r);return}Ht(t,!1)}},replay(){K||!W||ft(!0)},resize(){K||!W||ft(!1)},update(t){if(K)return;t.text!==void 0&&Bt.setText(t.text);let e=!1,i=!1;if(t.font!==void 0&&t.font!==l&&(l=t.font,z=ae(l),e=!0),t.weight!==void 0){const d=St(t.weight,1,1e3);d!==c&&(c=d,e=!0)}if(t.fill!==void 0){const d=St(t.fill,.05,1);d!==s&&(s=d,e=!0)}t.pitch!==void 0&&t.pitch!==m&&(m=t.pitch,e=!0),t.threadColor!==void 0&&(dt(t.threadColor),i=!0),t.sewRate!==void 0&&(h=Math.max(1,t.sewRate)),t.sewStyle!==void 0&&(R=t.sewStyle==="hand"?"hand":"machine"),t.animate!==void 0&&(P=t.animate),t.onTextChange!==void 0&&(O=t.onTextChange),t.sheen!==void 0&&Se(t.sheen),t.editable!==void 0&&Yt(t.editable),W&&(e?Jt(z,c,()=>{K||ft(!1)}):i&&(Ut(),kt(),$t(),Pt(),st()))},focus(){!K&&f&&(w==null||w.focus())},destroy(){if(!K){K=!0,xt=!1,cancelAnimationFrame(It),clearTimeout(Ot);for(const t of bt)clearTimeout(t);bt.clear(),window.removeEventListener("resize",Zt),k.removeEventListener("pointermove",vt),k.removeEventListener("pointerleave",Tt);for(const t of Y)t.remove();at=[],ct=[],I.rows=[],Rt=new Uint8Array(0),Lt=new Float32Array(0),wt=new Float32Array(0),Mt=new Float32Array(0),Z=lt=null,Ct=null,F=null,w=null}}};return Bt}function ce(y){const o=Q.useRef(null),r=Q.useRef(null),l=Q.useRef(y);l.current=y;const c=Q.useRef(y.onTextChange);c.current=y.onTextChange;const{text:s,font:h,weight:R,threadColor:E,pitch:P,fill:f,animate:m,sewStyle:O,sewRate:z,sheen:pt,editable:B,reducedMotion:ut}=y;return Q.useLayoutEffect(()=>{const G=o.current;if(!G)return;const dt=le(G,{...l.current,onTextChange:w=>{var F;return(F=c.current)==null?void 0:F.call(c,w)}});r.current=dt;let Y=0,N=0,k=!0,U;return typeof ResizeObserver<"u"&&(U=new ResizeObserver(w=>{const F=Math.round(w[0].contentRect.width);if(k){k=!1,N=F;return}F!==N&&(N=F,cancelAnimationFrame(Y),Y=requestAnimationFrame(()=>{var tt;return(tt=r.current)==null?void 0:tt.resize()}))}),U.observe(G)),()=>{U==null||U.disconnect(),cancelAnimationFrame(Y),dt.destroy(),r.current=null}},[ut]),Q.useEffect(()=>{var G;(G=r.current)==null||G.update({font:h,weight:R,threadColor:E,pitch:P,fill:f,animate:m,sewStyle:O,sewRate:z,sheen:pt,editable:B})},[h,R,E,P,f,m,O,z,pt,B]),Q.useEffect(()=>{var G;(G=r.current)==null||G.setText(s)},[s]),o}const se=Q.forwardRef(function({className:o,style:r,as:l="div","aria-label":c,role:s,"aria-describedby":h,...R},E){const P=ce(R),f=Q.useCallback(m=>{P.current=m,typeof E=="function"?E(m):E&&(E.current=m)},[P,E]);return Fe.jsx(l,{ref:f,className:o,style:r,role:R.editable?s:s??"img","aria-label":R.editable?c:c??R.text,"aria-describedby":h})});se.displayName="ThreadText";exports.THREAD_TEXT_CLASSES=Et;exports.ThreadText=se;exports.createThreadText=le;exports.useThreadText=ce;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const J=require("react"),Re=require("react/jsx-runtime"),St={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function ot(g,n){let o=Math.imul(g|0,374761393)+Math.imul(n|0,668265263)|0;return o=Math.imul(o^o>>>13,1274126177),((o^o>>>16)>>>0)/4294967295}function oe(g,n){const o=Math.floor(g),a=Math.floor(n),s=g-o,l=n-a,x=s*s*(3-2*s),F=l*l*(3-2*l),E=ot(o,a),P=ot(o+1,a),f=ot(o,a+1),y=ot(o+1,a+1);return E+(P-E)*x+(f-E)*F+(E-P-f+y)*x*F}const Et=1e20;function re(g,n,o,a,s){let l=0;a[0]=0,s[0]=-Et,s[1]=Et;for(let x=1;x<n;x++){let F=(g[x]+x*x-(g[a[l]]+a[l]*a[l]))/(2*x-2*a[l]);for(;F<=s[l];)l--,F=(g[x]+x*x-(g[a[l]]+a[l]*a[l]))/(2*x-2*a[l]);l++,a[l]=x,s[l]=F,s[l+1]=Et}l=0;for(let x=0;x<n;x++){for(;s[l+1]<x;)l++;o[x]=(x-a[l])*(x-a[l])+g[a[l]]}}function Le(g,n,o){const a=new Float64Array(n*o);for(let f=0;f<n*o;f++)a[f]=g[f]?Et:0;const s=Math.max(n,o),l=new Float64Array(s),x=new Float64Array(s),F=new Int32Array(s),E=new Float64Array(s+1);for(let f=0;f<n;f++){for(let y=0;y<o;y++)l[y]=a[y*n+f];re(l,o,x,F,E);for(let y=0;y<o;y++)a[y*n+f]=x[y]}for(let f=0;f<o;f++){for(let y=0;y<n;y++)l[y]=a[f*n+y];re(l,n,x,F,E);for(let y=0;y<n;y++)a[f*n+y]=x[y]}const P=new Float32Array(n*o);for(let f=0;f<n*o;f++)P[f]=Math.sqrt(a[f]);return P}function ie(g,n,o,a,s){let l=Float32Array.from(g);const x=new Float32Array(n*o),F=1/(2*a+1),E=(P,f)=>P<0?0:P>f?f:P;for(let P=0;P<s;P++){for(let f=0;f<o;f++){const y=f*n;let k=0;for(let j=-a;j<=a;j++)k+=l[y+E(j,n-1)];for(let j=0;j<n;j++)x[y+j]=k*F,k+=l[y+E(j+a+1,n-1)]-l[y+E(j-a,n-1)]}for(let f=0;f<n;f++){let y=0;for(let k=-a;k<=a;k++)y+=x[E(k,o-1)*n+f];for(let k=0;k<o;k++)l[k*n+f]=y*F,y+=x[E(k+a+1,o-1)*n+f]-x[E(k-a,o-1)*n+f]}}return l}function ae(g,n){if(!g)return n;const o=g.trim();if(o[0]==="#"){let s=o.slice(1);if(s.length===3&&(s=s[0]+s[0]+s[1]+s[1]+s[2]+s[2]),s.length>=6){const l=parseInt(s.slice(0,2),16),x=parseInt(s.slice(2,4),16),F=parseInt(s.slice(4,6),16);if(!Number.isNaN(l)&&!Number.isNaN(x)&&!Number.isNaN(F))return[l,x,F]}return n}const a=o.match(/rgba?\(([^)]+)\)/i);if(a){const s=a[1].split(",").map(l=>parseFloat(l));if(s.length>=3&&s.slice(0,3).every(l=>!Number.isNaN(l)))return[Math.round(s[0]),Math.round(s[1]),Math.round(s[2])]}return n}function H(g){return g<0?0:g>255?255:Math.round(g)}function bt(g,n,o){return g<n?n:g>o?o:g}function se(g){return(g.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function le(g,n){if(typeof window>"u"||typeof document>"u"||!g)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return n.text??""}};let o=n.text??"",a=n.font??"Georgia, serif",s=bt(n.weight??680,1,1e3),l=bt(n.fill??.9,.05,1),x=Math.max(1,n.sewRate??110),F=n.sewStyle==="hand"?"hand":"machine",E=n.sheen??!0,P=n.animate??!0,f=n.editable??!1,y=n.pitch,k=n.onTextChange,j=se(a);const gt=n.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let O=ae(n.threadColor??"#fffbf3",[255,251,243]),ft=[0,0,0],D=[0,0,0];function ut(t){O=ae(t,[255,251,243]),ft=[O[0]*.585,O[1]*.585,O[2]*.585],D=[O[0]*.47,O[1]*.47,O[2]*.47]}ut(n.threadColor??"#fffbf3");const G=[];let B,$;g instanceof HTMLCanvasElement?(B=g,$=g.parentElement??g):($=g,B=document.createElement("canvas"),G.push(B),$.appendChild(B)),B.classList.add(St.bg);const q=document.createElement("canvas");G.push(q),q.classList.add(St.fx),$.appendChild(q),getComputedStyle($).position==="static"&&($.style.position="relative"),B.style.display="block",B.style.width="100%",Object.assign(q.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let T=null,A=null,tt=!1,u=0,w=0,rt=0,At=0,it=4,at=[],dt=0,ht=0,qt=-1,zt="",_t=-1,Xt=-1,Ft=new Uint8Array(0),Rt=new Float32Array(0),pt=new Float32Array(0),wt=new Float32Array(0),Q=null,st=null,Mt=null,mt=[],et=3;const I={rows:[],idx:0,acc:0,rate:0,on:!1},K={x:0,y:0,set:!1};let nt=!0,Lt=0,xt=!1,yt=0,z=!1,Z=!1;function ue(){const t=$.getBoundingClientRect(),e=Math.max(1,Math.round(t.width||Math.min(window.innerWidth*.95,1240))),r=o||"Ag",d=B.getContext("2d");d&&(d.textBaseline="middle");let b=100;d&&(d.font=`${s} 100px ${a}`,b=d.measureText(r).width||100);const p=Math.max(8,100*(e*l)/b);let h=p*.62,M=p*.62,C=e*l;if(d){d.font=`${s} ${p}px ${a}`;const i=d.measureText(r);C=i.width||C,i.actualBoundingBoxAscent>0&&(h=i.actualBoundingBoxAscent),i.actualBoundingBoxDescent>0&&(M=i.actualBoundingBoxDescent)}const m=Math.max(1,Math.round(2*Math.max(h,M)*1.1));let c=Math.min(window.devicePixelRatio||1,1.7);for(;e*c*m*c>9e5&&c>.4;)c-=.1;u=Math.max(1,Math.round(e*c)),w=Math.max(1,Math.round(m*c)),rt=Math.max(4,Math.round(p*c)),At=Math.round(u/2-C*c/2);for(const i of[B,q])i.width=u,i.height=w,i.style.height=m+"px";$.style.height=m+"px",it=y??Math.max(3,w*.0095)}function de(){st&&_t===u&&Xt===w||(st=document.createElement("canvas"),st.width=u,st.height=w,Mt=st.getContext("2d",{willReadFrequently:!0}),_t=u,Xt=w)}function Ut(){const t=Math.max(7,it*2.5),e=Math.max(3.2,it*1.3);dt=Math.ceil(t)+2,ht=Math.ceil(e)+2,at=[];for(let r=0;r<20;r++){const d=.34+r/19*.82,b=document.createElement("canvas");b.width=dt,b.height=ht;const p=b.getContext("2d");if(!p){at.push(b);continue}const h=dt/2,M=ht/2,C=p.createLinearGradient(0,M-e/2,0,M+e/2),m=(R,N)=>`rgba(${H(R[0]*d)},${H(R[1]*d)},${H(R[2]*d)},${N})`;C.addColorStop(0,m(D,0)),C.addColorStop(.16,m(ft,1)),C.addColorStop(.5,m(O,1)),C.addColorStop(.84,m(ft,1)),C.addColorStop(1,m(D,0)),p.fillStyle=C,p.beginPath();const c=e/2;p.moveTo(h-t/2+c,M-c),p.lineTo(h+t/2-c,M-c),p.arc(h+t/2-c,M,c,-Math.PI/2,Math.PI/2),p.lineTo(h-t/2+c,M+c),p.arc(h-t/2+c,M,c,Math.PI/2,-Math.PI/2),p.closePath(),p.fill(),p.globalCompositeOperation="destination-in";const i=p.createLinearGradient(h-t/2,0,h+t/2,0);i.addColorStop(0,"rgba(0,0,0,0)"),i.addColorStop(.22,"rgba(0,0,0,1)"),i.addColorStop(.78,"rgba(0,0,0,1)"),i.addColorStop(1,"rgba(0,0,0,0)"),p.fillStyle=i,p.fillRect(0,0,dt,ht),at.push(b)}qt=it,zt=O.join(",")}function he(){at.length&&qt===it&&zt===O.join(",")||Ut()}function me(){if(!Mt)return;const t=Mt;t.clearRect(0,0,u,w),t.fillStyle="#fff",t.textAlign="left",t.textBaseline="middle",t.font=`${s} ${rt}px ${a}`,t.fillText(o,At,w*.5);const e=t.getImageData(0,0,u,w).data,r=new Uint8Array(u*w);for(let v=0;v<w;v++)for(let S=0;S<u;S++){const L=v*u+S,X=e[L*4+3]/255,U=oe(S*.5,v*.5)*.22+oe(S*1.8,v*1.8)*.1;r[L]=X>.5+(U-.16)?1:0}Ft=r;const d=Le(r,u,w),b=new Float32Array(u*w);for(let v=1;v<w-1;v++)for(let S=1;S<u-1;S++){const L=v*u+S;b[L]=(d[L]*4+d[L-1]+d[L+1]+d[L-u]+d[L+u])/8}const p=new Float32Array(u*w),h=new Float32Array(u*w),M=new Float32Array(u*w),C=new Float32Array(u*w);for(let v=1;v<w-1;v++)for(let S=1;S<u-1;S++){const L=v*u+S;if(!r[L])continue;const X=(b[L+1]-b[L-1])*.5,U=(b[L+u]-b[L-u])*.5;M[L]=X,C[L]=U,p[L]=X*X-U*U,h[L]=2*X*U}const m=Math.max(7,Math.round(w*.05)),c=ie(p,u,w,m,2),i=ie(h,u,w,m,2);pt=new Float32Array(u*w),wt=new Float32Array(u*w);for(let v=0;v<u*w;v++){if(!r[v])continue;const S=.5*Math.atan2(i[v],c[v]);pt[v]=Math.cos(S),wt[v]=Math.sin(S)}const R=Math.max(9,w*.04),N=new Float32Array(u*w),Y=-.45,W=-.62,V=.64;for(let v=1;v<w-1;v++)for(let S=1;S<u-1;S++){const L=v*u+S;if(!r[L])continue;let X=M[L],U=C[L];const Wt=Math.hypot(X,U)||1;X/=Wt,U/=Wt;const te=b[L],ee=(1-Math.min(te/R,1))*1.25;let Bt=-X*ee,Nt=-U*ee;const ne=1.5,jt=Math.hypot(Bt,Nt,ne);Bt/=jt,Nt/=jt;let Dt=Bt*Y+Nt*W+ne/jt*V;Dt<0&&(Dt=0);const Fe=Math.min(1,.45+.55*Math.min(te/(R*.7),1));N[L]=Math.min(1.12,(.5+.75*Dt)*Fe)}Rt=N,Q=document.createElement("canvas"),Q.width=u,Q.height=w;const _=Q.getContext("2d");if(_){const v=_.createImageData(u,w);for(let S=0;S<u*w;S++)r[S]&&(v.data[S*4]=255,v.data[S*4+1]=255,v.data[S*4+2]=255,v.data[S*4+3]=255);_.putImageData(v,0,0)}}function xe(){const t=Math.max(1.6,it*.6);et=t;const e=[];for(let r=0;r<w;r+=t)for(let d=0;d<u;d+=t){const b=(ot(Math.floor(d),Math.floor(r))-.5)*t*.9,p=(ot(Math.floor(r),Math.floor(d))-.5)*t*.9,h=Math.round(d+b),M=Math.round(r+p);if(h<1||M<1||h>=u-1||M>=w-1)continue;const C=M*u+h;if(!Ft[C])continue;const m=Math.atan2(wt[C],pt[C]),c=.86+ot(h*7,M*13)*.18;let i=Rt[C]*c;i=i<0?0:i>1.12?1.12:i,e.push({x:h,y:M,ang:m,idx:Math.min(19,Math.max(0,Math.round(i/1.12*19)))})}mt=e}function Gt(t,e){t.save(),t.translate(e.x,e.y),t.rotate(e.ang),t.drawImage(at[e.idx],-dt/2,-ht/2),t.restore()}function $t(){const t=B.getContext("2d");if(t)for(const e of mt)Gt(t,e)}function It(){const t=B.getContext("2d");t&&t.clearRect(0,0,u,w)}function Kt(t){if(!t.length)return[];const e=Math.max(4,et*1.5),r=new Map,d=(m,c)=>m+","+c;t.forEach((m,c)=>{const i=d(Math.floor(m.x/e),Math.floor(m.y/e));let R=r.get(i);R||r.set(i,R=[]),R.push(c)});const b=et*1.8*(et*1.8);function p(m){const c=t[m],i=Math.floor(c.x/e),R=Math.floor(c.y/e),N=[];for(let Y=-1;Y<=1;Y++)for(let W=-1;W<=1;W++){const V=r.get(d(i+Y,R+W));if(V)for(const _ of V){if(_===m)continue;const v=t[_].x-c.x,S=t[_].y-c.y;v*v+S*S<=b&&N.push(_)}}return N}const h=new Uint8Array(t.length),M=[],C=t.map((m,c)=>c).sort((m,c)=>t[m].x+t[m].y-(t[c].x+t[c].y));for(const m of C){if(h[m])continue;let c=[m];for(h[m]=1;c.length;){M.push(c.map(R=>t[R]));const i=[];for(const R of c)for(const N of p(R))h[N]||(h[N]=1,i.push(N));c=i}}return M}function ye(t){const e=Math.max(4,et*1.5),r=new Map,d=(C,m)=>C+","+m;t.forEach((C,m)=>{const c=d(Math.floor(C.x/e),Math.floor(C.y/e));let i=r.get(c);i||r.set(c,i=[]),i.push(m)});const b=et*1.8*(et*1.8),p=C=>{const m=t[C],c=Math.floor(m.x/e),i=Math.floor(m.y/e),R=[];for(let N=-1;N<=1;N++)for(let Y=-1;Y<=1;Y++){const W=r.get(d(c+N,i+Y));if(W)for(const V of W){if(V===C)continue;const _=t[V].x-m.x,v=t[V].y-m.y;_*_+v*v<=b&&R.push(V)}}return R},h=new Uint8Array(t.length),M=[];for(let C=0;C<t.length;C++){if(h[C])continue;const m=[];let c=[C];for(h[C]=1;c.length;){const i=[];for(const R of c){m.push(t[R]);for(const N of p(R))h[N]||(h[N]=1,i.push(N))}c=i}M.push(m)}return M}function ge(t){if(!t.length)return[];const e=p=>{let h=1/0;for(const M of p)M.x<h&&(h=M.x);return h},r=p=>{let h=0;for(const M of p)h+=M.y;return h/p.length},d=ye(t).sort((p,h)=>e(p)-e(h)),b=[];for(const p of d){const h=Kt(p);let M=1;for(const i of h)i.length>M&&(M=i.length);const C=Math.max(2,M*.45),m=h.filter(i=>i.length>=C).sort((i,R)=>r(i)-r(R)),c=h.filter(i=>i.length<C).sort((i,R)=>r(i)-r(R));for(const i of m)b.push(i);for(const i of c)b.push(i)}return b}function pe(){if(It(),gt||!P){$t(),I.on=!1;return}I.rows=F==="hand"?ge(mt):Kt(mt),I.idx=0,I.acc=0,I.rate=x,I.on=I.rows.length>0}function we(t){const e=B.getContext("2d");if(e)for(t>I.rows.length&&(t=I.rows.length);I.idx<t;){const r=I.rows[I.idx++];for(const d of r)Gt(e,d)}}function Me(t,e){const r=q.getContext("2d");if(!r||(r.clearRect(0,0,u,w),!E||!Q))return;const d=u*.32,b=r.createRadialGradient(t,e,0,t,e,d);b.addColorStop(0,"rgba(255,250,238,0.18)"),b.addColorStop(.5,"rgba(255,250,238,0.055)"),b.addColorStop(1,"rgba(255,250,238,0)"),r.fillStyle=b,r.fillRect(0,0,u,w),r.globalCompositeOperation="destination-in",r.drawImage(Q,0,0),r.globalCompositeOperation="source-over"}function Ce(){A||!f||(A=document.createElement("span"),A.className=St.caret,A.setAttribute("aria-hidden","true"),Object.assign(A.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${H(O[0])},${H(O[1])},${H(O[2])})`}),$.appendChild(A),G.push(A))}function Pt(){if(!f||!A)return;const t=B.getContext("2d");if(!t)return;t.font=`${s} ${rt}px ${a}`;const e=t.measureText(o).width,r=(B.clientWidth||u)/u,d=rt*.7;A.style.left=(At+e+rt*.05)*r+"px",A.style.top=.5*(B.clientHeight||w)-d*r/2+"px",A.style.height=d*r+"px",A.style.width=Math.max(2,Math.round(rt*.02*r))+"px",A.style.background=`rgb(${H(O[0])},${H(O[1])},${H(O[2])})`}function lt(){z||xt||(xt=!0,yt=0,Lt=requestAnimationFrame(Yt))}function Yt(t){if(z){xt=!1;return}yt||(yt=t);const e=Math.min(.25,(t-yt)/1e3);yt=t,I.on&&(I.acc+=I.rate*e,we(I.acc),I.idx>=I.rows.length&&(I.on=!1)),nt&&Q&&(Me(K.set?K.x:u*.5,K.set?K.y:w*.45),nt=!1);const r=f&&tt;if(A&&(A.style.opacity=r&&Math.floor(t/530)%2===0?"1":"0"),!I.on&&!nt&&!r){xt=!1;return}Lt=requestAnimationFrame(Yt)}function Ct(t){const e=$.getBoundingClientRect();K.x=(t.clientX-e.left)/(e.width||1)*u,K.y=(t.clientY-e.top)/(e.height||1)*w,K.set=!0,nt=!0,lt()}function vt(){K.set=!1,nt=!0,lt()}function ve(){T&&Ht(T.value,!0)}function Te(t){t.key==="Enter"&&(t.preventDefault(),Ot.replay())}function be(){tt=!0,lt()}function Se(){tt=!1,A&&(A.style.opacity="0")}function Vt(t){t===f&&T||(f=t,t?(T||(T=document.createElement("input"),T.type="text",T.value=o,T.maxLength=64,T.setAttribute("aria-label","Embroidered text — type to change it"),T.setAttribute("autocomplete","off"),T.setAttribute("autocapitalize","off"),T.spellcheck=!1,Object.assign(T.style,{position:"absolute",inset:"0",width:"100%",height:"100%",margin:"0",padding:"0",border:"0",outline:"none",background:"transparent",color:"transparent",caretColor:"transparent",font:"inherit",textAlign:"center",cursor:"text"}),T.addEventListener("input",ve),T.addEventListener("keydown",Te),T.addEventListener("focus",be),T.addEventListener("blur",Se),$.appendChild(T),G.push(T)),Ce(),Pt()):(T&&(T.remove(),T=null),tt=!1,A&&(A.style.opacity="0")))}function Ee(t){if(t!==E)if(E=t,t)$.addEventListener("pointermove",Ct,{passive:!0}),$.addEventListener("pointerleave",vt,{passive:!0}),K.set=!1,nt=!0,lt();else{$.removeEventListener("pointermove",Ct),$.removeEventListener("pointerleave",vt);const e=q.getContext("2d");e&&e.clearRect(0,0,u,w)}}function ct(t){ue(),de(),he(),me(),xe(),t?pe():(It(),$t(),I.on=!1),T&&T.value!==o&&(T.value=o),Pt(),nt=!0,lt()}function Ht(t,e){t=t??"",!(t===o&&Z)&&(o=t,Z&&(ct(!1),e&&k&&k(o)))}const Tt=new Set;function Jt(t,e,r){const d=`${e} 200px ${t}`;let b=!1;try{b=!!document.fonts&&document.fonts.check(d)}catch{b=!0}if(!document.fonts||b){r();return}let p=!1,h;const M=()=>{p||(p=!0,clearTimeout(h),Tt.delete(h),z||r())};document.fonts.load(d,o).then(()=>document.fonts.ready).then(M,M),h=setTimeout(M,1500),Tt.add(h)}function Ae(){z||(ct(!0),Z=!0)}f&&(f=!1,Vt(!0)),E&&($.addEventListener("pointermove",Ct,{passive:!0}),$.addEventListener("pointerleave",vt,{passive:!0})),Jt(j,s,Ae);let kt,Qt=-1;function Zt(){clearTimeout(kt),kt=setTimeout(()=>{if(z||!Z)return;const t=Math.round($.getBoundingClientRect().width);t!==Qt&&(Qt=t,ct(!1))},200)}window.addEventListener("resize",Zt);const Ot={get text(){return o},setText(t){if(!z){if(!Z){o=t??"",T&&(T.value=o);return}Ht(t,!1)}},replay(){z||!Z||ct(!0)},resize(){z||!Z||ct(!1)},update(t){if(z)return;t.text!==void 0&&Ot.setText(t.text);let e=!1,r=!1;if(t.font!==void 0&&t.font!==a&&(a=t.font,j=se(a),e=!0),t.weight!==void 0){const d=bt(t.weight,1,1e3);d!==s&&(s=d,e=!0)}if(t.fill!==void 0){const d=bt(t.fill,.05,1);d!==l&&(l=d,e=!0)}t.pitch!==void 0&&t.pitch!==y&&(y=t.pitch,e=!0),t.threadColor!==void 0&&(ut(t.threadColor),r=!0),t.sewRate!==void 0&&(x=Math.max(1,t.sewRate)),t.sewStyle!==void 0&&(F=t.sewStyle==="hand"?"hand":"machine"),t.animate!==void 0&&(P=t.animate),t.onTextChange!==void 0&&(k=t.onTextChange),t.sheen!==void 0&&Ee(t.sheen),t.editable!==void 0&&Vt(t.editable),Z&&(e?Jt(j,s,()=>{z||ct(!1)}):r&&(Ut(),It(),$t(),Pt(),lt()))},focus(){!z&&f&&(T==null||T.focus())},destroy(){if(!z){z=!0,xt=!1,cancelAnimationFrame(Lt),clearTimeout(kt);for(const t of Tt)clearTimeout(t);Tt.clear(),window.removeEventListener("resize",Zt),$.removeEventListener("pointermove",Ct),$.removeEventListener("pointerleave",vt);for(const t of G)t.remove();at=[],mt=[],I.rows=[],Ft=new Uint8Array(0),Rt=new Float32Array(0),pt=new Float32Array(0),wt=new Float32Array(0),Q=st=null,Mt=null,A=null,T=null}}};return Ot}function ce(g){const n=J.useRef(null),o=J.useRef(null),a=J.useRef(g);a.current=g;const s=J.useRef(g.onTextChange);s.current=g.onTextChange;const{text:l,font:x,weight:F,threadColor:E,pitch:P,fill:f,animate:y,sewStyle:k,sewRate:j,sheen:gt,editable:O,reducedMotion:ft}=g;return J.useLayoutEffect(()=>{const D=n.current;if(!D)return;const ut=le(D,{...a.current,onTextChange:T=>{var A;return(A=s.current)==null?void 0:A.call(s,T)}});o.current=ut;let G=0,B=0,$=!0,q;return typeof ResizeObserver<"u"&&(q=new ResizeObserver(T=>{const A=Math.round(T[0].contentRect.width);if($){$=!1,B=A;return}A!==B&&(B=A,cancelAnimationFrame(G),G=requestAnimationFrame(()=>{var tt;return(tt=o.current)==null?void 0:tt.resize()}))}),q.observe(D)),()=>{q==null||q.disconnect(),cancelAnimationFrame(G),ut.destroy(),o.current=null}},[ft]),J.useEffect(()=>{var D;(D=o.current)==null||D.update({font:x,weight:F,threadColor:E,pitch:P,fill:f,animate:y,sewStyle:k,sewRate:j,sheen:gt,editable:O})},[x,F,E,P,f,y,k,j,gt,O]),J.useEffect(()=>{var D;(D=o.current)==null||D.setText(l)},[l]),n}const fe=J.forwardRef(function({className:n,style:o,as:a="div","aria-label":s,role:l,"aria-describedby":x,...F},E){const P=ce(F),f=J.useCallback(y=>{P.current=y,typeof E=="function"?E(y):E&&(E.current=y)},[P,E]);return Re.jsx(a,{ref:f,className:n,style:o,role:F.editable?l:l??"img","aria-label":F.editable?s:s??F.text,"aria-describedby":x})});fe.displayName="ThreadText";exports.THREAD_TEXT_CLASSES=St;exports.ThreadText=fe;exports.createThreadText=le;exports.useThreadText=ce;
package/dist/index.d.ts CHANGED
@@ -81,8 +81,9 @@ export declare interface ThreadTextOptions {
81
81
  * How the word is sewn in:
82
82
  * - **'machine'** (default) — satin cross-rows appear in parallel across each stroke, like
83
83
  * machine embroidery (a BFS over the stitch graph).
84
- * - **'hand'** — a single continuous thread wanders stitch by stitch along each stroke and
85
- * carries to the next, laying one stitch at a time, like hand embroidery.
84
+ * - **'hand'** — works one letter at a time (left to right). Within each letter it enters at
85
+ * the widest region near the top and works its way down the strokes, then cleans up the thin
86
+ * serifs and terminals last — the way a person embroiders a shape.
86
87
  */
87
88
  sewStyle?: 'machine' | 'hand';
88
89
  /** Satin cross-rows (machine) or stitches (hand) laid per second during the sew-in. (default: 110) */
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { useRef as Tt, useLayoutEffect as Se, useEffect as ne, forwardRef as Ae, useCallback as Fe } from "react";
2
- import { jsx as Le } from "react/jsx-runtime";
3
- const zt = {
1
+ import { useRef as bt, useLayoutEffect as Ae, useEffect as oe, forwardRef as Fe, useCallback as Le } from "react";
2
+ import { jsx as Re } from "react/jsx-runtime";
3
+ const Dt = {
4
4
  /** Base canvas: the baked satin stitches (transparent ground). */
5
5
  bg: "tt-bg",
6
6
  /** Overlay canvas: cursor sheen (`mix-blend-mode: screen`). */
@@ -8,98 +8,98 @@ const zt = {
8
8
  /** Blinking text caret shown in editable mode. */
9
9
  caret: "tt-caret"
10
10
  };
11
- function nt(x, o) {
12
- let r = Math.imul(x | 0, 374761393) + Math.imul(o | 0, 668265263) | 0;
13
- return r = Math.imul(r ^ r >>> 13, 1274126177), ((r ^ r >>> 16) >>> 0) / 4294967295;
11
+ function nt(g, n) {
12
+ let o = Math.imul(g | 0, 374761393) + Math.imul(n | 0, 668265263) | 0;
13
+ return o = Math.imul(o ^ o >>> 13, 1274126177), ((o ^ o >>> 16) >>> 0) / 4294967295;
14
14
  }
15
- function oe(x, o) {
16
- const r = Math.floor(x), l = Math.floor(o), c = x - r, s = o - l, h = c * c * (3 - 2 * c), L = s * s * (3 - 2 * s), S = nt(r, l), P = nt(r + 1, l), f = nt(r, l + 1), m = nt(r + 1, l + 1);
17
- return S + (P - S) * h + (f - S) * L + (S - P - f + m) * h * L;
15
+ function re(g, n) {
16
+ const o = Math.floor(g), a = Math.floor(n), l = g - o, s = n - a, x = l * l * (3 - 2 * l), F = s * s * (3 - 2 * s), S = nt(o, a), P = nt(o + 1, a), f = nt(o, a + 1), y = nt(o + 1, a + 1);
17
+ return S + (P - S) * x + (f - S) * F + (S - P - f + y) * x * F;
18
18
  }
19
- const St = 1e20;
20
- function re(x, o, r, l, c) {
19
+ const Et = 1e20;
20
+ function ie(g, n, o, a, l) {
21
21
  let s = 0;
22
- l[0] = 0, c[0] = -St, c[1] = St;
23
- for (let h = 1; h < o; h++) {
24
- let L = (x[h] + h * h - (x[l[s]] + l[s] * l[s])) / (2 * h - 2 * l[s]);
25
- for (; L <= c[s]; )
26
- s--, L = (x[h] + h * h - (x[l[s]] + l[s] * l[s])) / (2 * h - 2 * l[s]);
27
- s++, l[s] = h, c[s] = L, c[s + 1] = St;
22
+ a[0] = 0, l[0] = -Et, l[1] = Et;
23
+ for (let x = 1; x < n; x++) {
24
+ let F = (g[x] + x * x - (g[a[s]] + a[s] * a[s])) / (2 * x - 2 * a[s]);
25
+ for (; F <= l[s]; )
26
+ s--, F = (g[x] + x * x - (g[a[s]] + a[s] * a[s])) / (2 * x - 2 * a[s]);
27
+ s++, a[s] = x, l[s] = F, l[s + 1] = Et;
28
28
  }
29
29
  s = 0;
30
- for (let h = 0; h < o; h++) {
31
- for (; c[s + 1] < h; ) s++;
32
- r[h] = (h - l[s]) * (h - l[s]) + x[l[s]];
30
+ for (let x = 0; x < n; x++) {
31
+ for (; l[s + 1] < x; ) s++;
32
+ o[x] = (x - a[s]) * (x - a[s]) + g[a[s]];
33
33
  }
34
34
  }
35
- function Re(x, o, r) {
36
- const l = new Float64Array(o * r);
37
- for (let f = 0; f < o * r; f++) l[f] = x[f] ? St : 0;
38
- const c = Math.max(o, r), s = new Float64Array(c), h = new Float64Array(c), L = new Int32Array(c), S = new Float64Array(c + 1);
39
- for (let f = 0; f < o; f++) {
40
- for (let m = 0; m < r; m++) s[m] = l[m * o + f];
41
- re(s, r, h, L, S);
42
- for (let m = 0; m < r; m++) l[m * o + f] = h[m];
35
+ function $e(g, n, o) {
36
+ const a = new Float64Array(n * o);
37
+ for (let f = 0; f < n * o; f++) a[f] = g[f] ? Et : 0;
38
+ const l = Math.max(n, o), s = new Float64Array(l), x = new Float64Array(l), F = new Int32Array(l), S = new Float64Array(l + 1);
39
+ for (let f = 0; f < n; f++) {
40
+ for (let y = 0; y < o; y++) s[y] = a[y * n + f];
41
+ ie(s, o, x, F, S);
42
+ for (let y = 0; y < o; y++) a[y * n + f] = x[y];
43
43
  }
44
- for (let f = 0; f < r; f++) {
45
- for (let m = 0; m < o; m++) s[m] = l[f * o + m];
46
- re(s, o, h, L, S);
47
- for (let m = 0; m < o; m++) l[f * o + m] = h[m];
44
+ for (let f = 0; f < o; f++) {
45
+ for (let y = 0; y < n; y++) s[y] = a[f * n + y];
46
+ ie(s, n, x, F, S);
47
+ for (let y = 0; y < n; y++) a[f * n + y] = x[y];
48
48
  }
49
- const P = new Float32Array(o * r);
50
- for (let f = 0; f < o * r; f++) P[f] = Math.sqrt(l[f]);
49
+ const P = new Float32Array(n * o);
50
+ for (let f = 0; f < n * o; f++) P[f] = Math.sqrt(a[f]);
51
51
  return P;
52
52
  }
53
- function ie(x, o, r, l, c) {
54
- let s = Float32Array.from(x);
55
- const h = new Float32Array(o * r), L = 1 / (2 * l + 1), S = (P, f) => P < 0 ? 0 : P > f ? f : P;
56
- for (let P = 0; P < c; P++) {
57
- for (let f = 0; f < r; f++) {
58
- const m = f * o;
59
- let B = 0;
60
- for (let q = -l; q <= l; q++) B += s[m + S(q, o - 1)];
61
- for (let q = 0; q < o; q++)
62
- h[m + q] = B * L, B += s[m + S(q + l + 1, o - 1)] - s[m + S(q - l, o - 1)];
63
- }
53
+ function ae(g, n, o, a, l) {
54
+ let s = Float32Array.from(g);
55
+ const x = new Float32Array(n * o), F = 1 / (2 * a + 1), S = (P, f) => P < 0 ? 0 : P > f ? f : P;
56
+ for (let P = 0; P < l; P++) {
64
57
  for (let f = 0; f < o; f++) {
65
- let m = 0;
66
- for (let B = -l; B <= l; B++) m += h[S(B, r - 1) * o + f];
67
- for (let B = 0; B < r; B++)
68
- s[B * o + f] = m * L, m += h[S(B + l + 1, r - 1) * o + f] - h[S(B - l, r - 1) * o + f];
58
+ const y = f * n;
59
+ let k = 0;
60
+ for (let j = -a; j <= a; j++) k += s[y + S(j, n - 1)];
61
+ for (let j = 0; j < n; j++)
62
+ x[y + j] = k * F, k += s[y + S(j + a + 1, n - 1)] - s[y + S(j - a, n - 1)];
63
+ }
64
+ for (let f = 0; f < n; f++) {
65
+ let y = 0;
66
+ for (let k = -a; k <= a; k++) y += x[S(k, o - 1) * n + f];
67
+ for (let k = 0; k < o; k++)
68
+ s[k * n + f] = y * F, y += x[S(k + a + 1, o - 1) * n + f] - x[S(k - a, o - 1) * n + f];
69
69
  }
70
70
  }
71
71
  return s;
72
72
  }
73
- function ae(x, o) {
74
- if (!x) return o;
75
- const r = x.trim();
76
- if (r[0] === "#") {
77
- let c = r.slice(1);
78
- if (c.length === 3 && (c = c[0] + c[0] + c[1] + c[1] + c[2] + c[2]), c.length >= 6) {
79
- const s = parseInt(c.slice(0, 2), 16), h = parseInt(c.slice(2, 4), 16), L = parseInt(c.slice(4, 6), 16);
80
- if (!Number.isNaN(s) && !Number.isNaN(h) && !Number.isNaN(L)) return [s, h, L];
73
+ function le(g, n) {
74
+ if (!g) return n;
75
+ const o = g.trim();
76
+ if (o[0] === "#") {
77
+ let l = o.slice(1);
78
+ if (l.length === 3 && (l = l[0] + l[0] + l[1] + l[1] + l[2] + l[2]), l.length >= 6) {
79
+ const s = parseInt(l.slice(0, 2), 16), x = parseInt(l.slice(2, 4), 16), F = parseInt(l.slice(4, 6), 16);
80
+ if (!Number.isNaN(s) && !Number.isNaN(x) && !Number.isNaN(F)) return [s, x, F];
81
81
  }
82
- return o;
82
+ return n;
83
83
  }
84
- const l = r.match(/rgba?\(([^)]+)\)/i);
85
- if (l) {
86
- const c = l[1].split(",").map((s) => parseFloat(s));
87
- if (c.length >= 3 && c.slice(0, 3).every((s) => !Number.isNaN(s)))
88
- return [Math.round(c[0]), Math.round(c[1]), Math.round(c[2])];
84
+ const a = o.match(/rgba?\(([^)]+)\)/i);
85
+ if (a) {
86
+ const l = a[1].split(",").map((s) => parseFloat(s));
87
+ if (l.length >= 3 && l.slice(0, 3).every((s) => !Number.isNaN(s)))
88
+ return [Math.round(l[0]), Math.round(l[1]), Math.round(l[2])];
89
89
  }
90
- return o;
90
+ return n;
91
91
  }
92
- function J(x) {
93
- return x < 0 ? 0 : x > 255 ? 255 : Math.round(x);
92
+ function H(g) {
93
+ return g < 0 ? 0 : g > 255 ? 255 : Math.round(g);
94
94
  }
95
- function Et(x, o, r) {
96
- return x < o ? o : x > r ? r : x;
95
+ function Tt(g, n, o) {
96
+ return g < n ? n : g > o ? o : g;
97
97
  }
98
- function le(x) {
99
- return (x.split(",")[0] || "serif").trim().replace(/^["']|["']$/g, "");
98
+ function se(g) {
99
+ return (g.split(",")[0] || "serif").trim().replace(/^["']|["']$/g, "");
100
100
  }
101
- function Ie(x, o) {
102
- if (typeof window > "u" || typeof document > "u" || !x)
101
+ function Ie(g, n) {
102
+ if (typeof window > "u" || typeof document > "u" || !g)
103
103
  return { setText() {
104
104
  }, replay() {
105
105
  }, resize() {
@@ -107,475 +107,477 @@ function Ie(x, o) {
107
107
  }, focus() {
108
108
  }, destroy() {
109
109
  }, get text() {
110
- return o.text ?? "";
110
+ return n.text ?? "";
111
111
  } };
112
- let r = o.text ?? "", l = o.font ?? "Georgia, serif", c = Et(o.weight ?? 680, 1, 1e3), s = Et(o.fill ?? 0.9, 0.05, 1), h = Math.max(1, o.sewRate ?? 110), L = o.sewStyle === "hand" ? "hand" : "machine", S = o.sheen ?? !0, P = o.animate ?? !0, f = o.editable ?? !1, m = o.pitch, B = o.onTextChange, q = le(l);
113
- const gt = o.reducedMotion ?? !!(window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches);
114
- let N = ae(o.threadColor ?? "#fffbf3", [255, 251, 243]), ft = [0, 0, 0], U = [0, 0, 0];
115
- function dt(t) {
116
- N = ae(t, [255, 251, 243]), ft = [N[0] * 0.585, N[1] * 0.585, N[2] * 0.585], U = [N[0] * 0.47, N[1] * 0.47, N[2] * 0.47];
117
- }
118
- dt(o.threadColor ?? "#fffbf3");
119
- const Y = [];
120
- let O, k;
121
- x instanceof HTMLCanvasElement ? (O = x, k = x.parentElement ?? x) : (k = x, O = document.createElement("canvas"), Y.push(O), k.appendChild(O)), O.classList.add(zt.bg);
122
- const X = document.createElement("canvas");
123
- Y.push(X), X.classList.add(zt.fx), k.appendChild(X), getComputedStyle(k).position === "static" && (k.style.position = "relative"), O.style.display = "block", O.style.width = "100%", Object.assign(X.style, { position: "absolute", inset: "0", width: "100%", pointerEvents: "none", mixBlendMode: "screen" });
124
- let w = null, F = null, W = !1, d = 0, g = 0, ot = 0, At = 0, rt = 4, it = [], ut = 0, ht = 0, qt = -1, _t = "", Gt = -1, Ut = -1, Ft = new Uint8Array(0), Lt = new Float32Array(0), pt = new Float32Array(0), wt = new Float32Array(0), Q = null, at = null, Mt = null, lt = [], tt = 3;
125
- const I = { rows: [], idx: 0, acc: 0, rate: 0, on: !1 }, H = { x: 0, y: 0, set: !1 };
126
- let et = !0, Rt = 0, mt = !1, yt = 0, K = !1, Z = !1;
112
+ let o = n.text ?? "", a = n.font ?? "Georgia, serif", l = Tt(n.weight ?? 680, 1, 1e3), s = Tt(n.fill ?? 0.9, 0.05, 1), x = Math.max(1, n.sewRate ?? 110), F = n.sewStyle === "hand" ? "hand" : "machine", S = n.sheen ?? !0, P = n.animate ?? !0, f = n.editable ?? !1, y = n.pitch, k = n.onTextChange, j = se(a);
113
+ const yt = n.reducedMotion ?? !!(window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches);
114
+ let B = le(n.threadColor ?? "#fffbf3", [255, 251, 243]), ct = [0, 0, 0], D = [0, 0, 0];
115
+ function ft(t) {
116
+ B = le(t, [255, 251, 243]), ct = [B[0] * 0.585, B[1] * 0.585, B[2] * 0.585], D = [B[0] * 0.47, B[1] * 0.47, B[2] * 0.47];
117
+ }
118
+ ft(n.threadColor ?? "#fffbf3");
119
+ const G = [];
120
+ let O, $;
121
+ g instanceof HTMLCanvasElement ? (O = g, $ = g.parentElement ?? g) : ($ = g, O = document.createElement("canvas"), G.push(O), $.appendChild(O)), O.classList.add(Dt.bg);
122
+ const z = document.createElement("canvas");
123
+ G.push(z), z.classList.add(Dt.fx), $.appendChild(z), getComputedStyle($).position === "static" && ($.style.position = "relative"), O.style.display = "block", O.style.width = "100%", Object.assign(z.style, { position: "absolute", inset: "0", width: "100%", pointerEvents: "none", mixBlendMode: "screen" });
124
+ let b = null, A = null, W = !1, u = 0, w = 0, ot = 0, St = 0, rt = 4, it = [], ut = 0, dt = 0, zt = -1, qt = "", _t = -1, Ut = -1, At = new Uint8Array(0), Ft = new Float32Array(0), gt = new Float32Array(0), pt = new Float32Array(0), J = null, at = null, wt = null, ht = [], tt = 3;
125
+ const I = { rows: [], idx: 0, acc: 0, rate: 0, on: !1 }, K = { x: 0, y: 0, set: !1 };
126
+ let et = !0, Lt = 0, mt = !1, xt = 0, q = !1, Q = !1;
127
127
  function ce() {
128
- const t = k.getBoundingClientRect(), e = Math.max(1, Math.round(t.width || Math.min(window.innerWidth * 0.95, 1240))), i = r || "Ag", u = O.getContext("2d");
129
- u && (u.textBaseline = "middle");
128
+ const t = $.getBoundingClientRect(), e = Math.max(1, Math.round(t.width || Math.min(window.innerWidth * 0.95, 1240))), r = o || "Ag", d = O.getContext("2d");
129
+ d && (d.textBaseline = "middle");
130
130
  let T = 100;
131
- u && (u.font = `${c} 100px ${l}`, T = u.measureText(i).width || 100);
132
- const C = Math.max(8, 100 * (e * s) / T);
133
- let b = C * 0.62, A = C * 0.62, E = e * s;
134
- if (u) {
135
- u.font = `${c} ${C}px ${l}`;
136
- const a = u.measureText(i);
137
- E = a.width || E, a.actualBoundingBoxAscent > 0 && (b = a.actualBoundingBoxAscent), a.actualBoundingBoxDescent > 0 && (A = a.actualBoundingBoxDescent);
131
+ d && (d.font = `${l} 100px ${a}`, T = d.measureText(r).width || 100);
132
+ const p = Math.max(8, 100 * (e * s) / T);
133
+ let h = p * 0.62, M = p * 0.62, C = e * s;
134
+ if (d) {
135
+ d.font = `${l} ${p}px ${a}`;
136
+ const i = d.measureText(r);
137
+ C = i.width || C, i.actualBoundingBoxAscent > 0 && (h = i.actualBoundingBoxAscent), i.actualBoundingBoxDescent > 0 && (M = i.actualBoundingBoxDescent);
138
138
  }
139
- const M = Math.max(1, Math.round(2 * Math.max(b, A) * 1.1));
140
- let n = Math.min(window.devicePixelRatio || 1, 1.7);
141
- for (; e * n * M * n > 9e5 && n > 0.4; ) n -= 0.1;
142
- d = Math.max(1, Math.round(e * n)), g = Math.max(1, Math.round(M * n)), ot = Math.max(4, Math.round(C * n)), At = Math.round(d / 2 - E * n / 2);
143
- for (const a of [O, X])
144
- a.width = d, a.height = g, a.style.height = M + "px";
145
- k.style.height = M + "px", rt = m ?? Math.max(3, g * 95e-4);
139
+ const m = Math.max(1, Math.round(2 * Math.max(h, M) * 1.1));
140
+ let c = Math.min(window.devicePixelRatio || 1, 1.7);
141
+ for (; e * c * m * c > 9e5 && c > 0.4; ) c -= 0.1;
142
+ u = Math.max(1, Math.round(e * c)), w = Math.max(1, Math.round(m * c)), ot = Math.max(4, Math.round(p * c)), St = Math.round(u / 2 - C * c / 2);
143
+ for (const i of [O, z])
144
+ i.width = u, i.height = w, i.style.height = m + "px";
145
+ $.style.height = m + "px", rt = y ?? Math.max(3, w * 95e-4);
146
146
  }
147
- function se() {
148
- at && Gt === d && Ut === g || (at = document.createElement("canvas"), at.width = d, at.height = g, Mt = at.getContext("2d", { willReadFrequently: !0 }), Gt = d, Ut = g);
147
+ function fe() {
148
+ at && _t === u && Ut === w || (at = document.createElement("canvas"), at.width = u, at.height = w, wt = at.getContext("2d", { willReadFrequently: !0 }), _t = u, Ut = w);
149
149
  }
150
150
  function Xt() {
151
151
  const t = Math.max(7, rt * 2.5), e = Math.max(3.2, rt * 1.3);
152
- ut = Math.ceil(t) + 2, ht = Math.ceil(e) + 2, it = [];
153
- for (let i = 0; i < 20; i++) {
154
- const u = 0.34 + i / 19 * 0.82, T = document.createElement("canvas");
155
- T.width = ut, T.height = ht;
156
- const C = T.getContext("2d");
157
- if (!C) {
152
+ ut = Math.ceil(t) + 2, dt = Math.ceil(e) + 2, it = [];
153
+ for (let r = 0; r < 20; r++) {
154
+ const d = 0.34 + r / 19 * 0.82, T = document.createElement("canvas");
155
+ T.width = ut, T.height = dt;
156
+ const p = T.getContext("2d");
157
+ if (!p) {
158
158
  it.push(T);
159
159
  continue;
160
160
  }
161
- const b = ut / 2, A = ht / 2, E = C.createLinearGradient(0, A - e / 2, 0, A + e / 2), M = (R, $) => `rgba(${J(R[0] * u)},${J(R[1] * u)},${J(R[2] * u)},${$})`;
162
- E.addColorStop(0, M(U, 0)), E.addColorStop(0.16, M(ft, 1)), E.addColorStop(0.5, M(N, 1)), E.addColorStop(0.84, M(ft, 1)), E.addColorStop(1, M(U, 0)), C.fillStyle = E, C.beginPath();
163
- const n = e / 2;
164
- C.moveTo(b - t / 2 + n, A - n), C.lineTo(b + t / 2 - n, A - n), C.arc(b + t / 2 - n, A, n, -Math.PI / 2, Math.PI / 2), C.lineTo(b - t / 2 + n, A + n), C.arc(b - t / 2 + n, A, n, Math.PI / 2, -Math.PI / 2), C.closePath(), C.fill(), C.globalCompositeOperation = "destination-in";
165
- const a = C.createLinearGradient(b - t / 2, 0, b + t / 2, 0);
166
- a.addColorStop(0, "rgba(0,0,0,0)"), a.addColorStop(0.22, "rgba(0,0,0,1)"), a.addColorStop(0.78, "rgba(0,0,0,1)"), a.addColorStop(1, "rgba(0,0,0,0)"), C.fillStyle = a, C.fillRect(0, 0, ut, ht), it.push(T);
161
+ const h = ut / 2, M = dt / 2, C = p.createLinearGradient(0, M - e / 2, 0, M + e / 2), m = (L, N) => `rgba(${H(L[0] * d)},${H(L[1] * d)},${H(L[2] * d)},${N})`;
162
+ C.addColorStop(0, m(D, 0)), C.addColorStop(0.16, m(ct, 1)), C.addColorStop(0.5, m(B, 1)), C.addColorStop(0.84, m(ct, 1)), C.addColorStop(1, m(D, 0)), p.fillStyle = C, p.beginPath();
163
+ const c = e / 2;
164
+ p.moveTo(h - t / 2 + c, M - c), p.lineTo(h + t / 2 - c, M - c), p.arc(h + t / 2 - c, M, c, -Math.PI / 2, Math.PI / 2), p.lineTo(h - t / 2 + c, M + c), p.arc(h - t / 2 + c, M, c, Math.PI / 2, -Math.PI / 2), p.closePath(), p.fill(), p.globalCompositeOperation = "destination-in";
165
+ const i = p.createLinearGradient(h - t / 2, 0, h + t / 2, 0);
166
+ i.addColorStop(0, "rgba(0,0,0,0)"), i.addColorStop(0.22, "rgba(0,0,0,1)"), i.addColorStop(0.78, "rgba(0,0,0,1)"), i.addColorStop(1, "rgba(0,0,0,0)"), p.fillStyle = i, p.fillRect(0, 0, ut, dt), it.push(T);
167
167
  }
168
- qt = rt, _t = N.join(",");
168
+ zt = rt, qt = B.join(",");
169
169
  }
170
- function fe() {
171
- it.length && qt === rt && _t === N.join(",") || Xt();
170
+ function ue() {
171
+ it.length && zt === rt && qt === B.join(",") || Xt();
172
172
  }
173
173
  function de() {
174
- if (!Mt) return;
175
- const t = Mt;
176
- t.clearRect(0, 0, d, g), t.fillStyle = "#fff", t.textAlign = "left", t.textBaseline = "middle", t.font = `${c} ${ot}px ${l}`, t.fillText(r, At, g * 0.5);
177
- const e = t.getImageData(0, 0, d, g).data, i = new Uint8Array(d * g);
178
- for (let y = 0; y < g; y++) for (let p = 0; p < d; p++) {
179
- const v = y * d + p, _ = e[v * 4 + 3] / 255, z = oe(p * 0.5, y * 0.5) * 0.22 + oe(p * 1.8, y * 1.8) * 0.1;
180
- i[v] = _ > 0.5 + (z - 0.16) ? 1 : 0;
174
+ if (!wt) return;
175
+ const t = wt;
176
+ t.clearRect(0, 0, u, w), t.fillStyle = "#fff", t.textAlign = "left", t.textBaseline = "middle", t.font = `${l} ${ot}px ${a}`, t.fillText(o, St, w * 0.5);
177
+ const e = t.getImageData(0, 0, u, w).data, r = new Uint8Array(u * w);
178
+ for (let v = 0; v < w; v++) for (let E = 0; E < u; E++) {
179
+ const R = v * u + E, U = e[R * 4 + 3] / 255, X = re(E * 0.5, v * 0.5) * 0.22 + re(E * 1.8, v * 1.8) * 0.1;
180
+ r[R] = U > 0.5 + (X - 0.16) ? 1 : 0;
181
181
  }
182
- Ft = i;
183
- const u = Re(i, d, g), T = new Float32Array(d * g);
184
- for (let y = 1; y < g - 1; y++) for (let p = 1; p < d - 1; p++) {
185
- const v = y * d + p;
186
- T[v] = (u[v] * 4 + u[v - 1] + u[v + 1] + u[v - d] + u[v + d]) / 8;
182
+ At = r;
183
+ const d = $e(r, u, w), T = new Float32Array(u * w);
184
+ for (let v = 1; v < w - 1; v++) for (let E = 1; E < u - 1; E++) {
185
+ const R = v * u + E;
186
+ T[R] = (d[R] * 4 + d[R - 1] + d[R + 1] + d[R - u] + d[R + u]) / 8;
187
187
  }
188
- const C = new Float32Array(d * g), b = new Float32Array(d * g), A = new Float32Array(d * g), E = new Float32Array(d * g);
189
- for (let y = 1; y < g - 1; y++) for (let p = 1; p < d - 1; p++) {
190
- const v = y * d + p;
191
- if (!i[v]) continue;
192
- const _ = (T[v + 1] - T[v - 1]) * 0.5, z = (T[v + d] - T[v - d]) * 0.5;
193
- A[v] = _, E[v] = z, C[v] = _ * _ - z * z, b[v] = 2 * _ * z;
188
+ const p = new Float32Array(u * w), h = new Float32Array(u * w), M = new Float32Array(u * w), C = new Float32Array(u * w);
189
+ for (let v = 1; v < w - 1; v++) for (let E = 1; E < u - 1; E++) {
190
+ const R = v * u + E;
191
+ if (!r[R]) continue;
192
+ const U = (T[R + 1] - T[R - 1]) * 0.5, X = (T[R + u] - T[R - u]) * 0.5;
193
+ M[R] = U, C[R] = X, p[R] = U * U - X * X, h[R] = 2 * U * X;
194
194
  }
195
- const M = Math.max(7, Math.round(g * 0.05)), n = ie(C, d, g, M, 2), a = ie(b, d, g, M, 2);
196
- pt = new Float32Array(d * g), wt = new Float32Array(d * g);
197
- for (let y = 0; y < d * g; y++) {
198
- if (!i[y]) continue;
199
- const p = 0.5 * Math.atan2(a[y], n[y]);
200
- pt[y] = Math.cos(p), wt[y] = Math.sin(p);
195
+ const m = Math.max(7, Math.round(w * 0.05)), c = ae(p, u, w, m, 2), i = ae(h, u, w, m, 2);
196
+ gt = new Float32Array(u * w), pt = new Float32Array(u * w);
197
+ for (let v = 0; v < u * w; v++) {
198
+ if (!r[v]) continue;
199
+ const E = 0.5 * Math.atan2(i[v], c[v]);
200
+ gt[v] = Math.cos(E), pt[v] = Math.sin(E);
201
201
  }
202
- const R = Math.max(9, g * 0.04), $ = new Float32Array(d * g), G = -0.45, V = -0.62, D = 0.64;
203
- for (let y = 1; y < g - 1; y++) for (let p = 1; p < d - 1; p++) {
204
- const v = y * d + p;
205
- if (!i[v]) continue;
206
- let _ = A[v], z = E[v];
207
- const xt = Math.hypot(_, z) || 1;
208
- _ /= xt, z /= xt;
209
- const Wt = T[v], te = (1 - Math.min(Wt / R, 1)) * 1.25;
210
- let Nt = -_ * te, Ot = -z * te;
211
- const ee = 1.5, Dt = Math.hypot(Nt, Ot, ee);
212
- Nt /= Dt, Ot /= Dt;
213
- let jt = Nt * G + Ot * V + ee / Dt * D;
202
+ const L = Math.max(9, w * 0.04), N = new Float32Array(u * w), Y = -0.45, Z = -0.62, V = 0.64;
203
+ for (let v = 1; v < w - 1; v++) for (let E = 1; E < u - 1; E++) {
204
+ const R = v * u + E;
205
+ if (!r[R]) continue;
206
+ let U = M[R], X = C[R];
207
+ const Wt = Math.hypot(U, X) || 1;
208
+ U /= Wt, X /= Wt;
209
+ const te = T[R], ee = (1 - Math.min(te / L, 1)) * 1.25;
210
+ let Bt = -U * ee, Ot = -X * ee;
211
+ const ne = 1.5, Nt = Math.hypot(Bt, Ot, ne);
212
+ Bt /= Nt, Ot /= Nt;
213
+ let jt = Bt * Y + Ot * Z + ne / Nt * V;
214
214
  jt < 0 && (jt = 0);
215
- const Ee = Math.min(1, 0.45 + 0.55 * Math.min(Wt / (R * 0.7), 1));
216
- $[v] = Math.min(1.12, (0.5 + 0.75 * jt) * Ee);
215
+ const Se = Math.min(1, 0.45 + 0.55 * Math.min(te / (L * 0.7), 1));
216
+ N[R] = Math.min(1.12, (0.5 + 0.75 * jt) * Se);
217
217
  }
218
- Lt = $, Q = document.createElement("canvas"), Q.width = d, Q.height = g;
219
- const j = Q.getContext("2d");
220
- if (j) {
221
- const y = j.createImageData(d, g);
222
- for (let p = 0; p < d * g; p++) i[p] && (y.data[p * 4] = 255, y.data[p * 4 + 1] = 255, y.data[p * 4 + 2] = 255, y.data[p * 4 + 3] = 255);
223
- j.putImageData(y, 0, 0);
218
+ Ft = N, J = document.createElement("canvas"), J.width = u, J.height = w;
219
+ const _ = J.getContext("2d");
220
+ if (_) {
221
+ const v = _.createImageData(u, w);
222
+ for (let E = 0; E < u * w; E++) r[E] && (v.data[E * 4] = 255, v.data[E * 4 + 1] = 255, v.data[E * 4 + 2] = 255, v.data[E * 4 + 3] = 255);
223
+ _.putImageData(v, 0, 0);
224
224
  }
225
225
  }
226
- function ue() {
226
+ function he() {
227
227
  const t = Math.max(1.6, rt * 0.6);
228
228
  tt = t;
229
229
  const e = [];
230
- for (let i = 0; i < g; i += t) for (let u = 0; u < d; u += t) {
231
- const T = (nt(Math.floor(u), Math.floor(i)) - 0.5) * t * 0.9, C = (nt(Math.floor(i), Math.floor(u)) - 0.5) * t * 0.9, b = Math.round(u + T), A = Math.round(i + C);
232
- if (b < 1 || A < 1 || b >= d - 1 || A >= g - 1) continue;
233
- const E = A * d + b;
234
- if (!Ft[E]) continue;
235
- const M = Math.atan2(wt[E], pt[E]), n = 0.86 + nt(b * 7, A * 13) * 0.18;
236
- let a = Lt[E] * n;
237
- a = a < 0 ? 0 : a > 1.12 ? 1.12 : a, e.push({ x: b, y: A, ang: M, idx: Math.min(19, Math.max(0, Math.round(a / 1.12 * 19))) });
230
+ for (let r = 0; r < w; r += t) for (let d = 0; d < u; d += t) {
231
+ const T = (nt(Math.floor(d), Math.floor(r)) - 0.5) * t * 0.9, p = (nt(Math.floor(r), Math.floor(d)) - 0.5) * t * 0.9, h = Math.round(d + T), M = Math.round(r + p);
232
+ if (h < 1 || M < 1 || h >= u - 1 || M >= w - 1) continue;
233
+ const C = M * u + h;
234
+ if (!At[C]) continue;
235
+ const m = Math.atan2(pt[C], gt[C]), c = 0.86 + nt(h * 7, M * 13) * 0.18;
236
+ let i = Ft[C] * c;
237
+ i = i < 0 ? 0 : i > 1.12 ? 1.12 : i, e.push({ x: h, y: M, ang: m, idx: Math.min(19, Math.max(0, Math.round(i / 1.12 * 19))) });
238
238
  }
239
- lt = e;
239
+ ht = e;
240
240
  }
241
- function Kt(t, e) {
242
- t.save(), t.translate(e.x, e.y), t.rotate(e.ang), t.drawImage(it[e.idx], -ut / 2, -ht / 2), t.restore();
241
+ function Gt(t, e) {
242
+ t.save(), t.translate(e.x, e.y), t.rotate(e.ang), t.drawImage(it[e.idx], -ut / 2, -dt / 2), t.restore();
243
243
  }
244
- function It() {
244
+ function Rt() {
245
245
  const t = O.getContext("2d");
246
246
  if (t)
247
- for (const e of lt) Kt(t, e);
247
+ for (const e of ht) Gt(t, e);
248
248
  }
249
249
  function $t() {
250
250
  const t = O.getContext("2d");
251
- t && t.clearRect(0, 0, d, g);
251
+ t && t.clearRect(0, 0, u, w);
252
252
  }
253
- function he(t) {
253
+ function Kt(t) {
254
254
  if (!t.length) return [];
255
- const e = Math.max(4, tt * 1.5), i = /* @__PURE__ */ new Map(), u = (M, n) => M + "," + n;
256
- t.forEach((M, n) => {
257
- const a = u(Math.floor(M.x / e), Math.floor(M.y / e));
258
- let R = i.get(a);
259
- R || i.set(a, R = []), R.push(n);
255
+ const e = Math.max(4, tt * 1.5), r = /* @__PURE__ */ new Map(), d = (m, c) => m + "," + c;
256
+ t.forEach((m, c) => {
257
+ const i = d(Math.floor(m.x / e), Math.floor(m.y / e));
258
+ let L = r.get(i);
259
+ L || r.set(i, L = []), L.push(c);
260
260
  });
261
261
  const T = tt * 1.8 * (tt * 1.8);
262
- function C(M) {
263
- const n = t[M], a = Math.floor(n.x / e), R = Math.floor(n.y / e), $ = [];
264
- for (let G = -1; G <= 1; G++) for (let V = -1; V <= 1; V++) {
265
- const D = i.get(u(a + G, R + V));
266
- if (D)
267
- for (const j of D) {
268
- if (j === M) continue;
269
- const y = t[j].x - n.x, p = t[j].y - n.y;
270
- y * y + p * p <= T && $.push(j);
262
+ function p(m) {
263
+ const c = t[m], i = Math.floor(c.x / e), L = Math.floor(c.y / e), N = [];
264
+ for (let Y = -1; Y <= 1; Y++) for (let Z = -1; Z <= 1; Z++) {
265
+ const V = r.get(d(i + Y, L + Z));
266
+ if (V)
267
+ for (const _ of V) {
268
+ if (_ === m) continue;
269
+ const v = t[_].x - c.x, E = t[_].y - c.y;
270
+ v * v + E * E <= T && N.push(_);
271
271
  }
272
272
  }
273
- return $;
273
+ return N;
274
274
  }
275
- const b = new Uint8Array(t.length), A = [], E = t.map((M, n) => n).sort((M, n) => t[M].x + t[M].y - (t[n].x + t[n].y));
276
- for (const M of E) {
277
- if (b[M]) continue;
278
- let n = [M];
279
- for (b[M] = 1; n.length; ) {
280
- A.push(n.map((R) => t[R]));
281
- const a = [];
282
- for (const R of n) for (const $ of C(R)) b[$] || (b[$] = 1, a.push($));
283
- n = a;
275
+ const h = new Uint8Array(t.length), M = [], C = t.map((m, c) => c).sort((m, c) => t[m].x + t[m].y - (t[c].x + t[c].y));
276
+ for (const m of C) {
277
+ if (h[m]) continue;
278
+ let c = [m];
279
+ for (h[m] = 1; c.length; ) {
280
+ M.push(c.map((L) => t[L]));
281
+ const i = [];
282
+ for (const L of c) for (const N of p(L)) h[N] || (h[N] = 1, i.push(N));
283
+ c = i;
284
284
  }
285
285
  }
286
- return A;
286
+ return M;
287
287
  }
288
288
  function me(t) {
289
- if (!t.length) return [];
290
- const e = Math.max(4, tt * 1.5), i = /* @__PURE__ */ new Map(), u = (n, a) => n + "," + a;
291
- t.forEach((n, a) => {
292
- const R = u(Math.floor(n.x / e), Math.floor(n.y / e));
293
- let $ = i.get(R);
294
- $ || i.set(R, $ = []), $.push(a);
289
+ const e = Math.max(4, tt * 1.5), r = /* @__PURE__ */ new Map(), d = (C, m) => C + "," + m;
290
+ t.forEach((C, m) => {
291
+ const c = d(Math.floor(C.x / e), Math.floor(C.y / e));
292
+ let i = r.get(c);
293
+ i || r.set(c, i = []), i.push(m);
295
294
  });
296
- const T = tt * 1.8 * (tt * 1.8), C = (n) => {
297
- const a = t[n], R = u(Math.floor(a.x / e), Math.floor(a.y / e)), $ = i.get(R);
298
- if (!$) return;
299
- const G = $.indexOf(n);
300
- G >= 0 && $.splice(G, 1), $.length || i.delete(R);
301
- };
302
- function b(n) {
303
- const a = t[n], R = Math.floor(a.x / e), $ = Math.floor(a.y / e);
304
- let G = -1, V = 1 / 0;
305
- for (let D = -1; D <= 1; D++) for (let j = -1; j <= 1; j++) {
306
- const y = i.get(u(R + D, $ + j));
307
- if (y)
308
- for (const p of y) {
309
- const v = t[p].x - a.x, _ = t[p].y - a.y, z = v * v + _ * _;
310
- z <= T && z < V && (V = z, G = p);
295
+ const T = tt * 1.8 * (tt * 1.8), p = (C) => {
296
+ const m = t[C], c = Math.floor(m.x / e), i = Math.floor(m.y / e), L = [];
297
+ for (let N = -1; N <= 1; N++) for (let Y = -1; Y <= 1; Y++) {
298
+ const Z = r.get(d(c + N, i + Y));
299
+ if (Z)
300
+ for (const V of Z) {
301
+ if (V === C) continue;
302
+ const _ = t[V].x - m.x, v = t[V].y - m.y;
303
+ _ * _ + v * v <= T && L.push(V);
311
304
  }
312
305
  }
313
- return G;
314
- }
315
- function A(n) {
316
- const a = t[n], R = Math.floor(a.x / e), $ = Math.floor(a.y / e);
317
- let G = -1, V = 1 / 0;
318
- for (let D = 1; D < 512; D++) {
319
- for (let j = -D; j <= D; j++) for (let y = -D; y <= D; y++) {
320
- if (Math.max(Math.abs(j), Math.abs(y)) !== D) continue;
321
- const p = i.get(u(R + j, $ + y));
322
- if (p)
323
- for (const v of p) {
324
- const _ = t[v].x - a.x, z = t[v].y - a.y, xt = _ * _ + z * z;
325
- xt < V && (V = xt, G = v);
326
- }
306
+ return L;
307
+ }, h = new Uint8Array(t.length), M = [];
308
+ for (let C = 0; C < t.length; C++) {
309
+ if (h[C]) continue;
310
+ const m = [];
311
+ let c = [C];
312
+ for (h[C] = 1; c.length; ) {
313
+ const i = [];
314
+ for (const L of c) {
315
+ m.push(t[L]);
316
+ for (const N of p(L)) h[N] || (h[N] = 1, i.push(N));
327
317
  }
328
- if (G >= 0 && D > Math.ceil(Math.sqrt(V) / e) + 1) break;
318
+ c = i;
329
319
  }
330
- return G;
331
- }
332
- let E = 0;
333
- for (let n = 1; n < t.length; n++) t[n].x + t[n].y < t[E].x + t[E].y && (E = n);
334
- const M = [t[E]];
335
- C(E);
336
- for (let n = 1; n < t.length; n++) {
337
- let a = b(E);
338
- if (a < 0 && (a = A(E)), a < 0) break;
339
- M.push(t[a]), C(a), E = a;
320
+ M.push(m);
340
321
  }
341
322
  return M;
342
323
  }
324
+ function xe(t) {
325
+ if (!t.length) return [];
326
+ const e = (p) => {
327
+ let h = 1 / 0;
328
+ for (const M of p) M.x < h && (h = M.x);
329
+ return h;
330
+ }, r = (p) => {
331
+ let h = 0;
332
+ for (const M of p) h += M.y;
333
+ return h / p.length;
334
+ }, d = me(t).sort((p, h) => e(p) - e(h)), T = [];
335
+ for (const p of d) {
336
+ const h = Kt(p);
337
+ let M = 1;
338
+ for (const i of h) i.length > M && (M = i.length);
339
+ const C = Math.max(2, M * 0.45), m = h.filter((i) => i.length >= C).sort((i, L) => r(i) - r(L)), c = h.filter((i) => i.length < C).sort((i, L) => r(i) - r(L));
340
+ for (const i of m) T.push(i);
341
+ for (const i of c) T.push(i);
342
+ }
343
+ return T;
344
+ }
343
345
  function ye() {
344
- if ($t(), gt || !P) {
345
- It(), I.on = !1;
346
+ if ($t(), yt || !P) {
347
+ Rt(), I.on = !1;
346
348
  return;
347
349
  }
348
- L === "hand" ? (I.rows = me(lt).map((t) => [t]), I.rate = Math.max(h, lt.length / 3.2)) : (I.rows = he(lt), I.rate = h), I.idx = 0, I.acc = 0, I.on = I.rows.length > 0;
350
+ I.rows = F === "hand" ? xe(ht) : Kt(ht), I.idx = 0, I.acc = 0, I.rate = x, I.on = I.rows.length > 0;
349
351
  }
350
- function xe(t) {
352
+ function ge(t) {
351
353
  const e = O.getContext("2d");
352
354
  if (e)
353
355
  for (t > I.rows.length && (t = I.rows.length); I.idx < t; ) {
354
- const i = I.rows[I.idx++];
355
- for (const u of i) Kt(e, u);
356
+ const r = I.rows[I.idx++];
357
+ for (const d of r) Gt(e, d);
356
358
  }
357
359
  }
358
- function ge(t, e) {
359
- const i = X.getContext("2d");
360
- if (!i || (i.clearRect(0, 0, d, g), !S || !Q)) return;
361
- const u = d * 0.32, T = i.createRadialGradient(t, e, 0, t, e, u);
362
- T.addColorStop(0, "rgba(255,250,238,0.18)"), T.addColorStop(0.5, "rgba(255,250,238,0.055)"), T.addColorStop(1, "rgba(255,250,238,0)"), i.fillStyle = T, i.fillRect(0, 0, d, g), i.globalCompositeOperation = "destination-in", i.drawImage(Q, 0, 0), i.globalCompositeOperation = "source-over";
360
+ function pe(t, e) {
361
+ const r = z.getContext("2d");
362
+ if (!r || (r.clearRect(0, 0, u, w), !S || !J)) return;
363
+ const d = u * 0.32, T = r.createRadialGradient(t, e, 0, t, e, d);
364
+ T.addColorStop(0, "rgba(255,250,238,0.18)"), T.addColorStop(0.5, "rgba(255,250,238,0.055)"), T.addColorStop(1, "rgba(255,250,238,0)"), r.fillStyle = T, r.fillRect(0, 0, u, w), r.globalCompositeOperation = "destination-in", r.drawImage(J, 0, 0), r.globalCompositeOperation = "source-over";
363
365
  }
364
- function pe() {
365
- F || !f || (F = document.createElement("span"), F.className = zt.caret, F.setAttribute("aria-hidden", "true"), Object.assign(F.style, { position: "absolute", pointerEvents: "none", borderRadius: "1px", opacity: "0", background: `rgb(${J(N[0])},${J(N[1])},${J(N[2])})` }), k.appendChild(F), Y.push(F));
366
+ function we() {
367
+ A || !f || (A = document.createElement("span"), A.className = Dt.caret, A.setAttribute("aria-hidden", "true"), Object.assign(A.style, { position: "absolute", pointerEvents: "none", borderRadius: "1px", opacity: "0", background: `rgb(${H(B[0])},${H(B[1])},${H(B[2])})` }), $.appendChild(A), G.push(A));
366
368
  }
367
- function kt() {
368
- if (!f || !F) return;
369
+ function It() {
370
+ if (!f || !A) return;
369
371
  const t = O.getContext("2d");
370
372
  if (!t) return;
371
- t.font = `${c} ${ot}px ${l}`;
372
- const e = t.measureText(r).width, i = (O.clientWidth || d) / d, u = ot * 0.7;
373
- F.style.left = (At + e + ot * 0.05) * i + "px", F.style.top = 0.5 * (O.clientHeight || g) - u * i / 2 + "px", F.style.height = u * i + "px", F.style.width = Math.max(2, Math.round(ot * 0.02 * i)) + "px", F.style.background = `rgb(${J(N[0])},${J(N[1])},${J(N[2])})`;
373
+ t.font = `${l} ${ot}px ${a}`;
374
+ const e = t.measureText(o).width, r = (O.clientWidth || u) / u, d = ot * 0.7;
375
+ A.style.left = (St + e + ot * 0.05) * r + "px", A.style.top = 0.5 * (O.clientHeight || w) - d * r / 2 + "px", A.style.height = d * r + "px", A.style.width = Math.max(2, Math.round(ot * 0.02 * r)) + "px", A.style.background = `rgb(${H(B[0])},${H(B[1])},${H(B[2])})`;
374
376
  }
375
- function ct() {
376
- K || mt || (mt = !0, yt = 0, Rt = requestAnimationFrame(Vt));
377
+ function lt() {
378
+ q || mt || (mt = !0, xt = 0, Lt = requestAnimationFrame(Yt));
377
379
  }
378
- function Vt(t) {
379
- if (K) {
380
+ function Yt(t) {
381
+ if (q) {
380
382
  mt = !1;
381
383
  return;
382
384
  }
383
- yt || (yt = t);
384
- const e = Math.min(0.25, (t - yt) / 1e3);
385
- yt = t, I.on && (I.acc += I.rate * e, xe(I.acc), I.idx >= I.rows.length && (I.on = !1)), et && Q && (ge(H.set ? H.x : d * 0.5, H.set ? H.y : g * 0.45), et = !1);
386
- const i = f && W;
387
- if (F && (F.style.opacity = i && Math.floor(t / 530) % 2 === 0 ? "1" : "0"), !I.on && !et && !i) {
385
+ xt || (xt = t);
386
+ const e = Math.min(0.25, (t - xt) / 1e3);
387
+ xt = t, I.on && (I.acc += I.rate * e, ge(I.acc), I.idx >= I.rows.length && (I.on = !1)), et && J && (pe(K.set ? K.x : u * 0.5, K.set ? K.y : w * 0.45), et = !1);
388
+ const r = f && W;
389
+ if (A && (A.style.opacity = r && Math.floor(t / 530) % 2 === 0 ? "1" : "0"), !I.on && !et && !r) {
388
390
  mt = !1;
389
391
  return;
390
392
  }
391
- Rt = requestAnimationFrame(Vt);
393
+ Lt = requestAnimationFrame(Yt);
392
394
  }
393
- function Ct(t) {
394
- const e = k.getBoundingClientRect();
395
- H.x = (t.clientX - e.left) / (e.width || 1) * d, H.y = (t.clientY - e.top) / (e.height || 1) * g, H.set = !0, et = !0, ct();
395
+ function Mt(t) {
396
+ const e = $.getBoundingClientRect();
397
+ K.x = (t.clientX - e.left) / (e.width || 1) * u, K.y = (t.clientY - e.top) / (e.height || 1) * w, K.set = !0, et = !0, lt();
396
398
  }
397
- function vt() {
398
- H.set = !1, et = !0, ct();
399
- }
400
- function we() {
401
- w && Ht(w.value, !0);
399
+ function Ct() {
400
+ K.set = !1, et = !0, lt();
402
401
  }
403
- function Me(t) {
404
- t.key === "Enter" && (t.preventDefault(), Bt.replay());
402
+ function Me() {
403
+ b && Ht(b.value, !0);
405
404
  }
406
- function Ce() {
407
- W = !0, ct();
405
+ function Ce(t) {
406
+ t.key === "Enter" && (t.preventDefault(), kt.replay());
408
407
  }
409
408
  function ve() {
410
- W = !1, F && (F.style.opacity = "0");
409
+ W = !0, lt();
411
410
  }
412
- function Yt(t) {
413
- t === f && w || (f = t, t ? (w || (w = document.createElement("input"), w.type = "text", w.value = r, w.maxLength = 64, w.setAttribute("aria-label", "Embroidered text — type to change it"), w.setAttribute("autocomplete", "off"), w.setAttribute("autocapitalize", "off"), w.spellcheck = !1, Object.assign(w.style, { position: "absolute", inset: "0", width: "100%", height: "100%", margin: "0", padding: "0", border: "0", outline: "none", background: "transparent", color: "transparent", caretColor: "transparent", font: "inherit", textAlign: "center", cursor: "text" }), w.addEventListener("input", we), w.addEventListener("keydown", Me), w.addEventListener("focus", Ce), w.addEventListener("blur", ve), k.appendChild(w), Y.push(w)), pe(), kt()) : (w && (w.remove(), w = null), W = !1, F && (F.style.opacity = "0")));
411
+ function be() {
412
+ W = !1, A && (A.style.opacity = "0");
413
+ }
414
+ function Vt(t) {
415
+ t === f && b || (f = t, t ? (b || (b = document.createElement("input"), b.type = "text", b.value = o, b.maxLength = 64, b.setAttribute("aria-label", "Embroidered text — type to change it"), b.setAttribute("autocomplete", "off"), b.setAttribute("autocapitalize", "off"), b.spellcheck = !1, Object.assign(b.style, { position: "absolute", inset: "0", width: "100%", height: "100%", margin: "0", padding: "0", border: "0", outline: "none", background: "transparent", color: "transparent", caretColor: "transparent", font: "inherit", textAlign: "center", cursor: "text" }), b.addEventListener("input", Me), b.addEventListener("keydown", Ce), b.addEventListener("focus", ve), b.addEventListener("blur", be), $.appendChild(b), G.push(b)), we(), It()) : (b && (b.remove(), b = null), W = !1, A && (A.style.opacity = "0")));
414
416
  }
415
- function be(t) {
417
+ function Te(t) {
416
418
  if (t !== S)
417
419
  if (S = t, t)
418
- k.addEventListener("pointermove", Ct, { passive: !0 }), k.addEventListener("pointerleave", vt, { passive: !0 }), H.set = !1, et = !0, ct();
420
+ $.addEventListener("pointermove", Mt, { passive: !0 }), $.addEventListener("pointerleave", Ct, { passive: !0 }), K.set = !1, et = !0, lt();
419
421
  else {
420
- k.removeEventListener("pointermove", Ct), k.removeEventListener("pointerleave", vt);
421
- const e = X.getContext("2d");
422
- e && e.clearRect(0, 0, d, g);
422
+ $.removeEventListener("pointermove", Mt), $.removeEventListener("pointerleave", Ct);
423
+ const e = z.getContext("2d");
424
+ e && e.clearRect(0, 0, u, w);
423
425
  }
424
426
  }
425
427
  function st(t) {
426
- ce(), se(), fe(), de(), ue(), t ? ye() : ($t(), It(), I.on = !1), w && w.value !== r && (w.value = r), kt(), et = !0, ct();
428
+ ce(), fe(), ue(), de(), he(), t ? ye() : ($t(), Rt(), I.on = !1), b && b.value !== o && (b.value = o), It(), et = !0, lt();
427
429
  }
428
430
  function Ht(t, e) {
429
- t = t ?? "", !(t === r && Z) && (r = t, Z && (st(!1), e && B && B(r)));
431
+ t = t ?? "", !(t === o && Q) && (o = t, Q && (st(!1), e && k && k(o)));
430
432
  }
431
- const bt = /* @__PURE__ */ new Set();
432
- function Jt(t, e, i) {
433
- const u = `${e} 200px ${t}`;
433
+ const vt = /* @__PURE__ */ new Set();
434
+ function Jt(t, e, r) {
435
+ const d = `${e} 200px ${t}`;
434
436
  let T = !1;
435
437
  try {
436
- T = !!document.fonts && document.fonts.check(u);
438
+ T = !!document.fonts && document.fonts.check(d);
437
439
  } catch {
438
440
  T = !0;
439
441
  }
440
442
  if (!document.fonts || T) {
441
- i();
443
+ r();
442
444
  return;
443
445
  }
444
- let C = !1, b;
445
- const A = () => {
446
- C || (C = !0, clearTimeout(b), bt.delete(b), K || i());
446
+ let p = !1, h;
447
+ const M = () => {
448
+ p || (p = !0, clearTimeout(h), vt.delete(h), q || r());
447
449
  };
448
- document.fonts.load(u, r).then(() => document.fonts.ready).then(A, A), b = setTimeout(A, 1500), bt.add(b);
450
+ document.fonts.load(d, o).then(() => document.fonts.ready).then(M, M), h = setTimeout(M, 1500), vt.add(h);
449
451
  }
450
- function Te() {
451
- K || (st(!0), Z = !0);
452
+ function Ee() {
453
+ q || (st(!0), Q = !0);
452
454
  }
453
- f && (f = !1, Yt(!0)), S && (k.addEventListener("pointermove", Ct, { passive: !0 }), k.addEventListener("pointerleave", vt, { passive: !0 })), Jt(q, c, Te);
455
+ f && (f = !1, Vt(!0)), S && ($.addEventListener("pointermove", Mt, { passive: !0 }), $.addEventListener("pointerleave", Ct, { passive: !0 })), Jt(j, l, Ee);
454
456
  let Pt, Qt = -1;
455
457
  function Zt() {
456
458
  clearTimeout(Pt), Pt = setTimeout(() => {
457
- if (K || !Z) return;
458
- const t = Math.round(k.getBoundingClientRect().width);
459
+ if (q || !Q) return;
460
+ const t = Math.round($.getBoundingClientRect().width);
459
461
  t !== Qt && (Qt = t, st(!1));
460
462
  }, 200);
461
463
  }
462
464
  window.addEventListener("resize", Zt);
463
- const Bt = {
465
+ const kt = {
464
466
  get text() {
465
- return r;
467
+ return o;
466
468
  },
467
469
  setText(t) {
468
- if (!K) {
469
- if (!Z) {
470
- r = t ?? "", w && (w.value = r);
470
+ if (!q) {
471
+ if (!Q) {
472
+ o = t ?? "", b && (b.value = o);
471
473
  return;
472
474
  }
473
475
  Ht(t, !1);
474
476
  }
475
477
  },
476
478
  replay() {
477
- K || !Z || st(!0);
479
+ q || !Q || st(!0);
478
480
  },
479
481
  resize() {
480
- K || !Z || st(!1);
482
+ q || !Q || st(!1);
481
483
  },
482
484
  update(t) {
483
- if (K) return;
484
- t.text !== void 0 && Bt.setText(t.text);
485
- let e = !1, i = !1;
486
- if (t.font !== void 0 && t.font !== l && (l = t.font, q = le(l), e = !0), t.weight !== void 0) {
487
- const u = Et(t.weight, 1, 1e3);
488
- u !== c && (c = u, e = !0);
485
+ if (q) return;
486
+ t.text !== void 0 && kt.setText(t.text);
487
+ let e = !1, r = !1;
488
+ if (t.font !== void 0 && t.font !== a && (a = t.font, j = se(a), e = !0), t.weight !== void 0) {
489
+ const d = Tt(t.weight, 1, 1e3);
490
+ d !== l && (l = d, e = !0);
489
491
  }
490
492
  if (t.fill !== void 0) {
491
- const u = Et(t.fill, 0.05, 1);
492
- u !== s && (s = u, e = !0);
493
+ const d = Tt(t.fill, 0.05, 1);
494
+ d !== s && (s = d, e = !0);
493
495
  }
494
- t.pitch !== void 0 && t.pitch !== m && (m = t.pitch, e = !0), t.threadColor !== void 0 && (dt(t.threadColor), i = !0), t.sewRate !== void 0 && (h = Math.max(1, t.sewRate)), t.sewStyle !== void 0 && (L = t.sewStyle === "hand" ? "hand" : "machine"), t.animate !== void 0 && (P = t.animate), t.onTextChange !== void 0 && (B = t.onTextChange), t.sheen !== void 0 && be(t.sheen), t.editable !== void 0 && Yt(t.editable), Z && (e ? Jt(q, c, () => {
495
- K || st(!1);
496
- }) : i && (Xt(), $t(), It(), kt(), ct()));
496
+ t.pitch !== void 0 && t.pitch !== y && (y = t.pitch, e = !0), t.threadColor !== void 0 && (ft(t.threadColor), r = !0), t.sewRate !== void 0 && (x = Math.max(1, t.sewRate)), t.sewStyle !== void 0 && (F = t.sewStyle === "hand" ? "hand" : "machine"), t.animate !== void 0 && (P = t.animate), t.onTextChange !== void 0 && (k = t.onTextChange), t.sheen !== void 0 && Te(t.sheen), t.editable !== void 0 && Vt(t.editable), Q && (e ? Jt(j, l, () => {
497
+ q || st(!1);
498
+ }) : r && (Xt(), $t(), Rt(), It(), lt()));
497
499
  },
498
500
  focus() {
499
- !K && f && (w == null || w.focus());
501
+ !q && f && (b == null || b.focus());
500
502
  },
501
503
  destroy() {
502
- if (!K) {
503
- K = !0, mt = !1, cancelAnimationFrame(Rt), clearTimeout(Pt);
504
- for (const t of bt) clearTimeout(t);
505
- bt.clear(), window.removeEventListener("resize", Zt), k.removeEventListener("pointermove", Ct), k.removeEventListener("pointerleave", vt);
506
- for (const t of Y) t.remove();
507
- it = [], lt = [], I.rows = [], Ft = new Uint8Array(0), Lt = new Float32Array(0), pt = new Float32Array(0), wt = new Float32Array(0), Q = at = null, Mt = null, F = null, w = null;
504
+ if (!q) {
505
+ q = !0, mt = !1, cancelAnimationFrame(Lt), clearTimeout(Pt);
506
+ for (const t of vt) clearTimeout(t);
507
+ vt.clear(), window.removeEventListener("resize", Zt), $.removeEventListener("pointermove", Mt), $.removeEventListener("pointerleave", Ct);
508
+ for (const t of G) t.remove();
509
+ it = [], ht = [], I.rows = [], At = new Uint8Array(0), Ft = new Float32Array(0), gt = new Float32Array(0), pt = new Float32Array(0), J = at = null, wt = null, A = null, b = null;
508
510
  }
509
511
  }
510
512
  };
511
- return Bt;
513
+ return kt;
512
514
  }
513
- function $e(x) {
514
- const o = Tt(null), r = Tt(null), l = Tt(x);
515
- l.current = x;
516
- const c = Tt(x.onTextChange);
517
- c.current = x.onTextChange;
518
- const { text: s, font: h, weight: L, threadColor: S, pitch: P, fill: f, animate: m, sewStyle: B, sewRate: q, sheen: gt, editable: N, reducedMotion: ft } = x;
519
- return Se(() => {
520
- const U = o.current;
521
- if (!U) return;
522
- const dt = Ie(U, {
523
- ...l.current,
515
+ function Pe(g) {
516
+ const n = bt(null), o = bt(null), a = bt(g);
517
+ a.current = g;
518
+ const l = bt(g.onTextChange);
519
+ l.current = g.onTextChange;
520
+ const { text: s, font: x, weight: F, threadColor: S, pitch: P, fill: f, animate: y, sewStyle: k, sewRate: j, sheen: yt, editable: B, reducedMotion: ct } = g;
521
+ return Ae(() => {
522
+ const D = n.current;
523
+ if (!D) return;
524
+ const ft = Ie(D, {
525
+ ...a.current,
524
526
  // Stable callback wrapper so typing edits always reach the latest handler.
525
- onTextChange: (w) => {
526
- var F;
527
- return (F = c.current) == null ? void 0 : F.call(c, w);
527
+ onTextChange: (b) => {
528
+ var A;
529
+ return (A = l.current) == null ? void 0 : A.call(l, b);
528
530
  }
529
531
  });
530
- r.current = dt;
531
- let Y = 0, O = 0, k = !0, X;
532
- return typeof ResizeObserver < "u" && (X = new ResizeObserver((w) => {
533
- const F = Math.round(w[0].contentRect.width);
534
- if (k) {
535
- k = !1, O = F;
532
+ o.current = ft;
533
+ let G = 0, O = 0, $ = !0, z;
534
+ return typeof ResizeObserver < "u" && (z = new ResizeObserver((b) => {
535
+ const A = Math.round(b[0].contentRect.width);
536
+ if ($) {
537
+ $ = !1, O = A;
536
538
  return;
537
539
  }
538
- F !== O && (O = F, cancelAnimationFrame(Y), Y = requestAnimationFrame(() => {
540
+ A !== O && (O = A, cancelAnimationFrame(G), G = requestAnimationFrame(() => {
539
541
  var W;
540
- return (W = r.current) == null ? void 0 : W.resize();
542
+ return (W = o.current) == null ? void 0 : W.resize();
541
543
  }));
542
- }), X.observe(U)), () => {
543
- X == null || X.disconnect(), cancelAnimationFrame(Y), dt.destroy(), r.current = null;
544
+ }), z.observe(D)), () => {
545
+ z == null || z.disconnect(), cancelAnimationFrame(G), ft.destroy(), o.current = null;
544
546
  };
545
- }, [ft]), ne(() => {
546
- var U;
547
- (U = r.current) == null || U.update({ font: h, weight: L, threadColor: S, pitch: P, fill: f, animate: m, sewStyle: B, sewRate: q, sheen: gt, editable: N });
548
- }, [h, L, S, P, f, m, B, q, gt, N]), ne(() => {
549
- var U;
550
- (U = r.current) == null || U.setText(s);
551
- }, [s]), o;
547
+ }, [ct]), oe(() => {
548
+ var D;
549
+ (D = o.current) == null || D.update({ font: x, weight: F, threadColor: S, pitch: P, fill: f, animate: y, sewStyle: k, sewRate: j, sheen: yt, editable: B });
550
+ }, [x, F, S, P, f, y, k, j, yt, B]), oe(() => {
551
+ var D;
552
+ (D = o.current) == null || D.setText(s);
553
+ }, [s]), n;
552
554
  }
553
- const ke = Ae(
554
- function({ className: o, style: r, as: l = "div", "aria-label": c, role: s, "aria-describedby": h, ...L }, S) {
555
- const P = $e(L), f = Fe(
556
- (m) => {
557
- P.current = m, typeof S == "function" ? S(m) : S && (S.current = m);
555
+ const ke = Fe(
556
+ function({ className: n, style: o, as: a = "div", "aria-label": l, role: s, "aria-describedby": x, ...F }, S) {
557
+ const P = Pe(F), f = Le(
558
+ (y) => {
559
+ P.current = y, typeof S == "function" ? S(y) : S && (S.current = y);
558
560
  },
559
561
  // eslint-disable-next-line react-hooks/exhaustive-deps
560
562
  [P, S]
561
563
  );
562
- return /* @__PURE__ */ Le(
563
- l,
564
+ return /* @__PURE__ */ Re(
565
+ a,
564
566
  {
565
567
  ref: f,
566
- className: o,
567
- style: r,
568
- role: L.editable ? s : s ?? "img",
569
- "aria-label": L.editable ? c : c ?? L.text,
570
- "aria-describedby": h
568
+ className: n,
569
+ style: o,
570
+ role: F.editable ? s : s ?? "img",
571
+ "aria-label": F.editable ? l : l ?? F.text,
572
+ "aria-describedby": x
571
573
  }
572
574
  );
573
575
  }
574
576
  );
575
577
  ke.displayName = "ThreadText";
576
578
  export {
577
- zt as THREAD_TEXT_CLASSES,
579
+ Dt as THREAD_TEXT_CLASSES,
578
580
  ke as ThreadText,
579
581
  Ie as createThreadText,
580
- $e as useThreadText
582
+ Pe as useThreadText
581
583
  };
@@ -1 +1 @@
1
- var ThreadText=(function(ht){"use strict";const Tt={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function J(l,n){let e=Math.imul(l|0,374761393)+Math.imul(n|0,668265263)|0;return e=Math.imul(e^e>>>13,1274126177),((e^e>>>16)>>>0)/4294967295}function qt(l,n){const e=Math.floor(l),r=Math.floor(n),a=l-e,u=n-r,x=a*a*(3-2*a),$=u*u*(3-2*u),I=J(e,r),_=J(e+1,r),h=J(e,r+1),p=J(e+1,r+1);return I+(_-I)*x+(h-I)*$+(I-_-h+p)*x*$}const mt=1e20;function zt(l,n,e,r,a){let u=0;r[0]=0,a[0]=-mt,a[1]=mt;for(let x=1;x<n;x++){let $=(l[x]+x*x-(l[r[u]]+r[u]*r[u]))/(2*x-2*r[u]);for(;$<=a[u];)u--,$=(l[x]+x*x-(l[r[u]]+r[u]*r[u]))/(2*x-2*r[u]);u++,r[u]=x,a[u]=$,a[u+1]=mt}u=0;for(let x=0;x<n;x++){for(;a[u+1]<x;)u++;e[x]=(x-r[u])*(x-r[u])+l[r[u]]}}function se(l,n,e){const r=new Float64Array(n*e);for(let h=0;h<n*e;h++)r[h]=l[h]?mt:0;const a=Math.max(n,e),u=new Float64Array(a),x=new Float64Array(a),$=new Int32Array(a),I=new Float64Array(a+1);for(let h=0;h<n;h++){for(let p=0;p<e;p++)u[p]=r[p*n+h];zt(u,e,x,$,I);for(let p=0;p<e;p++)r[p*n+h]=x[p]}for(let h=0;h<e;h++){for(let p=0;p<n;p++)u[p]=r[h*n+p];zt(u,n,x,$,I);for(let p=0;p<n;p++)r[h*n+p]=x[p]}const _=new Float32Array(n*e);for(let h=0;h<n*e;h++)_[h]=Math.sqrt(r[h]);return _}function Gt(l,n,e,r,a){let u=Float32Array.from(l);const x=new Float32Array(n*e),$=1/(2*r+1),I=(_,h)=>_<0?0:_>h?h:_;for(let _=0;_<a;_++){for(let h=0;h<e;h++){const p=h*n;let P=0;for(let G=-r;G<=r;G++)P+=u[p+I(G,n-1)];for(let G=0;G<n;G++)x[p+G]=P*$,P+=u[p+I(G+r+1,n-1)]-u[p+I(G-r,n-1)]}for(let h=0;h<n;h++){let p=0;for(let P=-r;P<=r;P++)p+=x[I(P,e-1)*n+h];for(let P=0;P<e;P++)u[P*n+h]=p*$,p+=x[I(P+r+1,e-1)*n+h]-x[I(P-r,e-1)*n+h]}}return u}function Ht(l,n){if(!l)return n;const e=l.trim();if(e[0]==="#"){let a=e.slice(1);if(a.length===3&&(a=a[0]+a[0]+a[1]+a[1]+a[2]+a[2]),a.length>=6){const u=parseInt(a.slice(0,2),16),x=parseInt(a.slice(2,4),16),$=parseInt(a.slice(4,6),16);if(!Number.isNaN(u)&&!Number.isNaN(x)&&!Number.isNaN($))return[u,x,$]}return n}const r=e.match(/rgba?\(([^)]+)\)/i);if(r){const a=r[1].split(",").map(u=>parseFloat(u));if(a.length>=3&&a.slice(0,3).every(u=>!Number.isNaN(u)))return[Math.round(a[0]),Math.round(a[1]),Math.round(a[2])]}return n}function X(l){return l<0?0:l>255?255:Math.round(l)}function yt(l,n,e){return l<n?n:l>e?e:l}function Ut(l){return(l.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function fe(l,n){if(typeof window>"u"||typeof document>"u"||!l)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return n.text??""}};let e=n.text??"",r=n.font??"Georgia, serif",a=yt(n.weight??680,1,1e3),u=yt(n.fill??.9,.05,1),x=Math.max(1,n.sewRate??110),$=n.sewStyle==="hand"?"hand":"machine",I=n.sheen??!0,_=n.animate??!0,h=n.editable??!1,p=n.pitch,P=n.onTextChange,G=Ut(r);const ye=n.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let D=Ht(n.threadColor??"#fffbf3",[255,251,243]),Et=[0,0,0],bt=[0,0,0];function Kt(t){D=Ht(t,[255,251,243]),Et=[D[0]*.585,D[1]*.585,D[2]*.585],bt=[D[0]*.47,D[1]*.47,D[2]*.47]}Kt(n.threadColor??"#fffbf3");const lt=[];let q,R;l instanceof HTMLCanvasElement?(q=l,R=l.parentElement??l):(R=l,q=document.createElement("canvas"),lt.push(q),R.appendChild(q)),q.classList.add(Tt.bg);const Q=document.createElement("canvas");lt.push(Q),Q.classList.add(Tt.fx),R.appendChild(Q),getComputedStyle(R).position==="static"&&(R.style.position="relative"),q.style.display="block",q.style.width="100%",Object.assign(Q.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let C=null,N=null,gt=!1,f=0,y=0,tt=0,Ft=0,et=4,nt=[],ct=0,st=0,Vt=-1,Yt="",Jt=-1,Qt=-1,Lt=new Uint8Array(0),Rt=new Float32Array(0),pt=new Float32Array(0),wt=new Float32Array(0),V=null,ot=null,Mt=null,rt=[],Z=3;const F={rows:[],idx:0,acc:0,rate:0,on:!1},K={x:0,y:0,set:!1};let W=!0,Nt=0,ft=!1,dt=0,H=!1,Y=!1;function xe(){const t=R.getBoundingClientRect(),o=Math.max(1,Math.round(t.width||Math.min(window.innerWidth*.95,1240))),c=e||"Ag",d=q.getContext("2d");d&&(d.textBaseline="middle");let T=100;d&&(d.font=`${a} 100px ${r}`,T=d.measureText(c).width||100);const M=Math.max(8,100*(o*u)/T);let S=M*.62,E=M*.62,A=o*u;if(d){d.font=`${a} ${M}px ${r}`;const s=d.measureText(c);A=s.width||A,s.actualBoundingBoxAscent>0&&(S=s.actualBoundingBoxAscent),s.actualBoundingBoxDescent>0&&(E=s.actualBoundingBoxDescent)}const w=Math.max(1,Math.round(2*Math.max(S,E)*1.1));let i=Math.min(window.devicePixelRatio||1,1.7);for(;o*i*w*i>9e5&&i>.4;)i-=.1;f=Math.max(1,Math.round(o*i)),y=Math.max(1,Math.round(w*i)),tt=Math.max(4,Math.round(M*i)),Ft=Math.round(f/2-A*i/2);for(const s of[q,Q])s.width=f,s.height=y,s.style.height=w+"px";R.style.height=w+"px",et=p??Math.max(3,y*.0095)}function ge(){ot&&Jt===f&&Qt===y||(ot=document.createElement("canvas"),ot.width=f,ot.height=y,Mt=ot.getContext("2d",{willReadFrequently:!0}),Jt=f,Qt=y)}function Zt(){const t=Math.max(7,et*2.5),o=Math.max(3.2,et*1.3);ct=Math.ceil(t)+2,st=Math.ceil(o)+2,nt=[];for(let c=0;c<20;c++){const d=.34+c/19*.82,T=document.createElement("canvas");T.width=ct,T.height=st;const M=T.getContext("2d");if(!M){nt.push(T);continue}const S=ct/2,E=st/2,A=M.createLinearGradient(0,E-o/2,0,E+o/2),w=(b,L)=>`rgba(${X(b[0]*d)},${X(b[1]*d)},${X(b[2]*d)},${L})`;A.addColorStop(0,w(bt,0)),A.addColorStop(.16,w(Et,1)),A.addColorStop(.5,w(D,1)),A.addColorStop(.84,w(Et,1)),A.addColorStop(1,w(bt,0)),M.fillStyle=A,M.beginPath();const i=o/2;M.moveTo(S-t/2+i,E-i),M.lineTo(S+t/2-i,E-i),M.arc(S+t/2-i,E,i,-Math.PI/2,Math.PI/2),M.lineTo(S-t/2+i,E+i),M.arc(S-t/2+i,E,i,Math.PI/2,-Math.PI/2),M.closePath(),M.fill(),M.globalCompositeOperation="destination-in";const s=M.createLinearGradient(S-t/2,0,S+t/2,0);s.addColorStop(0,"rgba(0,0,0,0)"),s.addColorStop(.22,"rgba(0,0,0,1)"),s.addColorStop(.78,"rgba(0,0,0,1)"),s.addColorStop(1,"rgba(0,0,0,0)"),M.fillStyle=s,M.fillRect(0,0,ct,st),nt.push(T)}Vt=et,Yt=D.join(",")}function pe(){nt.length&&Vt===et&&Yt===D.join(",")||Zt()}function we(){if(!Mt)return;const t=Mt;t.clearRect(0,0,f,y),t.fillStyle="#fff",t.textAlign="left",t.textBaseline="middle",t.font=`${a} ${tt}px ${r}`,t.fillText(e,Ft,y*.5);const o=t.getImageData(0,0,f,y).data,c=new Uint8Array(f*y);for(let m=0;m<y;m++)for(let g=0;g<f;g++){const v=m*f+g,j=o[v*4+3]/255,B=qt(g*.5,m*.5)*.22+qt(g*1.8,m*1.8)*.1;c[v]=j>.5+(B-.16)?1:0}Lt=c;const d=se(c,f,y),T=new Float32Array(f*y);for(let m=1;m<y-1;m++)for(let g=1;g<f-1;g++){const v=m*f+g;T[v]=(d[v]*4+d[v-1]+d[v+1]+d[v-f]+d[v+f])/8}const M=new Float32Array(f*y),S=new Float32Array(f*y),E=new Float32Array(f*y),A=new Float32Array(f*y);for(let m=1;m<y-1;m++)for(let g=1;g<f-1;g++){const v=m*f+g;if(!c[v])continue;const j=(T[v+1]-T[v-1])*.5,B=(T[v+f]-T[v-f])*.5;E[v]=j,A[v]=B,M[v]=j*j-B*B,S[v]=2*j*B}const w=Math.max(7,Math.round(y*.05)),i=Gt(M,f,y,w,2),s=Gt(S,f,y,w,2);pt=new Float32Array(f*y),wt=new Float32Array(f*y);for(let m=0;m<f*y;m++){if(!c[m])continue;const g=.5*Math.atan2(s[m],i[m]);pt[m]=Math.cos(g),wt[m]=Math.sin(g)}const b=Math.max(9,y*.04),L=new Float32Array(f*y),z=-.45,U=-.62,k=.64;for(let m=1;m<y-1;m++)for(let g=1;g<f-1;g++){const v=m*f+g;if(!c[v])continue;let j=E[v],B=A[v];const ut=Math.hypot(j,B)||1;j/=ut,B/=ut;const ae=T[v],le=(1-Math.min(ae/b,1))*1.25;let Bt=-j*le,Dt=-B*le;const ce=1.5,jt=Math.hypot(Bt,Dt,ce);Bt/=jt,Dt/=jt;let _t=Bt*z+Dt*U+ce/jt*k;_t<0&&(_t=0);const $e=Math.min(1,.45+.55*Math.min(ae/(b*.7),1));L[v]=Math.min(1.12,(.5+.75*_t)*$e)}Rt=L,V=document.createElement("canvas"),V.width=f,V.height=y;const O=V.getContext("2d");if(O){const m=O.createImageData(f,y);for(let g=0;g<f*y;g++)c[g]&&(m.data[g*4]=255,m.data[g*4+1]=255,m.data[g*4+2]=255,m.data[g*4+3]=255);O.putImageData(m,0,0)}}function Me(){const t=Math.max(1.6,et*.6);Z=t;const o=[];for(let c=0;c<y;c+=t)for(let d=0;d<f;d+=t){const T=(J(Math.floor(d),Math.floor(c))-.5)*t*.9,M=(J(Math.floor(c),Math.floor(d))-.5)*t*.9,S=Math.round(d+T),E=Math.round(c+M);if(S<1||E<1||S>=f-1||E>=y-1)continue;const A=E*f+S;if(!Lt[A])continue;const w=Math.atan2(wt[A],pt[A]),i=.86+J(S*7,E*13)*.18;let s=Rt[A]*i;s=s<0?0:s>1.12?1.12:s,o.push({x:S,y:E,ang:w,idx:Math.min(19,Math.max(0,Math.round(s/1.12*19)))})}rt=o}function Wt(t,o){t.save(),t.translate(o.x,o.y),t.rotate(o.ang),t.drawImage(nt[o.idx],-ct/2,-st/2),t.restore()}function It(){const t=q.getContext("2d");if(t)for(const o of rt)Wt(t,o)}function $t(){const t=q.getContext("2d");t&&t.clearRect(0,0,f,y)}function ve(t){if(!t.length)return[];const o=Math.max(4,Z*1.5),c=new Map,d=(w,i)=>w+","+i;t.forEach((w,i)=>{const s=d(Math.floor(w.x/o),Math.floor(w.y/o));let b=c.get(s);b||c.set(s,b=[]),b.push(i)});const T=Z*1.8*(Z*1.8);function M(w){const i=t[w],s=Math.floor(i.x/o),b=Math.floor(i.y/o),L=[];for(let z=-1;z<=1;z++)for(let U=-1;U<=1;U++){const k=c.get(d(s+z,b+U));if(k)for(const O of k){if(O===w)continue;const m=t[O].x-i.x,g=t[O].y-i.y;m*m+g*g<=T&&L.push(O)}}return L}const S=new Uint8Array(t.length),E=[],A=t.map((w,i)=>i).sort((w,i)=>t[w].x+t[w].y-(t[i].x+t[i].y));for(const w of A){if(S[w])continue;let i=[w];for(S[w]=1;i.length;){E.push(i.map(b=>t[b]));const s=[];for(const b of i)for(const L of M(b))S[L]||(S[L]=1,s.push(L));i=s}}return E}function Ce(t){if(!t.length)return[];const o=Math.max(4,Z*1.5),c=new Map,d=(i,s)=>i+","+s;t.forEach((i,s)=>{const b=d(Math.floor(i.x/o),Math.floor(i.y/o));let L=c.get(b);L||c.set(b,L=[]),L.push(s)});const T=Z*1.8*(Z*1.8),M=i=>{const s=t[i],b=d(Math.floor(s.x/o),Math.floor(s.y/o)),L=c.get(b);if(!L)return;const z=L.indexOf(i);z>=0&&L.splice(z,1),L.length||c.delete(b)};function S(i){const s=t[i],b=Math.floor(s.x/o),L=Math.floor(s.y/o);let z=-1,U=1/0;for(let k=-1;k<=1;k++)for(let O=-1;O<=1;O++){const m=c.get(d(b+k,L+O));if(m)for(const g of m){const v=t[g].x-s.x,j=t[g].y-s.y,B=v*v+j*j;B<=T&&B<U&&(U=B,z=g)}}return z}function E(i){const s=t[i],b=Math.floor(s.x/o),L=Math.floor(s.y/o);let z=-1,U=1/0;for(let k=1;k<512;k++){for(let O=-k;O<=k;O++)for(let m=-k;m<=k;m++){if(Math.max(Math.abs(O),Math.abs(m))!==k)continue;const g=c.get(d(b+O,L+m));if(g)for(const v of g){const j=t[v].x-s.x,B=t[v].y-s.y,ut=j*j+B*B;ut<U&&(U=ut,z=v)}}if(z>=0&&k>Math.ceil(Math.sqrt(U)/o)+1)break}return z}let A=0;for(let i=1;i<t.length;i++)t[i].x+t[i].y<t[A].x+t[A].y&&(A=i);const w=[t[A]];M(A);for(let i=1;i<t.length;i++){let s=S(A);if(s<0&&(s=E(A)),s<0)break;w.push(t[s]),M(s),A=s}return w}function Se(){if($t(),ye||!_){It(),F.on=!1;return}$==="hand"?(F.rows=Ce(rt).map(t=>[t]),F.rate=Math.max(x,rt.length/3.2)):(F.rows=ve(rt),F.rate=x),F.idx=0,F.acc=0,F.on=F.rows.length>0}function Te(t){const o=q.getContext("2d");if(o)for(t>F.rows.length&&(t=F.rows.length);F.idx<t;){const c=F.rows[F.idx++];for(const d of c)Wt(o,d)}}function Ae(t,o){const c=Q.getContext("2d");if(!c||(c.clearRect(0,0,f,y),!I||!V))return;const d=f*.32,T=c.createRadialGradient(t,o,0,t,o,d);T.addColorStop(0,"rgba(255,250,238,0.18)"),T.addColorStop(.5,"rgba(255,250,238,0.055)"),T.addColorStop(1,"rgba(255,250,238,0)"),c.fillStyle=T,c.fillRect(0,0,f,y),c.globalCompositeOperation="destination-in",c.drawImage(V,0,0),c.globalCompositeOperation="source-over"}function Ee(){N||!h||(N=document.createElement("span"),N.className=Tt.caret,N.setAttribute("aria-hidden","true"),Object.assign(N.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${X(D[0])},${X(D[1])},${X(D[2])})`}),R.appendChild(N),lt.push(N))}function Pt(){if(!h||!N)return;const t=q.getContext("2d");if(!t)return;t.font=`${a} ${tt}px ${r}`;const o=t.measureText(e).width,c=(q.clientWidth||f)/f,d=tt*.7;N.style.left=(Ft+o+tt*.05)*c+"px",N.style.top=.5*(q.clientHeight||y)-d*c/2+"px",N.style.height=d*c+"px",N.style.width=Math.max(2,Math.round(tt*.02*c))+"px",N.style.background=`rgb(${X(D[0])},${X(D[1])},${X(D[2])})`}function it(){H||ft||(ft=!0,dt=0,Nt=requestAnimationFrame(te))}function te(t){if(H){ft=!1;return}dt||(dt=t);const o=Math.min(.25,(t-dt)/1e3);dt=t,F.on&&(F.acc+=F.rate*o,Te(F.acc),F.idx>=F.rows.length&&(F.on=!1)),W&&V&&(Ae(K.set?K.x:f*.5,K.set?K.y:y*.45),W=!1);const c=h&&gt;if(N&&(N.style.opacity=c&&Math.floor(t/530)%2===0?"1":"0"),!F.on&&!W&&!c){ft=!1;return}Nt=requestAnimationFrame(te)}function vt(t){const o=R.getBoundingClientRect();K.x=(t.clientX-o.left)/(o.width||1)*f,K.y=(t.clientY-o.top)/(o.height||1)*y,K.set=!0,W=!0,it()}function Ct(){K.set=!1,W=!0,it()}function be(){C&&ne(C.value,!0)}function Fe(t){t.key==="Enter"&&(t.preventDefault(),Ot.replay())}function Le(){gt=!0,it()}function Re(){gt=!1,N&&(N.style.opacity="0")}function ee(t){t===h&&C||(h=t,t?(C||(C=document.createElement("input"),C.type="text",C.value=e,C.maxLength=64,C.setAttribute("aria-label","Embroidered text — type to change it"),C.setAttribute("autocomplete","off"),C.setAttribute("autocapitalize","off"),C.spellcheck=!1,Object.assign(C.style,{position:"absolute",inset:"0",width:"100%",height:"100%",margin:"0",padding:"0",border:"0",outline:"none",background:"transparent",color:"transparent",caretColor:"transparent",font:"inherit",textAlign:"center",cursor:"text"}),C.addEventListener("input",be),C.addEventListener("keydown",Fe),C.addEventListener("focus",Le),C.addEventListener("blur",Re),R.appendChild(C),lt.push(C)),Ee(),Pt()):(C&&(C.remove(),C=null),gt=!1,N&&(N.style.opacity="0")))}function Ne(t){if(t!==I)if(I=t,t)R.addEventListener("pointermove",vt,{passive:!0}),R.addEventListener("pointerleave",Ct,{passive:!0}),K.set=!1,W=!0,it();else{R.removeEventListener("pointermove",vt),R.removeEventListener("pointerleave",Ct);const o=Q.getContext("2d");o&&o.clearRect(0,0,f,y)}}function at(t){xe(),ge(),pe(),we(),Me(),t?Se():($t(),It(),F.on=!1),C&&C.value!==e&&(C.value=e),Pt(),W=!0,it()}function ne(t,o){t=t??"",!(t===e&&Y)&&(e=t,Y&&(at(!1),o&&P&&P(e)))}const St=new Set;function oe(t,o,c){const d=`${o} 200px ${t}`;let T=!1;try{T=!!document.fonts&&document.fonts.check(d)}catch{T=!0}if(!document.fonts||T){c();return}let M=!1,S;const E=()=>{M||(M=!0,clearTimeout(S),St.delete(S),H||c())};document.fonts.load(d,e).then(()=>document.fonts.ready).then(E,E),S=setTimeout(E,1500),St.add(S)}function Ie(){H||(at(!0),Y=!0)}h&&(h=!1,ee(!0)),I&&(R.addEventListener("pointermove",vt,{passive:!0}),R.addEventListener("pointerleave",Ct,{passive:!0})),oe(G,a,Ie);let kt,re=-1;function ie(){clearTimeout(kt),kt=setTimeout(()=>{if(H||!Y)return;const t=Math.round(R.getBoundingClientRect().width);t!==re&&(re=t,at(!1))},200)}window.addEventListener("resize",ie);const Ot={get text(){return e},setText(t){if(!H){if(!Y){e=t??"",C&&(C.value=e);return}ne(t,!1)}},replay(){H||!Y||at(!0)},resize(){H||!Y||at(!1)},update(t){if(H)return;t.text!==void 0&&Ot.setText(t.text);let o=!1,c=!1;if(t.font!==void 0&&t.font!==r&&(r=t.font,G=Ut(r),o=!0),t.weight!==void 0){const d=yt(t.weight,1,1e3);d!==a&&(a=d,o=!0)}if(t.fill!==void 0){const d=yt(t.fill,.05,1);d!==u&&(u=d,o=!0)}t.pitch!==void 0&&t.pitch!==p&&(p=t.pitch,o=!0),t.threadColor!==void 0&&(Kt(t.threadColor),c=!0),t.sewRate!==void 0&&(x=Math.max(1,t.sewRate)),t.sewStyle!==void 0&&($=t.sewStyle==="hand"?"hand":"machine"),t.animate!==void 0&&(_=t.animate),t.onTextChange!==void 0&&(P=t.onTextChange),t.sheen!==void 0&&Ne(t.sheen),t.editable!==void 0&&ee(t.editable),Y&&(o?oe(G,a,()=>{H||at(!1)}):c&&(Zt(),$t(),It(),Pt(),it()))},focus(){!H&&h&&(C==null||C.focus())},destroy(){if(!H){H=!0,ft=!1,cancelAnimationFrame(Nt),clearTimeout(kt);for(const t of St)clearTimeout(t);St.clear(),window.removeEventListener("resize",ie),R.removeEventListener("pointermove",vt),R.removeEventListener("pointerleave",Ct);for(const t of lt)t.remove();nt=[],rt=[],F.rows=[],Lt=new Uint8Array(0),Rt=new Float32Array(0),pt=new Float32Array(0),wt=new Float32Array(0),V=ot=null,Mt=null,N=null,C=null}}};return Ot}const de="data-threadtext",At=new WeakMap;function ue(l,n){const e=l.dataset,r={text:e.ttText??n};if(e.ttFont&&(r.font=e.ttFont),e.ttWeight!==void 0){const a=parseFloat(e.ttWeight);isNaN(a)||(r.weight=a)}if(e.ttThreadColor&&(r.threadColor=e.ttThreadColor),e.ttPitch!==void 0){const a=parseFloat(e.ttPitch);isNaN(a)||(r.pitch=a)}if(e.ttFill!==void 0){const a=parseFloat(e.ttFill);isNaN(a)||(r.fill=a)}if(e.ttSewStyle==="hand"&&(r.sewStyle="hand"),e.ttSewRate!==void 0){const a=parseFloat(e.ttSewRate);isNaN(a)||(r.sewRate=a)}return e.ttSheen==="false"&&(r.sheen=!1),e.ttAnimate==="false"&&(r.animate=!1),e.ttEditable==="true"&&(r.editable=!0),r}function he(l){Xt(l);const n=l.innerHTML,e=(l.dataset.ttText??l.textContent??"").trim();if(!e)return;const r=ue(l,e);l.innerHTML="",r.editable||(l.setAttribute("role","img"),l.setAttribute("aria-label",e));const a=fe(l,r);At.set(l,{instance:a,originalHTML:n})}function Xt(l){const n=At.get(l);n&&(n.instance.destroy(),l.removeAttribute("role"),l.removeAttribute("aria-label"),l.innerHTML=n.originalHTML,At.delete(l))}function xt(l=document){l.querySelectorAll(`[${de}]`).forEach(he)}function me(){const l=()=>{var n;typeof document<"u"&&((n=document.fonts)!=null&&n.ready)?document.fonts.ready.then(()=>xt()).catch(()=>xt()):xt()};typeof document<"u"&&document.readyState==="loading"?document.addEventListener("DOMContentLoaded",l,{once:!0}):l()}return me(),ht.destroy=Xt,ht.init=xt,Object.defineProperty(ht,Symbol.toStringTag,{value:"Module"}),ht})({});
1
+ var ThreadText=(function(ut){"use strict";const St={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function J(a,n){let e=Math.imul(a|0,374761393)+Math.imul(n|0,668265263)|0;return e=Math.imul(e^e>>>13,1274126177),((e^e>>>16)>>>0)/4294967295}function _t(a,n){const e=Math.floor(a),o=Math.floor(n),i=a-e,u=n-o,w=i*i*(3-2*i),$=u*u*(3-2*u),N=J(e,o),O=J(e+1,o),m=J(e,o+1),C=J(e+1,o+1);return N+(O-N)*w+(m-N)*$+(N-O-m+C)*w*$}const ht=1e20;function qt(a,n,e,o,i){let u=0;o[0]=0,i[0]=-ht,i[1]=ht;for(let w=1;w<n;w++){let $=(a[w]+w*w-(a[o[u]]+o[u]*o[u]))/(2*w-2*o[u]);for(;$<=i[u];)u--,$=(a[w]+w*w-(a[o[u]]+o[u]*o[u]))/(2*w-2*o[u]);u++,o[u]=w,i[u]=$,i[u+1]=ht}u=0;for(let w=0;w<n;w++){for(;i[u+1]<w;)u++;e[w]=(w-o[u])*(w-o[u])+a[o[u]]}}function fe(a,n,e){const o=new Float64Array(n*e);for(let m=0;m<n*e;m++)o[m]=a[m]?ht:0;const i=Math.max(n,e),u=new Float64Array(i),w=new Float64Array(i),$=new Int32Array(i),N=new Float64Array(i+1);for(let m=0;m<n;m++){for(let C=0;C<e;C++)u[C]=o[C*n+m];qt(u,e,w,$,N);for(let C=0;C<e;C++)o[C*n+m]=w[C]}for(let m=0;m<e;m++){for(let C=0;C<n;C++)u[C]=o[m*n+C];qt(u,n,w,$,N);for(let C=0;C<n;C++)o[m*n+C]=w[C]}const O=new Float32Array(n*e);for(let m=0;m<n*e;m++)O[m]=Math.sqrt(o[m]);return O}function zt(a,n,e,o,i){let u=Float32Array.from(a);const w=new Float32Array(n*e),$=1/(2*o+1),N=(O,m)=>O<0?0:O>m?m:O;for(let O=0;O<i;O++){for(let m=0;m<e;m++){const C=m*n;let P=0;for(let D=-o;D<=o;D++)P+=u[C+N(D,n-1)];for(let D=0;D<n;D++)w[C+D]=P*$,P+=u[C+N(D+o+1,n-1)]-u[C+N(D-o,n-1)]}for(let m=0;m<n;m++){let C=0;for(let P=-o;P<=o;P++)C+=w[N(P,e-1)*n+m];for(let P=0;P<e;P++)u[P*n+m]=C*$,C+=w[N(P+o+1,e-1)*n+m]-w[N(P-o,e-1)*n+m]}}return u}function Ut(a,n){if(!a)return n;const e=a.trim();if(e[0]==="#"){let i=e.slice(1);if(i.length===3&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),i.length>=6){const u=parseInt(i.slice(0,2),16),w=parseInt(i.slice(2,4),16),$=parseInt(i.slice(4,6),16);if(!Number.isNaN(u)&&!Number.isNaN(w)&&!Number.isNaN($))return[u,w,$]}return n}const o=e.match(/rgba?\(([^)]+)\)/i);if(o){const i=o[1].split(",").map(u=>parseFloat(u));if(i.length>=3&&i.slice(0,3).every(u=>!Number.isNaN(u)))return[Math.round(i[0]),Math.round(i[1]),Math.round(i[2])]}return n}function U(a){return a<0?0:a>255?255:Math.round(a)}function mt(a,n,e){return a<n?n:a>e?e:a}function Xt(a){return(a.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function de(a,n){if(typeof window>"u"||typeof document>"u"||!a)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return n.text??""}};let e=n.text??"",o=n.font??"Georgia, serif",i=mt(n.weight??680,1,1e3),u=mt(n.fill??.9,.05,1),w=Math.max(1,n.sewRate??110),$=n.sewStyle==="hand"?"hand":"machine",N=n.sheen??!0,O=n.animate??!0,m=n.editable??!1,C=n.pitch,P=n.onTextChange,D=Xt(o);const ge=n.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let k=Ut(n.threadColor??"#fffbf3",[255,251,243]),bt=[0,0,0],At=[0,0,0];function Ht(t){k=Ut(t,[255,251,243]),bt=[k[0]*.585,k[1]*.585,k[2]*.585],At=[k[0]*.47,k[1]*.47,k[2]*.47]}Ht(n.threadColor??"#fffbf3");const at=[];let B,L;a instanceof HTMLCanvasElement?(B=a,L=a.parentElement??a):(L=a,B=document.createElement("canvas"),at.push(B),L.appendChild(B)),B.classList.add(St.bg);const Q=document.createElement("canvas");at.push(Q),Q.classList.add(St.fx),L.appendChild(Q),getComputedStyle(L).position==="static"&&(L.style.position="relative"),B.style.display="block",B.style.width="100%",Object.assign(Q.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let T=null,R=null,gt=!1,f=0,x=0,tt=0,Et=0,et=4,nt=[],st=0,lt=0,Kt=-1,Yt="",Vt=-1,Jt=-1,Ft=new Uint8Array(0),Lt=new Float32Array(0),xt=new Float32Array(0),pt=new Float32Array(0),K=null,ot=null,wt=null,ct=[],Z=3;const F={rows:[],idx:0,acc:0,rate:0,on:!1},X={x:0,y:0,set:!1};let W=!0,Rt=0,ft=!1,dt=0,j=!1,Y=!1;function xe(){const t=L.getBoundingClientRect(),r=Math.max(1,Math.round(t.width||Math.min(window.innerWidth*.95,1240))),s=e||"Ag",d=B.getContext("2d");d&&(d.textBaseline="middle");let S=100;d&&(d.font=`${i} 100px ${o}`,S=d.measureText(s).width||100);const g=Math.max(8,100*(r*u)/S);let h=g*.62,p=g*.62,M=r*u;if(d){d.font=`${i} ${g}px ${o}`;const l=d.measureText(s);M=l.width||M,l.actualBoundingBoxAscent>0&&(h=l.actualBoundingBoxAscent),l.actualBoundingBoxDescent>0&&(p=l.actualBoundingBoxDescent)}const y=Math.max(1,Math.round(2*Math.max(h,p)*1.1));let c=Math.min(window.devicePixelRatio||1,1.7);for(;r*c*y*c>9e5&&c>.4;)c-=.1;f=Math.max(1,Math.round(r*c)),x=Math.max(1,Math.round(y*c)),tt=Math.max(4,Math.round(g*c)),Et=Math.round(f/2-M*c/2);for(const l of[B,Q])l.width=f,l.height=x,l.style.height=y+"px";L.style.height=y+"px",et=C??Math.max(3,x*.0095)}function pe(){ot&&Vt===f&&Jt===x||(ot=document.createElement("canvas"),ot.width=f,ot.height=x,wt=ot.getContext("2d",{willReadFrequently:!0}),Vt=f,Jt=x)}function Qt(){const t=Math.max(7,et*2.5),r=Math.max(3.2,et*1.3);st=Math.ceil(t)+2,lt=Math.ceil(r)+2,nt=[];for(let s=0;s<20;s++){const d=.34+s/19*.82,S=document.createElement("canvas");S.width=st,S.height=lt;const g=S.getContext("2d");if(!g){nt.push(S);continue}const h=st/2,p=lt/2,M=g.createLinearGradient(0,p-r/2,0,p+r/2),y=(A,I)=>`rgba(${U(A[0]*d)},${U(A[1]*d)},${U(A[2]*d)},${I})`;M.addColorStop(0,y(At,0)),M.addColorStop(.16,y(bt,1)),M.addColorStop(.5,y(k,1)),M.addColorStop(.84,y(bt,1)),M.addColorStop(1,y(At,0)),g.fillStyle=M,g.beginPath();const c=r/2;g.moveTo(h-t/2+c,p-c),g.lineTo(h+t/2-c,p-c),g.arc(h+t/2-c,p,c,-Math.PI/2,Math.PI/2),g.lineTo(h-t/2+c,p+c),g.arc(h-t/2+c,p,c,Math.PI/2,-Math.PI/2),g.closePath(),g.fill(),g.globalCompositeOperation="destination-in";const l=g.createLinearGradient(h-t/2,0,h+t/2,0);l.addColorStop(0,"rgba(0,0,0,0)"),l.addColorStop(.22,"rgba(0,0,0,1)"),l.addColorStop(.78,"rgba(0,0,0,1)"),l.addColorStop(1,"rgba(0,0,0,0)"),g.fillStyle=l,g.fillRect(0,0,st,lt),nt.push(S)}Kt=et,Yt=k.join(",")}function we(){nt.length&&Kt===et&&Yt===k.join(",")||Qt()}function Me(){if(!wt)return;const t=wt;t.clearRect(0,0,f,x),t.fillStyle="#fff",t.textAlign="left",t.textBaseline="middle",t.font=`${i} ${tt}px ${o}`,t.fillText(e,Et,x*.5);const r=t.getImageData(0,0,f,x).data,s=new Uint8Array(f*x);for(let v=0;v<x;v++)for(let b=0;b<f;b++){const E=v*f+b,q=r[E*4+3]/255,z=_t(b*.5,v*.5)*.22+_t(b*1.8,v*1.8)*.1;s[E]=q>.5+(z-.16)?1:0}Ft=s;const d=fe(s,f,x),S=new Float32Array(f*x);for(let v=1;v<x-1;v++)for(let b=1;b<f-1;b++){const E=v*f+b;S[E]=(d[E]*4+d[E-1]+d[E+1]+d[E-f]+d[E+f])/8}const g=new Float32Array(f*x),h=new Float32Array(f*x),p=new Float32Array(f*x),M=new Float32Array(f*x);for(let v=1;v<x-1;v++)for(let b=1;b<f-1;b++){const E=v*f+b;if(!s[E])continue;const q=(S[E+1]-S[E-1])*.5,z=(S[E+f]-S[E-f])*.5;p[E]=q,M[E]=z,g[E]=q*q-z*z,h[E]=2*q*z}const y=Math.max(7,Math.round(x*.05)),c=zt(g,f,x,y,2),l=zt(h,f,x,y,2);xt=new Float32Array(f*x),pt=new Float32Array(f*x);for(let v=0;v<f*x;v++){if(!s[v])continue;const b=.5*Math.atan2(l[v],c[v]);xt[v]=Math.cos(b),pt[v]=Math.sin(b)}const A=Math.max(9,x*.04),I=new Float32Array(f*x),G=-.45,V=-.62,H=.64;for(let v=1;v<x-1;v++)for(let b=1;b<f-1;b++){const E=v*f+b;if(!s[E])continue;let q=p[E],z=M[E];const ae=Math.hypot(q,z)||1;q/=ae,z/=ae;const se=S[E],le=(1-Math.min(se/A,1))*1.25;let Ot=-q*le,Bt=-z*le;const ce=1.5,Dt=Math.hypot(Ot,Bt,ce);Ot/=Dt,Bt/=Dt;let jt=Ot*G+Bt*V+ce/Dt*H;jt<0&&(jt=0);const Pe=Math.min(1,.45+.55*Math.min(se/(A*.7),1));I[E]=Math.min(1.12,(.5+.75*jt)*Pe)}Lt=I,K=document.createElement("canvas"),K.width=f,K.height=x;const _=K.getContext("2d");if(_){const v=_.createImageData(f,x);for(let b=0;b<f*x;b++)s[b]&&(v.data[b*4]=255,v.data[b*4+1]=255,v.data[b*4+2]=255,v.data[b*4+3]=255);_.putImageData(v,0,0)}}function ve(){const t=Math.max(1.6,et*.6);Z=t;const r=[];for(let s=0;s<x;s+=t)for(let d=0;d<f;d+=t){const S=(J(Math.floor(d),Math.floor(s))-.5)*t*.9,g=(J(Math.floor(s),Math.floor(d))-.5)*t*.9,h=Math.round(d+S),p=Math.round(s+g);if(h<1||p<1||h>=f-1||p>=x-1)continue;const M=p*f+h;if(!Ft[M])continue;const y=Math.atan2(pt[M],xt[M]),c=.86+J(h*7,p*13)*.18;let l=Lt[M]*c;l=l<0?0:l>1.12?1.12:l,r.push({x:h,y:p,ang:y,idx:Math.min(19,Math.max(0,Math.round(l/1.12*19)))})}ct=r}function Zt(t,r){t.save(),t.translate(r.x,r.y),t.rotate(r.ang),t.drawImage(nt[r.idx],-st/2,-lt/2),t.restore()}function Nt(){const t=B.getContext("2d");if(t)for(const r of ct)Zt(t,r)}function It(){const t=B.getContext("2d");t&&t.clearRect(0,0,f,x)}function Wt(t){if(!t.length)return[];const r=Math.max(4,Z*1.5),s=new Map,d=(y,c)=>y+","+c;t.forEach((y,c)=>{const l=d(Math.floor(y.x/r),Math.floor(y.y/r));let A=s.get(l);A||s.set(l,A=[]),A.push(c)});const S=Z*1.8*(Z*1.8);function g(y){const c=t[y],l=Math.floor(c.x/r),A=Math.floor(c.y/r),I=[];for(let G=-1;G<=1;G++)for(let V=-1;V<=1;V++){const H=s.get(d(l+G,A+V));if(H)for(const _ of H){if(_===y)continue;const v=t[_].x-c.x,b=t[_].y-c.y;v*v+b*b<=S&&I.push(_)}}return I}const h=new Uint8Array(t.length),p=[],M=t.map((y,c)=>c).sort((y,c)=>t[y].x+t[y].y-(t[c].x+t[c].y));for(const y of M){if(h[y])continue;let c=[y];for(h[y]=1;c.length;){p.push(c.map(A=>t[A]));const l=[];for(const A of c)for(const I of g(A))h[I]||(h[I]=1,l.push(I));c=l}}return p}function Ce(t){const r=Math.max(4,Z*1.5),s=new Map,d=(M,y)=>M+","+y;t.forEach((M,y)=>{const c=d(Math.floor(M.x/r),Math.floor(M.y/r));let l=s.get(c);l||s.set(c,l=[]),l.push(y)});const S=Z*1.8*(Z*1.8),g=M=>{const y=t[M],c=Math.floor(y.x/r),l=Math.floor(y.y/r),A=[];for(let I=-1;I<=1;I++)for(let G=-1;G<=1;G++){const V=s.get(d(c+I,l+G));if(V)for(const H of V){if(H===M)continue;const _=t[H].x-y.x,v=t[H].y-y.y;_*_+v*v<=S&&A.push(H)}}return A},h=new Uint8Array(t.length),p=[];for(let M=0;M<t.length;M++){if(h[M])continue;const y=[];let c=[M];for(h[M]=1;c.length;){const l=[];for(const A of c){y.push(t[A]);for(const I of g(A))h[I]||(h[I]=1,l.push(I))}c=l}p.push(y)}return p}function Se(t){if(!t.length)return[];const r=g=>{let h=1/0;for(const p of g)p.x<h&&(h=p.x);return h},s=g=>{let h=0;for(const p of g)h+=p.y;return h/g.length},d=Ce(t).sort((g,h)=>r(g)-r(h)),S=[];for(const g of d){const h=Wt(g);let p=1;for(const l of h)l.length>p&&(p=l.length);const M=Math.max(2,p*.45),y=h.filter(l=>l.length>=M).sort((l,A)=>s(l)-s(A)),c=h.filter(l=>l.length<M).sort((l,A)=>s(l)-s(A));for(const l of y)S.push(l);for(const l of c)S.push(l)}return S}function Te(){if(It(),ge||!O){Nt(),F.on=!1;return}F.rows=$==="hand"?Se(ct):Wt(ct),F.idx=0,F.acc=0,F.rate=w,F.on=F.rows.length>0}function be(t){const r=B.getContext("2d");if(r)for(t>F.rows.length&&(t=F.rows.length);F.idx<t;){const s=F.rows[F.idx++];for(const d of s)Zt(r,d)}}function Ae(t,r){const s=Q.getContext("2d");if(!s||(s.clearRect(0,0,f,x),!N||!K))return;const d=f*.32,S=s.createRadialGradient(t,r,0,t,r,d);S.addColorStop(0,"rgba(255,250,238,0.18)"),S.addColorStop(.5,"rgba(255,250,238,0.055)"),S.addColorStop(1,"rgba(255,250,238,0)"),s.fillStyle=S,s.fillRect(0,0,f,x),s.globalCompositeOperation="destination-in",s.drawImage(K,0,0),s.globalCompositeOperation="source-over"}function Ee(){R||!m||(R=document.createElement("span"),R.className=St.caret,R.setAttribute("aria-hidden","true"),Object.assign(R.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${U(k[0])},${U(k[1])},${U(k[2])})`}),L.appendChild(R),at.push(R))}function $t(){if(!m||!R)return;const t=B.getContext("2d");if(!t)return;t.font=`${i} ${tt}px ${o}`;const r=t.measureText(e).width,s=(B.clientWidth||f)/f,d=tt*.7;R.style.left=(Et+r+tt*.05)*s+"px",R.style.top=.5*(B.clientHeight||x)-d*s/2+"px",R.style.height=d*s+"px",R.style.width=Math.max(2,Math.round(tt*.02*s))+"px",R.style.background=`rgb(${U(k[0])},${U(k[1])},${U(k[2])})`}function rt(){j||ft||(ft=!0,dt=0,Rt=requestAnimationFrame(te))}function te(t){if(j){ft=!1;return}dt||(dt=t);const r=Math.min(.25,(t-dt)/1e3);dt=t,F.on&&(F.acc+=F.rate*r,be(F.acc),F.idx>=F.rows.length&&(F.on=!1)),W&&K&&(Ae(X.set?X.x:f*.5,X.set?X.y:x*.45),W=!1);const s=m&&gt;if(R&&(R.style.opacity=s&&Math.floor(t/530)%2===0?"1":"0"),!F.on&&!W&&!s){ft=!1;return}Rt=requestAnimationFrame(te)}function Mt(t){const r=L.getBoundingClientRect();X.x=(t.clientX-r.left)/(r.width||1)*f,X.y=(t.clientY-r.top)/(r.height||1)*x,X.set=!0,W=!0,rt()}function vt(){X.set=!1,W=!0,rt()}function Fe(){T&&ne(T.value,!0)}function Le(t){t.key==="Enter"&&(t.preventDefault(),kt.replay())}function Re(){gt=!0,rt()}function Ne(){gt=!1,R&&(R.style.opacity="0")}function ee(t){t===m&&T||(m=t,t?(T||(T=document.createElement("input"),T.type="text",T.value=e,T.maxLength=64,T.setAttribute("aria-label","Embroidered text — type to change it"),T.setAttribute("autocomplete","off"),T.setAttribute("autocapitalize","off"),T.spellcheck=!1,Object.assign(T.style,{position:"absolute",inset:"0",width:"100%",height:"100%",margin:"0",padding:"0",border:"0",outline:"none",background:"transparent",color:"transparent",caretColor:"transparent",font:"inherit",textAlign:"center",cursor:"text"}),T.addEventListener("input",Fe),T.addEventListener("keydown",Le),T.addEventListener("focus",Re),T.addEventListener("blur",Ne),L.appendChild(T),at.push(T)),Ee(),$t()):(T&&(T.remove(),T=null),gt=!1,R&&(R.style.opacity="0")))}function Ie(t){if(t!==N)if(N=t,t)L.addEventListener("pointermove",Mt,{passive:!0}),L.addEventListener("pointerleave",vt,{passive:!0}),X.set=!1,W=!0,rt();else{L.removeEventListener("pointermove",Mt),L.removeEventListener("pointerleave",vt);const r=Q.getContext("2d");r&&r.clearRect(0,0,f,x)}}function it(t){xe(),pe(),we(),Me(),ve(),t?Te():(It(),Nt(),F.on=!1),T&&T.value!==e&&(T.value=e),$t(),W=!0,rt()}function ne(t,r){t=t??"",!(t===e&&Y)&&(e=t,Y&&(it(!1),r&&P&&P(e)))}const Ct=new Set;function oe(t,r,s){const d=`${r} 200px ${t}`;let S=!1;try{S=!!document.fonts&&document.fonts.check(d)}catch{S=!0}if(!document.fonts||S){s();return}let g=!1,h;const p=()=>{g||(g=!0,clearTimeout(h),Ct.delete(h),j||s())};document.fonts.load(d,e).then(()=>document.fonts.ready).then(p,p),h=setTimeout(p,1500),Ct.add(h)}function $e(){j||(it(!0),Y=!0)}m&&(m=!1,ee(!0)),N&&(L.addEventListener("pointermove",Mt,{passive:!0}),L.addEventListener("pointerleave",vt,{passive:!0})),oe(D,i,$e);let Pt,re=-1;function ie(){clearTimeout(Pt),Pt=setTimeout(()=>{if(j||!Y)return;const t=Math.round(L.getBoundingClientRect().width);t!==re&&(re=t,it(!1))},200)}window.addEventListener("resize",ie);const kt={get text(){return e},setText(t){if(!j){if(!Y){e=t??"",T&&(T.value=e);return}ne(t,!1)}},replay(){j||!Y||it(!0)},resize(){j||!Y||it(!1)},update(t){if(j)return;t.text!==void 0&&kt.setText(t.text);let r=!1,s=!1;if(t.font!==void 0&&t.font!==o&&(o=t.font,D=Xt(o),r=!0),t.weight!==void 0){const d=mt(t.weight,1,1e3);d!==i&&(i=d,r=!0)}if(t.fill!==void 0){const d=mt(t.fill,.05,1);d!==u&&(u=d,r=!0)}t.pitch!==void 0&&t.pitch!==C&&(C=t.pitch,r=!0),t.threadColor!==void 0&&(Ht(t.threadColor),s=!0),t.sewRate!==void 0&&(w=Math.max(1,t.sewRate)),t.sewStyle!==void 0&&($=t.sewStyle==="hand"?"hand":"machine"),t.animate!==void 0&&(O=t.animate),t.onTextChange!==void 0&&(P=t.onTextChange),t.sheen!==void 0&&Ie(t.sheen),t.editable!==void 0&&ee(t.editable),Y&&(r?oe(D,i,()=>{j||it(!1)}):s&&(Qt(),It(),Nt(),$t(),rt()))},focus(){!j&&m&&(T==null||T.focus())},destroy(){if(!j){j=!0,ft=!1,cancelAnimationFrame(Rt),clearTimeout(Pt);for(const t of Ct)clearTimeout(t);Ct.clear(),window.removeEventListener("resize",ie),L.removeEventListener("pointermove",Mt),L.removeEventListener("pointerleave",vt);for(const t of at)t.remove();nt=[],ct=[],F.rows=[],Ft=new Uint8Array(0),Lt=new Float32Array(0),xt=new Float32Array(0),pt=new Float32Array(0),K=ot=null,wt=null,R=null,T=null}}};return kt}const ue="data-threadtext",Tt=new WeakMap;function he(a,n){const e=a.dataset,o={text:e.ttText??n};if(e.ttFont&&(o.font=e.ttFont),e.ttWeight!==void 0){const i=parseFloat(e.ttWeight);isNaN(i)||(o.weight=i)}if(e.ttThreadColor&&(o.threadColor=e.ttThreadColor),e.ttPitch!==void 0){const i=parseFloat(e.ttPitch);isNaN(i)||(o.pitch=i)}if(e.ttFill!==void 0){const i=parseFloat(e.ttFill);isNaN(i)||(o.fill=i)}if(e.ttSewStyle==="hand"&&(o.sewStyle="hand"),e.ttSewRate!==void 0){const i=parseFloat(e.ttSewRate);isNaN(i)||(o.sewRate=i)}return e.ttSheen==="false"&&(o.sheen=!1),e.ttAnimate==="false"&&(o.animate=!1),e.ttEditable==="true"&&(o.editable=!0),o}function me(a){Gt(a);const n=a.innerHTML,e=(a.dataset.ttText??a.textContent??"").trim();if(!e)return;const o=he(a,e);a.innerHTML="",o.editable||(a.setAttribute("role","img"),a.setAttribute("aria-label",e));const i=de(a,o);Tt.set(a,{instance:i,originalHTML:n})}function Gt(a){const n=Tt.get(a);n&&(n.instance.destroy(),a.removeAttribute("role"),a.removeAttribute("aria-label"),a.innerHTML=n.originalHTML,Tt.delete(a))}function yt(a=document){a.querySelectorAll(`[${ue}]`).forEach(me)}function ye(){const a=()=>{var n;typeof document<"u"&&((n=document.fonts)!=null&&n.ready)?document.fonts.ready.then(()=>yt()).catch(()=>yt()):yt()};typeof document<"u"&&document.readyState==="loading"?document.addEventListener("DOMContentLoaded",a,{once:!0}):a()}return ye(),ut.destroy=Gt,ut.init=yt,Object.defineProperty(ut,Symbol.toStringTag,{value:"Module"}),ut})({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liiift-studio/threadtext",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Render any text as photorealistic procedural satin-stitch embroidery, in real time in the browser, from the font's glyph geometry",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",