voice-ring 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +68 -2
- package/dist/index.cjs +41 -0
- package/dist/index.d.ts +554 -0
- package/dist/index.es.js +1186 -0
- package/package.json +65 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jakub Antalik
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,69 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Voice ring
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A voice-reactive ring of light for AI voice interfaces: a few rings lean off the view axis and bundle into a glassy ribbon, a spectrum runs around it, and the voice bends every ring together. It takes the colour of the voice's emotion and leans toward whoever is speaking.
|
|
4
|
+
|
|
5
|
+
Voice ring is the `aura` type of the voice orbs, as a library of its own.
|
|
6
|
+
|
|
7
|
+
## SwiftUI
|
|
8
|
+
|
|
9
|
+
The port lives in [`ports/ios/VoiceRingKit`](ports/ios/VoiceRingKit) and installs from the repository root with Swift Package Manager (iOS 17+ / macOS 14+, build through Xcode):
|
|
10
|
+
|
|
11
|
+
```swift
|
|
12
|
+
.package(url: "https://github.com/Jakubantalik/Libraries.dev", branch: "main")
|
|
13
|
+
.product(name: "VoiceRingKit", package: "Libraries.dev")
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```swift
|
|
17
|
+
import VoiceRingKit
|
|
18
|
+
|
|
19
|
+
struct VoiceScreen: View {
|
|
20
|
+
@State private var meter = VoiceMeter()
|
|
21
|
+
|
|
22
|
+
var body: some View {
|
|
23
|
+
VoiceRing(state: .listening, source: .meter(meter), size: 240)
|
|
24
|
+
.task { try? await meter.start() } // asks for the microphone
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Two models plug in:
|
|
30
|
+
|
|
31
|
+
- **Emotion** (`VoiceRingEmotion`, Pro): emotion2vec+ reads the tone of the voice, GoEmotions its words; pass `mood: emotion.mood`.
|
|
32
|
+
- **Direction** ([Voice direction](https://libraries.dev/voice-direction.html), free account): add `VoiceDirection.mfxl` to the app target and the ring leans toward the voice from the iPhone's stereo mics, no calibration.
|
|
33
|
+
|
|
34
|
+
Docs: https://libraries.dev/voice-ring.html
|
|
35
|
+
|
|
36
|
+
## React
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install voice-ring
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { VoiceRing, useMicrophone } from 'voice-ring';
|
|
44
|
+
|
|
45
|
+
function VoiceScreen() {
|
|
46
|
+
const mic = useMicrophone();
|
|
47
|
+
return (
|
|
48
|
+
<>
|
|
49
|
+
<VoiceRing size={240} state="listening" stream={mic.stream} />
|
|
50
|
+
<button onClick={mic.start}>Listen</button>
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Drive it yourself instead of the microphone (0–1, read every frame):
|
|
56
|
+
<VoiceRing size={240} state="speaking" level={() => player.level} />
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- `state`: `idle`, `listening`, `speaking`, `processing`.
|
|
60
|
+
- `stream` (a `MediaStream`) or `level` (a number, or a getter read every frame).
|
|
61
|
+
- `emotion`: `positive`, `negative` or `calm` shifts the spectrum toward its colour.
|
|
62
|
+
- `direction`: −1 left … 1 right, a number or a getter. A browser microphone is mono, so the side comes from you: a stereo capture, a diarised speaker, or where that person sits in your UI. The ring barely drifts but leans toward it, and meets the screen's edge through a soft lens; the `direction…` props tune it.
|
|
63
|
+
- `sensitivity` (0.85), `speed`, `theme` (`auto`, `dark`, `light`), `paused`.
|
|
64
|
+
|
|
65
|
+
A 2D canvas with a small WebGL pass for the edge lens; React 18+.
|
|
66
|
+
|
|
67
|
+
`src/` is also what the libraries.dev preview and Studio draw. The engine is copied from the voice orbs project (`Voice orbs/src`); keep the two in step.
|
|
68
|
+
|
|
69
|
+
MIT License.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const kn=require("react/jsx-runtime"),$=require("react");let Bt=null;function Fn(){if(typeof window>"u")return null;const t=window;return t.AudioContext??t.webkitAudioContext??null}function ss(){return Fn()!=null}function fn(){const t=Fn();return t?(Bt||(Bt=new t),Bt.state==="suspended"&&Bt.resume().catch(()=>{}),Bt):null}const nn=new WeakMap;function In(t){const n=fn();if(!n||t.getAudioTracks().length===0)return null;let e=nn.get(t);e||(e={node:n.createMediaStreamSource(t),refs:0},nn.set(t,e)),e.refs+=1;const s=n.createAnalyser();s.fftSize=1024,s.smoothingTimeConstant=.5,e.node.connect(s);let o=!1;return{analyser:s,release:()=>{if(!o){o=!0;try{e.node.disconnect(s)}catch{}if(e.refs-=1,e.refs<=0){try{e.node.disconnect()}catch{}nn.delete(t)}}}}}const qt={positive:{r:92,g:224,b:150},negative:{r:255,g:104,b:104},calm:{r:104,g:162,b:255}},Nn={green:qt.positive,red:qt.negative,blue:qt.calm},es=.7,os=1.1,as=.6;class cs{constructor(){this.glow={r:0,g:0,b:0,amount:0,t:0,size:0}}step(n,e,s,o,r){const c=this.glow,l=a=>r?1:1-Math.exp(-n/a),i=e?1:0;if(c.amount+=(i-c.amount)*l(i>c.amount?es:os),e){const a=c.amount<.03?1:l(as);c.r+=(e.r-c.r)*a,c.g+=(e.g-c.g)*a,c.b+=(e.b-c.b)*a}return c.t=s,c.size=o,c}}const Mt={move:2,pull:.7,deform:.1,squash:.5,lens:.67,stretch:1,split:1,blur:1,bounce:1};function rs(t,n){const e=Math.abs(t.move)+Math.abs(t.pull)+2*Math.abs(t.deform);return e===0?0:Math.ceil(n*.36*e)+2}class is{constructor(){this.x=0,this.v=0,this.landed=!1}step(n,e){const r=Math.max(1,Math.ceil(e*240)),c=e/r;for(let i=0;i<r;i++)this.v+=(15*15*(n-this.x)-2*.3*15*this.v)*c,this.x+=this.v*c;const l=this.x-n;return n<=0?this.landed=!1:l>=0&&(this.landed=!0),l<0&&!this.landed?0:l}}function ls(t,n,e,s,o=[1/0,1/0],r=0){if(Math.abs(n)<.002||s.move===0&&s.pull===0&&s.deform===0)return t;const c=e/2,l=e*.36,i=n<0?-1:1,a=Math.abs(n),M=(b,w)=>{const x=(b-c)/l,F=(w-c)/l,R=Math.max(0,Math.min(1,(x*i+1)/2)),O=Math.max(0,x*i);return n*l*(s.move+s.pull*R*R+s.deform*O*O*Math.exp(-F*F*1.5))},h=Math.max(0,Math.min(2,s.lens??1)),f=l*.9,p=i>0?o[1]:o[0],d=Number.isFinite(p)?Math.min(f*.45,l*.3*h*Math.max(0,s.stretch??1)):0;let m=1,v=1/0,_=1;if(Number.isFinite(p)){v=i>0?e+p:-p;const b=(w,x,F)=>{_=Math.max(_,F);const R=M(w,x)*i;R>1e-9&&(m=Math.min(m,Math.max(0,((v-w)*i-F-d)/R)))};for(const w of t.dots)b(w.x,w.y,w.r);for(const w of t.strokes)for(let x=0;x<w.pts.length;x+=2)b(w.pts[x],w.pts[x+1],1)}const u=m<1?Math.min(1,(1-m)/.35):0,g=u>0?r*(s.bounce??1):0,y=Math.min(1.4,u+Math.max(0,g)),N=l*.12*Math.max(0,-g),E=v-i*_,B=E-i*d,S=l*.55*y*(s.squash??0);let C=1/0,P=-1/0,q=!0;const G=(b,w)=>{const x=Math.max(0,Math.min(1,((b-c)/l*i+1)/2)),F=1-.15*s.deform*a*m*x;let R=b+M(b,w)*m+i*(S*.5-N),O=c+(w-c)*F;if(S>0){const k=(R-(B-i*S))*i;if(k>0){const I=k/S,T=S*(I/Math.sqrt(1+I*I));R=B-i*S+i*T,O=c+(O-c)*(1+.18*y*(s.squash??0)*(T/S))}}return q&&(B-R)*i<Math.max(S,f*.3)&&(C=Math.min(C,O),P=Math.max(P,O)),[R,O]};for(const b of t.dots)[b.x,b.y]=G(b.x,b.y);for(const b of t.strokes)for(let w=0;w<b.pts.length;w+=2){const[x,F]=G(b.pts[w],b.pts[w+1]);b.pts[w]=x,b.pts[w+1]=F}if(u>0&&P>C){const b=h*y;t.contact={side:i,x:E,y0:C,y1:P,depth:S,press:u,lens:b>.02?{zone:f,gap:d*Math.min(1,y),flare:.22*b*Math.max(0,s.stretch??1),split:f*.1*b*Math.max(0,s.split??1),blur:f*.075*b*Math.max(0,s.blur??1),cy:c}:void 0}}if(q=!1,t.light){const b=t.light;[b.cx,b.cy]=G(b.cx,b.cy);for(const w of b.spec)[w.x,w.y]=G(w.x,w.y)}return t}const ft=Math.PI*2;function Rt(t,n,e){return t+(n-t)*e}function j(t){return t<0?0:t>1?1:t}function dn(t,n,e){const s=j((e-t)/(n-t));return s*s*(3-2*s)}const $t=t=>t<1e-6?1:Math.sin(t)/t,hs=Math.hypot(2.1,1.3),us=Math.hypot(1.9,1.7),fs=Math.hypot(4.3-2.9,-3.7,-3.1),ds=Math.hypot(4.3+2.9,3.7,-3.1);function pn(t,n,e,s=1){const o=1/Math.max(.05,s),r=.9*e,c=-.7*e+1.3,l=2.1*e,i=-1.6*e,a=t*(.55*Math.sin(r)*$t(hs*o)+.45*Math.sin(c)*$t(us*o))+n*.5*(Math.cos(l-i)*$t(fs*o)-Math.cos(l+i)*$t(ds*o));return(M,h,f)=>(M*=o,h*=o,f*=o,t*(.55*Math.sin(2.1*M+1.3*h+r)+.45*Math.sin(1.7*f-1.9*h+c))+n*Math.sin(4.3*M-3.1*f+l)*Math.sin(3.7*h+2.9*M+i)-a)}function St(t,n){const e=Math.sin(t*12.9898+n*78.233)*43758.5453;return e-Math.floor(e)}function xt(t,n,e){const s=Math.sin(t*127.1+n*311.7+e*74.7)*43758.5453;return s-Math.floor(s)}function zt(t,n,e){const s=Math.floor(t),o=Math.floor(n),r=Math.floor(e);let c=t-s,l=n-o,i=e-r;c=c*c*(3-2*c),l=l*l*(3-2*l),i=i*i*(3-2*i);const a=Rt(xt(s,o,r),xt(s+1,o,r),c),M=Rt(xt(s,o+1,r),xt(s+1,o+1,r),c),h=Rt(xt(s,o,r+1),xt(s+1,o,r+1),c),f=Rt(xt(s,o+1,r+1),xt(s+1,o+1,r+1),c);return Rt(Rt(a,M,l),Rt(h,f,l),i)}function Mn(t,n){const e=Math.PI*(3-Math.sqrt(5)),s=1-2*(t+.5)/n,o=Math.sqrt(1-s*s),r=t*e;return[o*Math.cos(r),s,o*Math.sin(r)]}function Kt(t,n,e,s,o){const r=Math.sin(n),c=Math.cos(n),l=Math.sin(t),i=Math.cos(t);return(a,M,h)=>{const f=a*i+h*l,p=-a*l+h*i,d=M*c-p*r,m=M*r+p*c;return[e+f*o,s-d*o,m]}}function Dt(t,n=.6){return(t/200)**n}function _t(t,n,e=.3){const s=[];for(const o of t)(o.a??1)<.02||(o.r=Math.max(e,o.r),s.push(o));return s.sort((o,r)=>o.z-r.z),{dots:s,strokes:n}}const Wt=32;function ps(t,n=0,e=0,s=1){const o=t.r/255,r=t.g/255,c=t.b/255,l=Math.max(o,r,c),i=Math.min(o,r,c);let a=(l+i)/2,M=l===i?0:(l-i)/(1-Math.abs(2*a-1)),h=0;if(l!==i){const m=l-i;h=l===o?(r-c)/m%6:l===r?(c-o)/m+2:(o-r)/m+4,h*=60}h=((h+n)%360+360)%360,M=Math.min(1,M*(1+e)),a=.5+(a-.5)*(1-.6*e),a=Math.max(0,Math.min(1,a*s));const f=m=>(m+h/30)%12,p=M*Math.min(a,1-a),d=m=>a-p*Math.max(-1,Math.min(f(m)-3,9-f(m),1));return[Math.round(d(0)*255),Math.round(d(8)*255),Math.round(d(4)*255)]}function Ms(t){const n=Math.max(0,Math.min(1,t.saturation)),e=Math.max(0,Math.min(1,t.neutral)),s=t.start??.1,o=Math.max(.05,t.width??.6),r=[];for(let h=0;h<Wt;h++){const f=h/(Wt-1),p=Math.max(0,Math.min(1,(f-s)/o)),d=p*p*(3-2*p);r.push(n*(1-e*(1-d)))}const c=t.angle*Math.PI/180,l=Math.cos(c),i=Math.sin(c),a=t.size/2,M=t.size*.8;return{rgb:ps(t.accent,t.hue,Math.max(0,Math.min(1,t.vivid??0)),t.brightness),mix:r,saturation:n,at:(h,f)=>{const p=((h-a)*l+(f-a)*i)/M+.5;return Math.max(0,Math.min(Wt-1,Math.round(p*(Wt-1))))}}}const ms=[120,232,214],gs=[64,72,255];function En(t,n,e){t/=255,n/=255,e/=255;const s=Math.max(t,n,e),o=Math.min(t,n,e),r=(s+o)/2;if(s===o)return[0,0,r];const c=s-o,l=r>.5?c/(2-s-o):c/(s+o);return[(s===t?(n-e)/c+(n<e?6:0):s===n?(e-t)/c+2:(t-n)/c+4)/6,l,r]}function bs(t,n,e){const s=c=>(c+t*12)%12,o=n*Math.min(e,1-e),r=c=>e-o*Math.max(-1,Math.min(s(c)-3,9-s(c),1));return[r(0)*255,r(8)*255,r(4)*255]}const sn=t=>(t/=255)<=.04045?t/12.92:((t+.055)/1.055)**2.4,vs=t=>255*(t<=.0031308?12.92*t:1.055*Math.max(0,t)**(1/2.4)-.055);function un(t,n,e){const[s,o,r]=[sn(t),sn(n),sn(e)],c=Math.cbrt(.4122214708*s+.5363325363*o+.0514459929*r),l=Math.cbrt(.2119034982*s+.6806995451*o+.1073969566*r),i=Math.cbrt(.0883024619*s+.2817188376*o+.6299787005*r);return[.2104542553*c+.793617785*l-.0040720468*i,1.9779984951*c-2.428592205*l+.4505937099*i,.0259040371*c+.7827717662*l-.808675766*i]}function On(t,n,e){const s=(t+.3963377774*n+.2158037573*e)**3,o=(t-.1055613458*n-.0638541728*e)**3,r=(t-.0894841775*n-1.291485548*e)**3,c=l=>Math.max(0,Math.min(255,vs(l)));return[c(4.0767416621*s-3.3077115913*o+.2309699292*r),c(-1.2684380046*s+2.6097574011*o-.3413193965*r),c(-.0041960863*s-.7034186147*o+1.707614701*r)]}function ys(t,n,e,s){const o=s&&s.amount>.005?s:void 0;return t.map(([r,c,l,i])=>{if(e&&(c+=(e.r-c)*.85,l+=(e.g-l)*.85,i+=(e.b-i)*.85),o){const[,M,h]=En(c,l,i),[f]=En(o.r,o.g,o.b),p=bs((f+.1*Math.sin(2*Math.PI*r)+1)%1,M,h),d=un(c,l,i),m=un(p[0],p[1],p[2]),v=o.amount;[c,l,i]=On(d[0]+(m[0]-d[0])*v,d[1]+(m[1]-d[1])*v,d[2]+(m[2]-d[2])*v)}const a=n?1:.82;return[r,c*a,l*a,i*a]})}const Bn=(t,n,e)=>`rgb(${Math.round(t)},${Math.round(n)},${Math.round(e)})`;function xs(t,n=36){const e=t.filter(([a])=>a<1),s=e.length;if(s<3)return t;const o=e.map(([,a,M,h])=>un(a,M,h)),r=a=>(a%s+s)%s,c=a=>e[r(a)][0]+Math.floor(a/s),l=a=>{const M=c(a+1)-c(a-1);return o[r(a+1)].map((h,f)=>(h-o[r(a-1)][f])/M)},i=[];for(let a=0;a<=n;a++){const M=a/n;let h=-1;for(;h<s-1&&c(h+1)<=M;)h++;const f=c(h+1)-c(h),p=(M-c(h))/f,d=p*p,m=d*p,v=o[r(h)],_=o[r(h+1)],u=l(h),g=l(h+1),y=[0,1,2].map(S=>(2*m-3*d+1)*v[S]+(m-2*d+p)*f*u[S]+(-2*m+3*d)*_[S]+(m-d)*f*g[S]),[N,E,B]=On(y[0],y[1],y[2]);i.push([M,N,E,B])}return i}const Ss=1.5,qn=typeof CanvasRenderingContext2D=="function"&&"filter"in CanvasRenderingContext2D.prototype,Tn=new WeakMap;function en(t,n){return(typeof OffscreenCanvas=="function"?new OffscreenCanvas(t,n):Object.assign(document.createElement("canvas"),{width:t,height:n})).getContext("2d")}function ws(t){const{width:n,height:e}=t.canvas;let s=Tn.get(t);return(!s||s.full.canvas.width!==n||s.full.canvas.height!==e)&&(s={full:en(n,e)},qn||(s.half=en(Math.ceil(n/2),Math.ceil(e/2)),s.quarter=en(Math.ceil(n/4),Math.ceil(e/4))),Tn.set(t,s)),s.full.setTransform(1,0,0,1,0,0),s.full.clearRect(0,0,n,e),s.full.setTransform(t.getTransform()),s}function on(t,n){t.globalCompositeOperation="copy",t.imageSmoothingEnabled=!0,t.imageSmoothingQuality="high",t.drawImage(n.canvas,0,0,t.canvas.width,t.canvas.height)}function Es(t,n,e){const s=t.getTransform();t.save(),t.setTransform(1,0,0,1,0,0),t.globalCompositeOperation=e,t.globalAlpha=1,t.imageSmoothingEnabled=!0,t.imageSmoothingQuality="high",qn?(t.filter=`blur(${Ss*Math.hypot(s.a,s.b)}px)`,t.drawImage(n.full.canvas,0,0)):n.half&&n.quarter&&(on(n.half,n.full),on(n.quarter,n.half),on(n.half,n.quarter),t.drawImage(n.half.canvas,0,0,n.half.canvas.width*2,n.half.canvas.height*2)),t.restore()}function Rn(t,n,e){const s=typeof t.createConicGradient=="function"?t.createConicGradient(n.angle,n.cx,n.cy):t.createLinearGradient(n.cx-n.r,n.cy-n.r,n.cx+n.r,n.cy+n.r);for(const[o,r,c,l]of e)s.addColorStop(j(o),Bn(r,c,l));return s}function Ts(t,n,e,s,o,r){const c=xs(ys(e.stops,s,o,r)),l=Rn(t,e,c),i=n.strokes.map(u=>{const g=new Path2D,y=u.pts.length>>1;let N=0;for(let E=0;E<y;E++)E===0?g.moveTo(u.pts[0],u.pts[1]):g.lineTo(u.pts[2*E],u.pts[2*E+1]),N+=u.a[E];return u.closed&&g.closePath(),{p:g,a:y?N/y:1,w:u.w}}),a=Math.max(1,i.length),M=e.intensity,h=s?"lighter":"source-over",f=(u,g,y=t)=>{for(const N of i)y.lineWidth=u(N.w),y.globalAlpha=j(g(N.a)),y.stroke(N.p)},p=(u,g)=>{u.lineCap="round",u.lineJoin="round",u.globalCompositeOperation=h,u.strokeStyle=g},d=ws(t),m=d.full;p(m,Rn(m,e,c));const v=e.halo*M*(s?1:.2)/a;for(const[u,g]of[[.7,.045],[.42,.075],[.24,.11],[.12,.16]])f(()=>e.r*u,()=>g*v,m);const _=M*(s?1:.6);for(const[u,g]of[[16,.05],[8,.11],[4,.2]])f(y=>y*u,y=>g*_*y,m);if(Es(t,d,h),t.save(),p(t,l),s&&e.fringe>0){for(const[u,g,y]of[[1+e.fringe,ms,.16],[1-e.fringe,gs,.22]])t.save(),t.translate(e.cx,e.cy),t.scale(u,u),t.translate(-e.cx,-e.cy),t.strokeStyle=Bn(g[0],g[1],g[2]),f(N=>N*1.4/u,N=>y*M*N),t.restore();t.strokeStyle=l}if(f(u=>u,u=>.7*u*(.75+.25*M)),s)for(const u of e.spec){const g=t.createRadialGradient(u.x,u.y,0,u.x,u.y,u.r);g.addColorStop(0,"rgba(255,255,255,1)"),g.addColorStop(.35,"rgba(255,255,255,0.45)"),g.addColorStop(1,"rgba(255,255,255,0)"),t.strokeStyle=g,f(y=>y*2.2,y=>u.a*y)}t.restore()}const Rs=`
|
|
2
|
+
attribute vec2 aPos;
|
|
3
|
+
varying vec2 vUv;
|
|
4
|
+
void main() {
|
|
5
|
+
vUv = vec2(aPos.x + 1.0, 1.0 - aPos.y) * 0.5;
|
|
6
|
+
gl_Position = vec4(aPos, 0.0, 1.0);
|
|
7
|
+
}`,As=`
|
|
8
|
+
precision highp float;
|
|
9
|
+
uniform sampler2D uTex;
|
|
10
|
+
uniform vec2 uSize;
|
|
11
|
+
uniform float uWall, uSide, uZone, uGap, uFlare, uSplit, uBlur, uCy;
|
|
12
|
+
varying vec2 vUv;
|
|
13
|
+
const int TAPS = 16;
|
|
14
|
+
vec4 tap(vec2 p) { return texture2D(uTex, p / uSize); }
|
|
15
|
+
void main() {
|
|
16
|
+
vec2 p = vUv * uSize;
|
|
17
|
+
// 0 a zone back from the edge … 1 at it and past it
|
|
18
|
+
float t = clamp(1.0 - (uWall - p.x) * uSide / uZone, 0.0, 1.0);
|
|
19
|
+
if (t <= 0.0) { gl_FragColor = tap(p); return; }
|
|
20
|
+
float w = t * t;
|
|
21
|
+
// drawn out across the gap toward the edge, and opened a little taller
|
|
22
|
+
float d = (uWall - p.x) * uSide + uGap * w;
|
|
23
|
+
vec2 s = vec2(uWall - uSide * d, uCy + (p.y - uCy) / (1.0 + uFlare * w));
|
|
24
|
+
// dispersion: red bent further out than blue, along the stretch and the flare
|
|
25
|
+
vec2 split = vec2(uSide, 0.6 * (p.y - uCy) / uZone) * uSplit * w;
|
|
26
|
+
// the blur grows toward the edge, drawn out along the stretch
|
|
27
|
+
float b = uBlur * w;
|
|
28
|
+
vec3 rgb = vec3(0.0);
|
|
29
|
+
float a = 0.0;
|
|
30
|
+
for (int i = 0; i < TAPS; i++) {
|
|
31
|
+
float f = float(i);
|
|
32
|
+
float r = sqrt((f + 0.5) / float(TAPS)) * b;
|
|
33
|
+
vec2 o = vec2(cos(f * 2.39996) * 1.8, sin(f * 2.39996)) * r;
|
|
34
|
+
vec4 cr = tap(s + o + split);
|
|
35
|
+
vec4 cg = tap(s + o);
|
|
36
|
+
vec4 cb = tap(s + o - split);
|
|
37
|
+
rgb += vec3(cr.r, cg.g, cb.b);
|
|
38
|
+
a += max(cg.a, max(cr.a, cb.a));
|
|
39
|
+
}
|
|
40
|
+
gl_FragColor = vec4(rgb, a) / float(TAPS);
|
|
41
|
+
}`;let Vt;function Ps(){if(typeof document>"u")return null;const t=document.createElement("canvas"),n=t.getContext("webgl",{premultipliedAlpha:!0,antialias:!1,depth:!1});if(!n)return null;const e=(i,a)=>{const M=n.createShader(i);return n.shaderSource(M,a),n.compileShader(M),M},s=n.createProgram();if(n.attachShader(s,e(n.VERTEX_SHADER,Rs)),n.attachShader(s,e(n.FRAGMENT_SHADER,As)),n.linkProgram(s),!n.getProgramParameter(s,n.LINK_STATUS))return null;n.useProgram(s);const o=n.createBuffer();n.bindBuffer(n.ARRAY_BUFFER,o),n.bufferData(n.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),n.STATIC_DRAW);const r=n.getAttribLocation(s,"aPos");n.enableVertexAttribArray(r),n.vertexAttribPointer(r,2,n.FLOAT,!1,0,0);const c=n.createTexture();n.bindTexture(n.TEXTURE_2D,c),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.LINEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR),n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0);const l={};for(const i of["uSize","uWall","uSide","uZone","uGap","uFlare","uSplit","uBlur","uCy"])l[i]=n.getUniformLocation(s,i);return{gl:n,canvas:t,source:document.createElement("canvas"),tex:c,u:l}}function _s(t,n,e,s){if(Vt===void 0&&(Vt=Ps()),!Vt)return!1;const{gl:o,canvas:r,source:c,tex:l,u:i}=Vt,a=t.getTransform(),M=Math.hypot(a.a,a.b)||1,h=t.canvas.width,f=t.canvas.height,p=a.a*e+a.e,d=s.zone*M,m=s.blur*M,v=Math.max(0,Math.floor(n>0?p-d-2*m-4:0)),u=Math.min(h,Math.ceil(n>0?h:p+d+2*m+4))-v;if(u<2||f<2)return!1;(c.width!==u||c.height!==f)&&(c.width=u,c.height=f);const g=c.getContext("2d");return g.clearRect(0,0,u,f),g.drawImage(t.canvas,v,0,u,f,0,0,u,f),(r.width!==u||r.height!==f)&&(r.width=u,r.height=f),o.viewport(0,0,u,f),o.bindTexture(o.TEXTURE_2D,l),o.texImage2D(o.TEXTURE_2D,0,o.RGBA,o.RGBA,o.UNSIGNED_BYTE,c),o.uniform2f(i.uSize,u,f),o.uniform1f(i.uWall,p-v),o.uniform1f(i.uSide,n),o.uniform1f(i.uZone,d),o.uniform1f(i.uGap,s.gap*M),o.uniform1f(i.uFlare,s.flare),o.uniform1f(i.uSplit,s.split*M),o.uniform1f(i.uBlur,m),o.uniform1f(i.uCy,a.d*s.cy+a.f),o.clearColor(0,0,0,0),o.clear(o.COLOR_BUFFER_BIT),o.drawArrays(o.TRIANGLE_STRIP,0,4),t.save(),t.setTransform(1,0,0,1,0,0),t.globalCompositeOperation="copy",t.beginPath(),t.rect(v,0,u,f),t.clip(),t.drawImage(r,v,0),t.restore(),!0}function zn(t,n,e,s){const o=2.2/s.size,r=zt(t*o+s.t*.11,n*o-s.t*.08,s.t*.07),c=dn(.3,.75,r);return s.amount*(.2+.75*c)*j(1.3-e)}function Dn(t,n,e,s,o,r=0,c,l=0){const i=Math.round(n*1e3)/1e3,a=d=>e?d*(1-t):d+(255-d)*t,M=(e?1-t:t)*255;let h=s?a(s.r):M,f=s?a(s.g):M,p=s?a(s.b):M;return c&&l>0&&(h+=(a(c[0])-h)*l,f+=(a(c[1])-f)*l,p+=(a(c[2])-p)*l),o&&r>0&&(h+=(a(o.r)-h)*r,f+=(a(o.g)-f)*r,p+=(a(o.b)-p)*r),`rgba(${Math.round(h)},${Math.round(f)},${Math.round(p)},${i})`}const An=24,Pn=8;function Cs(t,n,e,s,o,r){const c=o&&o.amount>.005?o:void 0,l=r&&r.saturation>0?r:void 0,i=new Map;for(const a of n){const M=a.pts.length>>1,h=a.closed?M:M-1;let f="",p;for(let d=0;d<h;d++){const m=d+1===M?0:d+1,v=Math.round(j((a.a[d]+a.a[m])/2)*An);if(v===0){f="";continue}const _=c?Math.round(zn((a.pts[2*d]+a.pts[2*m])/2,(a.pts[2*d+1]+a.pts[2*m+1])/2,a.white,c)*Pn):0,u=l?l.at((a.pts[2*d]+a.pts[2*m])/2,(a.pts[2*d+1]+a.pts[2*m+1])/2):0,g=`${v}|${a.white}|${Math.round(a.w*20)}|${_}|${u}`;if(g!==f){let y=i.get(g);y||(y={path:new Path2D,white:a.white,w:a.w,a:v/An,gw:_/Pn,ci:u},i.set(g,y)),p=y,f=g,y.path.moveTo(a.pts[2*d],a.pts[2*d+1])}p.path.lineTo(a.pts[2*m],a.pts[2*m+1])}}t.lineCap="round",t.lineJoin="round";for(const a of i.values())t.strokeStyle=Dn(j(a.white),a.a,e,s,c,a.gw,l==null?void 0:l.rgb,l==null?void 0:l.mix[a.ci]),t.lineWidth=a.w,t.stroke(a.path)}function ks(t,n,e,s,o,r,c=!1){const l=o&&o.amount>.005?o:void 0,i=r&&r.saturation>0?r:void 0;for(const a of n){const M=j(a.white),h=l?zn(a.x,a.y,M,l):0,f=i?i.at(a.x,a.y):0;if(t.fillStyle=Dn(M,j(a.a??1),e,s,l,h,i==null?void 0:i.rgb,i==null?void 0:i.mix[f]),c){t.fillRect(a.x-a.r,a.y-a.r,2*a.r,2*a.r);continue}t.beginPath(),t.arc(a.x,a.y,a.r,0,ft),t.fill()}}function Fs(t,n,e,s,o,r){var l;const c=r&&r.saturation>0&&!n.light?Ms(r):void 0;n.light?Ts(t,n,n.light,e,s,o):n.strokes.length&&Cs(t,n.strokes,e,s,o,c),ks(t,n.dots,e,s,o,c,n.square),(l=n.contact)!=null&&l.lens&&_s(t,n.contact.side,n.contact.x,n.contact.lens)}const Is=[[0,255,150,90],[.12,255,110,120],[.24,255,80,170],[.4,190,80,255],[.58,90,92,255],[.74,60,132,255],[.84,170,90,255],[.93,240,104,165],[1,255,150,90]],Ns=(t,n,e,s)=>{const o=t/2,r=e.level,[c,l]=e.softBands,i=e.bands[2],a=e.drive,M=e.processing,h=.5*r+.5*e.soft,f=o*(s.radius??.56)*(1+(s.zoom??.17)*e.soft)*(1-.06*M),p=s.deform??1.45,d=.02+(.14*c+.06*r)*p,m=.01+(.07*l+.03*i)*p,v=pn(d,m,a,s.deformRadius??1.75),_=Math.max(.6,(s.lineW??1.85)*Dt(t,.5)),u=Math.max(1,Math.round(s.rings??6)),g=Math.max(24,Math.round(s.segs??140)),y=s.lean??.91,N=s.ringGap??.02,E=[];let B=0,S=0;for(let x=0;x<u;x++){const F=.16*(.5+St(x,2.1))*(x%2?1:-1),R=Math.max(.02,y*(.2+.8*St(x,3.1))+.03*Math.sin(n*.27+x*1.3)+.08*Math.sin(a*.35+x*1.7)),O=St(x,7.7)*ft+n*.05*(x%2?1:-1)+a*F,k=Math.sin(R)*Math.cos(O),I=Math.sin(R)*Math.sin(O),T=Math.cos(R),A=Math.hypot(k,T),z=T/A,L=-k/A,U=I*L,W=T*z-k*L,Z=-I*z,nt=f*(1+N*(x-(u-1)/2)),Y=Math.sin(R),X=[],ct=[],J=[];for(let Q=0;Q<g;Q++){const V=Q/g*ft,dt=Math.cos(V),rt=Math.sin(V),it=z*dt+U*rt,st=W*rt,mt=L*dt+Z*rt,ht=v(it,st,mt);X.push(it,st),ct.push(ht),B+=ht,S++,J.push(.62+.38*j((mt/Y+1)/2))}E.push({dirs:X,f:ct,a:J,rk:nt})}const C=S?B/S:0;let P=0,q=0;for(const{dirs:x,f:F}of E)for(let R=0;R<F.length;R++){const O=x[2*R],k=x[2*R+1],I=Math.hypot(O,k)||1;P+=(F[R]-C)*(O/I),q+=(F[R]-C)*(k/I)}P=S?2*P/S:0,q=S?2*q/S:0;const G=E.map(({dirs:x,f:F,a:R,rk:O})=>{const k=[];for(let I=0;I<F.length;I++){const T=x[2*I],A=x[2*I+1],z=Math.hypot(T,A)||1,L=O*(1+F[I]-C-P*(T/z)-q*(A/z));k.push(o+T*L,o-A*L)}return{pts:k,a:R,white:0,w:_,closed:!0}}),b=2.3+.25*Math.sin(n*.21)+2*e.spin,w={cx:o,cy:o,r:f,stops:Is,angle:-Math.PI/2-.35+.5*Math.sin(n*.07)+.4*Math.sin(a*.2)+e.spin,intensity:.62+.55*h+.5*M,halo:(s.halo??.5)*(1+.6*M),spec:[{x:o+Math.cos(b)*f,y:o+Math.sin(b)*f,r:f*(.5+.25*M),a:.5+.35*h+.4*M}],fringe:.016+.012*h};return{..._t([],G),light:w}},Ln=-.45,Gn=.55,Un=.7,Os=Math.hypot(Ln,Gn,Un),Bs=(t,n,e,s)=>{const o=t/2,r=e.level,[c,l,i]=e.bands,a=e.drive,M=e.processing,h=o*(s.radius??.72),f=h*(1+(s.zoom??.3)*r)*(1-.06*M),p=s.rMul??1,d=Math.max(4,Math.round(s.cells??17)),m=2*h/d,v=m/2-Math.max(.5,m*(s.gap??.24)/2),_=Math.ceil(f*1.25/m),u=(s.turn??.12)*n+.1*a+.5*e.spin,g=Math.sin(u),y=Math.cos(u),N=Math.sin(.35),E=Math.cos(.35),B=s.shade??.7,S=s.texture??.35,C=s.fade??1.3,P=s.strength??1.38,q=s.deform??1.7,G=.012+(.09*c+.03*r)*q,b=(.035*l+.025*i)*q,w=k=>G*(.55*Math.sin(2*k+.9*a)+.45*Math.sin(3*k-.7*a+1.3))+b*Math.sin(7*k+2.3*a)*Math.sin(5*k-1.7*a),x=.95*Math.sin(n*1.3),F=e.spectrum,R=F.length,O=[];for(let k=-_;k<=_;k++)for(let I=-_;I<=_;I++){const T=o+I*m,A=o+k*m,z=(T-o)/f,L=-(A-o)/f,U=w(Math.atan2(L,z)),W=Math.hypot(z,L)/(1+U);if(W>=1)continue;const Z=1/(1+U),nt=z*Z,Y=L*Z,X=Math.sqrt(Math.max(0,1-nt*nt-Y*Y)),ct=j((nt*Ln+Y*Gn+X*Un)/Os),J=1-B+B*ct,Q=Y*E+X*N,V=-Y*N+X*E,dt=nt*y-V*g,rt=nt*g+V*y,it=.65*zt(dt*2.2+a*.15,Q*2.2,rt*2.2-a*.1)+.35*zt(dt*4.6-a*.2,Q*4.6+7.3,rt*4.6),st=1-S+S*dn(.32,.68,it),mt=R?F[Math.min(R-1,Math.floor(W*R))]:r,ht=.35*r+.85*mt,gt=Math.exp(-((Y-x)**2)/.01)*M,lt=1-.4*C*(1-X),wt=(.35+.75*J*st+.3*ht+.2*gt)*lt*p,Ct=.22+.62*J*st+.22*ht+.3*gt;O.push({x:T,y:A,z:X*f,r:v*Math.min(1,wt),white:j(1-Ct*P),a:j((1-.75*C*(1-Math.sqrt(X)))*P)})}return{..._t(O,[],s.rMin??.4),square:!0}},qs=(t,n,e,s)=>{const o=t/2,r=t/2,c=.5*e.level+.5*e.soft,l=(1+(s.swell??.49)*c)*(1-.14*e.processing),i=t/2*(s.radius??.56),a=s.persp??.25,M=Kt(n*.12+e.drive*.03,.3,0,0,1),h=Dt(t,s.rsPow??.9)*(s.rMul??1),f=[],p=s.orbitN??12,d=s.particles??6;for(let m=0;m<p;m++){const v=St(m,1.7),_=St(m,5.2),u=St(m,8.9),g=i*(.45+.52*v),y=v*ft,N=Math.acos(2*_-1),E=Math.sin(N)*Math.cos(y),B=Math.cos(N),S=Math.sin(N)*Math.sin(y);let C=-B,P=E;const q=Math.max(1e-6,Math.sqrt(C*C+P*P));C/=q,P/=q;const G=-S*P,b=S*C,w=E*P-B*C,x=(.25+.55*u)*(u>.5?1:-1);for(let F=0;F<d;F++){const R=e.drive*x+F/d*ft+_*6,O=Math.cos(R),k=Math.sin(R),[I,T,A]=M((C*O+G*k)*g,(P*O+b*k)*g,w*k*g),z=j((A/i+1)/2),L=l/(1-a*A/i);f.push({x:o+I*L,y:r+T*L,z:A,r:((s.partR??.47)+(s.partRDepth??.65)*z)*h*L,white:.32-.24*z})}}return _t(f,[],s.rMin)},zs=(t,n,e,s)=>{const o=t/2,r=t/2,c=e.soft,[l,i]=e.softBands,a=t/2*(s.radius??.66)*(1+(s.zoom??.21)*e.level),M=e.drive,h=s.deform??1,f=s.wave??1,p=.015+(.1*l+.05*e.level)*h,d=.04*i*h,m=pn(p,d,M),v=.55+.05*Math.sin(n*.37),_=Math.cos(v),u=Math.sin(v);let g=0;for(let T=0;T<48;T++){const A=T/48*ft;g+=m(Math.cos(A),Math.sin(A)*_,Math.sin(A)*u)}g/=48;const y=(T,A,z)=>1+m(T,A,z)-g,E=Kt(0,.3,o,r,1),B=Dt(t,s.rsPow??.6)*(s.rMul??1),S=e.drive,C=[],P=s.ghostN??60;for(let T=0;T<P;T++){const A=Mn(T,P),z=a*y(A[0],A[1],A[2]),[L,U,W]=E(A[0]*z,A[1]*z,A[2]*z),Z=(W/a+1)/2;C.push({x:L,y:U,z:W,r:.65*B,white:.78,a:.1+.22*Z})}const q=-u,G=_,b=Math.max(1,Math.round(s.lanes??10)),w=Math.max(8,Math.round(s.segs??56)),x=e.processing,F=(s.laneGap??.062)*(1+.25*c)*(1-.4*x),R=S*1.6,O=.15*(.55+.9*l*f)*(1-.6*x),k=.06*(.5+1.2*i*f),I=.05+.05*c;for(let T=0;T<b;T++){const A=(T-(b-1)/2)*F,z=Math.abs(T-(b-1)/2)/Math.max(1,(b-1)/2);for(let L=0;L<w;L++){const U=L/w*ft,W=O*Math.sin(U*3-S*.95+T*.18)+k*Math.sin(U*5+S*.6)+I*Math.sin(U*2+n*.31+Math.sin(n*.17)*1.5),Z=A+W,nt=Math.cos(U),Y=Math.sin(U),X=nt,ct=Y*_+q*Z,J=Y*u+G*Z,Q=Math.sqrt(X*X+ct*ct+J*J),V=a*y(X/Q,ct/Q,J/Q)/Q,[dt,rt,it]=E(X*V,ct*V,J*V),st=(it/a+1)/2,mt=Math.max(0,W)*c,ht=Math.atan2(Math.sin(U-R),Math.cos(U-R)),gt=Math.exp(-(ht*ht)/.18)*x;C.push({x:dt,y:rt,z:it,r:((s.rBase??.49)+(s.rDepth??.78)*st)*(1-.25*z)*(1+1.2*mt+.5*gt)*B,white:.52-.44*st+.18*z-.3*gt,a:.4+.6*st})}}return _t(C,[],s.rMin)},Ds=(t,n,e,s)=>{const o=t/2,r=e.level,[c,l]=e.softBands,i=e.bands[2],a=e.drive,M=o*(s.radius??.6)*(1+(s.zoom??.06)*e.soft)*(1-.08*e.processing),h=Kt((s.yaw??.42)+.08*Math.sin(n*.23),s.tilt??.32,o,o,1),f=Math.max(.4,(s.lineW??.6)*Dt(t,.5)),p=E=>.06+.94*j((E/M+1)/2)**2,d=s.deform??1,m=.02+(.14*c+.06*r)*d,v=.01+(.07*l+.03*i)*d,_=pn(m,v,a),u=[],g=Math.max(24,Math.round(s.segs??96)),y=Math.max(0,Math.round(s.limbs??2));for(let E=0;E<y;E++){const B=.1+.05*Math.sin(n*.31+E*2.1),S=n*.17*(E%2?1:-1)+E*2.4,C=Math.sin(B)*Math.cos(S),P=Math.sin(B)*Math.sin(S),q=Math.cos(B),G=Math.hypot(C,q),b=q/G,w=-C/G,x=P*w,F=q*b-C*w,R=-P*b,O=[],k=[];for(let I=0;I<g;I++){const T=I/g*ft,A=b*Math.cos(T)+x*Math.sin(T),z=F*Math.sin(T),L=w*Math.cos(T)+R*Math.sin(T),U=M*(1+.006*E+_(A,z,L));O.push(o+A*U,o-z*U),k.push(.55+.35*j((L/Math.sin(B)+1)/2))}u.push({pts:O,a:k,white:0,w:f,closed:!0})}const N=Math.max(2,Math.round(s.circles??8));for(let E=0;E<N;E++){const[B,S,C]=Mn(E,N),P=a*.16*(.5+St(E,2.1))*(E%2?1:-1)+St(E,6.6)*ft,q=S*Math.cos(P)-C*Math.sin(P),G=S*Math.sin(P)+C*Math.cos(P),b=Math.max(1e-6,Math.hypot(G,B)),w=G/b,x=-B/b,F=q*x,R=G*w-B*x,O=-q*w,k=[],I=[];for(let T=0;T<g;T++){const A=T/g*ft,z=w*Math.cos(A)+F*Math.sin(A),L=R*Math.sin(A),U=x*Math.cos(A)+O*Math.sin(A),W=M*(1+_(z,L,U)),[Z,nt,Y]=h(z*W,L*W,U*W);k.push(Z,nt),I.push(p(Y))}u.push({pts:k,a:I,white:0,w:f,closed:!0})}return _t([],u,s.rMin)},Ls=(t,n,e,s)=>{const o=t/2,r=e.level,[c,l,i]=e.bands,a=e.drive,M=e.processing,h=o*(s.radius??.6)*(1+(s.zoom??.1)*r)*(1-.08*M),f=.95*Math.sin(n*1.3),p=Kt(n*.14,.32,o,o,1),d=Dt(t,s.rsPow??.6)*(s.rMul??1),m=Math.max(40,Math.round(s.dotN??900)),v=s.cloudFreq??2.3,_=s.deform??1,u=.018+(.12*c+.04*r)*_,g=(.045*l+.03*i)*_,y=[],N=[];let E=0;for(let S=0;S<m;S++){const C=Mn(S,m),[P,q,G]=C,b=.55*Math.sin(2.1*P+1.3*q+.9*a)+.45*Math.sin(1.7*G-1.9*q-.7*a+1.3),w=Math.sin(5.3*P-4.1*G+2.3*a)*Math.sin(4.7*q+3.1*P-1.7*a),x=u*b+g*w;y.push(C),N.push(x),E+=x/m}const B=[];for(let S=0;S<m;S++){const[C,P,q]=y[S],G=N[S]-E,b=h*(1+G),[w,x,F]=p(C*b,P*b,q*b),R=j((F/h+1)/2),O=.65*zt(C*v+a*.21,P*v-a*.15,q*v+a*.1)+.35*zt(C*v*2.1-a*.29,P*v*2.1+7.3,q*v*2.1+a*.24),k=dn(.34,.68,O),I=Math.exp(-((P-f)**2)/.012)*M,T=Math.max(0,G)/.16;B.push({x:w,y:x,z:F,r:((s.rBase??.27)+(s.rDepth??.84)*R)*(.22+.95*k+.6*I)*(1+.5*T)*d,white:.62-.52*R-.16*k-.3*I,a:.3+.7*R})}return _t(B,[],s.rMin??.25)},Gs=["orbit","sash","signal","swell","pixel","aura"],Us={orbit:qs,sash:zs,signal:Ds,swell:Ls,pixel:Bs,aura:Ns},ot={orbit:{speed:1.05,driveGain:.12,opts:{orbitN:12,particles:6},counts:{}},sash:{speed:1.5,driveGain:.8,gain:1.1,opts:{lanes:10,segs:56,ghostN:60},counts:{segs:.45,ghostN:.8}},signal:{speed:1.6,driveGain:2,opts:{circles:8,segs:96},counts:{circles:.5,segs:.5}},swell:{speed:1.4,driveGain:2.4,opts:{dotN:900},counts:{dotN:1}},pixel:{speed:1.2,driveGain:1.6,attack:.16,dotSize:.55,opts:{cells:17},counts:{cells:.5}},aura:{speed:1.6,driveGain:2,voiceSpeed:.9,lean:{move:.21,pull:.36,deform:.28,squash:0,bounce:.92,lens:.49,stretch:1.04,split:1.01,blur:1.24},opts:{rings:6,segs:140},counts:{segs:.5}}};function $n(t,n,e=1,s=1){const o=t in ot?t:"orbit",r=ot[o],c=Math.min(1.4,Math.max(.2,n/200))*Math.max(.1,e),l={...r.opts};for(const[i,a]of Object.entries(r.counts)){const M=l[i];M!=null&&(l[i]=Math.max(1,Math.round(M*c**a)))}return s!==1&&(l.rMul=Math.max(.1,s)),{frame:Us[o],speed:r.speed,driveGain:r.driveGain,gain:r.gain??1,opts:l}}function $s(t){let n=t;for(;n;){const e=n.getAttribute("data-theme");if(e==="dark")return!0;if(e==="light")return!1;if(n.classList.contains("dark"))return!0;if(n.classList.contains("light"))return!1;n=n.parentElement}return null}function Ws(){return typeof matchMedia>"u"||matchMedia("(prefers-color-scheme: dark)").matches}function Vs(t,n){const[e,s]=$.useState(!0);return $.useEffect(()=>{if(t==="dark"){s(!0);return}if(t==="light"){s(!1);return}const o=()=>{const i=$s(n.current);s(i??Ws())};o();const r=typeof matchMedia<"u"?matchMedia("(prefers-color-scheme: dark)"):null,c=()=>o();r==null||r.addEventListener("change",c);let l=null;return typeof MutationObserver<"u"&&n.current&&(l=new MutationObserver(o),l.observe(document.documentElement,{attributes:!0,attributeFilter:["class","data-theme"],subtree:!0})),()=>{r==null||r.removeEventListener("change",c),l==null||l.disconnect()}},[t,n]),e}function Xs(){const[t,n]=$.useState(!1);return $.useEffect(()=>{if(typeof matchMedia>"u")return;const e=matchMedia("(prefers-reduced-motion: reduce)");n(e.matches);const s=o=>n(o.matches);return e.addEventListener("change",s),()=>e.removeEventListener("change",s)},[]),t}const ut=16,Ks=2.1,js=.3,Ys=2.5,Hs=1.6,Zs=5,_n=2.2,Cn=[[80,300],[300,2e3],[2e3,6e3]],an=90,Js=7e3,cn=Math.PI*2,rn=.35,ln=.9;function Wn(t){return t<0?0:t>1?1:t}function hn(t,n){if(t<=n)return 0;const e=(t-n)/Math.max(.001,1-n);return Wn((1-Math.exp(-3*e))/(1-Math.exp(-3)))}function At(t,n,e,s,o){const r=n>t?s:o;return t+(n-t)*(1-Math.exp(-e/Math.max(.001,r)))}class Vn{constructor(){this.clock=0,this.t=0,this.drive=0,this.level=0,this.bands=[0,0,0],this.spectrum=new Float32Array(ut),this.floor=new Float32Array(ut+3).fill(1),this.heard=0,this.proc=0,this.spin=0,this.pan=0,this.panVel=0,this.raw={level:0,bands:[0,0,0],spectrum:new Float32Array(ut)},this.timeBuf=null,this.freqBuf=null,this.out={level:0,bands:[0,0,0],soft:0,softBands:[0,0,0],spectrum:this.spectrum,drive:0,processing:0,spin:0,pan:0}}readAnalyser(n,e,s){(!this.timeBuf||this.timeBuf.length!==n.fftSize)&&(this.timeBuf=new Float32Array(n.fftSize)),(!this.freqBuf||this.freqBuf.length!==n.frequencyBinCount)&&(this.freqBuf=new Uint8Array(n.frequencyBinCount));const o=this.timeBuf,r=this.freqBuf;n.getFloatTimeDomainData(o);let c=0;for(let h=0;h<o.length;h++)c+=o[h]*o[h];this.raw.level=Math.sqrt(c/o.length)*Zs*e,n.getByteFrequencyData(r);const l=n.context.sampleRate/n.fftSize,i=(h,f)=>{const p=Math.max(0,Math.floor(h/l)),d=Math.max(p,Math.min(r.length-1,Math.ceil(f/l)));let m=0;for(let v=p;v<=d;v++)m+=r[v];return m/(d-p+1)/255},a=(h,f)=>{const p=this.floor[h];return this.floor[h]=f<p?f:p+(f-p)*(1-Math.exp(-s/8)),Math.max(0,f-this.floor[h])/Math.max(.05,1-this.floor[h])};for(let h=0;h<3;h++)this.raw.bands[h]=a(h,i(Cn[h][0],Cn[h][1]))*_n*e;const M=Js/an;for(let h=0;h<ut;h++){const f=an*M**(h/ut),p=an*M**((h+1)/ut);this.raw.spectrum[h]=a(3+h,i(f,p))*_n*e}}readLevel(n,e){const s=Wn(n)*e,o=this.clock;this.raw.level=s,this.raw.bands[0]=s,this.raw.bands[1]=s*(.72+.28*Math.sin(o*2.3)),this.raw.bands[2]=s*(.6+.4*Math.sin(o*3.7+2));const r=.28+.1*Math.sin(o*2.3)+.05*Math.sin(o*5.1),c=.64+.1*Math.sin(o*1.7+1);for(let l=0;l<ut;l++){const i=l/(ut-1),a=Math.exp(-((i-r)**2)/.012)+.6*Math.exp(-((i-c)**2)/.008);this.raw.spectrum[l]=s*(.25+.75*a)*(1-.4*i)}}readSilence(){this.raw.level=0,this.raw.bands.fill(0),this.raw.spectrum.fill(0)}step(n,e,s){const{threshold:o,attack:r,release:c,rate:l}=e,i=this.proc=At(this.proc,e.processing?1:0,n,.35,.5),a=e.calm+(1-e.calm)*Math.min(1,Math.max(this.heard*2.5,i));s||(this.clock+=n,this.t+=n*l*a*(1+.5*i));const M=hn(this.raw.level,o);this.level=At(this.level,M,n,r,c),this.heard=At(this.heard,this.level,n,rn,ln);for(let u=0;u<3;u++)this.bands[u]=At(this.bands[u],hn(this.raw.bands[u],o*.6),n,r,c*1.15);for(let u=0;u<ut;u++)this.spectrum[u]=At(this.spectrum[u],hn(this.raw.spectrum[u],o*.6),n,r,c);const h=this.clock,f=s?.5:.5+.5*Math.sin(cn*h/6),p=e.idle*f*(1-i),d=this.out;d.level=this.level+(1-this.level)*p;for(let u=0;u<3;u++)d.bands[u]=this.bands[u]+(1-this.bands[u])*p*.6;d.soft=At(d.soft,d.level,n,rn,ln);for(let u=0;u<3;u++)d.softBands[u]=At(d.softBands[u],d.bands[u],n,rn,ln);if(s||(this.drive+=n*l*(a+e.driveGain*this.level+1.3*i)),d.drive=this.drive,d.processing=i,!s){const u=Math.ceil(this.spin/cn-1e-6)*cn,g=Math.min(js,(u-this.spin)*.6);this.spin+=n*(Ks*l*i+g*(1-i))}d.spin=this.spin;const m=Math.max(-1,Math.min(1,e.direction||0)),v=this.heard>.06&&!e.processing?m:0,_=Math.abs(v)>Math.abs(this.pan)?Ys:Hs;return this.panVel+=(_*_*(v-this.pan)-2*_*this.panVel)*n,this.pan+=this.panVel*n,d.pan=this.pan,d}}function Qs(t){if(!t)return;const n=t.trim().match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);if(n){let s=n[1];s.length===3&&(s=s.replace(/./g,r=>r+r));const o=parseInt(s,16);return{r:o>>16&255,g:o>>8&255,b:o&255}}const e=t.trim().match(/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i);if(e)return{r:Number(e[1]),g:Number(e[2]),b:Number(e[3])}}const te={idle:"Waiting",listening:"Listening",speaking:"Speaking",processing:"Thinking"},ne=1e3/62;function Xn({type:t="orbit",state:n="listening",size:e=160,stream:s,analyser:o,level:r,sensitivity:c=.85,threshold:l=.04,attack:i,release:a=.32,idle:M=.1,calm:h=.4,voiceSpeed:f,emotion:p=null,emotionColors:d,saturation:m=2,accent:v=null,gradientAngle:_=99,gradientSpin:u=12,neutral:g=1,colorBrightness:y=1.02,colorHue:N=0,gradientStart:E=.1,gradientWidth:B=.6,direction:S,directionMove:C,directionPull:P,directionDeform:q,directionSquash:G,directionLens:b,directionStretch:w,directionSplit:x,directionBlur:F,directionBounce:R,directionMargin:O,directionBounds:k,theme:I="auto",speed:T=1,paused:A=!1,color:z,dots:L=1,dotSize:U,opts:W,frame:Z,onLevel:nt,style:Y,"aria-label":X,...ct}){const J=$.useRef(null),Q=Vs(I,J),V=Xs(),dt=W?JSON.stringify(W):"",rt=!!(s||o||r!=null||n==="processing"),it=$.useRef(null);it.current||(it.current=new Vn);const st=$.useRef(null);st.current||(st.current=new cs);const mt=p?(d==null?void 0:d[p])??qt[p]:null,ht={saturation:Math.min(1,m),vivid:Math.max(0,Math.min(1,m-1)),brightness:y,hue:N,start:E,width:B,accent:v?Nn[v]:null,angle:_,spin:u,neutral:g,size:e},gt=U??ot[t in ot?t:"orbit"].dotSize??1,lt=ot[t in ot?t:"orbit"].lean??{},wt=O??ot[t in ot?t:"orbit"].margin??32,Ct={state:n,level:r,analyser:o,sensitivity:c,threshold:l,attack:i??ot[t in ot?t:"orbit"].attack??.06,release:a,idle:M,calm:h,voiceSpeed:f??ot[t in ot?t:"orbit"].voiceSpeed??1,onLevel:nt,emotionTint:mt,colors:ht,direction:S,bounds:k,lean:{move:C??lt.move??Mt.move,pull:P??lt.pull??Mt.pull,deform:q??lt.deform??Mt.deform,squash:G??lt.squash??Mt.squash,lens:b??lt.lens??Mt.lens,stretch:w??lt.stretch??Mt.stretch,split:x??lt.split??Mt.split,blur:F??lt.blur??Mt.blur,bounce:R??lt.bounce??Mt.bounce}},kt=$.useRef(Ct);kt.current=Ct;const Pt=S==null?0:rs(Ct.lean,e),[mn,Kn]=$.useState([1/0,1/0]),jt=Math.min(Pt,mn[0]),Yt=Math.min(Pt,mn[1]),bt=Pt?jt+wt:0,Ft=Pt?Yt+wt:0,Ht=$.useRef(null);return $.useEffect(()=>{if(!s)return;const et=In(s);return Ht.current=(et==null?void 0:et.analyser)??null,()=>{Ht.current=null,et==null||et.release()}},[s]),$.useEffect(()=>{const et=J.current;if(!et)return;const It=Math.min(2,typeof devicePixelRatio<"u"&&devicePixelRatio||1);et.width=Math.round((e+bt+Ft)*It),et.height=Math.round(e*It);const Lt=et.getContext("2d");if(!Lt)return;const Et=$n(t,e,L,gt),jn=W?{...Et.opts,...W}:Et.opts,Yn=Z??Et.frame,Hn=Qs(z),vt=it.current,Zn=st.current,Jn=new is;let gn=0;const Qn=(H,K,D)=>{var wn;Lt.setTransform(It,0,0,It,bt*It,0),Lt.clearRect(-bt,0,e+bt+Ft,e);const Nt=A||V?0:Jn.step(gn,D),yt=ls(Yn(e,vt.t,H,jn),H.pan,e,kt.current.lean,[jt,Yt],Nt);gn=((wn=yt.contact)==null?void 0:wn.press)??0;const at=kt.current.colors,pt=K.amount,tt=at.accent,Ot=tt?{r:tt.r+(K.r-tt.r)*pt,g:tt.g+(K.g-tt.g)*pt,b:tt.b+(K.b-tt.b)*pt}:{r:K.r,g:K.g,b:K.b},ns={...at,accent:Ot,saturation:at.saturation*(tt?1:pt),angle:at.angle+at.spin*vt.clock};Fs(Lt,yt,Q,Hn,yt.light?K:void 0,ns)};let bn=-1/0;const ts=H=>{var pt,tt;if(!Pt||H-bn<500)return;bn=H;const K=et.getBoundingClientRect().left+bt,D=(tt=(pt=kt.current.bounds)==null?void 0:pt.current)==null?void 0:tt.getBoundingClientRect(),Nt=D?D.left:0,yt=D?D.right:document.documentElement.clientWidth,at=[Math.max(0,Math.floor(K-Nt-wt)),Math.max(0,Math.floor(yt-K-e-wt))];Kn(Ot=>Math.abs(Ot[0]-at[0])>1||Math.abs(Ot[1]-at[1])>1?at:Ot)};let Gt=0;const vn=H=>{var tt;ts(H);const K=Gt?Math.min(.05,(H-Gt)/1e3):1/60;Gt=H;const D=kt.current,Nt=D.state==="listening"||D.state==="speaking",yt=Ht.current??D.analyser??null;Nt?yt?vt.readAnalyser(yt,D.sensitivity*Et.gain,K):D.level!=null?vt.readLevel(typeof D.level=="function"?D.level():D.level,D.sensitivity*Et.gain):vt.readSilence():vt.readSilence();const at=vt.step(K,{sensitivity:D.sensitivity,threshold:D.threshold,attack:D.attack,release:D.release,idle:D.idle,driveGain:Et.driveGain*D.voiceSpeed,calm:D.calm,rate:Et.speed*T,processing:D.state==="processing",direction:typeof D.direction=="function"?D.direction():D.direction??0},V);(tt=D.onLevel)==null||tt.call(D,at.level);const pt=Zn.step(K,D.emotionTint,vt.clock,e,A||V);Qn(at,pt,K)};if(vn(performance.now()),A||V&&!rt)return;let Zt=0,Ut=!1,yn=0;const xn=H=>{Ut&&(Zt=requestAnimationFrame(xn),!(H-yn<ne)&&(yn=H,vn(H)))},Jt=()=>{Ut||(Ut=!0,Gt=0,Zt=requestAnimationFrame(xn))},Qt=()=>{Ut=!1,cancelAnimationFrame(Zt)};let tn=!0;const Tt=typeof IntersectionObserver<"u"?new IntersectionObserver(([H])=>{tn=H.isIntersecting,tn&&document.visibilityState!=="hidden"?Jt():Qt()}):null;Tt==null||Tt.observe(et);const Sn=()=>{document.visibilityState==="hidden"?Qt():tn&&Jt()};return document.addEventListener("visibilitychange",Sn),Tt||Jt(),()=>{Qt(),Tt==null||Tt.disconnect(),document.removeEventListener("visibilitychange",Sn)}},[t,e,Pt,jt,Yt,bt,Ft,wt,Q,T,A,V,rt,z,L,gt,dt,Z,A||V?p:null,A||V?`${m}|${v}|${_}|${u}|${g}|${y}|${N}|${E}|${B}`:null]),kn.jsx("canvas",{ref:J,role:"img","aria-label":X??te[n],style:{width:e+bt+Ft,height:e,display:"block",marginLeft:-bt,marginRight:-Ft,...Y},...ct})}const se={echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1};function Xt(){return typeof navigator<"u"&&typeof navigator.mediaDevices<"u"&&typeof navigator.mediaDevices.getUserMedia=="function"}function ee(t={}){const{constraints:n,autoStart:e=!1}=t,[s,o]=$.useState(null),[r,c]=$.useState(()=>Xt()?"idle":"unsupported"),[l,i]=$.useState(null),a=$.useRef(null),M=$.useRef(n);M.current=n;const h=$.useCallback(()=>{const p=a.current;a.current=null,p&&p.getTracks().forEach(d=>d.stop()),o(null),c(Xt()?"idle":"unsupported")},[]),f=$.useCallback(async()=>{if(!Xt())return c("unsupported"),null;if(a.current)return a.current;fn(),c("requesting"),i(null);try{const p=await navigator.mediaDevices.getUserMedia({audio:{...se,...M.current??{}}});a.current=p,o(p),c("live");const d=()=>{a.current===p&&(a.current=null,o(null),c("idle"))};return p.getAudioTracks().forEach(m=>m.addEventListener("ended",d)),p}catch(p){const d=p instanceof Error?p:new Error(String(p));return i(d),c(d.name==="NotAllowedError"||d.name==="SecurityError"?"denied":"error"),null}},[]);return $.useEffect(()=>{e&&f()},[e]),$.useEffect(()=>()=>{const p=a.current;a.current=null,p&&p.getTracks().forEach(d=>d.stop())},[]),{stream:s,state:r,error:l,supported:Xt(),start:f,stop:h}}function oe(t){return kn.jsx(Xn,{...t,type:"aura"})}exports.ACCENT_COLORS=Nn;exports.EMOTION_COLORS=qt;exports.PRESETS=ot;exports.SPECTRUM_N=ut;exports.VOICE_ORB_TYPES=Gs;exports.VoiceFollower=Vn;exports.VoiceOrb=Xn;exports.VoiceRing=oe;exports.acquireAnalyser=In;exports.getAudioContext=fn;exports.isAudioSupported=ss;exports.resolvePreset=$n;exports.useMicrophone=ee;
|