longpipe 0.0.6 → 0.0.7
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 +3 -2
- package/dist/index.cjs +17 -17
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +17 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,8 +77,9 @@ new EffectsPipeline(stream, { background: imageBitmap })
|
|
|
77
77
|
// video: URL, Blob, or <video> — looped, muted, decoded on the main thread
|
|
78
78
|
new EffectsPipeline(stream, { background: { video: 'https://example.com/bg.mp4' } })
|
|
79
79
|
|
|
80
|
-
// solid color
|
|
81
|
-
new EffectsPipeline(stream, { background: { color:
|
|
80
|
+
// solid color — hex string or [r, g, b] floats in [0, 1]
|
|
81
|
+
new EffectsPipeline(stream, { background: { color: '#00b050' } }) // greenscreen
|
|
82
|
+
new EffectsPipeline(stream, { background: { color: [0, 0.7, 0.3] } })
|
|
82
83
|
```
|
|
83
84
|
|
|
84
85
|
Swap at runtime:
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
'use strict';var w=[{model:"xxs",dtype:"f16",resolution:{w:128,h:72},skipFrames:3},{model:"xs",dtype:"f16",resolution:{w:192,h:108},skipFrames:1},{model:"small",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"compact",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:256,h:144},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:512,h:288},skipFrames:0}];var Q=false;function se(i){Q=i;}function _(i){let t=`[longpipe/${i}]`,e=((...r)=>{Q&&console.log(t,...r);});return e.warn=(...r)=>{Q&&console.warn(t,...r);},e}var k=_("adaptive"),it=2e3,at=1e4,st=30,ot=20,ut=5e3,pt=.3,lt=15e3,W=class{constructor(t){this.opts=t;this.currentPresetIdx=w.findIndex(e=>e.model===t.initialModel),this.lastSwapAt=performance.now();}opts;timer=null;currentPresetIdx;lastSwapAt=0;overshootStart=0;headroomStart=0;start(){k(`started; backend=${this.opts.backendKind} initial=${this.opts.initialModel} idx=${this.currentPresetIdx}`),this.timer=setInterval(()=>{this.tick().catch(t=>k("tick failed:",t));},it);}stop(){this.timer&&clearInterval(this.timer),this.timer=null;}async tick(){if(typeof document<"u"&&document.hidden)return;let t=performance.now();if(t-this.lastSwapAt<at)return;let e=await this.opts.getStats();if(e.fps<ot?(this.overshootStart===0&&(this.overshootStart=t),t-this.overshootStart>=ut&&this.tryDowngrade(e.fps)):this.overshootStart=0,this.opts.backendKind==="webgpu"&&e.modelMs>0){let r=1e3/st*pt;e.modelMs<r?(this.headroomStart===0&&(this.headroomStart=t),t-this.headroomStart>=lt&&this.tryUpgrade(e.modelMs,r)):this.headroomStart=0;}}tryDowngrade(t){if(this.currentPresetIdx<=0)return;let e=this.currentPresetIdx-1;k(`downgrade ${w[this.currentPresetIdx].model} \u2192 ${w[e].model} (fps=${t})`),this.swap(e);}tryUpgrade(t,e){if(this.currentPresetIdx>=w.length-1)return;let r=this.currentPresetIdx+1;k(`upgrade ${w[this.currentPresetIdx].model} \u2192 ${w[r].model} (modelMs=${t.toFixed(1)} < ${e.toFixed(1)})`),this.swap(r);}async swap(t){let e=w[t];this.lastSwapAt=performance.now(),this.overshootStart=0,this.headroomStart=0;try{let r=this.opts.buildWeightsUrl(this.opts.weightsBaseUrl,e.model),n=await fetch(r);if(!n.ok)throw new Error(`weights fetch failed: ${n.status} ${r}`);let a=await n.arrayBuffer();await this.opts.swapPreset(e.model,a),this.currentPresetIdx=t,k(`swap to ${e.model} done`);}catch(r){k("swap failed:",r),this.opts.onError?.({message:`adaptive preset swap failed: ${r.message??String(r)}`,source:"adaptive",recoverable:true,cause:r});}}};async function oe(i){let t,e=false;if(i instanceof HTMLVideoElement){if(t=i.currentSrc||i.src,!t)throw new Error("background video: HTMLVideoElement has no src")}else if(i instanceof Blob)t=URL.createObjectURL(i),e=true;else if(typeof i=="string")t=i;else throw new Error("background video: unsupported input shape");let r=document.createElement("video");r.crossOrigin="anonymous",r.muted=true,r.loop=true,r.playsInline=true,r.src=t,await new Promise((p,l)=>{r.addEventListener("loadeddata",()=>p(),{once:true}),r.addEventListener("error",()=>l(new Error(`background video: failed to load ${t}`)),{once:true});});try{await r.play();}catch(p){throw new Error(`background video: play() rejected \u2014 ${p.message}`)}let n=new MessageChannel,a=n.port1,s=n.port2,o=false,u=r.requestVideoFrameCallback?.bind(r);if(u){let p=(l,h)=>{if(!o){try{let g=new VideoFrame(r,{timestamp:h.mediaTime*1e6});a.postMessage({frame:g},[g]);}catch{}u(p);}};u(p);}else {let p=()=>{if(!o){try{let l=new VideoFrame(r,{timestamp:performance.now()*1e3});a.postMessage({frame:l},[l]);}catch{}requestAnimationFrame(p);}};requestAnimationFrame(p);}return {port:s,transferList:[s],cleanup:()=>{o=true,a.close(),r.pause(),r.removeAttribute("src"),r.load(),e&&URL.revokeObjectURL(t);}}}var Z=4,ee=8,ue=16;async function te(i){if(typeof i=="string")return i==="none"?{background:{kind:"none"}}:i==="blur"?{background:{kind:"blur",sigma:ee}}:{background:{kind:"image",bitmap:await le(i)}};if(i instanceof ImageBitmap)return {background:{kind:"image",bitmap:i}};if(typeof HTMLImageElement<"u"&&i instanceof HTMLImageElement)return {background:{kind:"image",bitmap:await createImageBitmap(i)}};if(typeof HTMLVideoElement<"u"&&i instanceof HTMLVideoElement)return await pe(i);let t=i;if(t.color)return {background:{kind:"color",rgb:t.color}};if(t.blur!==void 0)return {background:{kind:"blur",sigma:ct(t.blur)}};if(t.image!==void 0)return {background:{kind:"image",bitmap:await dt(t.image)}};if(t.video!==void 0)return await pe(t.video);throw new Error(`background: unrecognized input shape \u2014 ${P(i)}`)}async function pe(i){let t;if(typeof i=="string")t=i;else if(typeof HTMLVideoElement<"u"&&i instanceof HTMLVideoElement)t=i;else if(i&&typeof i=="object"&&"data"in i&&"type"in i)t=i.data instanceof Blob?i.data:new Blob([i.data],{type:i.type});else throw new Error(`background.video: unrecognized shape \u2014 ${P(i)}`);let e=await oe(t);return {background:{kind:"video",port:e.port},transferList:e.transferList,cleanup:e.cleanup}}function ct(i){if(i===true)return ee;if("sigma"in i){if(typeof i.sigma!="number"||!Number.isFinite(i.sigma)||i.sigma<0)throw new Error(`background.blur.sigma must be a non-negative number, got ${i.sigma}`);return i.sigma}if("strength"in i){let t=i.strength;if(typeof t=="number"){let e=Math.max(0,Math.min(1,t));return Z+(ue-Z)*e}if(t==="low")return Z;if(t==="medium")return ee;if(t==="high")return ue;throw new Error(`background.blur.strength must be 'low' | 'medium' | 'high' | number, got ${P(t)}`)}throw new Error(`background.blur: must be true, { strength }, or { sigma } \u2014 got ${P(i)}`)}async function dt(i){if(i instanceof ImageBitmap)return i;if(typeof HTMLImageElement<"u"&&i instanceof HTMLImageElement)return createImageBitmap(i);if(typeof i=="string")return le(i);if(i&&typeof i=="object"&&"data"in i&&"type"in i){let t=i.data instanceof Blob?i.data:new Blob([i.data],{type:i.type});return createImageBitmap(t)}throw new Error(`background.image: unrecognized shape \u2014 ${P(i)}`)}async function le(i){let t=await fetch(i);if(!t.ok)throw new Error(`background: failed to load image from ${i} (HTTP ${t.status})`);let e=await t.blob();return createImageBitmap(e)}function P(i){return i===null?"null":typeof i!="object"?typeof i+"("+String(i)+")":`${i.constructor?.name??"Object"} ${JSON.stringify(i).slice(0,80)}`}function ce(){return {input:"MediaStreamTrackProcessor"in self?"mstp":"rvfc-postmessage",output:"MediaStreamTrackGenerator"in self?"mstg":ht()?"transfer-capture":"bitmap-shuttle"}}var B=null;function ht(){return B!==null||(B=!/Firefox/.test(navigator.userAgent)),B}function de(i,t,e){let r=[i];return e==="passthrough"&&r.push(...t.getAudioTracks()),new MediaStream(r)}var G=_("worker_controller"),A=class{worker;listeners=new Map;persistentEvents=new Set;constructor(t){this.worker=t,this.worker.addEventListener("message",this.handleMessage.bind(this)),G("constructed; message listener attached");}handleMessage(t){let{request_id:e,res:r}=t.data,n=this.listeners.get(e);G("msg received: request_id=",e,"handler?",!!n,"persistent?",this.persistentEvents.has(e)),n&&(n(r),this.persistentEvents.has(e)||this.listeners.delete(e));}addPersistentListener(t,e){this.persistentEvents.add(t),this.listeners.set(t,e),G("addPersistentListener:",t);}removePersistentListener(t){this.persistentEvents.delete(t),this.listeners.delete(t);}sendMessage(t,e,r=[]){let n=crypto.randomUUID();return G("sendMessage:",t,"request_id=",n,"transferables=",r.length),new Promise(a=>{this.listeners.set(n,o=>a(o));let s={cmd:t,data:e,request_id:n};this.worker.postMessage(s,r);})}terminate(){this.worker.terminate(),this.listeners.clear(),this.persistentEvents.clear();}};var he=_("input-postmessage/main");function fe(i){let t=document.createElement("video");t.srcObject=i,t.muted=true,t.autoplay=true,t.playsInline=true,t.play().catch(c=>{he.warn("video.play() rejected:",c);});let e=t.requestVideoFrameCallback?.bind(t);if(!e)throw new Error("setupPostMessageInput: requestVideoFrameCallback not supported on this browser");let r=new MessageChannel,n=r.port1,a=r.port2,s=false,o=(c,p)=>{if(!s){try{let l=new VideoFrame(t,{timestamp:p.mediaTime*1e6});n.postMessage({frame:l},[l]);}catch(l){he.warn("VideoFrame() failed; skipping frame:",l);}e(o);}};return e(o),{port:a,transferList:[a],cleanup:()=>{s=true,n.close(),t.srcObject=null,t.pause();}}}function me(i){let t=i.getVideoTracks();if(t.length===0)throw new Error("setupMstpInput: input MediaStream has no video tracks");let e=t[0],r=self.MediaStreamTrackProcessor;if(!r)throw new Error("setupMstpInput: MediaStreamTrackProcessor not supported on this browser");let a=new r({track:e}).readable;return {readable:a,transferList:[a],cleanup:()=>{a.cancel().catch(()=>{});}}}function ge(i,t){switch(i){case "mstp":{let e=me(t);return {initFields:{inputReadable:e.readable},transferList:e.transferList,cleanup:e.cleanup}}case "rvfc-postmessage":{let e=fe(t);return {initFields:{inputPort:e.port},transferList:e.transferList,cleanup:e.cleanup}}}}var ft=_("bitmap-shuttle/main"),mt=30;function _e(i,t=mt){let e=document.createElement("canvas");e.width=i.w,e.height=i.h;let r=e.getContext("bitmaprenderer");if(!r)throw new Error("setupBitmapShuttleOutput: bitmaprenderer context not available");let a=e.captureStream(t).getVideoTracks();if(a.length===0)throw new Error("setupBitmapShuttleOutput: captureStream produced no video tracks");let s=a[0],o=new MessageChannel,u=o.port1,c=o.port2,p=false,l=null,h=()=>{},g=3,T=0;return u.onmessage=U=>{if(p){if(T++,T<g){U.data.bmp.close();return}h();}try{r.transferFromImageBitmap(U.data.bmp);}catch(m){ft.warn("transferFromImageBitmap failed:",m);}},u.start(),{videoTrack:s,port:c,transferList:[c],startPassthrough:U=>{if(p)return;p=true;let m=document.createElement("video");m.srcObject=U,m.muted=true,m.playsInline=true,m.play().catch(()=>{}),l=m;let S="requestVideoFrameCallback"in m?y=>{m.requestVideoFrameCallback(y);}:y=>{requestAnimationFrame(y);},E=()=>{if(p){if(m.videoWidth===0){S(E);return}createImageBitmap(m,{resizeWidth:e.width,resizeHeight:e.height,resizeQuality:"medium"}).then(y=>{if(!p){y.close();return}try{r.transferFromImageBitmap(y);}catch{}S(E);}).catch(()=>{S(E);});}};S(E),h=()=>{p=false,l&&(l.srcObject=null,l.pause(),l=null);};},cleanup:()=>{h(),u.onmessage=null,u.close(),s.stop();}}}function be(){let i=self.MediaStreamTrackGenerator;if(!i)throw new Error("setupMstgOutput: MediaStreamTrackGenerator not supported on this browser");let t=new i({kind:"video"}),e=t.writable;return {videoTrack:t,writable:e,transferList:[e],cleanup:()=>{e.abort().catch(()=>{}),t.stop();}}}function ve(i,t=30){let e=document.createElement("canvas");e.width=i.w,e.height=i.h;let n=e.captureStream(t).getVideoTracks();if(n.length===0)throw new Error("setupTransferCaptureOutput: captureStream produced no video tracks");let a=n[0],s=e.transferControlToOffscreen();return {videoTrack:a,canvas:s,transferList:[s],cleanup:()=>{a.stop();}}}function we(i,t){switch(i){case "mstg":{let e=be();return {videoTrack:e.videoTrack,initFields:{outputWritable:e.writable},transferList:e.transferList,cleanup:e.cleanup}}case "transfer-capture":{let e=ve(t);return {videoTrack:e.videoTrack,initFields:{outputCanvas:e.canvas},transferList:e.transferList,cleanup:e.cleanup}}case "bitmap-shuttle":{let e=_e(t);return {videoTrack:e.videoTrack,initFields:{outputPort:e.port},transferList:e.transferList,startPassthrough:e.startPassthrough,cleanup:e.cleanup}}}}var re=`var jt=Object.defineProperty;var Kt=(s,e,r)=>e in s?jt(s,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[e]=r;var n=(s,e,r)=>Kt(s,typeof e!="symbol"?e+"":e,r);var Ee=!1;function Ae(s){Ee=s}function P(s){let e=\`[longpipe/\${s}]\`,r=((...t)=>{Ee&&console.log(e,...t)});return r.warn=(...t)=>{Ee&&console.warn(e,...t)},r}var Ie=[{model:"xxs",dtype:"f16",resolution:{w:128,h:72},skipFrames:3},{model:"xs",dtype:"f16",resolution:{w:192,h:108},skipFrames:1},{model:"small",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"compact",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:256,h:144},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:512,h:288},skipFrames:0}],Yt={fast:1,balanced:4,quality:6};function V(s){return s==="auto"?null:Ie[Yt[s]]}var N=class{constructor(e,r,t,o){n(this,"op");this.op=e.ops.BilinearUpsample(r,{outH:t,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var z=class{constructor(e,r,t,o){n(this,"op");this.op=e.ops.BicubicUpsample(r,{outH:t,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var X=class{constructor(e,r,t,o){n(this,"presenter");this.presenter=e.presenters.CompositeSolid(r,t,o)}run(){this.presenter.run()}};var $=class{constructor(e,r,t,o){n(this,"presenter");this.presenter=e.presenters.CompositeImage(r,t,o)}run(){this.presenter.run()}};var q=class{constructor(e,r,t){n(this,"downs",[]);n(this,"ups",[]);let o=Qt(t),i=r;for(let a=0;a<o;a++){let u=e.ops.BilinearUpsample(i,{outH:Math.max(1,Math.floor(i.h/2)),outW:Math.max(1,Math.floor(i.w/2))});this.downs.push(u),i=u.output}for(let a=o-1;a>=1;a--){let u=this.downs[a-1].output,p=e.ops.BilinearUpsample(i,{outH:u.h,outW:u.w});this.ups.push(p),i=p.output}}get output(){return this.ups.length>0?this.ups[this.ups.length-1].output:this.downs[0].output}run(){for(let e of this.downs)e.run();for(let e of this.ups)e.run()}};function Qt(s){let e=Math.max(1,3*s);return Math.max(2,Math.min(6,Math.round(Math.log2(e))))}var j=class{constructor(e,r,t,o){n(this,"blur");n(this,"presenter");this.blur=new q(e,r,o),this.presenter=e.presenters.CompositeImageBilinear(r,t,this.blur.output)}run(){this.blur.run(),this.presenter.run()}};var K=class{constructor(e){n(this,"backend",e);n(this,"displayInput");n(this,"image");n(this,"passthroughCompositor");n(this,"network",null);n(this,"networkInput",null);n(this,"upscaler",null);n(this,"compositor",null);n(this,"upscalerMode","bilinear");n(this,"bgConfig",{mode:"solid",color:[0,0,0]});let r=e.canvas;this.displayInput=e.ops.Input(r.height,r.width),this.image=this.displayInput.output,this.passthroughCompositor=e.presenters.CompositePassthrough(this.image)}attachNetwork(e,r,t){this.network=e,this.networkInput=r,this.upscalerMode=t.upscaler,this.bgConfig=t.background,this.upscaler=this.makeUpscaler(),this.compositor=this.makeCompositor()}hasNetwork(){return this.network!==null}setSource(e){this.networkInput?.setSource(e),this.displayInput.setSource(e)}setUpscaler(e){e!==this.upscalerMode&&(this.upscalerMode=e,this.network&&(this.upscaler=this.makeUpscaler(),this.compositor=this.makeCompositor()))}setBackground(e){this.bgConfig=e,this.network&&(this.compositor=this.makeCompositor())}run(){this.runModel(),this.runDisplay()}runDisplay(){if(!this.compositor)throw new Error("RenderOp.runDisplay called before attachNetwork");this.displayInput.run(),this.compositor.run()}runPassthrough(){this.displayInput.run(),this.passthroughCompositor.run()}runModel(){if(!this.network||!this.networkInput||!this.upscaler)throw new Error("RenderOp.runModel called before attachNetwork");this.networkInput.run(),this.network.run(),this.upscaler.run()}makeUpscaler(){if(!this.network)throw new Error("makeUpscaler called with no network");let{backend:e,network:r,image:t}=this;return this.upscalerMode==="bicubic"?new z(e,r.output,t.h,t.w):new N(e,r.output,t.h,t.w)}makeCompositor(){if(!this.upscaler)throw new Error("makeCompositor called before upscaler exists");let{backend:e,image:r,upscaler:t,bgConfig:o}=this;switch(o.mode){case"solid":return new X(e,r,t.output,o.color);case"image":return new $(e,r,t.output,o.image);case"blur":return new j(e,r,t.output,o.sigma)}}};var Jt=s=>typeof s=="object"&&s!==null&&typeof s.offset=="number"&&typeof s.length=="number";function Fe(s){if(s.byteLength<4)throw new Error("weights buffer too small");let e=new DataView(s,0,4).getUint32(0,!0),r=4+e;if(s.byteLength<r)throw new Error("weights buffer truncated (header)");let t=new Uint8Array(s,4,e),o=JSON.parse(new TextDecoder().decode(t)),i=o.__dtype__??"f32",a=i==="f16"?2:4;if(r%a!==0)throw new Error(\`payload not \${a}-byte aligned (header=\${e})\`);let u=(s.byteLength-r)/a,p=l=>{if(Jt(l)){let{offset:d,length:m}=l;if(d+m>u)throw new Error(\`array ref out of range: offset=\${d} length=\${m}\`);let x=r+d*a;return i==="f16"?new Uint16Array(s,x,m):new Float32Array(s,x,m)}if(Array.isArray(l))return l.map(p);if(typeof l=="object"&&l!==null){let d={};for(let m of Object.keys(l))m!=="__dtype__"&&(d[m]=p(l[m]));return d}return l};return p(o)}var C=class{constructor(e,r,t,o){n(this,"inputs");n(this,"output");n(this,"dwOp");n(this,"pwOp");this.inputs=[r],this.dwOp=e.ops.DepthwiseConv2d(r,t.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.pwOp=e.ops.Conv2d(this.dwOp.output,t.pw,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.output=this.pwOp.output}run(){this.dwOp.run(),this.pwOp.run()}};var c=class{constructor(e,r,t,o){n(this,"inputs");n(this,"output");n(this,"expandOp");n(this,"dwOp");n(this,"projOp");n(this,"addOp");this.inputs=[r];let i=o.midChannels!==o.inChannels,a=o.stride===1&&o.inChannels===o.outChannels;this.expandOp=i?e.ops.Conv2d(r,t.expand,{outChannels:o.midChannels,kernel:1,stride:1,padding:0,activation:"relu6"}):null;let u=this.expandOp?this.expandOp.output:r;this.dwOp=e.ops.DepthwiseConv2d(u,t.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.projOp=e.ops.Conv2d(this.dwOp.output,t.proj,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.addOp=a?e.ops.Add(r,this.projOp.output):null,this.output=this.addOp?this.addOp.output:this.projOp.output}run(){this.expandOp?.run(),this.dwOp.run(),this.projOp.run(),this.addOp?.run()}};var y=class{constructor(e,r,t,o,i){n(this,"inputs");n(this,"output");n(this,"upConcatOp");n(this,"conv1Op");n(this,"conv2Op");this.inputs=[r,t],this.upConcatOp=e.ops.UpsampleConcat(r,t,{outH:t.h,outW:t.w}),this.conv1Op=e.ops.Conv2d(this.upConcatOp.output,o.conv1,{outChannels:i.outChannels,kernel:3,stride:1,padding:1,activation:"relu6"}),this.conv2Op=e.ops.Conv2d(this.conv1Op.output,o.conv2,{outChannels:i.outChannels,kernel:3,stride:1,padding:1,activation:"relu6"}),this.output=this.conv2Op.output}run(){this.upConcatOp.run(),this.conv1Op.run(),this.conv2Op.run()}};var W=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:64}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:32}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:16}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:16,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var E=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:64,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:32}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:16}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:8}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:8,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var k=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.bottleneck=e.ops.Conv2d(this.s4b2.output,t.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s2b1.output,t.decoder.blocks[0],{outChannels:64}),this.dec1=new y(e,this.dec0.output,this.s1b1.output,t.decoder.blocks[1],{outChannels:32}),this.finalUp=e.ops.UpsampleConv1x1(this.dec1.output,t.decoder.finalUpsample,{outH:this.dec1.output.h*2,outW:this.dec1.output.w*2,outChannels:32,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var I=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:256,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:128}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:64}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:32}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:32,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var Zt=5,er={xxs:k,xs:k,small:k,compact:E,medium:W,large:W,xl:I},Oe=1e3,Y=class{constructor(e){n(this,"canvas");n(this,"backend");n(this,"backendKind");n(this,"topology");n(this,"preset",null);n(this,"enabled");n(this,"currentBackground");n(this,"modelTimingCounter",0);n(this,"renderOp");n(this,"bgImageInput",null);n(this,"bgVideoInput",null);n(this,"bgVideoPort",null);n(this,"skipCounter",0);n(this,"framesRenderedAt",[]);n(this,"modelRunSamples",[]);n(this,"displayRunSamples",[]);n(this,"skippedCount",0);this.backend=e.backend,this.backendKind=e.backendKind,this.canvas=e.canvas,this.enabled=e.enabled,this.currentBackground=e.background,this.topology=e.topology,this.renderOp=new K(this.backend)}process(e){if(this.renderOp.setSource(e),!this.enabled||this.currentBackground.kind==="none"||!this.renderOp.hasNetwork()){this.renderOp.runPassthrough(),this.framesRenderedAt.push(performance.now()),this.trim(this.framesRenderedAt);return}if(this.shouldRunModel()){let t=performance.now();this.renderOp.runModel(),this.backendKind==="webgpu"&&this.modelTimingCounter%Zt===0&&this.backend.sync().then(()=>{this.modelRunSamples.push({ts:performance.now(),ms:performance.now()-t}),this.trimSamples(this.modelRunSamples)}).catch(()=>{}),this.modelTimingCounter++}else this.skippedCount++;let r=performance.now();this.renderOp.runDisplay(),this.displayRunSamples.push({ts:performance.now(),ms:performance.now()-r}),this.trimSamples(this.displayRunSamples),this.framesRenderedAt.push(performance.now()),this.trim(this.framesRenderedAt)}shouldRunModel(){return this.skipCounter===0?(this.skipCounter=this.preset?.skipFrames??0,!0):(this.skipCounter--,!1)}setBackground(e){this.currentBackground=e,this.renderOp.setBackground(this.translateBackground(e))}setEnabled(e){this.enabled=e}setPreset(e,r){let t=er[e.model];if(!t)throw new Error(\`renderer: model '\${e.model}' not implemented in src/model/networks/\`);let o=Fe(r),i=this.backend.ops.Input(e.resolution.h,e.resolution.w),a=new t(this.backend,i.output,o);this.renderOp.attachNetwork(a,i,{upscaler:"bilinear",background:this.translateBackground(this.currentBackground)}),this.preset=e,this.skipCounter=0}destroy(){this.bgVideoPort&&(this.bgVideoPort.close(),this.bgVideoPort=null),this.backend.destroy()}getStats(){let e=performance.now();return this.trimRecent(this.framesRenderedAt,e),this.trimSamplesAt(this.modelRunSamples,e),this.trimSamplesAt(this.displayRunSamples,e),{fps:this.framesRenderedAt.length,modelFps:this.modelRunSamples.length,modelMs:Me(this.modelRunSamples.map(r=>r.ms)),displayMs:Me(this.displayRunSamples.map(r=>r.ms)),skipped:this.skippedCount,preset:this.preset?.model??"boot",skipFrames:this.preset?.skipFrames??0,enabled:this.enabled,inputPath:this.topology.input,outputPath:this.topology.output}}translateBackground(e){switch(e.kind!=="video"&&this.bgVideoPort&&(this.bgVideoPort.close(),this.bgVideoPort=null),e.kind){case"none":return{mode:"solid",color:[0,0,0]};case"color":return{mode:"solid",color:e.rgb};case"blur":return{mode:"blur",sigma:e.sigma};case"image":return this.bgImageInput||(this.bgImageInput=this.backend.ops.Input(this.canvas.height,this.canvas.width)),this.bgImageInput.setSource(e.bitmap),this.bgImageInput.run(),{mode:"image",image:this.bgImageInput.output};case"video":{this.bgVideoInput||(this.bgVideoInput=this.backend.ops.Input(this.canvas.height,this.canvas.width)),this.bgVideoPort&&this.bgVideoPort.close(),this.bgVideoPort=e.port;let r=this.bgVideoInput;return e.port.onmessage=t=>{let o=t.data.frame;try{r.setSource(o),r.run()}finally{o.close()}},e.port.start?.(),{mode:"image",image:this.bgVideoInput.output}}}}trim(e){e.length>240&&e.splice(0,e.length-240)}trimSamples(e){e.length>240&&e.splice(0,e.length-240)}trimRecent(e,r){let t=r-Oe,o=0;for(;o<e.length&&e[o]<t;)o++;o>0&&e.splice(0,o)}trimSamplesAt(e,r){let t=r-Oe,o=0;for(;o<e.length&&e[o].ts<t;)o++;o>0&&e.splice(0,o)}};function Me(s){if(s.length===0)return 0;let e=s.slice().sort((t,o)=>t-o),r=e.length>>1;return e.length%2?e[r]:(e[r-1]+e[r])/2}var L=new Float32Array(1),D=new Uint32Array(L.buffer);function tr(s){L[0]=s;let e=D[0],r=e>>>16&32768,t=e&2147483647,o=(t>>>23)-127+15;if((e&2139095040)===2139095040)return(e&8388607)!==0?r|32256:r|31744;if(o>=31)return r|31744;if(o<=0){if(o<-10)return r;let l=t&8388607|8388608,d=14-o,m=l>>>d,x=l>>>d-1&1,T=(l&(1<<d-1)-1)!==0?1:0;return x&&(T||m&1)&&(m+=1),r|m}let i=t>>>13&1023,a=t>>>12&1,u=(t&4095)!==0?1:0,p=o<<10|i;return a&&(u||i&1)&&(p+=1,(p>>>10&31)===31)?r|31744:r|p}function rr(s){let e=(s&32768)<<16,r=(s&31744)>>>10,t=s&1023;if(r===0){if(t===0)return D[0]=e,L[0];let o=t,i=1;for(;(o&1024)===0;)o<<=1,i-=1;return o&=1023,D[0]=e|i+127-15<<23|o<<13,L[0]}return r===31?(D[0]=e|2139095040|t<<13,L[0]):(D[0]=e|r+127-15<<23|t<<13,L[0])}function Q(s){let e=new Uint16Array(s.length);for(let r=0;r<s.length;r++)e[r]=tr(s[r]);return e}function A(s){let e=new Float32Array(s.length);for(let r=0;r<s.length;r++)e[r]=rr(s[r]);return e}var h=class{constructor(e){n(this,"backend",e);n(this,"shader","");n(this,"pipeline");n(this,"bindGroup");n(this,"uniformDefs",[]);n(this,"uniformBuffers",{})}createUniform(e,r){this.uniformDefs.push({name:e,type:r})}setUniform(e,r){let t=this.backend.device.createBuffer({size:r.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});r instanceof Uint32Array?new Uint32Array(t.getMappedRange()).set(r):new Float32Array(t.getMappedRange()).set(r),t.unmap(),this.uniformBuffers[e]=t}defaultBindGroup(){let e=[],r=0;for(let t of this.inputs)e.push({binding:r++,resource:{buffer:t.buffer}});for(let t of this.weights)e.push({binding:r++,resource:{buffer:t.buffer}});for(let t of this.uniformDefs)e.push({binding:r++,resource:{buffer:this.uniformBuffers[t.name]}});return e.push({binding:r,resource:{buffer:this.output.buffer}}),this.backend.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:e})}defaultSetup(){let e=this.backend.device.createShaderModule({code:this.shader});this.pipeline=this.backend.device.createComputePipeline({layout:"auto",compute:{module:e,entryPoint:"main"}}),this.bindGroup=this.defaultBindGroup()}run(){let e=this.backend.device.createCommandEncoder(),r=e.beginComputePass();r.setPipeline(this.pipeline),r.setBindGroup(0,this.bindGroup),r.dispatchWorkgroups(...this.dispatch),r.end(),this.backend.device.queue.submit([e.finish()])}};var Re=\`// Conv2d compute shader \\u2014 handles all variants:
|
|
1
|
+
'use strict';var w=[{model:"xxs",dtype:"f16",resolution:{w:128,h:72},skipFrames:3},{model:"xs",dtype:"f16",resolution:{w:192,h:108},skipFrames:1},{model:"small",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"compact",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:256,h:144},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:512,h:288},skipFrames:0}];var Q=false;function se(n){Q=n;}function _(n){let t=`[longpipe/${n}]`,e=((...r)=>{Q&&console.log(t,...r);});return e.warn=(...r)=>{Q&&console.warn(t,...r);},e}var C=_("adaptive"),it=2e3,at=1e4,st=30,ot=20,ut=5e3,pt=.3,lt=15e3,W=class{constructor(t){this.opts=t;this.currentPresetIdx=w.findIndex(e=>e.model===t.initialModel),this.lastSwapAt=performance.now();}opts;timer=null;currentPresetIdx;lastSwapAt=0;overshootStart=0;headroomStart=0;start(){C(`started; backend=${this.opts.backendKind} initial=${this.opts.initialModel} idx=${this.currentPresetIdx}`),this.timer=setInterval(()=>{this.tick().catch(t=>C("tick failed:",t));},it);}stop(){this.timer&&clearInterval(this.timer),this.timer=null;}async tick(){if(typeof document<"u"&&document.hidden)return;let t=performance.now();if(t-this.lastSwapAt<at)return;let e=await this.opts.getStats();if(e.fps<ot?(this.overshootStart===0&&(this.overshootStart=t),t-this.overshootStart>=ut&&this.tryDowngrade(e.fps)):this.overshootStart=0,this.opts.backendKind==="webgpu"&&e.modelMs>0){let r=1e3/st*pt;e.modelMs<r?(this.headroomStart===0&&(this.headroomStart=t),t-this.headroomStart>=lt&&this.tryUpgrade(e.modelMs,r)):this.headroomStart=0;}}tryDowngrade(t){if(this.currentPresetIdx<=0)return;let e=this.currentPresetIdx-1;C(`downgrade ${w[this.currentPresetIdx].model} \u2192 ${w[e].model} (fps=${t})`),this.swap(e);}tryUpgrade(t,e){if(this.currentPresetIdx>=w.length-1)return;let r=this.currentPresetIdx+1;C(`upgrade ${w[this.currentPresetIdx].model} \u2192 ${w[r].model} (modelMs=${t.toFixed(1)} < ${e.toFixed(1)})`),this.swap(r);}async swap(t){let e=w[t];this.lastSwapAt=performance.now(),this.overshootStart=0,this.headroomStart=0;try{let r=this.opts.buildWeightsUrl(this.opts.weightsBaseUrl,e.model),i=await fetch(r);if(!i.ok)throw new Error(`weights fetch failed: ${i.status} ${r}`);let a=await i.arrayBuffer();await this.opts.swapPreset(e.model,a),this.currentPresetIdx=t,C(`swap to ${e.model} done`);}catch(r){C("swap failed:",r),this.opts.onError?.({message:`adaptive preset swap failed: ${r.message??String(r)}`,source:"adaptive",recoverable:true,cause:r});}}};async function oe(n){let t,e=false;if(n instanceof HTMLVideoElement){if(t=n.currentSrc||n.src,!t)throw new Error("background video: HTMLVideoElement has no src")}else if(n instanceof Blob)t=URL.createObjectURL(n),e=true;else if(typeof n=="string")t=n;else throw new Error("background video: unsupported input shape");let r=document.createElement("video");r.crossOrigin="anonymous",r.muted=true,r.loop=true,r.playsInline=true,r.src=t,await new Promise((p,l)=>{r.addEventListener("loadeddata",()=>p(),{once:true}),r.addEventListener("error",()=>l(new Error(`background video: failed to load ${t}`)),{once:true});});try{await r.play();}catch(p){throw new Error(`background video: play() rejected \u2014 ${p.message}`)}let i=new MessageChannel,a=i.port1,s=i.port2,o=false,u=r.requestVideoFrameCallback?.bind(r);if(u){let p=(l,h)=>{if(!o){try{let g=new VideoFrame(r,{timestamp:h.mediaTime*1e6});a.postMessage({frame:g},[g]);}catch{}u(p);}};u(p);}else {let p=()=>{if(!o){try{let l=new VideoFrame(r,{timestamp:performance.now()*1e3});a.postMessage({frame:l},[l]);}catch{}requestAnimationFrame(p);}};requestAnimationFrame(p);}return {port:s,transferList:[s],cleanup:()=>{o=true,a.close(),r.pause(),r.removeAttribute("src"),r.load(),e&&URL.revokeObjectURL(t);}}}var Z=4,ee=8,ue=16;async function te(n){if(typeof n=="string")return n==="none"?{background:{kind:"none"}}:n==="blur"?{background:{kind:"blur",sigma:ee}}:{background:{kind:"image",bitmap:await le(n)}};if(n instanceof ImageBitmap)return {background:{kind:"image",bitmap:n}};if(typeof HTMLImageElement<"u"&&n instanceof HTMLImageElement)return {background:{kind:"image",bitmap:await createImageBitmap(n)}};if(typeof HTMLVideoElement<"u"&&n instanceof HTMLVideoElement)return await pe(n);let t=n;if(t.color!==void 0)return {background:{kind:"color",rgb:ct(t.color)}};if(t.blur!==void 0)return {background:{kind:"blur",sigma:dt(t.blur)}};if(t.image!==void 0)return {background:{kind:"image",bitmap:await ht(t.image)}};if(t.video!==void 0)return await pe(t.video);throw new Error(`background: unrecognized input shape \u2014 ${y(n)}`)}async function pe(n){let t;if(typeof n=="string")t=n;else if(typeof HTMLVideoElement<"u"&&n instanceof HTMLVideoElement)t=n;else if(n&&typeof n=="object"&&"data"in n&&"type"in n)t=n.data instanceof Blob?n.data:new Blob([n.data],{type:n.type});else throw new Error(`background.video: unrecognized shape \u2014 ${y(n)}`);let e=await oe(t);return {background:{kind:"video",port:e.port},transferList:e.transferList,cleanup:e.cleanup}}function ct(n){if(typeof n=="string"){let t=n.trim().replace(/^#/,"");if(/^[0-9a-fA-F]{6}$/.test(t))return [parseInt(t.slice(0,2),16)/255,parseInt(t.slice(2,4),16)/255,parseInt(t.slice(4,6),16)/255];if(/^[0-9a-fA-F]{3}$/.test(t))return [parseInt(t[0]+t[0],16)/255,parseInt(t[1]+t[1],16)/255,parseInt(t[2]+t[2],16)/255];throw new Error(`background.color: hex must be #rgb or #rrggbb, got ${y(n)}`)}if(!Array.isArray(n)||n.length!==3||!n.every(t=>typeof t=="number"&&Number.isFinite(t)&&t>=0&&t<=1))throw new Error(`background.color: expected hex string or [r, g, b] floats in [0, 1], got ${y(n)}`);return [n[0],n[1],n[2]]}function dt(n){if(n===true)return ee;if("sigma"in n){if(typeof n.sigma!="number"||!Number.isFinite(n.sigma)||n.sigma<0)throw new Error(`background.blur.sigma must be a non-negative number, got ${n.sigma}`);return n.sigma}if("strength"in n){let t=n.strength;if(typeof t=="number"){let e=Math.max(0,Math.min(1,t));return Z+(ue-Z)*e}if(t==="low")return Z;if(t==="medium")return ee;if(t==="high")return ue;throw new Error(`background.blur.strength must be 'low' | 'medium' | 'high' | number, got ${y(t)}`)}throw new Error(`background.blur: must be true, { strength }, or { sigma } \u2014 got ${y(n)}`)}async function ht(n){if(n instanceof ImageBitmap)return n;if(typeof HTMLImageElement<"u"&&n instanceof HTMLImageElement)return createImageBitmap(n);if(typeof n=="string")return le(n);if(n&&typeof n=="object"&&"data"in n&&"type"in n){let t=n.data instanceof Blob?n.data:new Blob([n.data],{type:n.type});return createImageBitmap(t)}throw new Error(`background.image: unrecognized shape \u2014 ${y(n)}`)}async function le(n){let t=await fetch(n);if(!t.ok)throw new Error(`background: failed to load image from ${n} (HTTP ${t.status})`);let e=await t.blob();return createImageBitmap(e)}function y(n){return n===null?"null":typeof n!="object"?typeof n+"("+String(n)+")":`${n.constructor?.name??"Object"} ${JSON.stringify(n).slice(0,80)}`}function ce(){return {input:"MediaStreamTrackProcessor"in self?"mstp":"rvfc-postmessage",output:"MediaStreamTrackGenerator"in self?"mstg":ft()?"transfer-capture":"bitmap-shuttle"}}var B=null;function ft(){return B!==null||(B=!/Firefox/.test(navigator.userAgent)),B}function de(n,t,e){let r=[n];return e==="passthrough"&&r.push(...t.getAudioTracks()),new MediaStream(r)}var G=_("worker_controller"),A=class{worker;listeners=new Map;persistentEvents=new Set;constructor(t){this.worker=t,this.worker.addEventListener("message",this.handleMessage.bind(this)),G("constructed; message listener attached");}handleMessage(t){let{request_id:e,res:r}=t.data,i=this.listeners.get(e);G("msg received: request_id=",e,"handler?",!!i,"persistent?",this.persistentEvents.has(e)),i&&(i(r),this.persistentEvents.has(e)||this.listeners.delete(e));}addPersistentListener(t,e){this.persistentEvents.add(t),this.listeners.set(t,e),G("addPersistentListener:",t);}removePersistentListener(t){this.persistentEvents.delete(t),this.listeners.delete(t);}sendMessage(t,e,r=[]){let i=crypto.randomUUID();return G("sendMessage:",t,"request_id=",i,"transferables=",r.length),new Promise(a=>{this.listeners.set(i,o=>a(o));let s={cmd:t,data:e,request_id:i};this.worker.postMessage(s,r);})}terminate(){this.worker.terminate(),this.listeners.clear(),this.persistentEvents.clear();}};var he=_("input-postmessage/main");function fe(n){let t=document.createElement("video");t.srcObject=n,t.muted=true,t.autoplay=true,t.playsInline=true,t.play().catch(c=>{he.warn("video.play() rejected:",c);});let e=t.requestVideoFrameCallback?.bind(t);if(!e)throw new Error("setupPostMessageInput: requestVideoFrameCallback not supported on this browser");let r=new MessageChannel,i=r.port1,a=r.port2,s=false,o=(c,p)=>{if(!s){try{let l=new VideoFrame(t,{timestamp:p.mediaTime*1e6});i.postMessage({frame:l},[l]);}catch(l){he.warn("VideoFrame() failed; skipping frame:",l);}e(o);}};return e(o),{port:a,transferList:[a],cleanup:()=>{s=true,i.close(),t.srcObject=null,t.pause();}}}function me(n){let t=n.getVideoTracks();if(t.length===0)throw new Error("setupMstpInput: input MediaStream has no video tracks");let e=t[0],r=self.MediaStreamTrackProcessor;if(!r)throw new Error("setupMstpInput: MediaStreamTrackProcessor not supported on this browser");let a=new r({track:e}).readable;return {readable:a,transferList:[a],cleanup:()=>{a.cancel().catch(()=>{});}}}function ge(n,t){switch(n){case "mstp":{let e=me(t);return {initFields:{inputReadable:e.readable},transferList:e.transferList,cleanup:e.cleanup}}case "rvfc-postmessage":{let e=fe(t);return {initFields:{inputPort:e.port},transferList:e.transferList,cleanup:e.cleanup}}}}var mt=_("bitmap-shuttle/main"),gt=30;function _e(n,t=gt){let e=document.createElement("canvas");e.width=n.w,e.height=n.h;let r=e.getContext("bitmaprenderer");if(!r)throw new Error("setupBitmapShuttleOutput: bitmaprenderer context not available");let a=e.captureStream(t).getVideoTracks();if(a.length===0)throw new Error("setupBitmapShuttleOutput: captureStream produced no video tracks");let s=a[0],o=new MessageChannel,u=o.port1,c=o.port2,p=false,l=null,h=()=>{},g=3,T=0;return u.onmessage=U=>{if(p){if(T++,T<g){U.data.bmp.close();return}h();}try{r.transferFromImageBitmap(U.data.bmp);}catch(m){mt.warn("transferFromImageBitmap failed:",m);}},u.start(),{videoTrack:s,port:c,transferList:[c],startPassthrough:U=>{if(p)return;p=true;let m=document.createElement("video");m.srcObject=U,m.muted=true,m.playsInline=true,m.play().catch(()=>{}),l=m;let S="requestVideoFrameCallback"in m?k=>{m.requestVideoFrameCallback(k);}:k=>{requestAnimationFrame(k);},E=()=>{if(p){if(m.videoWidth===0){S(E);return}createImageBitmap(m,{resizeWidth:e.width,resizeHeight:e.height,resizeQuality:"medium"}).then(k=>{if(!p){k.close();return}try{r.transferFromImageBitmap(k);}catch{}S(E);}).catch(()=>{S(E);});}};S(E),h=()=>{p=false,l&&(l.srcObject=null,l.pause(),l=null);};},cleanup:()=>{h(),u.onmessage=null,u.close(),s.stop();}}}function be(){let n=self.MediaStreamTrackGenerator;if(!n)throw new Error("setupMstgOutput: MediaStreamTrackGenerator not supported on this browser");let t=new n({kind:"video"}),e=t.writable;return {videoTrack:t,writable:e,transferList:[e],cleanup:()=>{e.abort().catch(()=>{}),t.stop();}}}function ve(n,t=30){let e=document.createElement("canvas");e.width=n.w,e.height=n.h;let i=e.captureStream(t).getVideoTracks();if(i.length===0)throw new Error("setupTransferCaptureOutput: captureStream produced no video tracks");let a=i[0],s=e.transferControlToOffscreen();return {videoTrack:a,canvas:s,transferList:[s],cleanup:()=>{a.stop();}}}function we(n,t){switch(n){case "mstg":{let e=be();return {videoTrack:e.videoTrack,initFields:{outputWritable:e.writable},transferList:e.transferList,cleanup:e.cleanup}}case "transfer-capture":{let e=ve(t);return {videoTrack:e.videoTrack,initFields:{outputCanvas:e.canvas},transferList:e.transferList,cleanup:e.cleanup}}case "bitmap-shuttle":{let e=_e(t);return {videoTrack:e.videoTrack,initFields:{outputPort:e.port},transferList:e.transferList,startPassthrough:e.startPassthrough,cleanup:e.cleanup}}}}var re=`var jt=Object.defineProperty;var Kt=(s,e,r)=>e in s?jt(s,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[e]=r;var n=(s,e,r)=>Kt(s,typeof e!="symbol"?e+"":e,r);var Ee=!1;function Ae(s){Ee=s}function P(s){let e=\`[longpipe/\${s}]\`,r=((...t)=>{Ee&&console.log(e,...t)});return r.warn=(...t)=>{Ee&&console.warn(e,...t)},r}var Ie=[{model:"xxs",dtype:"f16",resolution:{w:128,h:72},skipFrames:3},{model:"xs",dtype:"f16",resolution:{w:192,h:108},skipFrames:1},{model:"small",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"compact",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:256,h:144},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:512,h:288},skipFrames:0}],Yt={fast:1,balanced:4,quality:6};function V(s){return s==="auto"?null:Ie[Yt[s]]}var N=class{constructor(e,r,t,o){n(this,"op");this.op=e.ops.BilinearUpsample(r,{outH:t,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var z=class{constructor(e,r,t,o){n(this,"op");this.op=e.ops.BicubicUpsample(r,{outH:t,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var X=class{constructor(e,r,t,o){n(this,"presenter");this.presenter=e.presenters.CompositeSolid(r,t,o)}run(){this.presenter.run()}};var $=class{constructor(e,r,t,o){n(this,"presenter");this.presenter=e.presenters.CompositeImage(r,t,o)}run(){this.presenter.run()}};var q=class{constructor(e,r,t){n(this,"downs",[]);n(this,"ups",[]);let o=Qt(t),i=r;for(let a=0;a<o;a++){let u=e.ops.BilinearUpsample(i,{outH:Math.max(1,Math.floor(i.h/2)),outW:Math.max(1,Math.floor(i.w/2))});this.downs.push(u),i=u.output}for(let a=o-1;a>=1;a--){let u=this.downs[a-1].output,p=e.ops.BilinearUpsample(i,{outH:u.h,outW:u.w});this.ups.push(p),i=p.output}}get output(){return this.ups.length>0?this.ups[this.ups.length-1].output:this.downs[0].output}run(){for(let e of this.downs)e.run();for(let e of this.ups)e.run()}};function Qt(s){let e=Math.max(1,3*s);return Math.max(2,Math.min(6,Math.round(Math.log2(e))))}var j=class{constructor(e,r,t,o){n(this,"blur");n(this,"presenter");this.blur=new q(e,r,o),this.presenter=e.presenters.CompositeImageBilinear(r,t,this.blur.output)}run(){this.blur.run(),this.presenter.run()}};var K=class{constructor(e){n(this,"backend",e);n(this,"displayInput");n(this,"image");n(this,"passthroughCompositor");n(this,"network",null);n(this,"networkInput",null);n(this,"upscaler",null);n(this,"compositor",null);n(this,"upscalerMode","bilinear");n(this,"bgConfig",{mode:"solid",color:[0,0,0]});let r=e.canvas;this.displayInput=e.ops.Input(r.height,r.width),this.image=this.displayInput.output,this.passthroughCompositor=e.presenters.CompositePassthrough(this.image)}attachNetwork(e,r,t){this.network=e,this.networkInput=r,this.upscalerMode=t.upscaler,this.bgConfig=t.background,this.upscaler=this.makeUpscaler(),this.compositor=this.makeCompositor()}hasNetwork(){return this.network!==null}setSource(e){this.networkInput?.setSource(e),this.displayInput.setSource(e)}setUpscaler(e){e!==this.upscalerMode&&(this.upscalerMode=e,this.network&&(this.upscaler=this.makeUpscaler(),this.compositor=this.makeCompositor()))}setBackground(e){this.bgConfig=e,this.network&&(this.compositor=this.makeCompositor())}run(){this.runModel(),this.runDisplay()}runDisplay(){if(!this.compositor)throw new Error("RenderOp.runDisplay called before attachNetwork");this.displayInput.run(),this.compositor.run()}runPassthrough(){this.displayInput.run(),this.passthroughCompositor.run()}runModel(){if(!this.network||!this.networkInput||!this.upscaler)throw new Error("RenderOp.runModel called before attachNetwork");this.networkInput.run(),this.network.run(),this.upscaler.run()}makeUpscaler(){if(!this.network)throw new Error("makeUpscaler called with no network");let{backend:e,network:r,image:t}=this;return this.upscalerMode==="bicubic"?new z(e,r.output,t.h,t.w):new N(e,r.output,t.h,t.w)}makeCompositor(){if(!this.upscaler)throw new Error("makeCompositor called before upscaler exists");let{backend:e,image:r,upscaler:t,bgConfig:o}=this;switch(o.mode){case"solid":return new X(e,r,t.output,o.color);case"image":return new $(e,r,t.output,o.image);case"blur":return new j(e,r,t.output,o.sigma)}}};var Jt=s=>typeof s=="object"&&s!==null&&typeof s.offset=="number"&&typeof s.length=="number";function Fe(s){if(s.byteLength<4)throw new Error("weights buffer too small");let e=new DataView(s,0,4).getUint32(0,!0),r=4+e;if(s.byteLength<r)throw new Error("weights buffer truncated (header)");let t=new Uint8Array(s,4,e),o=JSON.parse(new TextDecoder().decode(t)),i=o.__dtype__??"f32",a=i==="f16"?2:4;if(r%a!==0)throw new Error(\`payload not \${a}-byte aligned (header=\${e})\`);let u=(s.byteLength-r)/a,p=l=>{if(Jt(l)){let{offset:d,length:m}=l;if(d+m>u)throw new Error(\`array ref out of range: offset=\${d} length=\${m}\`);let x=r+d*a;return i==="f16"?new Uint16Array(s,x,m):new Float32Array(s,x,m)}if(Array.isArray(l))return l.map(p);if(typeof l=="object"&&l!==null){let d={};for(let m of Object.keys(l))m!=="__dtype__"&&(d[m]=p(l[m]));return d}return l};return p(o)}var C=class{constructor(e,r,t,o){n(this,"inputs");n(this,"output");n(this,"dwOp");n(this,"pwOp");this.inputs=[r],this.dwOp=e.ops.DepthwiseConv2d(r,t.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.pwOp=e.ops.Conv2d(this.dwOp.output,t.pw,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.output=this.pwOp.output}run(){this.dwOp.run(),this.pwOp.run()}};var c=class{constructor(e,r,t,o){n(this,"inputs");n(this,"output");n(this,"expandOp");n(this,"dwOp");n(this,"projOp");n(this,"addOp");this.inputs=[r];let i=o.midChannels!==o.inChannels,a=o.stride===1&&o.inChannels===o.outChannels;this.expandOp=i?e.ops.Conv2d(r,t.expand,{outChannels:o.midChannels,kernel:1,stride:1,padding:0,activation:"relu6"}):null;let u=this.expandOp?this.expandOp.output:r;this.dwOp=e.ops.DepthwiseConv2d(u,t.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.projOp=e.ops.Conv2d(this.dwOp.output,t.proj,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.addOp=a?e.ops.Add(r,this.projOp.output):null,this.output=this.addOp?this.addOp.output:this.projOp.output}run(){this.expandOp?.run(),this.dwOp.run(),this.projOp.run(),this.addOp?.run()}};var y=class{constructor(e,r,t,o,i){n(this,"inputs");n(this,"output");n(this,"upConcatOp");n(this,"conv1Op");n(this,"conv2Op");this.inputs=[r,t],this.upConcatOp=e.ops.UpsampleConcat(r,t,{outH:t.h,outW:t.w}),this.conv1Op=e.ops.Conv2d(this.upConcatOp.output,o.conv1,{outChannels:i.outChannels,kernel:3,stride:1,padding:1,activation:"relu6"}),this.conv2Op=e.ops.Conv2d(this.conv1Op.output,o.conv2,{outChannels:i.outChannels,kernel:3,stride:1,padding:1,activation:"relu6"}),this.output=this.conv2Op.output}run(){this.upConcatOp.run(),this.conv1Op.run(),this.conv2Op.run()}};var W=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:64}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:32}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:16}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:16,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var E=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:64,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:32}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:16}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:8}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:8,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var k=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.bottleneck=e.ops.Conv2d(this.s4b2.output,t.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s2b1.output,t.decoder.blocks[0],{outChannels:64}),this.dec1=new y(e,this.dec0.output,this.s1b1.output,t.decoder.blocks[1],{outChannels:32}),this.finalUp=e.ops.UpsampleConv1x1(this.dec1.output,t.decoder.finalUpsample,{outH:this.dec1.output.h*2,outW:this.dec1.output.w*2,outChannels:32,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var I=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:256,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:128}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:64}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:32}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:32,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var Zt=5,er={xxs:k,xs:k,small:k,compact:E,medium:W,large:W,xl:I},Oe=1e3,Y=class{constructor(e){n(this,"canvas");n(this,"backend");n(this,"backendKind");n(this,"topology");n(this,"preset",null);n(this,"enabled");n(this,"currentBackground");n(this,"modelTimingCounter",0);n(this,"renderOp");n(this,"bgImageInput",null);n(this,"bgVideoInput",null);n(this,"bgVideoPort",null);n(this,"skipCounter",0);n(this,"framesRenderedAt",[]);n(this,"modelRunSamples",[]);n(this,"displayRunSamples",[]);n(this,"skippedCount",0);this.backend=e.backend,this.backendKind=e.backendKind,this.canvas=e.canvas,this.enabled=e.enabled,this.currentBackground=e.background,this.topology=e.topology,this.renderOp=new K(this.backend)}process(e){if(this.renderOp.setSource(e),!this.enabled||this.currentBackground.kind==="none"||!this.renderOp.hasNetwork()){this.renderOp.runPassthrough(),this.framesRenderedAt.push(performance.now()),this.trim(this.framesRenderedAt);return}if(this.shouldRunModel()){let t=performance.now();this.renderOp.runModel(),this.backendKind==="webgpu"&&this.modelTimingCounter%Zt===0&&this.backend.sync().then(()=>{this.modelRunSamples.push({ts:performance.now(),ms:performance.now()-t}),this.trimSamples(this.modelRunSamples)}).catch(()=>{}),this.modelTimingCounter++}else this.skippedCount++;let r=performance.now();this.renderOp.runDisplay(),this.displayRunSamples.push({ts:performance.now(),ms:performance.now()-r}),this.trimSamples(this.displayRunSamples),this.framesRenderedAt.push(performance.now()),this.trim(this.framesRenderedAt)}shouldRunModel(){return this.skipCounter===0?(this.skipCounter=this.preset?.skipFrames??0,!0):(this.skipCounter--,!1)}setBackground(e){this.currentBackground=e,this.renderOp.setBackground(this.translateBackground(e))}setEnabled(e){this.enabled=e}setPreset(e,r){let t=er[e.model];if(!t)throw new Error(\`renderer: model '\${e.model}' not implemented in src/model/networks/\`);let o=Fe(r),i=this.backend.ops.Input(e.resolution.h,e.resolution.w),a=new t(this.backend,i.output,o);this.renderOp.attachNetwork(a,i,{upscaler:"bilinear",background:this.translateBackground(this.currentBackground)}),this.preset=e,this.skipCounter=0}destroy(){this.bgVideoPort&&(this.bgVideoPort.close(),this.bgVideoPort=null),this.backend.destroy()}getStats(){let e=performance.now();return this.trimRecent(this.framesRenderedAt,e),this.trimSamplesAt(this.modelRunSamples,e),this.trimSamplesAt(this.displayRunSamples,e),{fps:this.framesRenderedAt.length,modelFps:this.modelRunSamples.length,modelMs:Me(this.modelRunSamples.map(r=>r.ms)),displayMs:Me(this.displayRunSamples.map(r=>r.ms)),skipped:this.skippedCount,preset:this.preset?.model??"boot",skipFrames:this.preset?.skipFrames??0,enabled:this.enabled,inputPath:this.topology.input,outputPath:this.topology.output}}translateBackground(e){switch(e.kind!=="video"&&this.bgVideoPort&&(this.bgVideoPort.close(),this.bgVideoPort=null),e.kind){case"none":return{mode:"solid",color:[0,0,0]};case"color":return{mode:"solid",color:e.rgb};case"blur":return{mode:"blur",sigma:e.sigma};case"image":return this.bgImageInput||(this.bgImageInput=this.backend.ops.Input(this.canvas.height,this.canvas.width)),this.bgImageInput.setSource(e.bitmap),this.bgImageInput.run(),{mode:"image",image:this.bgImageInput.output};case"video":{this.bgVideoInput||(this.bgVideoInput=this.backend.ops.Input(this.canvas.height,this.canvas.width)),this.bgVideoPort&&this.bgVideoPort.close(),this.bgVideoPort=e.port;let r=this.bgVideoInput;return e.port.onmessage=t=>{let o=t.data.frame;try{r.setSource(o),r.run()}finally{o.close()}},e.port.start?.(),{mode:"image",image:this.bgVideoInput.output}}}}trim(e){e.length>240&&e.splice(0,e.length-240)}trimSamples(e){e.length>240&&e.splice(0,e.length-240)}trimRecent(e,r){let t=r-Oe,o=0;for(;o<e.length&&e[o]<t;)o++;o>0&&e.splice(0,o)}trimSamplesAt(e,r){let t=r-Oe,o=0;for(;o<e.length&&e[o].ts<t;)o++;o>0&&e.splice(0,o)}};function Me(s){if(s.length===0)return 0;let e=s.slice().sort((t,o)=>t-o),r=e.length>>1;return e.length%2?e[r]:(e[r-1]+e[r])/2}var L=new Float32Array(1),D=new Uint32Array(L.buffer);function tr(s){L[0]=s;let e=D[0],r=e>>>16&32768,t=e&2147483647,o=(t>>>23)-127+15;if((e&2139095040)===2139095040)return(e&8388607)!==0?r|32256:r|31744;if(o>=31)return r|31744;if(o<=0){if(o<-10)return r;let l=t&8388607|8388608,d=14-o,m=l>>>d,x=l>>>d-1&1,T=(l&(1<<d-1)-1)!==0?1:0;return x&&(T||m&1)&&(m+=1),r|m}let i=t>>>13&1023,a=t>>>12&1,u=(t&4095)!==0?1:0,p=o<<10|i;return a&&(u||i&1)&&(p+=1,(p>>>10&31)===31)?r|31744:r|p}function rr(s){let e=(s&32768)<<16,r=(s&31744)>>>10,t=s&1023;if(r===0){if(t===0)return D[0]=e,L[0];let o=t,i=1;for(;(o&1024)===0;)o<<=1,i-=1;return o&=1023,D[0]=e|i+127-15<<23|o<<13,L[0]}return r===31?(D[0]=e|2139095040|t<<13,L[0]):(D[0]=e|r+127-15<<23|t<<13,L[0])}function Q(s){let e=new Uint16Array(s.length);for(let r=0;r<s.length;r++)e[r]=tr(s[r]);return e}function A(s){let e=new Float32Array(s.length);for(let r=0;r<s.length;r++)e[r]=rr(s[r]);return e}var h=class{constructor(e){n(this,"backend",e);n(this,"shader","");n(this,"pipeline");n(this,"bindGroup");n(this,"uniformDefs",[]);n(this,"uniformBuffers",{})}createUniform(e,r){this.uniformDefs.push({name:e,type:r})}setUniform(e,r){let t=this.backend.device.createBuffer({size:r.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});r instanceof Uint32Array?new Uint32Array(t.getMappedRange()).set(r):new Float32Array(t.getMappedRange()).set(r),t.unmap(),this.uniformBuffers[e]=t}defaultBindGroup(){let e=[],r=0;for(let t of this.inputs)e.push({binding:r++,resource:{buffer:t.buffer}});for(let t of this.weights)e.push({binding:r++,resource:{buffer:t.buffer}});for(let t of this.uniformDefs)e.push({binding:r++,resource:{buffer:this.uniformBuffers[t.name]}});return e.push({binding:r,resource:{buffer:this.output.buffer}}),this.backend.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:e})}defaultSetup(){let e=this.backend.device.createShaderModule({code:this.shader});this.pipeline=this.backend.device.createComputePipeline({layout:"auto",compute:{module:e,entryPoint:"main"}}),this.bindGroup=this.defaultBindGroup()}run(){let e=this.backend.device.createCommandEncoder(),r=e.beginComputePass();r.setPipeline(this.pipeline),r.setBindGroup(0,this.bindGroup),r.dispatchWorkgroups(...this.dispatch),r.end(),this.backend.device.queue.submit([e.finish()])}};var Re=\`// Conv2d compute shader \\u2014 handles all variants:
|
|
2
2
|
// 1\\xD71 (pointwise), 3\\xD73, 5\\xD75, strided, BN-fused
|
|
3
3
|
//
|
|
4
4
|
// Tensor layout: NHWC with channels in vec4 groups
|
|
@@ -2460,7 +2460,7 @@ const vec2 VERTS[6] = vec2[6](
|
|
|
2460
2460
|
vec2(-1.0,1.0), vec2(1.0,-1.0), vec2(1.0,1.0)
|
|
2461
2461
|
);
|
|
2462
2462
|
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,Be=class{constructor(e,r,t){n(this,"backend",e);n(this,"output");n(this,"gl");n(this,"program");n(this,"srcTex");n(this,"uOutW");n(this,"uOutH");n(this,"uSrc");n(this,"source",null);let o=e.gl;this.gl=o,this.output=e.tensor(r,t,4),this.srcTex=o.createTexture(),o.bindTexture(o.TEXTURE_2D,this.srcTex),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MIN_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MAG_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_S,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_T,o.CLAMP_TO_EDGE);let i=o.createShader(o.VERTEX_SHADER);o.shaderSource(i,ao),o.compileShader(i);let a=o.createShader(o.FRAGMENT_SHADER);if(o.shaderSource(a,Lt),o.compileShader(a),!o.getShaderParameter(a,o.COMPILE_STATUS))throw new Error(\`Input GLSL compile error: \${o.getShaderInfoLog(a)}\`);if(this.program=o.createProgram(),o.attachShader(this.program,i),o.attachShader(this.program,a),o.linkProgram(this.program),!o.getProgramParameter(this.program,o.LINK_STATUS))throw new Error(\`Input GLSL link error: \${o.getProgramInfoLog(this.program)}\`);this.uSrc=o.getUniformLocation(this.program,"u_src"),this.uOutW=o.getUniformLocation(this.program,"u_out_w"),this.uOutH=o.getUniformLocation(this.program,"u_out_h")}setSource(e){this.source=e}run(){if(!this.source)throw new Error("InputWebGL.run() called before setSource()");let e=this.gl;e.bindTexture(e.TEXTURE_2D,this.srcTex),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,this.source),e.useProgram(this.program),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.srcTex),e.uniform1i(this.uSrc,0),e.uniform1i(this.uOutW,this.output.w),e.uniform1i(this.uOutH,this.output.h),e.bindFramebuffer(e.FRAMEBUFFER,this.backend.fbo),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.output.texture,0),e.viewport(0,0,this.output.texW,this.output.texH),e.bindVertexArray(null),e.drawArrays(e.TRIANGLES,0,6)}};var U=class s{constructor(e,r,t){n(this,"gl",e);n(this,"canvas",r);n(this,"dtype",t);n(this,"ops");n(this,"presenters");n(this,"fbo");n(this,"textureFormat");this.fbo=e.createFramebuffer(),this.textureFormat=t==="f16"?{internalFormat:e.RGBA16F,format:e.RGBA,type:e.HALF_FLOAT,bytesPerElement:2}:{internalFormat:e.RGBA32F,format:e.RGBA,type:e.FLOAT,bytesPerElement:4},this.ops={Conv2d:(o,i,a)=>new he(this,o,i,a),DepthwiseConv2d:(o,i,a)=>new fe(this,o,i,a),Add:(o,i)=>new ge(this,o,i),Sigmoid:o=>new _e(this,o),BilinearUpsample:(o,i)=>new be(this,o,i),BicubicUpsample:(o,i)=>new ve(this,o,i),ChannelConcat:(o,i)=>new ye(this,o,i),Conv2dAdd:(o,i,a,u)=>new ke(this,o,i,a,u),UpsampleConcat:(o,i,a)=>new we(this,o,i,a),UpsampleConv1x1:(o,i,a)=>new Ce(this,o,i,a),UpsampleSigmoid:(o,i)=>new xe(this,o,i),Input:(o,i)=>new Be(this,o,i)},this.presenters={CompositeSolid:(o,i,a)=>new Te(this,o,i,a),CompositeImage:(o,i,a)=>new Pe(this,o,i,a),CompositeImageBilinear:(o,i,a)=>new We(this,o,i,a),CompositePassthrough:o=>new Ge(this,o)}}static isAvailable(){let e=null;try{return e=new OffscreenCanvas(1,1).getContext("webgl2"),!(!e||!e.getExtension("EXT_color_buffer_float"))}catch{return!1}finally{e?.getExtension("WEBGL_lose_context")?.loseContext()}}static create(e){let r=e.canvas.getContext("webgl2");if(!r)throw new Error("WebGL2 not available");if(!r.getExtension("EXT_color_buffer_float"))throw new Error("EXT_color_buffer_float not available");return new s(r,e.canvas,e.dtype??"f32")}bindDisplayFramebuffer(){this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.viewport(0,0,this.canvas.width,this.canvas.height)}toTextureView(e){if(e===null)return null;let r=this.dtype==="f16",t=e instanceof Uint16Array;return r===t?e:r?Q(e):A(e)}tensor(e,r,t,o){let i=r*(t/4),a=e,u=this.gl,p=u.createTexture(),l=this.textureFormat,d=this.toTextureView(o??null);return u.bindTexture(u.TEXTURE_2D,p),u.texImage2D(u.TEXTURE_2D,0,l.internalFormat,i,a,0,l.format,l.type,d),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_MIN_FILTER,u.NEAREST),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_MAG_FILTER,u.NEAREST),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_WRAP_S,u.CLAMP_TO_EDGE),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_WRAP_T,u.CLAMP_TO_EDGE),{h:e,w:r,c:t,texture:p,texW:i,texH:a}}upload(e){return{data:e}}async readback(e){let r=this.gl,t=this.textureFormat;if(r.bindFramebuffer(r.FRAMEBUFFER,this.fbo),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,e.texture,0),this.dtype==="f16"){let i=new Uint16Array(e.texW*e.texH*4);return r.readPixels(0,0,e.texW,e.texH,t.format,r.HALF_FLOAT,i),r.bindFramebuffer(r.FRAMEBUFFER,null),A(i)}let o=new Float32Array(e.texW*e.texH*4);return r.readPixels(0,0,e.texW,e.texH,t.format,r.FLOAT,o),r.bindFramebuffer(r.FRAMEBUFFER,null),o}async sync(){let e=this.gl,r=e.fenceSync(e.SYNC_GPU_COMMANDS_COMPLETE,0);if(!r){e.finish();return}for(e.flush();;){let t=e.clientWaitSync(r,0,0);if(t===e.ALREADY_SIGNALED||t===e.CONDITION_SATISFIED){e.deleteSync(r);return}if(t===e.WAIT_FAILED)throw e.deleteSync(r),new Error("WebGLBackend.sync: clientWaitSync returned WAIT_FAILED");await new Promise(o=>setTimeout(o,1))}}destroy(){this.gl.deleteFramebuffer(this.fbo),this.gl.getExtension("WEBGL_lose_context")?.loseContext()}};var Le=P("setup_backend");async function At(s,e,r={}){let t=s.backend==="webgpu"||s.backend==="auto",o=!!s.outputCanvas,i=()=>s.outputCanvas??new OffscreenCanvas(e.w,e.h),a=null;if(t&&await F.isAvailable()){let p=s.dtype==="f16"&&!await F.hasF16Support()?"f32":s.dtype,l=i();try{let d=await F.create({canvas:l,dtype:p});return d.device.lost.then(m=>{m.reason!=="destroyed"&&r.onContextLost?.({message:\`WebGPU device lost: \${m.reason}\${m.message?" \\u2014 "+m.message:""}\`,source:"backend-lost",recoverable:!1,cause:m})}).catch(()=>{}),{backend:d,resolvedBackend:"webgpu",resolvedDtype:p,canvas:l}}catch(d){Le.warn("WebGPU isAvailable but create() threw; trying WebGL fallback:",d),a=d,o&&Le.warn("transfer-capture topology: WebGL fallback may also fail on the same canvas")}}if(U.isAvailable()){let p=i();try{let l=U.create({canvas:p,dtype:s.dtype});return p.addEventListener("webglcontextlost",d=>{r.onContextLost?.({message:"WebGL context lost",source:"backend-lost",recoverable:!1,cause:d})}),{backend:l,resolvedBackend:"webgl",resolvedDtype:s.dtype,canvas:p}}catch(l){Le.warn("WebGL create() threw:",l),a=l}}let u=a?\` (last error: \${a.message??a})\`:"";throw new Error(\`setup_backend: no usable GPU backend\${u}\`)}var Ue=.5,uo=3,Ft=10,po=30,S=P("autotune"),Ot={xxs:k,xs:k,small:k,compact:E,medium:W,large:W,xl:I};async function Mt(s,e=po){s instanceof U&&(Ue=Ue*.5);let r=1e3/e*Ue;S(\`start; budget per source frame: \${r.toFixed(1)}ms (source \${e}fps \\xD7 \${Ue} safety)\`),S("backend dtype:",s.dtype);let t=null;for(let o of Ie){if(!Ot[o.model]){S("skip",o.model,"(network class not implemented in TS yet)");continue}try{S(\`bench \${o.model} @ \${o.resolution.w}\\xD7\${o.resolution.h} skipFrames=\${o.skipFrames} \\u2026\`);let i=await mo(s,o),a=i<=r;if(S(\` \${o.model}: \${i.toFixed(1)}ms / source frame \${a?"\\u2713 within budget":"\\u2717 over budget"}\`),(a||t===null)&&(t=o),!a)break}catch(i){S(" bench failed for",o.model,":",i);break}}if(!t)throw new Error("autotune: no implementable preset available");return S("picked",t.model),t}function lo(s){let e=Object.create(s);return e.ops={...s.ops,Conv2d:(r,t,o)=>{let i={weights:new Float32Array(o.kernel*o.kernel*r.c*o.outChannels),bias:new Float32Array(o.outChannels)};return s.ops.Conv2d(r,i,o)},DepthwiseConv2d:(r,t,o)=>{let i={weights:new Float32Array(o.kernel*o.kernel*r.c),bias:new Float32Array(r.c)};return s.ops.DepthwiseConv2d(r,i,o)},Conv2dAdd:(r,t,o,i)=>{let a={weights:new Float32Array(i.kernel*i.kernel*r.c*i.outChannels),bias:new Float32Array(i.outChannels)};return s.ops.Conv2dAdd(r,t,a,i)},UpsampleConv1x1:(r,t,o)=>{let i={weights:new Float32Array(r.c*o.outChannels),bias:new Float32Array(o.outChannels)};return s.ops.UpsampleConv1x1(r,i,o)}},e}function co(){let s=new Proxy({},{get:()=>s});return s}async function mo(s,e){let r=Ot[e.model];if(!r)throw new Error(\`microbench: no network class for '\${e.model}'\`);let t=lo(s),o=t.tensor(e.resolution.h,e.resolution.w,4),i=new r(t,o,co());for(let l=0;l<uo;l++)i.run(),await s.sync();let a=e.skipFrames+1,u=performance.now();for(let l=0;l<Ft;l++)l%a===0&&i.run();return await s.sync(),(performance.now()-u)/Ft}async function Rt(s,e,r){let t;if(s==="auto")t=await Mt(r);else if(typeof s=="string"){let o=V(s);if(!o)throw new Error(\`resolve_preset: unknown preset name '\${s}'\`);t=o}else t=s;return t.dtype!==e?{...t,dtype:e}:t}function Dt(s){let e=null,r=null;return s.onmessage=t=>{let{frame:o}=t.data;if(r){let i=r;r=null,i(o)}else e&&e.close(),e=o},s.start?.(),new ReadableStream({pull(t){if(e){t.enqueue(e),e=null;return}return new Promise(o=>{r=i=>{t.enqueue(i),o()}})},cancel(){e&&(e.close(),e=null),s.close()}},{highWaterMark:0})}function Ht(s){switch(s.topology.input){case"mstp":if(!s.inputReadable)throw new Error("create_input: topology.input='mstp' but InitData.inputReadable missing");return s.inputReadable;case"rvfc-postmessage":if(!s.inputPort)throw new Error("create_input: topology.input='rvfc-postmessage' but InitData.inputPort missing");return Dt(s.inputPort)}}function Vt(s){return new TransformStream({transform(e,r){s.process(e);let t=new VideoFrame(s.canvas,{timestamp:e.timestamp});e.close(),r.enqueue(t)}})}function Nt(s){return new WritableStream({write(e){s.process(e),e.close()}})}function zt(s,e){return new WritableStream({write(r){s.process(r),r.close();let t=s.canvas.transferToImageBitmap();e.postMessage({bmp:t},[t])},close(){e.close()}})}var ho=P("create_output");function Xt(s,e,r){switch(s.topology.output){case"mstg":{if(!s.outputWritable)throw new Error("create_output: topology.output='mstg' but InitData.outputWritable missing");let t=Vt(e);return t.readable.pipeTo(s.outputWritable,{signal:r}).catch(o=>{r.aborted||ho.warn("mstg downstream pipe failed:",o)}),t.writable}case"transfer-capture":return Nt(e);case"bitmap-shuttle":{if(!s.outputPort)throw new Error("create_output: topology.output='bitmap-shuttle' but InitData.outputPort missing");return zt(e,s.outputPort)}}}function $t(s){if(!s.onFirstFrame)return s.input.pipeTo(s.output,{signal:s.signal});let e=!1,r=s.onFirstFrame,t=new TransformStream({transform(o,i){i.enqueue(o),e||(e=!0,queueMicrotask(r))}});return s.input.pipeThrough(t,{signal:s.signal}).pipeTo(s.output,{signal:s.signal})}var _=P("worker");_("script loaded");var w=null,O=null,Se=null;self.onmessage=async function(s){let{cmd:e,data:r,request_id:t}=s.data;_("cmd received:",e,"request_id:",t);try{let o=await fo(e,r);_("cmd ok:",e),Co(t,o)}catch(o){_("cmd FAILED:",e,o),H("error",{message:\`\${e} failed: \${o.message??String(o)}\`,source:"worker",recoverable:!1,cause:o})}};async function fo(s,e){switch(s){case"init":return go(e);case"startRender":return _o(e.weights);case"setBackground":return bo(e);case"setEnabled":return vo(e.enabled);case"setPreset":return yo(e);case"getStats":return w?.getStats()??null;case"destroy":return xo();default:throw new Error(\`unknown cmd: \${s}\`)}}async function go(s){if(Ae(!!s.debug),_("handleInit: start; topology=",s.topology,"preset=",s.preset,"backend=",s.backend,"dtype=",s.dtype),w)throw new Error("handleInit: already initialized");_("handleInit: setupBackend\\u2026");let e=await At(s,s.canvasSize,{onContextLost:i=>{_("GPU context lost:",i.message),H("error",i)}});_("handleInit: backend ready:",e.resolvedBackend,e.resolvedDtype,"canvas:",e.canvas.width,"x",e.canvas.height),_("handleInit: constructing Renderer (boot mode)\\u2026"),w=new Y({backend:e.backend,backendKind:e.resolvedBackend,canvas:e.canvas,background:s.background,enabled:s.enabled,topology:s.topology}),O=new AbortController,_("handleInit: createInputStream\\u2026");let r=Ht(s);_("handleInit: createOutputSink\\u2026");let t=Xt(s,w,O.signal);_("handleInit: starting pipe (passthrough)\\u2026"),$t({input:r,output:t,signal:O.signal}).then(()=>{_("pipe completed (input ended)")}).catch(i=>{if(O?.signal.aborted){_("pipe aborted (expected on destroy)");return}_("pipe FAILED:",i),H("error",{message:\`pipe failed: \${i.message}\`,source:"worker",recoverable:!1,cause:i})}),_("handleInit: resolvePreset\\u2026");let o=await Rt(s.preset,e.resolvedDtype,e.backend);return _("handleInit: preset resolved:",o),Se=o,_("handleInit: done; returning InitResponse, awaiting startRender"),{resolvedPreset:o,resolvedBackend:e.resolvedBackend,resolvedDtype:e.resolvedDtype}}async function _o(s){if(_("handleStartRender: start; weights bytes:",s.byteLength),!w||!Se)throw new Error("handleStartRender: handleInit not completed");_("handleStartRender: attaching network via setPreset\\u2026"),w.setPreset(Se,s),_("handleStartRender: ready (effect mode active)"),H("ready",void 0)}async function bo(s){w?.setBackground(s)}async function vo(s){w?.setEnabled(s)}async function yo(s){if(!w)throw new Error("handleSetPreset: not initialized");if(!s.weights)throw new Error("handleSetPreset: weights required for runtime preset swap");if(s.preset==="auto")throw new Error("handleSetPreset: 'auto' not supported on runtime swap (use at init for autotune)");let e=typeof s.preset=="string"?V(s.preset)??wo(s.preset):s.preset;return w.setPreset(e,s.weights),{resolvedPreset:e}}async function xo(){O?.abort(),O=null,w?.destroy(),w=null,Se=null}function wo(s){throw new Error(\`handleSetPreset: unknown preset '\${s}'\`)}function Co(s,e){let r={request_id:s,res:e};self.postMessage(r)}function H(s,e){let r={request_id:s,res:e};self.postMessage(r)}function al(s){H("stats",s)}export{al as emitStats};
|
|
2463
|
-
`;var x=_("pipeline");function
|
|
2463
|
+
`;var x=_("pipeline");function _t(){{let n=new Blob([re],{type:"application/javascript"}),t=URL.createObjectURL(n),e=new Worker(t,{type:"module"});return URL.revokeObjectURL(t),e}}var bt="https://cdn.longpipe.dev/models/v/0.0.1/",vt={background:"blur",preset:"auto",weightsBaseUrl:bt,audio:"passthrough",enabled:true,adaptive:true,debug:false},xe={w:1280,h:720};function wt(n,t){if(t)return t;let r=n.getVideoTracks()[0]?.getSettings()??{};return {w:r.width||xe.w,h:r.height||xe.h}}function ye(n,t){return `${n.replace(/\/$/,"")}/model_${t}.bin`}var ne=class{stream;ready;controller;worker;inputCleanup;outputCleanup;adaptive=null;bgCleanup=null;constructor(t,e){let r={...vt,...e};se(r.debug);let i=ce(),a=ge(i.input,t),s=wt(t,r.outputResolution),o=we(i.output,s);this.inputCleanup=a.cleanup,this.outputCleanup=o.cleanup,this.stream=de(o.videoTrack,t,r.audio),o.startPassthrough?.(t),this.worker=_t(),this.controller=new A(this.worker),this.ready=new Promise((p,l)=>{this.controller.addPersistentListener("ready",()=>{x("ready handler invoked; resolving .ready"),r.onReady?.(),p();}),this.controller.addPersistentListener("error",h=>{console.error(`[longpipe/pipeline] error (${h.source}):`,h.message),h.recoverable||l(new Error(h.message)),r.onError?.(h);});});let u={topology:i,preset:r.preset,enabled:r.enabled,backend:"auto",dtype:"f16",canvasSize:s,debug:r.debug,...a.initFields,...o.initFields},c=[...a.transferList,...o.transferList];this.bootstrap(u,r.background,c,r.weightsBaseUrl,r.adaptive,r.onError);}async bootstrap(t,e,r,i,a,s){try{x("normalizing background\u2026");let o=await te(e);this.bgCleanup=o.cleanup??null;let u={...t,background:o.background},c=[...r,...o.transferList??[]];x("sending init\u2026");let p=await this.controller.sendMessage("init",u,c);x("init resolved:",p);let l=ye(i,p.resolvedPreset.model);x("fetching weights:",l);let h=await fetch(l);if(!h.ok)throw new Error(`weights fetch failed: ${h.status} ${l}`);let g=await h.arrayBuffer();x("weights bytes:",g.byteLength),x("sending startRender\u2026"),await this.controller.sendMessage("startRender",{weights:g},[g]),x("startRender resolved; awaiting first frame"),u.preset==="auto"&&a&&(this.adaptive=new W({backendKind:p.resolvedBackend,initialModel:p.resolvedPreset.model,weightsBaseUrl:i,buildWeightsUrl:ye,getStats:()=>this.getStats(),swapPreset:async(T,J)=>{await this.controller.sendMessage("setPreset",{preset:T,weights:J},[J]);},onError:s}),this.adaptive.start());}catch(o){console.error("[longpipe/pipeline] bootstrap failed:",o),this.controller.handleMessage.call(this.controller,{data:{request_id:"error",res:{message:o.message??String(o),source:"worker",recoverable:false,cause:o}}});}}then(t,e){return this.ready.then(()=>t?t(this):this,e)}async setBackground(t){let e=await te(t),r=this.bgCleanup;this.bgCleanup=e.cleanup??null,await this.controller.sendMessage("setBackground",e.background,e.transferList),r?.();}setPreset(t,e){this.controller.sendMessage("setPreset",{preset:t,weights:e});}setEnabled(t){this.controller.sendMessage("setEnabled",{enabled:t});}async getStats(){return this.controller.sendMessage("getStats",{})}destroy(){this.adaptive?.stop(),this.adaptive=null,this.bgCleanup?.(),this.bgCleanup=null,this.controller.sendMessage("destroy",{}),this.controller.terminate(),this.inputCleanup(),this.outputCleanup();}};var P=new Float32Array(1),I=new Uint32Array(P.buffer);function xt(n){P[0]=n;let t=I[0],e=t>>>16&32768,r=t&2147483647,i=(r>>>23)-127+15;if((t&2139095040)===2139095040)return (t&8388607)!==0?e|32256:e|31744;if(i>=31)return e|31744;if(i<=0){if(i<-10)return e;let c=r&8388607|8388608,p=14-i,l=c>>>p,h=c>>>p-1&1,g=(c&(1<<p-1)-1)!==0?1:0;return h&&(g||l&1)&&(l+=1),e|l}let a=r>>>13&1023,s=r>>>12&1,o=(r&4095)!==0?1:0,u=i<<10|a;return s&&(o||a&1)&&(u+=1,(u>>>10&31)===31)?e|31744:e|u}function yt(n){let t=(n&32768)<<16,e=(n&31744)>>>10,r=n&1023;if(e===0){if(r===0)return I[0]=t,P[0];let i=r,a=1;for(;(i&1024)===0;)i<<=1,a-=1;return i&=1023,I[0]=t|a+127-15<<23|i<<13,P[0]}return e===31?(I[0]=t|2139095040|r<<13,P[0]):(I[0]=t|e+127-15<<23|r<<13,P[0])}function ke(n){let t=new Uint16Array(n.length);for(let e=0;e<n.length;e++)t[e]=xt(n[e]);return t}function ie(n){let t=new Float32Array(n.length);for(let e=0;e<n.length;e++)t[e]=yt(n[e]);return t}var d=class{constructor(t){this.backend=t;}backend;shader="";pipeline;bindGroup;uniformDefs=[];uniformBuffers={};createUniform(t,e){this.uniformDefs.push({name:t,type:e});}setUniform(t,e){let r=this.backend.device.createBuffer({size:e.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:true});e instanceof Uint32Array?new Uint32Array(r.getMappedRange()).set(e):new Float32Array(r.getMappedRange()).set(e),r.unmap(),this.uniformBuffers[t]=r;}defaultBindGroup(){let t=[],e=0;for(let r of this.inputs)t.push({binding:e++,resource:{buffer:r.buffer}});for(let r of this.weights)t.push({binding:e++,resource:{buffer:r.buffer}});for(let r of this.uniformDefs)t.push({binding:e++,resource:{buffer:this.uniformBuffers[r.name]}});return t.push({binding:e,resource:{buffer:this.output.buffer}}),this.backend.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:t})}defaultSetup(){let t=this.backend.device.createShaderModule({code:this.shader});this.pipeline=this.backend.device.createComputePipeline({layout:"auto",compute:{module:t,entryPoint:"main"}}),this.bindGroup=this.defaultBindGroup();}run(){let t=this.backend.device.createCommandEncoder(),e=t.beginComputePass();e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.dispatchWorkgroups(...this.dispatch),e.end(),this.backend.device.queue.submit([t.finish()]);}};var Ce=`// Conv2d compute shader \u2014 handles all variants:
|
|
2464
2464
|
// 1\xD71 (pointwise), 3\xD73, 5\xD75, strided, BN-fused
|
|
2465
2465
|
//
|
|
2466
2466
|
// Tensor layout: NHWC with channels in vec4 groups
|
|
@@ -2616,7 +2616,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
2616
2616
|
|
|
2617
2617
|
output_buf[y * params.out_w * O + x * O + o] = result;
|
|
2618
2618
|
}
|
|
2619
|
-
`;function b(
|
|
2619
|
+
`;function b(n,t,e,r){return typeof r=="number"?Math.floor((n+2*r-t)/e)+1:r==="same"?Math.ceil(n/e):Math.floor((n-t)/e)+1}function Pt(n,t,e,r){return Math.floor(Math.max((t-1)*r+e-n,0)/2)}function v(n,t,e,r,i){return typeof n=="number"?n:n==="same"?Pt(t,e,r,i):0}function f(n){return n instanceof Float32Array||n instanceof Uint16Array?n:new Float32Array(n)}var F=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,i){super(t),this.shader=t.dtype==="f16"?Pe:Ce;let a=b(e.h,i.kernel,i.stride,i.padding),s=b(e.w,i.kernel,i.stride,i.padding),o=e.c/4,u=i.outChannels/4,c=v(i.padding,e.h,a,i.kernel,i.stride),p=v(i.padding,e.w,s,i.kernel,i.stride);this.output=t.tensor(a,s,i.outChannels),this.inputs=[e],this.weights=[t.upload(f(r.weights)),t.upload(f(r.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,a,s,o,u,i.kernel,i.kernel,i.stride,c,p,i.activation==="relu6"?1:0])),this.defaultSetup(),this.dispatch=[Math.ceil(s/8),Math.ceil(a/8),u];}};var Ie=`// Depthwise Conv2d \u2014 groups = in_channels (each channel convolved independently).
|
|
2620
2620
|
//
|
|
2621
2621
|
// Weight layout: [K*K][channel_groups] array of vec4
|
|
2622
2622
|
// weight index = (ky*kernel_w + kx) * channel_groups + c
|
|
@@ -2756,7 +2756,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
2756
2756
|
|
|
2757
2757
|
output_buf[y * params.out_w * C + x * C + c] = result;
|
|
2758
2758
|
}
|
|
2759
|
-
`;var O=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,
|
|
2759
|
+
`;var O=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,i){super(t),this.shader=t.dtype==="f16"?Te:Ie;let a=b(e.h,i.kernel,i.stride,i.padding),s=b(e.w,i.kernel,i.stride,i.padding),o=e.c/4,u=v(i.padding,e.h,a,i.kernel,i.stride),c=v(i.padding,e.w,s,i.kernel,i.stride);this.output=t.tensor(a,s,e.c),this.inputs=[e],this.weights=[t.upload(f(r.weights)),t.upload(f(r.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,a,s,o,i.kernel,i.kernel,i.stride,u,c,i.activation==="relu6"?1:0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(s/8),Math.ceil(a/8),o];}};var Ue=`// Element-wise add of two tensors \u2014 used for residual connections in MBConv blocks.
|
|
2760
2760
|
// Operates on the flat float buffer directly; layout is irrelevant for a pure element-wise op.
|
|
2761
2761
|
|
|
2762
2762
|
struct Params {
|
|
@@ -2800,7 +2800,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
2800
2800
|
if (idx >= params.size) { return; }
|
|
2801
2801
|
output[idx] = input_a[idx] + input_b[idx];
|
|
2802
2802
|
}
|
|
2803
|
-
`;var M=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Se:Ue;let
|
|
2803
|
+
`;var M=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Se:Ue;let i=e.h*e.w*e.c;this.output=t.tensor(e.h,e.w,e.c),this.inputs=[e,r],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([i,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(i/256),1,1];}};var Ee=`// Element-wise sigmoid: output = 1 / (1 + exp(-x)).
|
|
2804
2804
|
// Operates on packed vec4 buffers (NHWC layout). exp() and arithmetic are element-wise on vec4.
|
|
2805
2805
|
|
|
2806
2806
|
struct Params {
|
|
@@ -2956,7 +2956,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
2956
2956
|
|
|
2957
2957
|
output_buf[oy * params.out_w * C + ox * C + c] = vec4<f16>(result);
|
|
2958
2958
|
}
|
|
2959
|
-
`;var D=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Ge:Be;let
|
|
2959
|
+
`;var D=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Ge:Be;let i=e.c/4;this.output=t.tensor(r.outH,r.outW,e.c),this.inputs=[e],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,r.outH,r.outW,i,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(r.outW/8),Math.ceil(r.outH/8),i];}};var Ae=`// Bicubic upsample (arbitrary scale) \u2014 Keys cubic, a=-0.75 (PyTorch default
|
|
2960
2960
|
// for mode='bicubic', align_corners=False). Direct 2D, 4\xD74 = 16 taps per
|
|
2961
2961
|
// output pixel. NHWC vec4 layout: index = y*W*(C/4) + x*(C/4) + c_group.
|
|
2962
2962
|
|
|
@@ -3092,7 +3092,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3092
3092
|
|
|
3093
3093
|
output_buf[oy * params.out_w * C + ox * C + c] = vec4<f16>(acc);
|
|
3094
3094
|
}
|
|
3095
|
-
`;var H=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Fe:Ae;let
|
|
3095
|
+
`;var H=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Fe:Ae;let i=e.c/4;this.output=t.tensor(r.outH,r.outW,e.c),this.inputs=[e],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,r.outH,r.outW,i,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(r.outW/8),Math.ceil(r.outH/8),i];}};var Oe=`// Channel concatenation: output = cat(A, B, dim=channel).
|
|
3096
3096
|
// Both A and B must share the same H\xD7W and be in NHWC vec4 format.
|
|
3097
3097
|
// Output layout: for each (y, x), the first a_groups vec4s come from A,
|
|
3098
3098
|
// followed by b_groups vec4s from B.
|
|
@@ -3178,7 +3178,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3178
3178
|
output_buf[out_idx] = input_b[y * W * Bg + x * Bg + c_b];
|
|
3179
3179
|
}
|
|
3180
3180
|
}
|
|
3181
|
-
`;var L=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Me:Oe;let
|
|
3181
|
+
`;var L=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Me:Oe;let i=e.c/4,a=r.c/4,s=i+a;this.output=t.tensor(e.h,e.w,e.c+r.c),this.inputs=[e,r],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,i,a,s,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),s];}};var Re=`// Conv2d + skip add fused.
|
|
3182
3182
|
// Identical to conv2d.wgsl except skip is an activation input (binding 1),
|
|
3183
3183
|
// added element-wise to the conv result at write time.
|
|
3184
3184
|
// Eliminates the separate add dispatch and its intermediate buffer round-trip.
|
|
@@ -3326,7 +3326,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3326
3326
|
let out_idx = y * params.out_w * O + x * O + o;
|
|
3327
3327
|
output_buf[out_idx] = result + skip_buf[out_idx];
|
|
3328
3328
|
}
|
|
3329
|
-
`;var V=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,
|
|
3329
|
+
`;var V=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,i,a){super(t),this.shader=t.dtype==="f16"?De:Re;let s=b(e.h,a.kernel,a.stride,a.padding),o=b(e.w,a.kernel,a.stride,a.padding),u=e.c/4,c=a.outChannels/4,p=v(a.padding,e.h,s,a.kernel,a.stride),l=v(a.padding,e.w,o,a.kernel,a.stride);this.output=t.tensor(s,o,a.outChannels),this.inputs=[e,r],this.weights=[t.upload(f(i.weights)),t.upload(f(i.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,s,o,u,c,a.kernel,a.kernel,a.stride,p,l,a.activation==="relu6"?1:0])),this.defaultSetup(),this.dispatch=[Math.ceil(o/8),Math.ceil(s/8),c];}};var He=`// Bilinear upsample + channel concat fused.
|
|
3330
3330
|
// input_a is the decoder tensor at small spatial resolution (in_h \xD7 in_w).
|
|
3331
3331
|
// input_b is the encoder skip feature already at output resolution (out_h \xD7 out_w).
|
|
3332
3332
|
// For output channels 0..a_groups-1: bilinearly interpolate from input_a.
|
|
@@ -3447,7 +3447,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3447
3447
|
output_buf[out_idx] = input_b[oy * params.out_w * params.b_groups + ox * params.b_groups + c_b];
|
|
3448
3448
|
}
|
|
3449
3449
|
}
|
|
3450
|
-
`;var z=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r,
|
|
3450
|
+
`;var z=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r,i){super(t),this.shader=t.dtype==="f16"?Le:He;let a=e.c/4,s=r.c/4,o=a+s;this.output=t.tensor(i.outH,i.outW,e.c+r.c),this.inputs=[e,r],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,i.outH,i.outW,a,s,o,0])),this.defaultSetup(),this.dispatch=[Math.ceil(i.outW/8),Math.ceil(i.outH/8),o];}};var Ve=`// Bilinear upsample + 1\xD71 pointwise conv fused.
|
|
3451
3451
|
// For each output pixel, bilinearly samples the small input for each in_group,
|
|
3452
3452
|
// immediately applies the 1\xD71 conv weights, and writes the activated result.
|
|
3453
3453
|
// Eliminates the intermediate full-resolution upsample buffer.
|
|
@@ -3581,7 +3581,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3581
3581
|
|
|
3582
3582
|
output_buf[oy * params.out_w * params.out_groups + ox * params.out_groups + og] = result;
|
|
3583
3583
|
}
|
|
3584
|
-
`;var N=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,
|
|
3584
|
+
`;var N=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,i){super(t),this.shader=t.dtype==="f16"?ze:Ve;let a=e.c/4,s=i.outChannels/4;this.output=t.tensor(i.outH,i.outW,i.outChannels),this.inputs=[e],this.weights=[t.upload(f(r.weights)),t.upload(f(r.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,i.outH,i.outW,a,s,i.activation==="relu6"?1:0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(i.outW/8),Math.ceil(i.outH/8),s];}};var Ne=`// Bilinear upsample + sigmoid fused.
|
|
3585
3585
|
// Identical to bilinear_upsample.wgsl except sigmoid is applied at write time.
|
|
3586
3586
|
// Eliminates the intermediate full-resolution buffer and the separate sigmoid dispatch.
|
|
3587
3587
|
|
|
@@ -3690,7 +3690,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3690
3690
|
|
|
3691
3691
|
output_buf[oy * params.out_w * C + ox * C + c] = vec4<f16>(1.0 / (1.0 + exp(-result)));
|
|
3692
3692
|
}
|
|
3693
|
-
`;var $=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?$e:Ne;let
|
|
3693
|
+
`;var $=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?$e:Ne;let i=e.c/4;this.output=t.tensor(r.outH,r.outW,e.c),this.inputs=[e],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,r.outH,r.outW,i,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(r.outW/8),Math.ceil(r.outH/8),i];}};var qe=`// Composite an RGBA image over a solid background, gated by a 1-ch alpha.
|
|
3694
3694
|
// Fragment writes the canvas's swapchain texture (premultiplied output).
|
|
3695
3695
|
//
|
|
3696
3696
|
// Caller invariants (matched in CompositeSolidWebGPU):
|
|
@@ -3784,7 +3784,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
3784
3784
|
let rgb = fg * a + params.bgColor.rgb * (1.0 - a);
|
|
3785
3785
|
return vec4<f32>(rgb, 1.0);
|
|
3786
3786
|
}
|
|
3787
|
-
`;var q=class{constructor(t,e,r,
|
|
3787
|
+
`;var q=class{constructor(t,e,r,i){this.backend=t;if(e.h!==r.h||e.w!==r.w)throw new Error(`CompositeSolid: image (${e.h}\xD7${e.w}) and alpha (${r.h}\xD7${r.w}) must match. Run the upscaler first.`);let a=t.device;this.uniformBuffer=a.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let s=new ArrayBuffer(32);new Uint32Array(s,0,1)[0]=e.w,new Float32Array(s,16,4).set([i[0],i[1],i[2],0]),a.queue.writeBuffer(this.uniformBuffer,0,s);let o=t.dtype==="f16"?Xe:qe,u=a.createShaderModule({code:o});this.pipeline=a.createRenderPipeline({layout:"auto",vertex:{module:u,entryPoint:"vs"},fragment:{module:u,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=a.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:r.buffer}},{binding:2,resource:{buffer:this.uniformBuffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositeSolidWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var je=`// Like composite_solid but bg is an NHWC vec4 storage buffer (e.g. virtual
|
|
3788
3788
|
// background image, or a blurred copy of the input).
|
|
3789
3789
|
|
|
3790
3790
|
struct VertexOut {
|
|
@@ -3870,7 +3870,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
3870
3870
|
let rgb = fg * a + bgc * (1.0 - a);
|
|
3871
3871
|
return vec4<f32>(rgb, 1.0);
|
|
3872
3872
|
}
|
|
3873
|
-
`;var X=class{constructor(t,e,r,
|
|
3873
|
+
`;var X=class{constructor(t,e,r,i){this.backend=t;if(e.h!==r.h||e.w!==r.w||e.h!==i.h||e.w!==i.w)throw new Error(`CompositeImage: image (${e.h}\xD7${e.w}), alpha (${r.h}\xD7${r.w}), and bg (${i.h}\xD7${i.w}) must all match. Run upscaler / resizer first.`);let a=t.device;this.uniformBuffer=a.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let s=new ArrayBuffer(16);new Uint32Array(s,0,1)[0]=e.w,a.queue.writeBuffer(this.uniformBuffer,0,s);let o=t.dtype==="f16"?Ke:je,u=a.createShaderModule({code:o});this.pipeline=a.createRenderPipeline({layout:"auto",vertex:{module:u,entryPoint:"vs"},fragment:{module:u,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=a.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:r.buffer}},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:i.buffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositeImageWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var Ye=`// Like composite_image but bg is sampled bilinearly \u2014 bg may be smaller than
|
|
3874
3874
|
// (image, alpha). Used by CompositorBlur to skip the final full-res upsample
|
|
3875
3875
|
// in the blur pyramid and let this shader's own per-pixel scan do the
|
|
3876
3876
|
// expansion (the work is already happening here for the composite anyway).
|
|
@@ -3996,7 +3996,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
3996
3996
|
let rgb = fg * a + bgc * (1.0 - a);
|
|
3997
3997
|
return vec4<f32>(rgb, 1.0);
|
|
3998
3998
|
}
|
|
3999
|
-
`;var j=class{constructor(t,e,r,
|
|
3999
|
+
`;var j=class{constructor(t,e,r,i){this.backend=t;if(e.h!==r.h||e.w!==r.w)throw new Error(`CompositeImageBilinear: image (${e.h}\xD7${e.w}) and alpha (${r.h}\xD7${r.w}) must match.`);let a=t.device;this.uniformBuffer=a.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let s=new ArrayBuffer(16),o=new Uint32Array(s);o[0]=e.w,o[1]=e.h,o[2]=i.w,o[3]=i.h,a.queue.writeBuffer(this.uniformBuffer,0,s);let u=t.dtype==="f16"?Je:Ye,c=a.createShaderModule({code:u});this.pipeline=a.createRenderPipeline({layout:"auto",vertex:{module:c,entryPoint:"vs"},fragment:{module:c,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=a.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:r.buffer}},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:i.buffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositeImageBilinearWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var Qe=`// Passthrough "compositor" \u2014 writes the image directly to the canvas
|
|
4000
4000
|
// swapchain texture with no alpha math and no background. Used by RenderOp
|
|
4001
4001
|
// when the renderer is in disabled state, so the output canvas reflects
|
|
4002
4002
|
// the unmodified input frame instead of a stale matted result.
|
|
@@ -4070,7 +4070,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
4070
4070
|
let i = y * params.width + x;
|
|
4071
4071
|
return vec4<f32>(vec3<f32>(image[i].rgb), 1.0);
|
|
4072
4072
|
}
|
|
4073
|
-
`;var K=class{constructor(t,e){this.backend=t;let r=t.device;this.uniformBuffer=r.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let
|
|
4073
|
+
`;var K=class{constructor(t,e){this.backend=t;let r=t.device;this.uniformBuffer=r.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let i=new ArrayBuffer(16);new Uint32Array(i,0,1)[0]=e.w,r.queue.writeBuffer(this.uniformBuffer,0,i);let a=t.dtype==="f16"?Ze:Qe,s=r.createShaderModule({code:a});this.pipeline=r.createRenderPipeline({layout:"auto",vertex:{module:s,entryPoint:"vs"},fragment:{module:s,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=r.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:this.uniformBuffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositePassthroughWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var et=`// Input op \u2014 sample a regular 2D source texture (RGBA8 unorm) into the NHWC
|
|
4074
4074
|
// vec4<f32> output buffer at the target resolution. Used for ImageBitmap
|
|
4075
4075
|
// sources, which are uploaded into a persistent staging texture via
|
|
4076
4076
|
// copyExternalImageToTexture before each dispatch.
|
|
@@ -4190,4 +4190,4 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4190
4190
|
let rgba = textureSampleBaseClampToEdge(src_tex, src_sampler, uv);
|
|
4191
4191
|
output_buf[y * params.out_w + x] = vec4<f16>(rgba);
|
|
4192
4192
|
}
|
|
4193
|
-
`;var
|
|
4193
|
+
`;var ir=n=>typeof VideoFrame<"u"&&n instanceof VideoFrame,Y=class{output;device;dtype;sampler;uniformBuffer;dispatch;pipeline2d=null;pipelineExternal=null;stagingTex=null;stagingW=0;stagingH=0;source=null;constructor(t,e,r){this.device=t.device,this.dtype=t.dtype,this.output=t.tensor(e,r,4),this.sampler=this.device.createSampler({magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),this.uniformBuffer=this.device.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let i=new ArrayBuffer(16);new Uint32Array(i,0,2).set([r,e]),this.device.queue.writeBuffer(this.uniformBuffer,0,i),this.dispatch=[Math.ceil(r/8),Math.ceil(e/8),1],this.pipeline2d=this.buildPipeline(this.dtype==="f16"?tt:et);}setSource(t){this.source=t;}run(){if(!this.source)throw new Error("InputWebGPU.run() called before setSource()");ir(this.source)?this.runExternal(this.source):this.run2d(this.source);}run2d(t){this.ensureStagingTexture(t.width,t.height),this.device.queue.copyExternalImageToTexture({source:t,flipY:false},{texture:this.stagingTex},[t.width,t.height]);let e=this.device.createBindGroup({layout:this.pipeline2d.getBindGroupLayout(0),entries:[{binding:0,resource:this.stagingTex.createView()},{binding:1,resource:this.sampler},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:this.output.buffer}}]});this.dispatchOnce(this.pipeline2d,e);}runExternal(t){this.pipelineExternal||(this.pipelineExternal=this.buildPipeline(this.dtype==="f16"?nt:rt));let e=this.device.importExternalTexture({source:t}),r=this.device.createBindGroup({layout:this.pipelineExternal.getBindGroupLayout(0),entries:[{binding:0,resource:e},{binding:1,resource:this.sampler},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:this.output.buffer}}]});this.dispatchOnce(this.pipelineExternal,r);}ensureStagingTexture(t,e){this.stagingTex&&this.stagingW===t&&this.stagingH===e||(this.stagingTex?.destroy(),this.stagingTex=this.device.createTexture({size:[t,e,1],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),this.stagingW=t,this.stagingH=e);}buildPipeline(t){let e=this.device.createShaderModule({code:t});return this.device.createComputePipeline({layout:"auto",compute:{module:e,entryPoint:"main"}})}dispatchOnce(t,e){let r=this.device.createCommandEncoder(),i=r.beginComputePass();i.setPipeline(t),i.setBindGroup(0,e),i.dispatchWorkgroups(...this.dispatch),i.end(),this.device.queue.submit([r.finish()]);}};var ar=navigator.gpu?GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST:0,ae=class n{constructor(t,e,r){this.device=t;this.canvas=e;this.dtype=r;this.bytesPerElement=r==="f16"?2:4;let i=e.getContext("webgpu");if(!i)throw new Error("Failed to get WebGPU context from canvas");this.canvasContext=i,this.canvasFormat=navigator.gpu.getPreferredCanvasFormat(),this.canvasContext.configure({device:t,format:this.canvasFormat,alphaMode:"premultiplied"}),this.ops={Conv2d:(a,s,o)=>new F(this,a,s,o),DepthwiseConv2d:(a,s,o)=>new O(this,a,s,o),Add:(a,s)=>new M(this,a,s),Sigmoid:a=>new R(this,a),BilinearUpsample:(a,s)=>new D(this,a,s),BicubicUpsample:(a,s)=>new H(this,a,s),ChannelConcat:(a,s)=>new L(this,a,s),Conv2dAdd:(a,s,o,u)=>new V(this,a,s,o,u),UpsampleConcat:(a,s,o)=>new z(this,a,s,o),UpsampleConv1x1:(a,s,o)=>new N(this,a,s,o),UpsampleSigmoid:(a,s)=>new $(this,a,s),Input:(a,s)=>new Y(this,a,s)},this.presenters={CompositeSolid:(a,s,o)=>{let u=new q(this,a,s,o);return {run:()=>{u.setOutput(this.getCurrentDisplayTexture()),u.run();}}},CompositeImage:(a,s,o)=>{let u=new X(this,a,s,o);return {run:()=>{u.setOutput(this.getCurrentDisplayTexture()),u.run();}}},CompositeImageBilinear:(a,s,o)=>{let u=new j(this,a,s,o);return {run:()=>{u.setOutput(this.getCurrentDisplayTexture()),u.run();}}},CompositePassthrough:a=>{let s=new K(this,a);return {run:()=>{s.setOutput(this.getCurrentDisplayTexture()),s.run();}}}};}device;canvas;dtype;ops;presenters;canvasContext;canvasFormat;bytesPerElement;static async isAvailable(){return navigator.gpu?await navigator.gpu.requestAdapter()!==null:false}static async hasF16Support(){if(!navigator.gpu)return false;let t=await navigator.gpu.requestAdapter();return t?t.features.has("shader-f16"):false}static async create(t){let e=t.dtype??"f32",r=t.device;if(r){if(e==="f16"&&!r.features.has("shader-f16"))throw new Error("WebGPU dtype='f16' requested but supplied device lacks `shader-f16`")}else {let i=await navigator.gpu.requestAdapter();if(!i)throw new Error("WebGPU adapter not available");if(e==="f16"&&!i.features.has("shader-f16"))throw new Error("WebGPU dtype='f16' requested but adapter lacks `shader-f16` feature");r=await i.requestDevice({requiredFeatures:e==="f16"?["shader-f16"]:[]});}return new n(r,t.canvas,e)}getCurrentDisplayTexture(){return this.canvasContext.getCurrentTexture()}tensor(t,e,r,i){let s=t*e*r*this.bytesPerElement,o=this.device.createBuffer({size:s,usage:ar,mappedAtCreation:i!==void 0});if(i!==void 0){let u=o.getMappedRange();this.writeView(u,i),o.unmap();}return {h:t,w:e,c:r,buffer:o}}upload(t){let r=t.length*this.bytesPerElement,i=this.device.createBuffer({size:r,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,mappedAtCreation:true});return this.writeView(i.getMappedRange(),t),i.unmap(),{buffer:i}}writeView(t,e){let r=this.dtype==="f16",i=e instanceof Uint16Array;if(r===i){r?new Uint16Array(t).set(e):new Float32Array(t).set(e);return}r?new Uint16Array(t).set(ke(e)):new Float32Array(t).set(ie(e));}async readback(t){let e=this.device.createBuffer({size:t.buffer.size,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),r=this.device.createCommandEncoder();r.copyBufferToBuffer(t.buffer,0,e,0,t.buffer.size),this.device.queue.submit([r.finish()]),await e.mapAsync(GPUMapMode.READ);let i=e.getMappedRange(),a=this.dtype==="f16"?ie(new Uint16Array(i.slice(0))):new Float32Array(i.slice(0));return e.unmap(),e.destroy(),a}async sync(){await this.device.queue.onSubmittedWorkDone();}destroy(){this.device.destroy();}};exports.EffectsPipeline=ne;exports.WebGPUBackend=ae;
|
package/dist/index.d.cts
CHANGED
|
@@ -97,7 +97,7 @@ interface ManualPreset {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
type BackgroundInput = 'blur' | 'none' | string | ImageBitmap | HTMLImageElement | HTMLVideoElement | {
|
|
100
|
-
color:
|
|
100
|
+
color: ColorInput;
|
|
101
101
|
} | {
|
|
102
102
|
blur: BlurInput;
|
|
103
103
|
} | {
|
|
@@ -110,6 +110,7 @@ type BlurInput = true | {
|
|
|
110
110
|
} | {
|
|
111
111
|
sigma: number;
|
|
112
112
|
};
|
|
113
|
+
type ColorInput = string | [number, number, number];
|
|
113
114
|
type ImageInput = ImageBitmap | HTMLImageElement | string | {
|
|
114
115
|
data: ArrayBuffer | Blob | Uint8Array;
|
|
115
116
|
type: string;
|
|
@@ -224,4 +225,4 @@ declare class WebGPUBackend implements Backend {
|
|
|
224
225
|
destroy(): void;
|
|
225
226
|
}
|
|
226
227
|
|
|
227
|
-
export { type Activation, type AudioMode, type Backend, type Background, type BackgroundInput, type BlurInput, type Conv2dParams, type DepthwiseParams, Pipeline as EffectsPipeline, type ErrorSource, type ImageInput, type ManualPreset, type ModelName, type Op, type PipelineError, type PipelineOptions, type PresetName, type Tensor, type VideoInput, WebGPUBackend };
|
|
228
|
+
export { type Activation, type AudioMode, type Backend, type Background, type BackgroundInput, type BlurInput, type ColorInput, type Conv2dParams, type DepthwiseParams, Pipeline as EffectsPipeline, type ErrorSource, type ImageInput, type ManualPreset, type ModelName, type Op, type PipelineError, type PipelineOptions, type PresetName, type Tensor, type VideoInput, WebGPUBackend };
|
package/dist/index.d.ts
CHANGED
|
@@ -97,7 +97,7 @@ interface ManualPreset {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
type BackgroundInput = 'blur' | 'none' | string | ImageBitmap | HTMLImageElement | HTMLVideoElement | {
|
|
100
|
-
color:
|
|
100
|
+
color: ColorInput;
|
|
101
101
|
} | {
|
|
102
102
|
blur: BlurInput;
|
|
103
103
|
} | {
|
|
@@ -110,6 +110,7 @@ type BlurInput = true | {
|
|
|
110
110
|
} | {
|
|
111
111
|
sigma: number;
|
|
112
112
|
};
|
|
113
|
+
type ColorInput = string | [number, number, number];
|
|
113
114
|
type ImageInput = ImageBitmap | HTMLImageElement | string | {
|
|
114
115
|
data: ArrayBuffer | Blob | Uint8Array;
|
|
115
116
|
type: string;
|
|
@@ -224,4 +225,4 @@ declare class WebGPUBackend implements Backend {
|
|
|
224
225
|
destroy(): void;
|
|
225
226
|
}
|
|
226
227
|
|
|
227
|
-
export { type Activation, type AudioMode, type Backend, type Background, type BackgroundInput, type BlurInput, type Conv2dParams, type DepthwiseParams, Pipeline as EffectsPipeline, type ErrorSource, type ImageInput, type ManualPreset, type ModelName, type Op, type PipelineError, type PipelineOptions, type PresetName, type Tensor, type VideoInput, WebGPUBackend };
|
|
228
|
+
export { type Activation, type AudioMode, type Backend, type Background, type BackgroundInput, type BlurInput, type ColorInput, type Conv2dParams, type DepthwiseParams, Pipeline as EffectsPipeline, type ErrorSource, type ImageInput, type ManualPreset, type ModelName, type Op, type PipelineError, type PipelineOptions, type PresetName, type Tensor, type VideoInput, WebGPUBackend };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var w=[{model:"xxs",dtype:"f16",resolution:{w:128,h:72},skipFrames:3},{model:"xs",dtype:"f16",resolution:{w:192,h:108},skipFrames:1},{model:"small",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"compact",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:256,h:144},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:512,h:288},skipFrames:0}];var Q=false;function se(i){Q=i;}function _(i){let t=`[longpipe/${i}]`,e=((...r)=>{Q&&console.log(t,...r);});return e.warn=(...r)=>{Q&&console.warn(t,...r);},e}var k=_("adaptive"),it=2e3,at=1e4,st=30,ot=20,ut=5e3,pt=.3,lt=15e3,W=class{constructor(t){this.opts=t;this.currentPresetIdx=w.findIndex(e=>e.model===t.initialModel),this.lastSwapAt=performance.now();}opts;timer=null;currentPresetIdx;lastSwapAt=0;overshootStart=0;headroomStart=0;start(){k(`started; backend=${this.opts.backendKind} initial=${this.opts.initialModel} idx=${this.currentPresetIdx}`),this.timer=setInterval(()=>{this.tick().catch(t=>k("tick failed:",t));},it);}stop(){this.timer&&clearInterval(this.timer),this.timer=null;}async tick(){if(typeof document<"u"&&document.hidden)return;let t=performance.now();if(t-this.lastSwapAt<at)return;let e=await this.opts.getStats();if(e.fps<ot?(this.overshootStart===0&&(this.overshootStart=t),t-this.overshootStart>=ut&&this.tryDowngrade(e.fps)):this.overshootStart=0,this.opts.backendKind==="webgpu"&&e.modelMs>0){let r=1e3/st*pt;e.modelMs<r?(this.headroomStart===0&&(this.headroomStart=t),t-this.headroomStart>=lt&&this.tryUpgrade(e.modelMs,r)):this.headroomStart=0;}}tryDowngrade(t){if(this.currentPresetIdx<=0)return;let e=this.currentPresetIdx-1;k(`downgrade ${w[this.currentPresetIdx].model} \u2192 ${w[e].model} (fps=${t})`),this.swap(e);}tryUpgrade(t,e){if(this.currentPresetIdx>=w.length-1)return;let r=this.currentPresetIdx+1;k(`upgrade ${w[this.currentPresetIdx].model} \u2192 ${w[r].model} (modelMs=${t.toFixed(1)} < ${e.toFixed(1)})`),this.swap(r);}async swap(t){let e=w[t];this.lastSwapAt=performance.now(),this.overshootStart=0,this.headroomStart=0;try{let r=this.opts.buildWeightsUrl(this.opts.weightsBaseUrl,e.model),n=await fetch(r);if(!n.ok)throw new Error(`weights fetch failed: ${n.status} ${r}`);let a=await n.arrayBuffer();await this.opts.swapPreset(e.model,a),this.currentPresetIdx=t,k(`swap to ${e.model} done`);}catch(r){k("swap failed:",r),this.opts.onError?.({message:`adaptive preset swap failed: ${r.message??String(r)}`,source:"adaptive",recoverable:true,cause:r});}}};async function oe(i){let t,e=false;if(i instanceof HTMLVideoElement){if(t=i.currentSrc||i.src,!t)throw new Error("background video: HTMLVideoElement has no src")}else if(i instanceof Blob)t=URL.createObjectURL(i),e=true;else if(typeof i=="string")t=i;else throw new Error("background video: unsupported input shape");let r=document.createElement("video");r.crossOrigin="anonymous",r.muted=true,r.loop=true,r.playsInline=true,r.src=t,await new Promise((p,l)=>{r.addEventListener("loadeddata",()=>p(),{once:true}),r.addEventListener("error",()=>l(new Error(`background video: failed to load ${t}`)),{once:true});});try{await r.play();}catch(p){throw new Error(`background video: play() rejected \u2014 ${p.message}`)}let n=new MessageChannel,a=n.port1,s=n.port2,o=false,u=r.requestVideoFrameCallback?.bind(r);if(u){let p=(l,h)=>{if(!o){try{let g=new VideoFrame(r,{timestamp:h.mediaTime*1e6});a.postMessage({frame:g},[g]);}catch{}u(p);}};u(p);}else {let p=()=>{if(!o){try{let l=new VideoFrame(r,{timestamp:performance.now()*1e3});a.postMessage({frame:l},[l]);}catch{}requestAnimationFrame(p);}};requestAnimationFrame(p);}return {port:s,transferList:[s],cleanup:()=>{o=true,a.close(),r.pause(),r.removeAttribute("src"),r.load(),e&&URL.revokeObjectURL(t);}}}var Z=4,ee=8,ue=16;async function te(i){if(typeof i=="string")return i==="none"?{background:{kind:"none"}}:i==="blur"?{background:{kind:"blur",sigma:ee}}:{background:{kind:"image",bitmap:await le(i)}};if(i instanceof ImageBitmap)return {background:{kind:"image",bitmap:i}};if(typeof HTMLImageElement<"u"&&i instanceof HTMLImageElement)return {background:{kind:"image",bitmap:await createImageBitmap(i)}};if(typeof HTMLVideoElement<"u"&&i instanceof HTMLVideoElement)return await pe(i);let t=i;if(t.color)return {background:{kind:"color",rgb:t.color}};if(t.blur!==void 0)return {background:{kind:"blur",sigma:ct(t.blur)}};if(t.image!==void 0)return {background:{kind:"image",bitmap:await dt(t.image)}};if(t.video!==void 0)return await pe(t.video);throw new Error(`background: unrecognized input shape \u2014 ${P(i)}`)}async function pe(i){let t;if(typeof i=="string")t=i;else if(typeof HTMLVideoElement<"u"&&i instanceof HTMLVideoElement)t=i;else if(i&&typeof i=="object"&&"data"in i&&"type"in i)t=i.data instanceof Blob?i.data:new Blob([i.data],{type:i.type});else throw new Error(`background.video: unrecognized shape \u2014 ${P(i)}`);let e=await oe(t);return {background:{kind:"video",port:e.port},transferList:e.transferList,cleanup:e.cleanup}}function ct(i){if(i===true)return ee;if("sigma"in i){if(typeof i.sigma!="number"||!Number.isFinite(i.sigma)||i.sigma<0)throw new Error(`background.blur.sigma must be a non-negative number, got ${i.sigma}`);return i.sigma}if("strength"in i){let t=i.strength;if(typeof t=="number"){let e=Math.max(0,Math.min(1,t));return Z+(ue-Z)*e}if(t==="low")return Z;if(t==="medium")return ee;if(t==="high")return ue;throw new Error(`background.blur.strength must be 'low' | 'medium' | 'high' | number, got ${P(t)}`)}throw new Error(`background.blur: must be true, { strength }, or { sigma } \u2014 got ${P(i)}`)}async function dt(i){if(i instanceof ImageBitmap)return i;if(typeof HTMLImageElement<"u"&&i instanceof HTMLImageElement)return createImageBitmap(i);if(typeof i=="string")return le(i);if(i&&typeof i=="object"&&"data"in i&&"type"in i){let t=i.data instanceof Blob?i.data:new Blob([i.data],{type:i.type});return createImageBitmap(t)}throw new Error(`background.image: unrecognized shape \u2014 ${P(i)}`)}async function le(i){let t=await fetch(i);if(!t.ok)throw new Error(`background: failed to load image from ${i} (HTTP ${t.status})`);let e=await t.blob();return createImageBitmap(e)}function P(i){return i===null?"null":typeof i!="object"?typeof i+"("+String(i)+")":`${i.constructor?.name??"Object"} ${JSON.stringify(i).slice(0,80)}`}function ce(){return {input:"MediaStreamTrackProcessor"in self?"mstp":"rvfc-postmessage",output:"MediaStreamTrackGenerator"in self?"mstg":ht()?"transfer-capture":"bitmap-shuttle"}}var B=null;function ht(){return B!==null||(B=!/Firefox/.test(navigator.userAgent)),B}function de(i,t,e){let r=[i];return e==="passthrough"&&r.push(...t.getAudioTracks()),new MediaStream(r)}var G=_("worker_controller"),A=class{worker;listeners=new Map;persistentEvents=new Set;constructor(t){this.worker=t,this.worker.addEventListener("message",this.handleMessage.bind(this)),G("constructed; message listener attached");}handleMessage(t){let{request_id:e,res:r}=t.data,n=this.listeners.get(e);G("msg received: request_id=",e,"handler?",!!n,"persistent?",this.persistentEvents.has(e)),n&&(n(r),this.persistentEvents.has(e)||this.listeners.delete(e));}addPersistentListener(t,e){this.persistentEvents.add(t),this.listeners.set(t,e),G("addPersistentListener:",t);}removePersistentListener(t){this.persistentEvents.delete(t),this.listeners.delete(t);}sendMessage(t,e,r=[]){let n=crypto.randomUUID();return G("sendMessage:",t,"request_id=",n,"transferables=",r.length),new Promise(a=>{this.listeners.set(n,o=>a(o));let s={cmd:t,data:e,request_id:n};this.worker.postMessage(s,r);})}terminate(){this.worker.terminate(),this.listeners.clear(),this.persistentEvents.clear();}};var he=_("input-postmessage/main");function fe(i){let t=document.createElement("video");t.srcObject=i,t.muted=true,t.autoplay=true,t.playsInline=true,t.play().catch(c=>{he.warn("video.play() rejected:",c);});let e=t.requestVideoFrameCallback?.bind(t);if(!e)throw new Error("setupPostMessageInput: requestVideoFrameCallback not supported on this browser");let r=new MessageChannel,n=r.port1,a=r.port2,s=false,o=(c,p)=>{if(!s){try{let l=new VideoFrame(t,{timestamp:p.mediaTime*1e6});n.postMessage({frame:l},[l]);}catch(l){he.warn("VideoFrame() failed; skipping frame:",l);}e(o);}};return e(o),{port:a,transferList:[a],cleanup:()=>{s=true,n.close(),t.srcObject=null,t.pause();}}}function me(i){let t=i.getVideoTracks();if(t.length===0)throw new Error("setupMstpInput: input MediaStream has no video tracks");let e=t[0],r=self.MediaStreamTrackProcessor;if(!r)throw new Error("setupMstpInput: MediaStreamTrackProcessor not supported on this browser");let a=new r({track:e}).readable;return {readable:a,transferList:[a],cleanup:()=>{a.cancel().catch(()=>{});}}}function ge(i,t){switch(i){case "mstp":{let e=me(t);return {initFields:{inputReadable:e.readable},transferList:e.transferList,cleanup:e.cleanup}}case "rvfc-postmessage":{let e=fe(t);return {initFields:{inputPort:e.port},transferList:e.transferList,cleanup:e.cleanup}}}}var ft=_("bitmap-shuttle/main"),mt=30;function _e(i,t=mt){let e=document.createElement("canvas");e.width=i.w,e.height=i.h;let r=e.getContext("bitmaprenderer");if(!r)throw new Error("setupBitmapShuttleOutput: bitmaprenderer context not available");let a=e.captureStream(t).getVideoTracks();if(a.length===0)throw new Error("setupBitmapShuttleOutput: captureStream produced no video tracks");let s=a[0],o=new MessageChannel,u=o.port1,c=o.port2,p=false,l=null,h=()=>{},g=3,T=0;return u.onmessage=U=>{if(p){if(T++,T<g){U.data.bmp.close();return}h();}try{r.transferFromImageBitmap(U.data.bmp);}catch(m){ft.warn("transferFromImageBitmap failed:",m);}},u.start(),{videoTrack:s,port:c,transferList:[c],startPassthrough:U=>{if(p)return;p=true;let m=document.createElement("video");m.srcObject=U,m.muted=true,m.playsInline=true,m.play().catch(()=>{}),l=m;let S="requestVideoFrameCallback"in m?y=>{m.requestVideoFrameCallback(y);}:y=>{requestAnimationFrame(y);},E=()=>{if(p){if(m.videoWidth===0){S(E);return}createImageBitmap(m,{resizeWidth:e.width,resizeHeight:e.height,resizeQuality:"medium"}).then(y=>{if(!p){y.close();return}try{r.transferFromImageBitmap(y);}catch{}S(E);}).catch(()=>{S(E);});}};S(E),h=()=>{p=false,l&&(l.srcObject=null,l.pause(),l=null);};},cleanup:()=>{h(),u.onmessage=null,u.close(),s.stop();}}}function be(){let i=self.MediaStreamTrackGenerator;if(!i)throw new Error("setupMstgOutput: MediaStreamTrackGenerator not supported on this browser");let t=new i({kind:"video"}),e=t.writable;return {videoTrack:t,writable:e,transferList:[e],cleanup:()=>{e.abort().catch(()=>{}),t.stop();}}}function ve(i,t=30){let e=document.createElement("canvas");e.width=i.w,e.height=i.h;let n=e.captureStream(t).getVideoTracks();if(n.length===0)throw new Error("setupTransferCaptureOutput: captureStream produced no video tracks");let a=n[0],s=e.transferControlToOffscreen();return {videoTrack:a,canvas:s,transferList:[s],cleanup:()=>{a.stop();}}}function we(i,t){switch(i){case "mstg":{let e=be();return {videoTrack:e.videoTrack,initFields:{outputWritable:e.writable},transferList:e.transferList,cleanup:e.cleanup}}case "transfer-capture":{let e=ve(t);return {videoTrack:e.videoTrack,initFields:{outputCanvas:e.canvas},transferList:e.transferList,cleanup:e.cleanup}}case "bitmap-shuttle":{let e=_e(t);return {videoTrack:e.videoTrack,initFields:{outputPort:e.port},transferList:e.transferList,startPassthrough:e.startPassthrough,cleanup:e.cleanup}}}}var re=`var jt=Object.defineProperty;var Kt=(s,e,r)=>e in s?jt(s,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[e]=r;var n=(s,e,r)=>Kt(s,typeof e!="symbol"?e+"":e,r);var Ee=!1;function Ae(s){Ee=s}function P(s){let e=\`[longpipe/\${s}]\`,r=((...t)=>{Ee&&console.log(e,...t)});return r.warn=(...t)=>{Ee&&console.warn(e,...t)},r}var Ie=[{model:"xxs",dtype:"f16",resolution:{w:128,h:72},skipFrames:3},{model:"xs",dtype:"f16",resolution:{w:192,h:108},skipFrames:1},{model:"small",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"compact",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:256,h:144},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:512,h:288},skipFrames:0}],Yt={fast:1,balanced:4,quality:6};function V(s){return s==="auto"?null:Ie[Yt[s]]}var N=class{constructor(e,r,t,o){n(this,"op");this.op=e.ops.BilinearUpsample(r,{outH:t,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var z=class{constructor(e,r,t,o){n(this,"op");this.op=e.ops.BicubicUpsample(r,{outH:t,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var X=class{constructor(e,r,t,o){n(this,"presenter");this.presenter=e.presenters.CompositeSolid(r,t,o)}run(){this.presenter.run()}};var $=class{constructor(e,r,t,o){n(this,"presenter");this.presenter=e.presenters.CompositeImage(r,t,o)}run(){this.presenter.run()}};var q=class{constructor(e,r,t){n(this,"downs",[]);n(this,"ups",[]);let o=Qt(t),i=r;for(let a=0;a<o;a++){let u=e.ops.BilinearUpsample(i,{outH:Math.max(1,Math.floor(i.h/2)),outW:Math.max(1,Math.floor(i.w/2))});this.downs.push(u),i=u.output}for(let a=o-1;a>=1;a--){let u=this.downs[a-1].output,p=e.ops.BilinearUpsample(i,{outH:u.h,outW:u.w});this.ups.push(p),i=p.output}}get output(){return this.ups.length>0?this.ups[this.ups.length-1].output:this.downs[0].output}run(){for(let e of this.downs)e.run();for(let e of this.ups)e.run()}};function Qt(s){let e=Math.max(1,3*s);return Math.max(2,Math.min(6,Math.round(Math.log2(e))))}var j=class{constructor(e,r,t,o){n(this,"blur");n(this,"presenter");this.blur=new q(e,r,o),this.presenter=e.presenters.CompositeImageBilinear(r,t,this.blur.output)}run(){this.blur.run(),this.presenter.run()}};var K=class{constructor(e){n(this,"backend",e);n(this,"displayInput");n(this,"image");n(this,"passthroughCompositor");n(this,"network",null);n(this,"networkInput",null);n(this,"upscaler",null);n(this,"compositor",null);n(this,"upscalerMode","bilinear");n(this,"bgConfig",{mode:"solid",color:[0,0,0]});let r=e.canvas;this.displayInput=e.ops.Input(r.height,r.width),this.image=this.displayInput.output,this.passthroughCompositor=e.presenters.CompositePassthrough(this.image)}attachNetwork(e,r,t){this.network=e,this.networkInput=r,this.upscalerMode=t.upscaler,this.bgConfig=t.background,this.upscaler=this.makeUpscaler(),this.compositor=this.makeCompositor()}hasNetwork(){return this.network!==null}setSource(e){this.networkInput?.setSource(e),this.displayInput.setSource(e)}setUpscaler(e){e!==this.upscalerMode&&(this.upscalerMode=e,this.network&&(this.upscaler=this.makeUpscaler(),this.compositor=this.makeCompositor()))}setBackground(e){this.bgConfig=e,this.network&&(this.compositor=this.makeCompositor())}run(){this.runModel(),this.runDisplay()}runDisplay(){if(!this.compositor)throw new Error("RenderOp.runDisplay called before attachNetwork");this.displayInput.run(),this.compositor.run()}runPassthrough(){this.displayInput.run(),this.passthroughCompositor.run()}runModel(){if(!this.network||!this.networkInput||!this.upscaler)throw new Error("RenderOp.runModel called before attachNetwork");this.networkInput.run(),this.network.run(),this.upscaler.run()}makeUpscaler(){if(!this.network)throw new Error("makeUpscaler called with no network");let{backend:e,network:r,image:t}=this;return this.upscalerMode==="bicubic"?new z(e,r.output,t.h,t.w):new N(e,r.output,t.h,t.w)}makeCompositor(){if(!this.upscaler)throw new Error("makeCompositor called before upscaler exists");let{backend:e,image:r,upscaler:t,bgConfig:o}=this;switch(o.mode){case"solid":return new X(e,r,t.output,o.color);case"image":return new $(e,r,t.output,o.image);case"blur":return new j(e,r,t.output,o.sigma)}}};var Jt=s=>typeof s=="object"&&s!==null&&typeof s.offset=="number"&&typeof s.length=="number";function Fe(s){if(s.byteLength<4)throw new Error("weights buffer too small");let e=new DataView(s,0,4).getUint32(0,!0),r=4+e;if(s.byteLength<r)throw new Error("weights buffer truncated (header)");let t=new Uint8Array(s,4,e),o=JSON.parse(new TextDecoder().decode(t)),i=o.__dtype__??"f32",a=i==="f16"?2:4;if(r%a!==0)throw new Error(\`payload not \${a}-byte aligned (header=\${e})\`);let u=(s.byteLength-r)/a,p=l=>{if(Jt(l)){let{offset:d,length:m}=l;if(d+m>u)throw new Error(\`array ref out of range: offset=\${d} length=\${m}\`);let x=r+d*a;return i==="f16"?new Uint16Array(s,x,m):new Float32Array(s,x,m)}if(Array.isArray(l))return l.map(p);if(typeof l=="object"&&l!==null){let d={};for(let m of Object.keys(l))m!=="__dtype__"&&(d[m]=p(l[m]));return d}return l};return p(o)}var C=class{constructor(e,r,t,o){n(this,"inputs");n(this,"output");n(this,"dwOp");n(this,"pwOp");this.inputs=[r],this.dwOp=e.ops.DepthwiseConv2d(r,t.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.pwOp=e.ops.Conv2d(this.dwOp.output,t.pw,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.output=this.pwOp.output}run(){this.dwOp.run(),this.pwOp.run()}};var c=class{constructor(e,r,t,o){n(this,"inputs");n(this,"output");n(this,"expandOp");n(this,"dwOp");n(this,"projOp");n(this,"addOp");this.inputs=[r];let i=o.midChannels!==o.inChannels,a=o.stride===1&&o.inChannels===o.outChannels;this.expandOp=i?e.ops.Conv2d(r,t.expand,{outChannels:o.midChannels,kernel:1,stride:1,padding:0,activation:"relu6"}):null;let u=this.expandOp?this.expandOp.output:r;this.dwOp=e.ops.DepthwiseConv2d(u,t.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.projOp=e.ops.Conv2d(this.dwOp.output,t.proj,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.addOp=a?e.ops.Add(r,this.projOp.output):null,this.output=this.addOp?this.addOp.output:this.projOp.output}run(){this.expandOp?.run(),this.dwOp.run(),this.projOp.run(),this.addOp?.run()}};var y=class{constructor(e,r,t,o,i){n(this,"inputs");n(this,"output");n(this,"upConcatOp");n(this,"conv1Op");n(this,"conv2Op");this.inputs=[r,t],this.upConcatOp=e.ops.UpsampleConcat(r,t,{outH:t.h,outW:t.w}),this.conv1Op=e.ops.Conv2d(this.upConcatOp.output,o.conv1,{outChannels:i.outChannels,kernel:3,stride:1,padding:1,activation:"relu6"}),this.conv2Op=e.ops.Conv2d(this.conv1Op.output,o.conv2,{outChannels:i.outChannels,kernel:3,stride:1,padding:1,activation:"relu6"}),this.output=this.conv2Op.output}run(){this.upConcatOp.run(),this.conv1Op.run(),this.conv2Op.run()}};var W=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:64}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:32}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:16}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:16,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var E=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:64,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:32}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:16}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:8}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:8,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var k=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.bottleneck=e.ops.Conv2d(this.s4b2.output,t.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s2b1.output,t.decoder.blocks[0],{outChannels:64}),this.dec1=new y(e,this.dec0.output,this.s1b1.output,t.decoder.blocks[1],{outChannels:32}),this.finalUp=e.ops.UpsampleConv1x1(this.dec1.output,t.decoder.finalUpsample,{outH:this.dec1.output.h*2,outW:this.dec1.output.w*2,outChannels:32,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var I=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:256,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:128}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:64}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:32}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:32,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var Zt=5,er={xxs:k,xs:k,small:k,compact:E,medium:W,large:W,xl:I},Oe=1e3,Y=class{constructor(e){n(this,"canvas");n(this,"backend");n(this,"backendKind");n(this,"topology");n(this,"preset",null);n(this,"enabled");n(this,"currentBackground");n(this,"modelTimingCounter",0);n(this,"renderOp");n(this,"bgImageInput",null);n(this,"bgVideoInput",null);n(this,"bgVideoPort",null);n(this,"skipCounter",0);n(this,"framesRenderedAt",[]);n(this,"modelRunSamples",[]);n(this,"displayRunSamples",[]);n(this,"skippedCount",0);this.backend=e.backend,this.backendKind=e.backendKind,this.canvas=e.canvas,this.enabled=e.enabled,this.currentBackground=e.background,this.topology=e.topology,this.renderOp=new K(this.backend)}process(e){if(this.renderOp.setSource(e),!this.enabled||this.currentBackground.kind==="none"||!this.renderOp.hasNetwork()){this.renderOp.runPassthrough(),this.framesRenderedAt.push(performance.now()),this.trim(this.framesRenderedAt);return}if(this.shouldRunModel()){let t=performance.now();this.renderOp.runModel(),this.backendKind==="webgpu"&&this.modelTimingCounter%Zt===0&&this.backend.sync().then(()=>{this.modelRunSamples.push({ts:performance.now(),ms:performance.now()-t}),this.trimSamples(this.modelRunSamples)}).catch(()=>{}),this.modelTimingCounter++}else this.skippedCount++;let r=performance.now();this.renderOp.runDisplay(),this.displayRunSamples.push({ts:performance.now(),ms:performance.now()-r}),this.trimSamples(this.displayRunSamples),this.framesRenderedAt.push(performance.now()),this.trim(this.framesRenderedAt)}shouldRunModel(){return this.skipCounter===0?(this.skipCounter=this.preset?.skipFrames??0,!0):(this.skipCounter--,!1)}setBackground(e){this.currentBackground=e,this.renderOp.setBackground(this.translateBackground(e))}setEnabled(e){this.enabled=e}setPreset(e,r){let t=er[e.model];if(!t)throw new Error(\`renderer: model '\${e.model}' not implemented in src/model/networks/\`);let o=Fe(r),i=this.backend.ops.Input(e.resolution.h,e.resolution.w),a=new t(this.backend,i.output,o);this.renderOp.attachNetwork(a,i,{upscaler:"bilinear",background:this.translateBackground(this.currentBackground)}),this.preset=e,this.skipCounter=0}destroy(){this.bgVideoPort&&(this.bgVideoPort.close(),this.bgVideoPort=null),this.backend.destroy()}getStats(){let e=performance.now();return this.trimRecent(this.framesRenderedAt,e),this.trimSamplesAt(this.modelRunSamples,e),this.trimSamplesAt(this.displayRunSamples,e),{fps:this.framesRenderedAt.length,modelFps:this.modelRunSamples.length,modelMs:Me(this.modelRunSamples.map(r=>r.ms)),displayMs:Me(this.displayRunSamples.map(r=>r.ms)),skipped:this.skippedCount,preset:this.preset?.model??"boot",skipFrames:this.preset?.skipFrames??0,enabled:this.enabled,inputPath:this.topology.input,outputPath:this.topology.output}}translateBackground(e){switch(e.kind!=="video"&&this.bgVideoPort&&(this.bgVideoPort.close(),this.bgVideoPort=null),e.kind){case"none":return{mode:"solid",color:[0,0,0]};case"color":return{mode:"solid",color:e.rgb};case"blur":return{mode:"blur",sigma:e.sigma};case"image":return this.bgImageInput||(this.bgImageInput=this.backend.ops.Input(this.canvas.height,this.canvas.width)),this.bgImageInput.setSource(e.bitmap),this.bgImageInput.run(),{mode:"image",image:this.bgImageInput.output};case"video":{this.bgVideoInput||(this.bgVideoInput=this.backend.ops.Input(this.canvas.height,this.canvas.width)),this.bgVideoPort&&this.bgVideoPort.close(),this.bgVideoPort=e.port;let r=this.bgVideoInput;return e.port.onmessage=t=>{let o=t.data.frame;try{r.setSource(o),r.run()}finally{o.close()}},e.port.start?.(),{mode:"image",image:this.bgVideoInput.output}}}}trim(e){e.length>240&&e.splice(0,e.length-240)}trimSamples(e){e.length>240&&e.splice(0,e.length-240)}trimRecent(e,r){let t=r-Oe,o=0;for(;o<e.length&&e[o]<t;)o++;o>0&&e.splice(0,o)}trimSamplesAt(e,r){let t=r-Oe,o=0;for(;o<e.length&&e[o].ts<t;)o++;o>0&&e.splice(0,o)}};function Me(s){if(s.length===0)return 0;let e=s.slice().sort((t,o)=>t-o),r=e.length>>1;return e.length%2?e[r]:(e[r-1]+e[r])/2}var L=new Float32Array(1),D=new Uint32Array(L.buffer);function tr(s){L[0]=s;let e=D[0],r=e>>>16&32768,t=e&2147483647,o=(t>>>23)-127+15;if((e&2139095040)===2139095040)return(e&8388607)!==0?r|32256:r|31744;if(o>=31)return r|31744;if(o<=0){if(o<-10)return r;let l=t&8388607|8388608,d=14-o,m=l>>>d,x=l>>>d-1&1,T=(l&(1<<d-1)-1)!==0?1:0;return x&&(T||m&1)&&(m+=1),r|m}let i=t>>>13&1023,a=t>>>12&1,u=(t&4095)!==0?1:0,p=o<<10|i;return a&&(u||i&1)&&(p+=1,(p>>>10&31)===31)?r|31744:r|p}function rr(s){let e=(s&32768)<<16,r=(s&31744)>>>10,t=s&1023;if(r===0){if(t===0)return D[0]=e,L[0];let o=t,i=1;for(;(o&1024)===0;)o<<=1,i-=1;return o&=1023,D[0]=e|i+127-15<<23|o<<13,L[0]}return r===31?(D[0]=e|2139095040|t<<13,L[0]):(D[0]=e|r+127-15<<23|t<<13,L[0])}function Q(s){let e=new Uint16Array(s.length);for(let r=0;r<s.length;r++)e[r]=tr(s[r]);return e}function A(s){let e=new Float32Array(s.length);for(let r=0;r<s.length;r++)e[r]=rr(s[r]);return e}var h=class{constructor(e){n(this,"backend",e);n(this,"shader","");n(this,"pipeline");n(this,"bindGroup");n(this,"uniformDefs",[]);n(this,"uniformBuffers",{})}createUniform(e,r){this.uniformDefs.push({name:e,type:r})}setUniform(e,r){let t=this.backend.device.createBuffer({size:r.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});r instanceof Uint32Array?new Uint32Array(t.getMappedRange()).set(r):new Float32Array(t.getMappedRange()).set(r),t.unmap(),this.uniformBuffers[e]=t}defaultBindGroup(){let e=[],r=0;for(let t of this.inputs)e.push({binding:r++,resource:{buffer:t.buffer}});for(let t of this.weights)e.push({binding:r++,resource:{buffer:t.buffer}});for(let t of this.uniformDefs)e.push({binding:r++,resource:{buffer:this.uniformBuffers[t.name]}});return e.push({binding:r,resource:{buffer:this.output.buffer}}),this.backend.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:e})}defaultSetup(){let e=this.backend.device.createShaderModule({code:this.shader});this.pipeline=this.backend.device.createComputePipeline({layout:"auto",compute:{module:e,entryPoint:"main"}}),this.bindGroup=this.defaultBindGroup()}run(){let e=this.backend.device.createCommandEncoder(),r=e.beginComputePass();r.setPipeline(this.pipeline),r.setBindGroup(0,this.bindGroup),r.dispatchWorkgroups(...this.dispatch),r.end(),this.backend.device.queue.submit([e.finish()])}};var Re=\`// Conv2d compute shader \\u2014 handles all variants:
|
|
1
|
+
var w=[{model:"xxs",dtype:"f16",resolution:{w:128,h:72},skipFrames:3},{model:"xs",dtype:"f16",resolution:{w:192,h:108},skipFrames:1},{model:"small",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"compact",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:256,h:144},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:512,h:288},skipFrames:0}];var Q=false;function se(n){Q=n;}function _(n){let t=`[longpipe/${n}]`,e=((...r)=>{Q&&console.log(t,...r);});return e.warn=(...r)=>{Q&&console.warn(t,...r);},e}var C=_("adaptive"),it=2e3,at=1e4,st=30,ot=20,ut=5e3,pt=.3,lt=15e3,W=class{constructor(t){this.opts=t;this.currentPresetIdx=w.findIndex(e=>e.model===t.initialModel),this.lastSwapAt=performance.now();}opts;timer=null;currentPresetIdx;lastSwapAt=0;overshootStart=0;headroomStart=0;start(){C(`started; backend=${this.opts.backendKind} initial=${this.opts.initialModel} idx=${this.currentPresetIdx}`),this.timer=setInterval(()=>{this.tick().catch(t=>C("tick failed:",t));},it);}stop(){this.timer&&clearInterval(this.timer),this.timer=null;}async tick(){if(typeof document<"u"&&document.hidden)return;let t=performance.now();if(t-this.lastSwapAt<at)return;let e=await this.opts.getStats();if(e.fps<ot?(this.overshootStart===0&&(this.overshootStart=t),t-this.overshootStart>=ut&&this.tryDowngrade(e.fps)):this.overshootStart=0,this.opts.backendKind==="webgpu"&&e.modelMs>0){let r=1e3/st*pt;e.modelMs<r?(this.headroomStart===0&&(this.headroomStart=t),t-this.headroomStart>=lt&&this.tryUpgrade(e.modelMs,r)):this.headroomStart=0;}}tryDowngrade(t){if(this.currentPresetIdx<=0)return;let e=this.currentPresetIdx-1;C(`downgrade ${w[this.currentPresetIdx].model} \u2192 ${w[e].model} (fps=${t})`),this.swap(e);}tryUpgrade(t,e){if(this.currentPresetIdx>=w.length-1)return;let r=this.currentPresetIdx+1;C(`upgrade ${w[this.currentPresetIdx].model} \u2192 ${w[r].model} (modelMs=${t.toFixed(1)} < ${e.toFixed(1)})`),this.swap(r);}async swap(t){let e=w[t];this.lastSwapAt=performance.now(),this.overshootStart=0,this.headroomStart=0;try{let r=this.opts.buildWeightsUrl(this.opts.weightsBaseUrl,e.model),i=await fetch(r);if(!i.ok)throw new Error(`weights fetch failed: ${i.status} ${r}`);let a=await i.arrayBuffer();await this.opts.swapPreset(e.model,a),this.currentPresetIdx=t,C(`swap to ${e.model} done`);}catch(r){C("swap failed:",r),this.opts.onError?.({message:`adaptive preset swap failed: ${r.message??String(r)}`,source:"adaptive",recoverable:true,cause:r});}}};async function oe(n){let t,e=false;if(n instanceof HTMLVideoElement){if(t=n.currentSrc||n.src,!t)throw new Error("background video: HTMLVideoElement has no src")}else if(n instanceof Blob)t=URL.createObjectURL(n),e=true;else if(typeof n=="string")t=n;else throw new Error("background video: unsupported input shape");let r=document.createElement("video");r.crossOrigin="anonymous",r.muted=true,r.loop=true,r.playsInline=true,r.src=t,await new Promise((p,l)=>{r.addEventListener("loadeddata",()=>p(),{once:true}),r.addEventListener("error",()=>l(new Error(`background video: failed to load ${t}`)),{once:true});});try{await r.play();}catch(p){throw new Error(`background video: play() rejected \u2014 ${p.message}`)}let i=new MessageChannel,a=i.port1,s=i.port2,o=false,u=r.requestVideoFrameCallback?.bind(r);if(u){let p=(l,h)=>{if(!o){try{let g=new VideoFrame(r,{timestamp:h.mediaTime*1e6});a.postMessage({frame:g},[g]);}catch{}u(p);}};u(p);}else {let p=()=>{if(!o){try{let l=new VideoFrame(r,{timestamp:performance.now()*1e3});a.postMessage({frame:l},[l]);}catch{}requestAnimationFrame(p);}};requestAnimationFrame(p);}return {port:s,transferList:[s],cleanup:()=>{o=true,a.close(),r.pause(),r.removeAttribute("src"),r.load(),e&&URL.revokeObjectURL(t);}}}var Z=4,ee=8,ue=16;async function te(n){if(typeof n=="string")return n==="none"?{background:{kind:"none"}}:n==="blur"?{background:{kind:"blur",sigma:ee}}:{background:{kind:"image",bitmap:await le(n)}};if(n instanceof ImageBitmap)return {background:{kind:"image",bitmap:n}};if(typeof HTMLImageElement<"u"&&n instanceof HTMLImageElement)return {background:{kind:"image",bitmap:await createImageBitmap(n)}};if(typeof HTMLVideoElement<"u"&&n instanceof HTMLVideoElement)return await pe(n);let t=n;if(t.color!==void 0)return {background:{kind:"color",rgb:ct(t.color)}};if(t.blur!==void 0)return {background:{kind:"blur",sigma:dt(t.blur)}};if(t.image!==void 0)return {background:{kind:"image",bitmap:await ht(t.image)}};if(t.video!==void 0)return await pe(t.video);throw new Error(`background: unrecognized input shape \u2014 ${y(n)}`)}async function pe(n){let t;if(typeof n=="string")t=n;else if(typeof HTMLVideoElement<"u"&&n instanceof HTMLVideoElement)t=n;else if(n&&typeof n=="object"&&"data"in n&&"type"in n)t=n.data instanceof Blob?n.data:new Blob([n.data],{type:n.type});else throw new Error(`background.video: unrecognized shape \u2014 ${y(n)}`);let e=await oe(t);return {background:{kind:"video",port:e.port},transferList:e.transferList,cleanup:e.cleanup}}function ct(n){if(typeof n=="string"){let t=n.trim().replace(/^#/,"");if(/^[0-9a-fA-F]{6}$/.test(t))return [parseInt(t.slice(0,2),16)/255,parseInt(t.slice(2,4),16)/255,parseInt(t.slice(4,6),16)/255];if(/^[0-9a-fA-F]{3}$/.test(t))return [parseInt(t[0]+t[0],16)/255,parseInt(t[1]+t[1],16)/255,parseInt(t[2]+t[2],16)/255];throw new Error(`background.color: hex must be #rgb or #rrggbb, got ${y(n)}`)}if(!Array.isArray(n)||n.length!==3||!n.every(t=>typeof t=="number"&&Number.isFinite(t)&&t>=0&&t<=1))throw new Error(`background.color: expected hex string or [r, g, b] floats in [0, 1], got ${y(n)}`);return [n[0],n[1],n[2]]}function dt(n){if(n===true)return ee;if("sigma"in n){if(typeof n.sigma!="number"||!Number.isFinite(n.sigma)||n.sigma<0)throw new Error(`background.blur.sigma must be a non-negative number, got ${n.sigma}`);return n.sigma}if("strength"in n){let t=n.strength;if(typeof t=="number"){let e=Math.max(0,Math.min(1,t));return Z+(ue-Z)*e}if(t==="low")return Z;if(t==="medium")return ee;if(t==="high")return ue;throw new Error(`background.blur.strength must be 'low' | 'medium' | 'high' | number, got ${y(t)}`)}throw new Error(`background.blur: must be true, { strength }, or { sigma } \u2014 got ${y(n)}`)}async function ht(n){if(n instanceof ImageBitmap)return n;if(typeof HTMLImageElement<"u"&&n instanceof HTMLImageElement)return createImageBitmap(n);if(typeof n=="string")return le(n);if(n&&typeof n=="object"&&"data"in n&&"type"in n){let t=n.data instanceof Blob?n.data:new Blob([n.data],{type:n.type});return createImageBitmap(t)}throw new Error(`background.image: unrecognized shape \u2014 ${y(n)}`)}async function le(n){let t=await fetch(n);if(!t.ok)throw new Error(`background: failed to load image from ${n} (HTTP ${t.status})`);let e=await t.blob();return createImageBitmap(e)}function y(n){return n===null?"null":typeof n!="object"?typeof n+"("+String(n)+")":`${n.constructor?.name??"Object"} ${JSON.stringify(n).slice(0,80)}`}function ce(){return {input:"MediaStreamTrackProcessor"in self?"mstp":"rvfc-postmessage",output:"MediaStreamTrackGenerator"in self?"mstg":ft()?"transfer-capture":"bitmap-shuttle"}}var B=null;function ft(){return B!==null||(B=!/Firefox/.test(navigator.userAgent)),B}function de(n,t,e){let r=[n];return e==="passthrough"&&r.push(...t.getAudioTracks()),new MediaStream(r)}var G=_("worker_controller"),A=class{worker;listeners=new Map;persistentEvents=new Set;constructor(t){this.worker=t,this.worker.addEventListener("message",this.handleMessage.bind(this)),G("constructed; message listener attached");}handleMessage(t){let{request_id:e,res:r}=t.data,i=this.listeners.get(e);G("msg received: request_id=",e,"handler?",!!i,"persistent?",this.persistentEvents.has(e)),i&&(i(r),this.persistentEvents.has(e)||this.listeners.delete(e));}addPersistentListener(t,e){this.persistentEvents.add(t),this.listeners.set(t,e),G("addPersistentListener:",t);}removePersistentListener(t){this.persistentEvents.delete(t),this.listeners.delete(t);}sendMessage(t,e,r=[]){let i=crypto.randomUUID();return G("sendMessage:",t,"request_id=",i,"transferables=",r.length),new Promise(a=>{this.listeners.set(i,o=>a(o));let s={cmd:t,data:e,request_id:i};this.worker.postMessage(s,r);})}terminate(){this.worker.terminate(),this.listeners.clear(),this.persistentEvents.clear();}};var he=_("input-postmessage/main");function fe(n){let t=document.createElement("video");t.srcObject=n,t.muted=true,t.autoplay=true,t.playsInline=true,t.play().catch(c=>{he.warn("video.play() rejected:",c);});let e=t.requestVideoFrameCallback?.bind(t);if(!e)throw new Error("setupPostMessageInput: requestVideoFrameCallback not supported on this browser");let r=new MessageChannel,i=r.port1,a=r.port2,s=false,o=(c,p)=>{if(!s){try{let l=new VideoFrame(t,{timestamp:p.mediaTime*1e6});i.postMessage({frame:l},[l]);}catch(l){he.warn("VideoFrame() failed; skipping frame:",l);}e(o);}};return e(o),{port:a,transferList:[a],cleanup:()=>{s=true,i.close(),t.srcObject=null,t.pause();}}}function me(n){let t=n.getVideoTracks();if(t.length===0)throw new Error("setupMstpInput: input MediaStream has no video tracks");let e=t[0],r=self.MediaStreamTrackProcessor;if(!r)throw new Error("setupMstpInput: MediaStreamTrackProcessor not supported on this browser");let a=new r({track:e}).readable;return {readable:a,transferList:[a],cleanup:()=>{a.cancel().catch(()=>{});}}}function ge(n,t){switch(n){case "mstp":{let e=me(t);return {initFields:{inputReadable:e.readable},transferList:e.transferList,cleanup:e.cleanup}}case "rvfc-postmessage":{let e=fe(t);return {initFields:{inputPort:e.port},transferList:e.transferList,cleanup:e.cleanup}}}}var mt=_("bitmap-shuttle/main"),gt=30;function _e(n,t=gt){let e=document.createElement("canvas");e.width=n.w,e.height=n.h;let r=e.getContext("bitmaprenderer");if(!r)throw new Error("setupBitmapShuttleOutput: bitmaprenderer context not available");let a=e.captureStream(t).getVideoTracks();if(a.length===0)throw new Error("setupBitmapShuttleOutput: captureStream produced no video tracks");let s=a[0],o=new MessageChannel,u=o.port1,c=o.port2,p=false,l=null,h=()=>{},g=3,T=0;return u.onmessage=U=>{if(p){if(T++,T<g){U.data.bmp.close();return}h();}try{r.transferFromImageBitmap(U.data.bmp);}catch(m){mt.warn("transferFromImageBitmap failed:",m);}},u.start(),{videoTrack:s,port:c,transferList:[c],startPassthrough:U=>{if(p)return;p=true;let m=document.createElement("video");m.srcObject=U,m.muted=true,m.playsInline=true,m.play().catch(()=>{}),l=m;let S="requestVideoFrameCallback"in m?k=>{m.requestVideoFrameCallback(k);}:k=>{requestAnimationFrame(k);},E=()=>{if(p){if(m.videoWidth===0){S(E);return}createImageBitmap(m,{resizeWidth:e.width,resizeHeight:e.height,resizeQuality:"medium"}).then(k=>{if(!p){k.close();return}try{r.transferFromImageBitmap(k);}catch{}S(E);}).catch(()=>{S(E);});}};S(E),h=()=>{p=false,l&&(l.srcObject=null,l.pause(),l=null);};},cleanup:()=>{h(),u.onmessage=null,u.close(),s.stop();}}}function be(){let n=self.MediaStreamTrackGenerator;if(!n)throw new Error("setupMstgOutput: MediaStreamTrackGenerator not supported on this browser");let t=new n({kind:"video"}),e=t.writable;return {videoTrack:t,writable:e,transferList:[e],cleanup:()=>{e.abort().catch(()=>{}),t.stop();}}}function ve(n,t=30){let e=document.createElement("canvas");e.width=n.w,e.height=n.h;let i=e.captureStream(t).getVideoTracks();if(i.length===0)throw new Error("setupTransferCaptureOutput: captureStream produced no video tracks");let a=i[0],s=e.transferControlToOffscreen();return {videoTrack:a,canvas:s,transferList:[s],cleanup:()=>{a.stop();}}}function we(n,t){switch(n){case "mstg":{let e=be();return {videoTrack:e.videoTrack,initFields:{outputWritable:e.writable},transferList:e.transferList,cleanup:e.cleanup}}case "transfer-capture":{let e=ve(t);return {videoTrack:e.videoTrack,initFields:{outputCanvas:e.canvas},transferList:e.transferList,cleanup:e.cleanup}}case "bitmap-shuttle":{let e=_e(t);return {videoTrack:e.videoTrack,initFields:{outputPort:e.port},transferList:e.transferList,startPassthrough:e.startPassthrough,cleanup:e.cleanup}}}}var re=`var jt=Object.defineProperty;var Kt=(s,e,r)=>e in s?jt(s,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[e]=r;var n=(s,e,r)=>Kt(s,typeof e!="symbol"?e+"":e,r);var Ee=!1;function Ae(s){Ee=s}function P(s){let e=\`[longpipe/\${s}]\`,r=((...t)=>{Ee&&console.log(e,...t)});return r.warn=(...t)=>{Ee&&console.warn(e,...t)},r}var Ie=[{model:"xxs",dtype:"f16",resolution:{w:128,h:72},skipFrames:3},{model:"xs",dtype:"f16",resolution:{w:192,h:108},skipFrames:1},{model:"small",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"compact",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:256,h:144},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:256,h:144},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:512,h:288},skipFrames:0}],Yt={fast:1,balanced:4,quality:6};function V(s){return s==="auto"?null:Ie[Yt[s]]}var N=class{constructor(e,r,t,o){n(this,"op");this.op=e.ops.BilinearUpsample(r,{outH:t,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var z=class{constructor(e,r,t,o){n(this,"op");this.op=e.ops.BicubicUpsample(r,{outH:t,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var X=class{constructor(e,r,t,o){n(this,"presenter");this.presenter=e.presenters.CompositeSolid(r,t,o)}run(){this.presenter.run()}};var $=class{constructor(e,r,t,o){n(this,"presenter");this.presenter=e.presenters.CompositeImage(r,t,o)}run(){this.presenter.run()}};var q=class{constructor(e,r,t){n(this,"downs",[]);n(this,"ups",[]);let o=Qt(t),i=r;for(let a=0;a<o;a++){let u=e.ops.BilinearUpsample(i,{outH:Math.max(1,Math.floor(i.h/2)),outW:Math.max(1,Math.floor(i.w/2))});this.downs.push(u),i=u.output}for(let a=o-1;a>=1;a--){let u=this.downs[a-1].output,p=e.ops.BilinearUpsample(i,{outH:u.h,outW:u.w});this.ups.push(p),i=p.output}}get output(){return this.ups.length>0?this.ups[this.ups.length-1].output:this.downs[0].output}run(){for(let e of this.downs)e.run();for(let e of this.ups)e.run()}};function Qt(s){let e=Math.max(1,3*s);return Math.max(2,Math.min(6,Math.round(Math.log2(e))))}var j=class{constructor(e,r,t,o){n(this,"blur");n(this,"presenter");this.blur=new q(e,r,o),this.presenter=e.presenters.CompositeImageBilinear(r,t,this.blur.output)}run(){this.blur.run(),this.presenter.run()}};var K=class{constructor(e){n(this,"backend",e);n(this,"displayInput");n(this,"image");n(this,"passthroughCompositor");n(this,"network",null);n(this,"networkInput",null);n(this,"upscaler",null);n(this,"compositor",null);n(this,"upscalerMode","bilinear");n(this,"bgConfig",{mode:"solid",color:[0,0,0]});let r=e.canvas;this.displayInput=e.ops.Input(r.height,r.width),this.image=this.displayInput.output,this.passthroughCompositor=e.presenters.CompositePassthrough(this.image)}attachNetwork(e,r,t){this.network=e,this.networkInput=r,this.upscalerMode=t.upscaler,this.bgConfig=t.background,this.upscaler=this.makeUpscaler(),this.compositor=this.makeCompositor()}hasNetwork(){return this.network!==null}setSource(e){this.networkInput?.setSource(e),this.displayInput.setSource(e)}setUpscaler(e){e!==this.upscalerMode&&(this.upscalerMode=e,this.network&&(this.upscaler=this.makeUpscaler(),this.compositor=this.makeCompositor()))}setBackground(e){this.bgConfig=e,this.network&&(this.compositor=this.makeCompositor())}run(){this.runModel(),this.runDisplay()}runDisplay(){if(!this.compositor)throw new Error("RenderOp.runDisplay called before attachNetwork");this.displayInput.run(),this.compositor.run()}runPassthrough(){this.displayInput.run(),this.passthroughCompositor.run()}runModel(){if(!this.network||!this.networkInput||!this.upscaler)throw new Error("RenderOp.runModel called before attachNetwork");this.networkInput.run(),this.network.run(),this.upscaler.run()}makeUpscaler(){if(!this.network)throw new Error("makeUpscaler called with no network");let{backend:e,network:r,image:t}=this;return this.upscalerMode==="bicubic"?new z(e,r.output,t.h,t.w):new N(e,r.output,t.h,t.w)}makeCompositor(){if(!this.upscaler)throw new Error("makeCompositor called before upscaler exists");let{backend:e,image:r,upscaler:t,bgConfig:o}=this;switch(o.mode){case"solid":return new X(e,r,t.output,o.color);case"image":return new $(e,r,t.output,o.image);case"blur":return new j(e,r,t.output,o.sigma)}}};var Jt=s=>typeof s=="object"&&s!==null&&typeof s.offset=="number"&&typeof s.length=="number";function Fe(s){if(s.byteLength<4)throw new Error("weights buffer too small");let e=new DataView(s,0,4).getUint32(0,!0),r=4+e;if(s.byteLength<r)throw new Error("weights buffer truncated (header)");let t=new Uint8Array(s,4,e),o=JSON.parse(new TextDecoder().decode(t)),i=o.__dtype__??"f32",a=i==="f16"?2:4;if(r%a!==0)throw new Error(\`payload not \${a}-byte aligned (header=\${e})\`);let u=(s.byteLength-r)/a,p=l=>{if(Jt(l)){let{offset:d,length:m}=l;if(d+m>u)throw new Error(\`array ref out of range: offset=\${d} length=\${m}\`);let x=r+d*a;return i==="f16"?new Uint16Array(s,x,m):new Float32Array(s,x,m)}if(Array.isArray(l))return l.map(p);if(typeof l=="object"&&l!==null){let d={};for(let m of Object.keys(l))m!=="__dtype__"&&(d[m]=p(l[m]));return d}return l};return p(o)}var C=class{constructor(e,r,t,o){n(this,"inputs");n(this,"output");n(this,"dwOp");n(this,"pwOp");this.inputs=[r],this.dwOp=e.ops.DepthwiseConv2d(r,t.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.pwOp=e.ops.Conv2d(this.dwOp.output,t.pw,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.output=this.pwOp.output}run(){this.dwOp.run(),this.pwOp.run()}};var c=class{constructor(e,r,t,o){n(this,"inputs");n(this,"output");n(this,"expandOp");n(this,"dwOp");n(this,"projOp");n(this,"addOp");this.inputs=[r];let i=o.midChannels!==o.inChannels,a=o.stride===1&&o.inChannels===o.outChannels;this.expandOp=i?e.ops.Conv2d(r,t.expand,{outChannels:o.midChannels,kernel:1,stride:1,padding:0,activation:"relu6"}):null;let u=this.expandOp?this.expandOp.output:r;this.dwOp=e.ops.DepthwiseConv2d(u,t.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.projOp=e.ops.Conv2d(this.dwOp.output,t.proj,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.addOp=a?e.ops.Add(r,this.projOp.output):null,this.output=this.addOp?this.addOp.output:this.projOp.output}run(){this.expandOp?.run(),this.dwOp.run(),this.projOp.run(),this.addOp?.run()}};var y=class{constructor(e,r,t,o,i){n(this,"inputs");n(this,"output");n(this,"upConcatOp");n(this,"conv1Op");n(this,"conv2Op");this.inputs=[r,t],this.upConcatOp=e.ops.UpsampleConcat(r,t,{outH:t.h,outW:t.w}),this.conv1Op=e.ops.Conv2d(this.upConcatOp.output,o.conv1,{outChannels:i.outChannels,kernel:3,stride:1,padding:1,activation:"relu6"}),this.conv2Op=e.ops.Conv2d(this.conv1Op.output,o.conv2,{outChannels:i.outChannels,kernel:3,stride:1,padding:1,activation:"relu6"}),this.output=this.conv2Op.output}run(){this.upConcatOp.run(),this.conv1Op.run(),this.conv2Op.run()}};var W=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:64}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:32}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:16}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:16,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var E=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:64,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:32}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:16}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:8}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:8,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var k=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.bottleneck=e.ops.Conv2d(this.s4b2.output,t.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s2b1.output,t.decoder.blocks[0],{outChannels:64}),this.dec1=new y(e,this.dec0.output,this.s1b1.output,t.decoder.blocks[1],{outChannels:32}),this.finalUp=e.ops.UpsampleConv1x1(this.dec1.output,t.decoder.finalUpsample,{outH:this.dec1.output.h*2,outW:this.dec1.output.w*2,outChannels:32,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var I=class{constructor(e,r,t){n(this,"output");n(this,"stem");n(this,"s0");n(this,"s1b0");n(this,"s1b1");n(this,"s2b0");n(this,"s2b1");n(this,"s3b0");n(this,"s3b1");n(this,"s3b2");n(this,"s4b0");n(this,"s4b1");n(this,"s4b2");n(this,"s5b0");n(this,"s5b1");n(this,"s5b2");n(this,"s5b3");n(this,"s6b0");n(this,"bottleneck");n(this,"dec0");n(this,"dec1");n(this,"dec2");n(this,"finalUp");n(this,"outConv");n(this,"alpha");this.stem=e.ops.Conv2d(r,t.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new C(e,this.stem.output,t.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new c(e,this.s0.output,t.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new c(e,this.s1b0.output,t.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new c(e,this.s1b1.output,t.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new c(e,this.s2b0.output,t.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new c(e,this.s2b1.output,t.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new c(e,this.s3b0.output,t.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new c(e,this.s3b1.output,t.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new c(e,this.s3b2.output,t.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new c(e,this.s4b0.output,t.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new c(e,this.s4b1.output,t.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new c(e,this.s4b2.output,t.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new c(e,this.s5b0.output,t.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new c(e,this.s5b1.output,t.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new c(e,this.s5b2.output,t.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new c(e,this.s5b3.output,t.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=e.ops.Conv2d(this.s6b0.output,t.bottleneck,{outChannels:256,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new y(e,this.bottleneck.output,this.s4b2.output,t.decoder.blocks[0],{outChannels:128}),this.dec1=new y(e,this.dec0.output,this.s2b1.output,t.decoder.blocks[1],{outChannels:64}),this.dec2=new y(e,this.dec1.output,this.s1b1.output,t.decoder.blocks[2],{outChannels:32}),this.finalUp=e.ops.UpsampleConv1x1(this.dec2.output,t.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:32,activation:"relu6"}),this.outConv=e.ops.Conv2d(this.finalUp.output,t.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=e.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var Zt=5,er={xxs:k,xs:k,small:k,compact:E,medium:W,large:W,xl:I},Oe=1e3,Y=class{constructor(e){n(this,"canvas");n(this,"backend");n(this,"backendKind");n(this,"topology");n(this,"preset",null);n(this,"enabled");n(this,"currentBackground");n(this,"modelTimingCounter",0);n(this,"renderOp");n(this,"bgImageInput",null);n(this,"bgVideoInput",null);n(this,"bgVideoPort",null);n(this,"skipCounter",0);n(this,"framesRenderedAt",[]);n(this,"modelRunSamples",[]);n(this,"displayRunSamples",[]);n(this,"skippedCount",0);this.backend=e.backend,this.backendKind=e.backendKind,this.canvas=e.canvas,this.enabled=e.enabled,this.currentBackground=e.background,this.topology=e.topology,this.renderOp=new K(this.backend)}process(e){if(this.renderOp.setSource(e),!this.enabled||this.currentBackground.kind==="none"||!this.renderOp.hasNetwork()){this.renderOp.runPassthrough(),this.framesRenderedAt.push(performance.now()),this.trim(this.framesRenderedAt);return}if(this.shouldRunModel()){let t=performance.now();this.renderOp.runModel(),this.backendKind==="webgpu"&&this.modelTimingCounter%Zt===0&&this.backend.sync().then(()=>{this.modelRunSamples.push({ts:performance.now(),ms:performance.now()-t}),this.trimSamples(this.modelRunSamples)}).catch(()=>{}),this.modelTimingCounter++}else this.skippedCount++;let r=performance.now();this.renderOp.runDisplay(),this.displayRunSamples.push({ts:performance.now(),ms:performance.now()-r}),this.trimSamples(this.displayRunSamples),this.framesRenderedAt.push(performance.now()),this.trim(this.framesRenderedAt)}shouldRunModel(){return this.skipCounter===0?(this.skipCounter=this.preset?.skipFrames??0,!0):(this.skipCounter--,!1)}setBackground(e){this.currentBackground=e,this.renderOp.setBackground(this.translateBackground(e))}setEnabled(e){this.enabled=e}setPreset(e,r){let t=er[e.model];if(!t)throw new Error(\`renderer: model '\${e.model}' not implemented in src/model/networks/\`);let o=Fe(r),i=this.backend.ops.Input(e.resolution.h,e.resolution.w),a=new t(this.backend,i.output,o);this.renderOp.attachNetwork(a,i,{upscaler:"bilinear",background:this.translateBackground(this.currentBackground)}),this.preset=e,this.skipCounter=0}destroy(){this.bgVideoPort&&(this.bgVideoPort.close(),this.bgVideoPort=null),this.backend.destroy()}getStats(){let e=performance.now();return this.trimRecent(this.framesRenderedAt,e),this.trimSamplesAt(this.modelRunSamples,e),this.trimSamplesAt(this.displayRunSamples,e),{fps:this.framesRenderedAt.length,modelFps:this.modelRunSamples.length,modelMs:Me(this.modelRunSamples.map(r=>r.ms)),displayMs:Me(this.displayRunSamples.map(r=>r.ms)),skipped:this.skippedCount,preset:this.preset?.model??"boot",skipFrames:this.preset?.skipFrames??0,enabled:this.enabled,inputPath:this.topology.input,outputPath:this.topology.output}}translateBackground(e){switch(e.kind!=="video"&&this.bgVideoPort&&(this.bgVideoPort.close(),this.bgVideoPort=null),e.kind){case"none":return{mode:"solid",color:[0,0,0]};case"color":return{mode:"solid",color:e.rgb};case"blur":return{mode:"blur",sigma:e.sigma};case"image":return this.bgImageInput||(this.bgImageInput=this.backend.ops.Input(this.canvas.height,this.canvas.width)),this.bgImageInput.setSource(e.bitmap),this.bgImageInput.run(),{mode:"image",image:this.bgImageInput.output};case"video":{this.bgVideoInput||(this.bgVideoInput=this.backend.ops.Input(this.canvas.height,this.canvas.width)),this.bgVideoPort&&this.bgVideoPort.close(),this.bgVideoPort=e.port;let r=this.bgVideoInput;return e.port.onmessage=t=>{let o=t.data.frame;try{r.setSource(o),r.run()}finally{o.close()}},e.port.start?.(),{mode:"image",image:this.bgVideoInput.output}}}}trim(e){e.length>240&&e.splice(0,e.length-240)}trimSamples(e){e.length>240&&e.splice(0,e.length-240)}trimRecent(e,r){let t=r-Oe,o=0;for(;o<e.length&&e[o]<t;)o++;o>0&&e.splice(0,o)}trimSamplesAt(e,r){let t=r-Oe,o=0;for(;o<e.length&&e[o].ts<t;)o++;o>0&&e.splice(0,o)}};function Me(s){if(s.length===0)return 0;let e=s.slice().sort((t,o)=>t-o),r=e.length>>1;return e.length%2?e[r]:(e[r-1]+e[r])/2}var L=new Float32Array(1),D=new Uint32Array(L.buffer);function tr(s){L[0]=s;let e=D[0],r=e>>>16&32768,t=e&2147483647,o=(t>>>23)-127+15;if((e&2139095040)===2139095040)return(e&8388607)!==0?r|32256:r|31744;if(o>=31)return r|31744;if(o<=0){if(o<-10)return r;let l=t&8388607|8388608,d=14-o,m=l>>>d,x=l>>>d-1&1,T=(l&(1<<d-1)-1)!==0?1:0;return x&&(T||m&1)&&(m+=1),r|m}let i=t>>>13&1023,a=t>>>12&1,u=(t&4095)!==0?1:0,p=o<<10|i;return a&&(u||i&1)&&(p+=1,(p>>>10&31)===31)?r|31744:r|p}function rr(s){let e=(s&32768)<<16,r=(s&31744)>>>10,t=s&1023;if(r===0){if(t===0)return D[0]=e,L[0];let o=t,i=1;for(;(o&1024)===0;)o<<=1,i-=1;return o&=1023,D[0]=e|i+127-15<<23|o<<13,L[0]}return r===31?(D[0]=e|2139095040|t<<13,L[0]):(D[0]=e|r+127-15<<23|t<<13,L[0])}function Q(s){let e=new Uint16Array(s.length);for(let r=0;r<s.length;r++)e[r]=tr(s[r]);return e}function A(s){let e=new Float32Array(s.length);for(let r=0;r<s.length;r++)e[r]=rr(s[r]);return e}var h=class{constructor(e){n(this,"backend",e);n(this,"shader","");n(this,"pipeline");n(this,"bindGroup");n(this,"uniformDefs",[]);n(this,"uniformBuffers",{})}createUniform(e,r){this.uniformDefs.push({name:e,type:r})}setUniform(e,r){let t=this.backend.device.createBuffer({size:r.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});r instanceof Uint32Array?new Uint32Array(t.getMappedRange()).set(r):new Float32Array(t.getMappedRange()).set(r),t.unmap(),this.uniformBuffers[e]=t}defaultBindGroup(){let e=[],r=0;for(let t of this.inputs)e.push({binding:r++,resource:{buffer:t.buffer}});for(let t of this.weights)e.push({binding:r++,resource:{buffer:t.buffer}});for(let t of this.uniformDefs)e.push({binding:r++,resource:{buffer:this.uniformBuffers[t.name]}});return e.push({binding:r,resource:{buffer:this.output.buffer}}),this.backend.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:e})}defaultSetup(){let e=this.backend.device.createShaderModule({code:this.shader});this.pipeline=this.backend.device.createComputePipeline({layout:"auto",compute:{module:e,entryPoint:"main"}}),this.bindGroup=this.defaultBindGroup()}run(){let e=this.backend.device.createCommandEncoder(),r=e.beginComputePass();r.setPipeline(this.pipeline),r.setBindGroup(0,this.bindGroup),r.dispatchWorkgroups(...this.dispatch),r.end(),this.backend.device.queue.submit([e.finish()])}};var Re=\`// Conv2d compute shader \\u2014 handles all variants:
|
|
2
2
|
// 1\\xD71 (pointwise), 3\\xD73, 5\\xD75, strided, BN-fused
|
|
3
3
|
//
|
|
4
4
|
// Tensor layout: NHWC with channels in vec4 groups
|
|
@@ -2460,7 +2460,7 @@ const vec2 VERTS[6] = vec2[6](
|
|
|
2460
2460
|
vec2(-1.0,1.0), vec2(1.0,-1.0), vec2(1.0,1.0)
|
|
2461
2461
|
);
|
|
2462
2462
|
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,Be=class{constructor(e,r,t){n(this,"backend",e);n(this,"output");n(this,"gl");n(this,"program");n(this,"srcTex");n(this,"uOutW");n(this,"uOutH");n(this,"uSrc");n(this,"source",null);let o=e.gl;this.gl=o,this.output=e.tensor(r,t,4),this.srcTex=o.createTexture(),o.bindTexture(o.TEXTURE_2D,this.srcTex),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MIN_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MAG_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_S,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_T,o.CLAMP_TO_EDGE);let i=o.createShader(o.VERTEX_SHADER);o.shaderSource(i,ao),o.compileShader(i);let a=o.createShader(o.FRAGMENT_SHADER);if(o.shaderSource(a,Lt),o.compileShader(a),!o.getShaderParameter(a,o.COMPILE_STATUS))throw new Error(\`Input GLSL compile error: \${o.getShaderInfoLog(a)}\`);if(this.program=o.createProgram(),o.attachShader(this.program,i),o.attachShader(this.program,a),o.linkProgram(this.program),!o.getProgramParameter(this.program,o.LINK_STATUS))throw new Error(\`Input GLSL link error: \${o.getProgramInfoLog(this.program)}\`);this.uSrc=o.getUniformLocation(this.program,"u_src"),this.uOutW=o.getUniformLocation(this.program,"u_out_w"),this.uOutH=o.getUniformLocation(this.program,"u_out_h")}setSource(e){this.source=e}run(){if(!this.source)throw new Error("InputWebGL.run() called before setSource()");let e=this.gl;e.bindTexture(e.TEXTURE_2D,this.srcTex),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,this.source),e.useProgram(this.program),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.srcTex),e.uniform1i(this.uSrc,0),e.uniform1i(this.uOutW,this.output.w),e.uniform1i(this.uOutH,this.output.h),e.bindFramebuffer(e.FRAMEBUFFER,this.backend.fbo),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.output.texture,0),e.viewport(0,0,this.output.texW,this.output.texH),e.bindVertexArray(null),e.drawArrays(e.TRIANGLES,0,6)}};var U=class s{constructor(e,r,t){n(this,"gl",e);n(this,"canvas",r);n(this,"dtype",t);n(this,"ops");n(this,"presenters");n(this,"fbo");n(this,"textureFormat");this.fbo=e.createFramebuffer(),this.textureFormat=t==="f16"?{internalFormat:e.RGBA16F,format:e.RGBA,type:e.HALF_FLOAT,bytesPerElement:2}:{internalFormat:e.RGBA32F,format:e.RGBA,type:e.FLOAT,bytesPerElement:4},this.ops={Conv2d:(o,i,a)=>new he(this,o,i,a),DepthwiseConv2d:(o,i,a)=>new fe(this,o,i,a),Add:(o,i)=>new ge(this,o,i),Sigmoid:o=>new _e(this,o),BilinearUpsample:(o,i)=>new be(this,o,i),BicubicUpsample:(o,i)=>new ve(this,o,i),ChannelConcat:(o,i)=>new ye(this,o,i),Conv2dAdd:(o,i,a,u)=>new ke(this,o,i,a,u),UpsampleConcat:(o,i,a)=>new we(this,o,i,a),UpsampleConv1x1:(o,i,a)=>new Ce(this,o,i,a),UpsampleSigmoid:(o,i)=>new xe(this,o,i),Input:(o,i)=>new Be(this,o,i)},this.presenters={CompositeSolid:(o,i,a)=>new Te(this,o,i,a),CompositeImage:(o,i,a)=>new Pe(this,o,i,a),CompositeImageBilinear:(o,i,a)=>new We(this,o,i,a),CompositePassthrough:o=>new Ge(this,o)}}static isAvailable(){let e=null;try{return e=new OffscreenCanvas(1,1).getContext("webgl2"),!(!e||!e.getExtension("EXT_color_buffer_float"))}catch{return!1}finally{e?.getExtension("WEBGL_lose_context")?.loseContext()}}static create(e){let r=e.canvas.getContext("webgl2");if(!r)throw new Error("WebGL2 not available");if(!r.getExtension("EXT_color_buffer_float"))throw new Error("EXT_color_buffer_float not available");return new s(r,e.canvas,e.dtype??"f32")}bindDisplayFramebuffer(){this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.viewport(0,0,this.canvas.width,this.canvas.height)}toTextureView(e){if(e===null)return null;let r=this.dtype==="f16",t=e instanceof Uint16Array;return r===t?e:r?Q(e):A(e)}tensor(e,r,t,o){let i=r*(t/4),a=e,u=this.gl,p=u.createTexture(),l=this.textureFormat,d=this.toTextureView(o??null);return u.bindTexture(u.TEXTURE_2D,p),u.texImage2D(u.TEXTURE_2D,0,l.internalFormat,i,a,0,l.format,l.type,d),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_MIN_FILTER,u.NEAREST),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_MAG_FILTER,u.NEAREST),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_WRAP_S,u.CLAMP_TO_EDGE),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_WRAP_T,u.CLAMP_TO_EDGE),{h:e,w:r,c:t,texture:p,texW:i,texH:a}}upload(e){return{data:e}}async readback(e){let r=this.gl,t=this.textureFormat;if(r.bindFramebuffer(r.FRAMEBUFFER,this.fbo),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,e.texture,0),this.dtype==="f16"){let i=new Uint16Array(e.texW*e.texH*4);return r.readPixels(0,0,e.texW,e.texH,t.format,r.HALF_FLOAT,i),r.bindFramebuffer(r.FRAMEBUFFER,null),A(i)}let o=new Float32Array(e.texW*e.texH*4);return r.readPixels(0,0,e.texW,e.texH,t.format,r.FLOAT,o),r.bindFramebuffer(r.FRAMEBUFFER,null),o}async sync(){let e=this.gl,r=e.fenceSync(e.SYNC_GPU_COMMANDS_COMPLETE,0);if(!r){e.finish();return}for(e.flush();;){let t=e.clientWaitSync(r,0,0);if(t===e.ALREADY_SIGNALED||t===e.CONDITION_SATISFIED){e.deleteSync(r);return}if(t===e.WAIT_FAILED)throw e.deleteSync(r),new Error("WebGLBackend.sync: clientWaitSync returned WAIT_FAILED");await new Promise(o=>setTimeout(o,1))}}destroy(){this.gl.deleteFramebuffer(this.fbo),this.gl.getExtension("WEBGL_lose_context")?.loseContext()}};var Le=P("setup_backend");async function At(s,e,r={}){let t=s.backend==="webgpu"||s.backend==="auto",o=!!s.outputCanvas,i=()=>s.outputCanvas??new OffscreenCanvas(e.w,e.h),a=null;if(t&&await F.isAvailable()){let p=s.dtype==="f16"&&!await F.hasF16Support()?"f32":s.dtype,l=i();try{let d=await F.create({canvas:l,dtype:p});return d.device.lost.then(m=>{m.reason!=="destroyed"&&r.onContextLost?.({message:\`WebGPU device lost: \${m.reason}\${m.message?" \\u2014 "+m.message:""}\`,source:"backend-lost",recoverable:!1,cause:m})}).catch(()=>{}),{backend:d,resolvedBackend:"webgpu",resolvedDtype:p,canvas:l}}catch(d){Le.warn("WebGPU isAvailable but create() threw; trying WebGL fallback:",d),a=d,o&&Le.warn("transfer-capture topology: WebGL fallback may also fail on the same canvas")}}if(U.isAvailable()){let p=i();try{let l=U.create({canvas:p,dtype:s.dtype});return p.addEventListener("webglcontextlost",d=>{r.onContextLost?.({message:"WebGL context lost",source:"backend-lost",recoverable:!1,cause:d})}),{backend:l,resolvedBackend:"webgl",resolvedDtype:s.dtype,canvas:p}}catch(l){Le.warn("WebGL create() threw:",l),a=l}}let u=a?\` (last error: \${a.message??a})\`:"";throw new Error(\`setup_backend: no usable GPU backend\${u}\`)}var Ue=.5,uo=3,Ft=10,po=30,S=P("autotune"),Ot={xxs:k,xs:k,small:k,compact:E,medium:W,large:W,xl:I};async function Mt(s,e=po){s instanceof U&&(Ue=Ue*.5);let r=1e3/e*Ue;S(\`start; budget per source frame: \${r.toFixed(1)}ms (source \${e}fps \\xD7 \${Ue} safety)\`),S("backend dtype:",s.dtype);let t=null;for(let o of Ie){if(!Ot[o.model]){S("skip",o.model,"(network class not implemented in TS yet)");continue}try{S(\`bench \${o.model} @ \${o.resolution.w}\\xD7\${o.resolution.h} skipFrames=\${o.skipFrames} \\u2026\`);let i=await mo(s,o),a=i<=r;if(S(\` \${o.model}: \${i.toFixed(1)}ms / source frame \${a?"\\u2713 within budget":"\\u2717 over budget"}\`),(a||t===null)&&(t=o),!a)break}catch(i){S(" bench failed for",o.model,":",i);break}}if(!t)throw new Error("autotune: no implementable preset available");return S("picked",t.model),t}function lo(s){let e=Object.create(s);return e.ops={...s.ops,Conv2d:(r,t,o)=>{let i={weights:new Float32Array(o.kernel*o.kernel*r.c*o.outChannels),bias:new Float32Array(o.outChannels)};return s.ops.Conv2d(r,i,o)},DepthwiseConv2d:(r,t,o)=>{let i={weights:new Float32Array(o.kernel*o.kernel*r.c),bias:new Float32Array(r.c)};return s.ops.DepthwiseConv2d(r,i,o)},Conv2dAdd:(r,t,o,i)=>{let a={weights:new Float32Array(i.kernel*i.kernel*r.c*i.outChannels),bias:new Float32Array(i.outChannels)};return s.ops.Conv2dAdd(r,t,a,i)},UpsampleConv1x1:(r,t,o)=>{let i={weights:new Float32Array(r.c*o.outChannels),bias:new Float32Array(o.outChannels)};return s.ops.UpsampleConv1x1(r,i,o)}},e}function co(){let s=new Proxy({},{get:()=>s});return s}async function mo(s,e){let r=Ot[e.model];if(!r)throw new Error(\`microbench: no network class for '\${e.model}'\`);let t=lo(s),o=t.tensor(e.resolution.h,e.resolution.w,4),i=new r(t,o,co());for(let l=0;l<uo;l++)i.run(),await s.sync();let a=e.skipFrames+1,u=performance.now();for(let l=0;l<Ft;l++)l%a===0&&i.run();return await s.sync(),(performance.now()-u)/Ft}async function Rt(s,e,r){let t;if(s==="auto")t=await Mt(r);else if(typeof s=="string"){let o=V(s);if(!o)throw new Error(\`resolve_preset: unknown preset name '\${s}'\`);t=o}else t=s;return t.dtype!==e?{...t,dtype:e}:t}function Dt(s){let e=null,r=null;return s.onmessage=t=>{let{frame:o}=t.data;if(r){let i=r;r=null,i(o)}else e&&e.close(),e=o},s.start?.(),new ReadableStream({pull(t){if(e){t.enqueue(e),e=null;return}return new Promise(o=>{r=i=>{t.enqueue(i),o()}})},cancel(){e&&(e.close(),e=null),s.close()}},{highWaterMark:0})}function Ht(s){switch(s.topology.input){case"mstp":if(!s.inputReadable)throw new Error("create_input: topology.input='mstp' but InitData.inputReadable missing");return s.inputReadable;case"rvfc-postmessage":if(!s.inputPort)throw new Error("create_input: topology.input='rvfc-postmessage' but InitData.inputPort missing");return Dt(s.inputPort)}}function Vt(s){return new TransformStream({transform(e,r){s.process(e);let t=new VideoFrame(s.canvas,{timestamp:e.timestamp});e.close(),r.enqueue(t)}})}function Nt(s){return new WritableStream({write(e){s.process(e),e.close()}})}function zt(s,e){return new WritableStream({write(r){s.process(r),r.close();let t=s.canvas.transferToImageBitmap();e.postMessage({bmp:t},[t])},close(){e.close()}})}var ho=P("create_output");function Xt(s,e,r){switch(s.topology.output){case"mstg":{if(!s.outputWritable)throw new Error("create_output: topology.output='mstg' but InitData.outputWritable missing");let t=Vt(e);return t.readable.pipeTo(s.outputWritable,{signal:r}).catch(o=>{r.aborted||ho.warn("mstg downstream pipe failed:",o)}),t.writable}case"transfer-capture":return Nt(e);case"bitmap-shuttle":{if(!s.outputPort)throw new Error("create_output: topology.output='bitmap-shuttle' but InitData.outputPort missing");return zt(e,s.outputPort)}}}function $t(s){if(!s.onFirstFrame)return s.input.pipeTo(s.output,{signal:s.signal});let e=!1,r=s.onFirstFrame,t=new TransformStream({transform(o,i){i.enqueue(o),e||(e=!0,queueMicrotask(r))}});return s.input.pipeThrough(t,{signal:s.signal}).pipeTo(s.output,{signal:s.signal})}var _=P("worker");_("script loaded");var w=null,O=null,Se=null;self.onmessage=async function(s){let{cmd:e,data:r,request_id:t}=s.data;_("cmd received:",e,"request_id:",t);try{let o=await fo(e,r);_("cmd ok:",e),Co(t,o)}catch(o){_("cmd FAILED:",e,o),H("error",{message:\`\${e} failed: \${o.message??String(o)}\`,source:"worker",recoverable:!1,cause:o})}};async function fo(s,e){switch(s){case"init":return go(e);case"startRender":return _o(e.weights);case"setBackground":return bo(e);case"setEnabled":return vo(e.enabled);case"setPreset":return yo(e);case"getStats":return w?.getStats()??null;case"destroy":return xo();default:throw new Error(\`unknown cmd: \${s}\`)}}async function go(s){if(Ae(!!s.debug),_("handleInit: start; topology=",s.topology,"preset=",s.preset,"backend=",s.backend,"dtype=",s.dtype),w)throw new Error("handleInit: already initialized");_("handleInit: setupBackend\\u2026");let e=await At(s,s.canvasSize,{onContextLost:i=>{_("GPU context lost:",i.message),H("error",i)}});_("handleInit: backend ready:",e.resolvedBackend,e.resolvedDtype,"canvas:",e.canvas.width,"x",e.canvas.height),_("handleInit: constructing Renderer (boot mode)\\u2026"),w=new Y({backend:e.backend,backendKind:e.resolvedBackend,canvas:e.canvas,background:s.background,enabled:s.enabled,topology:s.topology}),O=new AbortController,_("handleInit: createInputStream\\u2026");let r=Ht(s);_("handleInit: createOutputSink\\u2026");let t=Xt(s,w,O.signal);_("handleInit: starting pipe (passthrough)\\u2026"),$t({input:r,output:t,signal:O.signal}).then(()=>{_("pipe completed (input ended)")}).catch(i=>{if(O?.signal.aborted){_("pipe aborted (expected on destroy)");return}_("pipe FAILED:",i),H("error",{message:\`pipe failed: \${i.message}\`,source:"worker",recoverable:!1,cause:i})}),_("handleInit: resolvePreset\\u2026");let o=await Rt(s.preset,e.resolvedDtype,e.backend);return _("handleInit: preset resolved:",o),Se=o,_("handleInit: done; returning InitResponse, awaiting startRender"),{resolvedPreset:o,resolvedBackend:e.resolvedBackend,resolvedDtype:e.resolvedDtype}}async function _o(s){if(_("handleStartRender: start; weights bytes:",s.byteLength),!w||!Se)throw new Error("handleStartRender: handleInit not completed");_("handleStartRender: attaching network via setPreset\\u2026"),w.setPreset(Se,s),_("handleStartRender: ready (effect mode active)"),H("ready",void 0)}async function bo(s){w?.setBackground(s)}async function vo(s){w?.setEnabled(s)}async function yo(s){if(!w)throw new Error("handleSetPreset: not initialized");if(!s.weights)throw new Error("handleSetPreset: weights required for runtime preset swap");if(s.preset==="auto")throw new Error("handleSetPreset: 'auto' not supported on runtime swap (use at init for autotune)");let e=typeof s.preset=="string"?V(s.preset)??wo(s.preset):s.preset;return w.setPreset(e,s.weights),{resolvedPreset:e}}async function xo(){O?.abort(),O=null,w?.destroy(),w=null,Se=null}function wo(s){throw new Error(\`handleSetPreset: unknown preset '\${s}'\`)}function Co(s,e){let r={request_id:s,res:e};self.postMessage(r)}function H(s,e){let r={request_id:s,res:e};self.postMessage(r)}function al(s){H("stats",s)}export{al as emitStats};
|
|
2463
|
-
`;var x=_("pipeline");function
|
|
2463
|
+
`;var x=_("pipeline");function _t(){{let n=new Blob([re],{type:"application/javascript"}),t=URL.createObjectURL(n),e=new Worker(t,{type:"module"});return URL.revokeObjectURL(t),e}}var bt="https://cdn.longpipe.dev/models/v/0.0.1/",vt={background:"blur",preset:"auto",weightsBaseUrl:bt,audio:"passthrough",enabled:true,adaptive:true,debug:false},xe={w:1280,h:720};function wt(n,t){if(t)return t;let r=n.getVideoTracks()[0]?.getSettings()??{};return {w:r.width||xe.w,h:r.height||xe.h}}function ye(n,t){return `${n.replace(/\/$/,"")}/model_${t}.bin`}var ne=class{stream;ready;controller;worker;inputCleanup;outputCleanup;adaptive=null;bgCleanup=null;constructor(t,e){let r={...vt,...e};se(r.debug);let i=ce(),a=ge(i.input,t),s=wt(t,r.outputResolution),o=we(i.output,s);this.inputCleanup=a.cleanup,this.outputCleanup=o.cleanup,this.stream=de(o.videoTrack,t,r.audio),o.startPassthrough?.(t),this.worker=_t(),this.controller=new A(this.worker),this.ready=new Promise((p,l)=>{this.controller.addPersistentListener("ready",()=>{x("ready handler invoked; resolving .ready"),r.onReady?.(),p();}),this.controller.addPersistentListener("error",h=>{console.error(`[longpipe/pipeline] error (${h.source}):`,h.message),h.recoverable||l(new Error(h.message)),r.onError?.(h);});});let u={topology:i,preset:r.preset,enabled:r.enabled,backend:"auto",dtype:"f16",canvasSize:s,debug:r.debug,...a.initFields,...o.initFields},c=[...a.transferList,...o.transferList];this.bootstrap(u,r.background,c,r.weightsBaseUrl,r.adaptive,r.onError);}async bootstrap(t,e,r,i,a,s){try{x("normalizing background\u2026");let o=await te(e);this.bgCleanup=o.cleanup??null;let u={...t,background:o.background},c=[...r,...o.transferList??[]];x("sending init\u2026");let p=await this.controller.sendMessage("init",u,c);x("init resolved:",p);let l=ye(i,p.resolvedPreset.model);x("fetching weights:",l);let h=await fetch(l);if(!h.ok)throw new Error(`weights fetch failed: ${h.status} ${l}`);let g=await h.arrayBuffer();x("weights bytes:",g.byteLength),x("sending startRender\u2026"),await this.controller.sendMessage("startRender",{weights:g},[g]),x("startRender resolved; awaiting first frame"),u.preset==="auto"&&a&&(this.adaptive=new W({backendKind:p.resolvedBackend,initialModel:p.resolvedPreset.model,weightsBaseUrl:i,buildWeightsUrl:ye,getStats:()=>this.getStats(),swapPreset:async(T,J)=>{await this.controller.sendMessage("setPreset",{preset:T,weights:J},[J]);},onError:s}),this.adaptive.start());}catch(o){console.error("[longpipe/pipeline] bootstrap failed:",o),this.controller.handleMessage.call(this.controller,{data:{request_id:"error",res:{message:o.message??String(o),source:"worker",recoverable:false,cause:o}}});}}then(t,e){return this.ready.then(()=>t?t(this):this,e)}async setBackground(t){let e=await te(t),r=this.bgCleanup;this.bgCleanup=e.cleanup??null,await this.controller.sendMessage("setBackground",e.background,e.transferList),r?.();}setPreset(t,e){this.controller.sendMessage("setPreset",{preset:t,weights:e});}setEnabled(t){this.controller.sendMessage("setEnabled",{enabled:t});}async getStats(){return this.controller.sendMessage("getStats",{})}destroy(){this.adaptive?.stop(),this.adaptive=null,this.bgCleanup?.(),this.bgCleanup=null,this.controller.sendMessage("destroy",{}),this.controller.terminate(),this.inputCleanup(),this.outputCleanup();}};var P=new Float32Array(1),I=new Uint32Array(P.buffer);function xt(n){P[0]=n;let t=I[0],e=t>>>16&32768,r=t&2147483647,i=(r>>>23)-127+15;if((t&2139095040)===2139095040)return (t&8388607)!==0?e|32256:e|31744;if(i>=31)return e|31744;if(i<=0){if(i<-10)return e;let c=r&8388607|8388608,p=14-i,l=c>>>p,h=c>>>p-1&1,g=(c&(1<<p-1)-1)!==0?1:0;return h&&(g||l&1)&&(l+=1),e|l}let a=r>>>13&1023,s=r>>>12&1,o=(r&4095)!==0?1:0,u=i<<10|a;return s&&(o||a&1)&&(u+=1,(u>>>10&31)===31)?e|31744:e|u}function yt(n){let t=(n&32768)<<16,e=(n&31744)>>>10,r=n&1023;if(e===0){if(r===0)return I[0]=t,P[0];let i=r,a=1;for(;(i&1024)===0;)i<<=1,a-=1;return i&=1023,I[0]=t|a+127-15<<23|i<<13,P[0]}return e===31?(I[0]=t|2139095040|r<<13,P[0]):(I[0]=t|e+127-15<<23|r<<13,P[0])}function ke(n){let t=new Uint16Array(n.length);for(let e=0;e<n.length;e++)t[e]=xt(n[e]);return t}function ie(n){let t=new Float32Array(n.length);for(let e=0;e<n.length;e++)t[e]=yt(n[e]);return t}var d=class{constructor(t){this.backend=t;}backend;shader="";pipeline;bindGroup;uniformDefs=[];uniformBuffers={};createUniform(t,e){this.uniformDefs.push({name:t,type:e});}setUniform(t,e){let r=this.backend.device.createBuffer({size:e.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:true});e instanceof Uint32Array?new Uint32Array(r.getMappedRange()).set(e):new Float32Array(r.getMappedRange()).set(e),r.unmap(),this.uniformBuffers[t]=r;}defaultBindGroup(){let t=[],e=0;for(let r of this.inputs)t.push({binding:e++,resource:{buffer:r.buffer}});for(let r of this.weights)t.push({binding:e++,resource:{buffer:r.buffer}});for(let r of this.uniformDefs)t.push({binding:e++,resource:{buffer:this.uniformBuffers[r.name]}});return t.push({binding:e,resource:{buffer:this.output.buffer}}),this.backend.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:t})}defaultSetup(){let t=this.backend.device.createShaderModule({code:this.shader});this.pipeline=this.backend.device.createComputePipeline({layout:"auto",compute:{module:t,entryPoint:"main"}}),this.bindGroup=this.defaultBindGroup();}run(){let t=this.backend.device.createCommandEncoder(),e=t.beginComputePass();e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.dispatchWorkgroups(...this.dispatch),e.end(),this.backend.device.queue.submit([t.finish()]);}};var Ce=`// Conv2d compute shader \u2014 handles all variants:
|
|
2464
2464
|
// 1\xD71 (pointwise), 3\xD73, 5\xD75, strided, BN-fused
|
|
2465
2465
|
//
|
|
2466
2466
|
// Tensor layout: NHWC with channels in vec4 groups
|
|
@@ -2616,7 +2616,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
2616
2616
|
|
|
2617
2617
|
output_buf[y * params.out_w * O + x * O + o] = result;
|
|
2618
2618
|
}
|
|
2619
|
-
`;function b(
|
|
2619
|
+
`;function b(n,t,e,r){return typeof r=="number"?Math.floor((n+2*r-t)/e)+1:r==="same"?Math.ceil(n/e):Math.floor((n-t)/e)+1}function Pt(n,t,e,r){return Math.floor(Math.max((t-1)*r+e-n,0)/2)}function v(n,t,e,r,i){return typeof n=="number"?n:n==="same"?Pt(t,e,r,i):0}function f(n){return n instanceof Float32Array||n instanceof Uint16Array?n:new Float32Array(n)}var F=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,i){super(t),this.shader=t.dtype==="f16"?Pe:Ce;let a=b(e.h,i.kernel,i.stride,i.padding),s=b(e.w,i.kernel,i.stride,i.padding),o=e.c/4,u=i.outChannels/4,c=v(i.padding,e.h,a,i.kernel,i.stride),p=v(i.padding,e.w,s,i.kernel,i.stride);this.output=t.tensor(a,s,i.outChannels),this.inputs=[e],this.weights=[t.upload(f(r.weights)),t.upload(f(r.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,a,s,o,u,i.kernel,i.kernel,i.stride,c,p,i.activation==="relu6"?1:0])),this.defaultSetup(),this.dispatch=[Math.ceil(s/8),Math.ceil(a/8),u];}};var Ie=`// Depthwise Conv2d \u2014 groups = in_channels (each channel convolved independently).
|
|
2620
2620
|
//
|
|
2621
2621
|
// Weight layout: [K*K][channel_groups] array of vec4
|
|
2622
2622
|
// weight index = (ky*kernel_w + kx) * channel_groups + c
|
|
@@ -2756,7 +2756,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
2756
2756
|
|
|
2757
2757
|
output_buf[y * params.out_w * C + x * C + c] = result;
|
|
2758
2758
|
}
|
|
2759
|
-
`;var O=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,
|
|
2759
|
+
`;var O=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,i){super(t),this.shader=t.dtype==="f16"?Te:Ie;let a=b(e.h,i.kernel,i.stride,i.padding),s=b(e.w,i.kernel,i.stride,i.padding),o=e.c/4,u=v(i.padding,e.h,a,i.kernel,i.stride),c=v(i.padding,e.w,s,i.kernel,i.stride);this.output=t.tensor(a,s,e.c),this.inputs=[e],this.weights=[t.upload(f(r.weights)),t.upload(f(r.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,a,s,o,i.kernel,i.kernel,i.stride,u,c,i.activation==="relu6"?1:0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(s/8),Math.ceil(a/8),o];}};var Ue=`// Element-wise add of two tensors \u2014 used for residual connections in MBConv blocks.
|
|
2760
2760
|
// Operates on the flat float buffer directly; layout is irrelevant for a pure element-wise op.
|
|
2761
2761
|
|
|
2762
2762
|
struct Params {
|
|
@@ -2800,7 +2800,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
2800
2800
|
if (idx >= params.size) { return; }
|
|
2801
2801
|
output[idx] = input_a[idx] + input_b[idx];
|
|
2802
2802
|
}
|
|
2803
|
-
`;var M=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Se:Ue;let
|
|
2803
|
+
`;var M=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Se:Ue;let i=e.h*e.w*e.c;this.output=t.tensor(e.h,e.w,e.c),this.inputs=[e,r],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([i,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(i/256),1,1];}};var Ee=`// Element-wise sigmoid: output = 1 / (1 + exp(-x)).
|
|
2804
2804
|
// Operates on packed vec4 buffers (NHWC layout). exp() and arithmetic are element-wise on vec4.
|
|
2805
2805
|
|
|
2806
2806
|
struct Params {
|
|
@@ -2956,7 +2956,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
2956
2956
|
|
|
2957
2957
|
output_buf[oy * params.out_w * C + ox * C + c] = vec4<f16>(result);
|
|
2958
2958
|
}
|
|
2959
|
-
`;var D=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Ge:Be;let
|
|
2959
|
+
`;var D=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Ge:Be;let i=e.c/4;this.output=t.tensor(r.outH,r.outW,e.c),this.inputs=[e],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,r.outH,r.outW,i,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(r.outW/8),Math.ceil(r.outH/8),i];}};var Ae=`// Bicubic upsample (arbitrary scale) \u2014 Keys cubic, a=-0.75 (PyTorch default
|
|
2960
2960
|
// for mode='bicubic', align_corners=False). Direct 2D, 4\xD74 = 16 taps per
|
|
2961
2961
|
// output pixel. NHWC vec4 layout: index = y*W*(C/4) + x*(C/4) + c_group.
|
|
2962
2962
|
|
|
@@ -3092,7 +3092,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3092
3092
|
|
|
3093
3093
|
output_buf[oy * params.out_w * C + ox * C + c] = vec4<f16>(acc);
|
|
3094
3094
|
}
|
|
3095
|
-
`;var H=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Fe:Ae;let
|
|
3095
|
+
`;var H=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Fe:Ae;let i=e.c/4;this.output=t.tensor(r.outH,r.outW,e.c),this.inputs=[e],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,r.outH,r.outW,i,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(r.outW/8),Math.ceil(r.outH/8),i];}};var Oe=`// Channel concatenation: output = cat(A, B, dim=channel).
|
|
3096
3096
|
// Both A and B must share the same H\xD7W and be in NHWC vec4 format.
|
|
3097
3097
|
// Output layout: for each (y, x), the first a_groups vec4s come from A,
|
|
3098
3098
|
// followed by b_groups vec4s from B.
|
|
@@ -3178,7 +3178,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3178
3178
|
output_buf[out_idx] = input_b[y * W * Bg + x * Bg + c_b];
|
|
3179
3179
|
}
|
|
3180
3180
|
}
|
|
3181
|
-
`;var L=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Me:Oe;let
|
|
3181
|
+
`;var L=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Me:Oe;let i=e.c/4,a=r.c/4,s=i+a;this.output=t.tensor(e.h,e.w,e.c+r.c),this.inputs=[e,r],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,i,a,s,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),s];}};var Re=`// Conv2d + skip add fused.
|
|
3182
3182
|
// Identical to conv2d.wgsl except skip is an activation input (binding 1),
|
|
3183
3183
|
// added element-wise to the conv result at write time.
|
|
3184
3184
|
// Eliminates the separate add dispatch and its intermediate buffer round-trip.
|
|
@@ -3326,7 +3326,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3326
3326
|
let out_idx = y * params.out_w * O + x * O + o;
|
|
3327
3327
|
output_buf[out_idx] = result + skip_buf[out_idx];
|
|
3328
3328
|
}
|
|
3329
|
-
`;var V=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,
|
|
3329
|
+
`;var V=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,i,a){super(t),this.shader=t.dtype==="f16"?De:Re;let s=b(e.h,a.kernel,a.stride,a.padding),o=b(e.w,a.kernel,a.stride,a.padding),u=e.c/4,c=a.outChannels/4,p=v(a.padding,e.h,s,a.kernel,a.stride),l=v(a.padding,e.w,o,a.kernel,a.stride);this.output=t.tensor(s,o,a.outChannels),this.inputs=[e,r],this.weights=[t.upload(f(i.weights)),t.upload(f(i.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,s,o,u,c,a.kernel,a.kernel,a.stride,p,l,a.activation==="relu6"?1:0])),this.defaultSetup(),this.dispatch=[Math.ceil(o/8),Math.ceil(s/8),c];}};var He=`// Bilinear upsample + channel concat fused.
|
|
3330
3330
|
// input_a is the decoder tensor at small spatial resolution (in_h \xD7 in_w).
|
|
3331
3331
|
// input_b is the encoder skip feature already at output resolution (out_h \xD7 out_w).
|
|
3332
3332
|
// For output channels 0..a_groups-1: bilinearly interpolate from input_a.
|
|
@@ -3447,7 +3447,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3447
3447
|
output_buf[out_idx] = input_b[oy * params.out_w * params.b_groups + ox * params.b_groups + c_b];
|
|
3448
3448
|
}
|
|
3449
3449
|
}
|
|
3450
|
-
`;var z=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r,
|
|
3450
|
+
`;var z=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r,i){super(t),this.shader=t.dtype==="f16"?Le:He;let a=e.c/4,s=r.c/4,o=a+s;this.output=t.tensor(i.outH,i.outW,e.c+r.c),this.inputs=[e,r],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,i.outH,i.outW,a,s,o,0])),this.defaultSetup(),this.dispatch=[Math.ceil(i.outW/8),Math.ceil(i.outH/8),o];}};var Ve=`// Bilinear upsample + 1\xD71 pointwise conv fused.
|
|
3451
3451
|
// For each output pixel, bilinearly samples the small input for each in_group,
|
|
3452
3452
|
// immediately applies the 1\xD71 conv weights, and writes the activated result.
|
|
3453
3453
|
// Eliminates the intermediate full-resolution upsample buffer.
|
|
@@ -3581,7 +3581,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3581
3581
|
|
|
3582
3582
|
output_buf[oy * params.out_w * params.out_groups + ox * params.out_groups + og] = result;
|
|
3583
3583
|
}
|
|
3584
|
-
`;var N=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,
|
|
3584
|
+
`;var N=class extends d{inputs;weights;output;dispatch;shader;constructor(t,e,r,i){super(t),this.shader=t.dtype==="f16"?ze:Ve;let a=e.c/4,s=i.outChannels/4;this.output=t.tensor(i.outH,i.outW,i.outChannels),this.inputs=[e],this.weights=[t.upload(f(r.weights)),t.upload(f(r.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,i.outH,i.outW,a,s,i.activation==="relu6"?1:0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(i.outW/8),Math.ceil(i.outH/8),s];}};var Ne=`// Bilinear upsample + sigmoid fused.
|
|
3585
3585
|
// Identical to bilinear_upsample.wgsl except sigmoid is applied at write time.
|
|
3586
3586
|
// Eliminates the intermediate full-resolution buffer and the separate sigmoid dispatch.
|
|
3587
3587
|
|
|
@@ -3690,7 +3690,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3690
3690
|
|
|
3691
3691
|
output_buf[oy * params.out_w * C + ox * C + c] = vec4<f16>(1.0 / (1.0 + exp(-result)));
|
|
3692
3692
|
}
|
|
3693
|
-
`;var $=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?$e:Ne;let
|
|
3693
|
+
`;var $=class extends d{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?$e:Ne;let i=e.c/4;this.output=t.tensor(r.outH,r.outW,e.c),this.inputs=[e],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,r.outH,r.outW,i,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(r.outW/8),Math.ceil(r.outH/8),i];}};var qe=`// Composite an RGBA image over a solid background, gated by a 1-ch alpha.
|
|
3694
3694
|
// Fragment writes the canvas's swapchain texture (premultiplied output).
|
|
3695
3695
|
//
|
|
3696
3696
|
// Caller invariants (matched in CompositeSolidWebGPU):
|
|
@@ -3784,7 +3784,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
3784
3784
|
let rgb = fg * a + params.bgColor.rgb * (1.0 - a);
|
|
3785
3785
|
return vec4<f32>(rgb, 1.0);
|
|
3786
3786
|
}
|
|
3787
|
-
`;var q=class{constructor(t,e,r,
|
|
3787
|
+
`;var q=class{constructor(t,e,r,i){this.backend=t;if(e.h!==r.h||e.w!==r.w)throw new Error(`CompositeSolid: image (${e.h}\xD7${e.w}) and alpha (${r.h}\xD7${r.w}) must match. Run the upscaler first.`);let a=t.device;this.uniformBuffer=a.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let s=new ArrayBuffer(32);new Uint32Array(s,0,1)[0]=e.w,new Float32Array(s,16,4).set([i[0],i[1],i[2],0]),a.queue.writeBuffer(this.uniformBuffer,0,s);let o=t.dtype==="f16"?Xe:qe,u=a.createShaderModule({code:o});this.pipeline=a.createRenderPipeline({layout:"auto",vertex:{module:u,entryPoint:"vs"},fragment:{module:u,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=a.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:r.buffer}},{binding:2,resource:{buffer:this.uniformBuffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositeSolidWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var je=`// Like composite_solid but bg is an NHWC vec4 storage buffer (e.g. virtual
|
|
3788
3788
|
// background image, or a blurred copy of the input).
|
|
3789
3789
|
|
|
3790
3790
|
struct VertexOut {
|
|
@@ -3870,7 +3870,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
3870
3870
|
let rgb = fg * a + bgc * (1.0 - a);
|
|
3871
3871
|
return vec4<f32>(rgb, 1.0);
|
|
3872
3872
|
}
|
|
3873
|
-
`;var X=class{constructor(t,e,r,
|
|
3873
|
+
`;var X=class{constructor(t,e,r,i){this.backend=t;if(e.h!==r.h||e.w!==r.w||e.h!==i.h||e.w!==i.w)throw new Error(`CompositeImage: image (${e.h}\xD7${e.w}), alpha (${r.h}\xD7${r.w}), and bg (${i.h}\xD7${i.w}) must all match. Run upscaler / resizer first.`);let a=t.device;this.uniformBuffer=a.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let s=new ArrayBuffer(16);new Uint32Array(s,0,1)[0]=e.w,a.queue.writeBuffer(this.uniformBuffer,0,s);let o=t.dtype==="f16"?Ke:je,u=a.createShaderModule({code:o});this.pipeline=a.createRenderPipeline({layout:"auto",vertex:{module:u,entryPoint:"vs"},fragment:{module:u,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=a.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:r.buffer}},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:i.buffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositeImageWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var Ye=`// Like composite_image but bg is sampled bilinearly \u2014 bg may be smaller than
|
|
3874
3874
|
// (image, alpha). Used by CompositorBlur to skip the final full-res upsample
|
|
3875
3875
|
// in the blur pyramid and let this shader's own per-pixel scan do the
|
|
3876
3876
|
// expansion (the work is already happening here for the composite anyway).
|
|
@@ -3996,7 +3996,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
3996
3996
|
let rgb = fg * a + bgc * (1.0 - a);
|
|
3997
3997
|
return vec4<f32>(rgb, 1.0);
|
|
3998
3998
|
}
|
|
3999
|
-
`;var j=class{constructor(t,e,r,
|
|
3999
|
+
`;var j=class{constructor(t,e,r,i){this.backend=t;if(e.h!==r.h||e.w!==r.w)throw new Error(`CompositeImageBilinear: image (${e.h}\xD7${e.w}) and alpha (${r.h}\xD7${r.w}) must match.`);let a=t.device;this.uniformBuffer=a.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let s=new ArrayBuffer(16),o=new Uint32Array(s);o[0]=e.w,o[1]=e.h,o[2]=i.w,o[3]=i.h,a.queue.writeBuffer(this.uniformBuffer,0,s);let u=t.dtype==="f16"?Je:Ye,c=a.createShaderModule({code:u});this.pipeline=a.createRenderPipeline({layout:"auto",vertex:{module:c,entryPoint:"vs"},fragment:{module:c,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=a.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:r.buffer}},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:i.buffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositeImageBilinearWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var Qe=`// Passthrough "compositor" \u2014 writes the image directly to the canvas
|
|
4000
4000
|
// swapchain texture with no alpha math and no background. Used by RenderOp
|
|
4001
4001
|
// when the renderer is in disabled state, so the output canvas reflects
|
|
4002
4002
|
// the unmodified input frame instead of a stale matted result.
|
|
@@ -4070,7 +4070,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
4070
4070
|
let i = y * params.width + x;
|
|
4071
4071
|
return vec4<f32>(vec3<f32>(image[i].rgb), 1.0);
|
|
4072
4072
|
}
|
|
4073
|
-
`;var K=class{constructor(t,e){this.backend=t;let r=t.device;this.uniformBuffer=r.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let
|
|
4073
|
+
`;var K=class{constructor(t,e){this.backend=t;let r=t.device;this.uniformBuffer=r.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let i=new ArrayBuffer(16);new Uint32Array(i,0,1)[0]=e.w,r.queue.writeBuffer(this.uniformBuffer,0,i);let a=t.dtype==="f16"?Ze:Qe,s=r.createShaderModule({code:a});this.pipeline=r.createRenderPipeline({layout:"auto",vertex:{module:s,entryPoint:"vs"},fragment:{module:s,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=r.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:this.uniformBuffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositePassthroughWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var et=`// Input op \u2014 sample a regular 2D source texture (RGBA8 unorm) into the NHWC
|
|
4074
4074
|
// vec4<f32> output buffer at the target resolution. Used for ImageBitmap
|
|
4075
4075
|
// sources, which are uploaded into a persistent staging texture via
|
|
4076
4076
|
// copyExternalImageToTexture before each dispatch.
|
|
@@ -4190,4 +4190,4 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4190
4190
|
let rgba = textureSampleBaseClampToEdge(src_tex, src_sampler, uv);
|
|
4191
4191
|
output_buf[y * params.out_w + x] = vec4<f16>(rgba);
|
|
4192
4192
|
}
|
|
4193
|
-
`;var
|
|
4193
|
+
`;var ir=n=>typeof VideoFrame<"u"&&n instanceof VideoFrame,Y=class{output;device;dtype;sampler;uniformBuffer;dispatch;pipeline2d=null;pipelineExternal=null;stagingTex=null;stagingW=0;stagingH=0;source=null;constructor(t,e,r){this.device=t.device,this.dtype=t.dtype,this.output=t.tensor(e,r,4),this.sampler=this.device.createSampler({magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),this.uniformBuffer=this.device.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let i=new ArrayBuffer(16);new Uint32Array(i,0,2).set([r,e]),this.device.queue.writeBuffer(this.uniformBuffer,0,i),this.dispatch=[Math.ceil(r/8),Math.ceil(e/8),1],this.pipeline2d=this.buildPipeline(this.dtype==="f16"?tt:et);}setSource(t){this.source=t;}run(){if(!this.source)throw new Error("InputWebGPU.run() called before setSource()");ir(this.source)?this.runExternal(this.source):this.run2d(this.source);}run2d(t){this.ensureStagingTexture(t.width,t.height),this.device.queue.copyExternalImageToTexture({source:t,flipY:false},{texture:this.stagingTex},[t.width,t.height]);let e=this.device.createBindGroup({layout:this.pipeline2d.getBindGroupLayout(0),entries:[{binding:0,resource:this.stagingTex.createView()},{binding:1,resource:this.sampler},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:this.output.buffer}}]});this.dispatchOnce(this.pipeline2d,e);}runExternal(t){this.pipelineExternal||(this.pipelineExternal=this.buildPipeline(this.dtype==="f16"?nt:rt));let e=this.device.importExternalTexture({source:t}),r=this.device.createBindGroup({layout:this.pipelineExternal.getBindGroupLayout(0),entries:[{binding:0,resource:e},{binding:1,resource:this.sampler},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:this.output.buffer}}]});this.dispatchOnce(this.pipelineExternal,r);}ensureStagingTexture(t,e){this.stagingTex&&this.stagingW===t&&this.stagingH===e||(this.stagingTex?.destroy(),this.stagingTex=this.device.createTexture({size:[t,e,1],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),this.stagingW=t,this.stagingH=e);}buildPipeline(t){let e=this.device.createShaderModule({code:t});return this.device.createComputePipeline({layout:"auto",compute:{module:e,entryPoint:"main"}})}dispatchOnce(t,e){let r=this.device.createCommandEncoder(),i=r.beginComputePass();i.setPipeline(t),i.setBindGroup(0,e),i.dispatchWorkgroups(...this.dispatch),i.end(),this.device.queue.submit([r.finish()]);}};var ar=navigator.gpu?GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST:0,ae=class n{constructor(t,e,r){this.device=t;this.canvas=e;this.dtype=r;this.bytesPerElement=r==="f16"?2:4;let i=e.getContext("webgpu");if(!i)throw new Error("Failed to get WebGPU context from canvas");this.canvasContext=i,this.canvasFormat=navigator.gpu.getPreferredCanvasFormat(),this.canvasContext.configure({device:t,format:this.canvasFormat,alphaMode:"premultiplied"}),this.ops={Conv2d:(a,s,o)=>new F(this,a,s,o),DepthwiseConv2d:(a,s,o)=>new O(this,a,s,o),Add:(a,s)=>new M(this,a,s),Sigmoid:a=>new R(this,a),BilinearUpsample:(a,s)=>new D(this,a,s),BicubicUpsample:(a,s)=>new H(this,a,s),ChannelConcat:(a,s)=>new L(this,a,s),Conv2dAdd:(a,s,o,u)=>new V(this,a,s,o,u),UpsampleConcat:(a,s,o)=>new z(this,a,s,o),UpsampleConv1x1:(a,s,o)=>new N(this,a,s,o),UpsampleSigmoid:(a,s)=>new $(this,a,s),Input:(a,s)=>new Y(this,a,s)},this.presenters={CompositeSolid:(a,s,o)=>{let u=new q(this,a,s,o);return {run:()=>{u.setOutput(this.getCurrentDisplayTexture()),u.run();}}},CompositeImage:(a,s,o)=>{let u=new X(this,a,s,o);return {run:()=>{u.setOutput(this.getCurrentDisplayTexture()),u.run();}}},CompositeImageBilinear:(a,s,o)=>{let u=new j(this,a,s,o);return {run:()=>{u.setOutput(this.getCurrentDisplayTexture()),u.run();}}},CompositePassthrough:a=>{let s=new K(this,a);return {run:()=>{s.setOutput(this.getCurrentDisplayTexture()),s.run();}}}};}device;canvas;dtype;ops;presenters;canvasContext;canvasFormat;bytesPerElement;static async isAvailable(){return navigator.gpu?await navigator.gpu.requestAdapter()!==null:false}static async hasF16Support(){if(!navigator.gpu)return false;let t=await navigator.gpu.requestAdapter();return t?t.features.has("shader-f16"):false}static async create(t){let e=t.dtype??"f32",r=t.device;if(r){if(e==="f16"&&!r.features.has("shader-f16"))throw new Error("WebGPU dtype='f16' requested but supplied device lacks `shader-f16`")}else {let i=await navigator.gpu.requestAdapter();if(!i)throw new Error("WebGPU adapter not available");if(e==="f16"&&!i.features.has("shader-f16"))throw new Error("WebGPU dtype='f16' requested but adapter lacks `shader-f16` feature");r=await i.requestDevice({requiredFeatures:e==="f16"?["shader-f16"]:[]});}return new n(r,t.canvas,e)}getCurrentDisplayTexture(){return this.canvasContext.getCurrentTexture()}tensor(t,e,r,i){let s=t*e*r*this.bytesPerElement,o=this.device.createBuffer({size:s,usage:ar,mappedAtCreation:i!==void 0});if(i!==void 0){let u=o.getMappedRange();this.writeView(u,i),o.unmap();}return {h:t,w:e,c:r,buffer:o}}upload(t){let r=t.length*this.bytesPerElement,i=this.device.createBuffer({size:r,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,mappedAtCreation:true});return this.writeView(i.getMappedRange(),t),i.unmap(),{buffer:i}}writeView(t,e){let r=this.dtype==="f16",i=e instanceof Uint16Array;if(r===i){r?new Uint16Array(t).set(e):new Float32Array(t).set(e);return}r?new Uint16Array(t).set(ke(e)):new Float32Array(t).set(ie(e));}async readback(t){let e=this.device.createBuffer({size:t.buffer.size,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),r=this.device.createCommandEncoder();r.copyBufferToBuffer(t.buffer,0,e,0,t.buffer.size),this.device.queue.submit([r.finish()]),await e.mapAsync(GPUMapMode.READ);let i=e.getMappedRange(),a=this.dtype==="f16"?ie(new Uint16Array(i.slice(0))):new Float32Array(i.slice(0));return e.unmap(),e.destroy(),a}async sync(){await this.device.queue.onSubmittedWorkDone();}destroy(){this.device.destroy();}};export{ne as EffectsPipeline,ae as WebGPUBackend};
|
package/package.json
CHANGED