@overglaze/web 0.0.0-stage → 0.9.1

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.
Files changed (51) hide show
  1. package/LICENSE +98 -0
  2. package/README.md +63 -2
  3. package/desktops/desktop.js +40 -0
  4. package/desktops/fonts/DMMono-Medium.woff2 +0 -0
  5. package/desktops/fonts/DMMono-Regular.woff2 +0 -0
  6. package/desktops/fonts/NotoSerif-VF.woff2 +0 -0
  7. package/desktops/fonts/OFL-DMMono.txt +93 -0
  8. package/desktops/fonts/OFL-NotoSerif.txt +93 -0
  9. package/desktops/fonts/OFL-SpaceGrotesk.txt +93 -0
  10. package/desktops/fonts/SpaceGrotesk-Bold.woff2 +0 -0
  11. package/desktops/fonts/SpaceGrotesk-Medium.woff2 +0 -0
  12. package/desktops/fonts/SpaceGrotesk-Regular.woff2 +0 -0
  13. package/desktops/wallpapers.js +227 -0
  14. package/embed.css +53 -0
  15. package/embed.js +6 -0
  16. package/engine/core.js +6 -0
  17. package/engine/cursor.js +6 -0
  18. package/engine/descriptor.js +6 -0
  19. package/engine/files.js +6 -0
  20. package/engine/globals.js +6 -0
  21. package/engine/golden-globals.js +6 -0
  22. package/engine/imgui-ops.js +6 -0
  23. package/engine/keys.js +6 -0
  24. package/engine/modules.js +6 -0
  25. package/engine/naga.wasm +0 -0
  26. package/engine/naga.wasm.notices.txt +2344 -0
  27. package/engine/ops.js +6 -0
  28. package/engine/param-store.js +6 -0
  29. package/engine/plugin-js.wasm +0 -0
  30. package/engine/plugin-js.wasm.notices.txt +4411 -0
  31. package/engine/plugin-storage.js +6 -0
  32. package/engine/session.js +9 -0
  33. package/engine/shaders.js +7 -0
  34. package/engine/tex.js +6 -0
  35. package/engine/uniforms.js +6 -0
  36. package/engine/worker.js +74 -0
  37. package/host/api.js +30 -0
  38. package/host/assets.js +6 -0
  39. package/host/bootstrap.js +7 -0
  40. package/host/imgui.js +6 -0
  41. package/host/params.js +6 -0
  42. package/host/seeded_random.js +6 -0
  43. package/host/storage.js +6 -0
  44. package/host/webio.js +6 -0
  45. package/host/webshim.js +6 -0
  46. package/package.json +19 -4
  47. package/player/fill.js +6 -0
  48. package/player/panel.css +92 -0
  49. package/player/panel.js +6 -0
  50. package/player/player.css +210 -0
  51. package/player/player.js +6 -0
@@ -0,0 +1,6 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var h=Object.defineProperty;var l=(n,t)=>h(n,"name",{value:t,configurable:!0});const a=5242880;function o(n){let t=0;for(let e=0;e<n.length;e++){const r=n.charCodeAt(e);if(r<128)t+=1;else if(r<2048)t+=2;else if(r>=55296&&r<=56319&&e+1<n.length){const i=n.charCodeAt(e+1);i>=56320&&i<=57343?(t+=4,e++):t+=3}else t+=3}return t}l(o,"utf8Length");function c(n,t){let e=0,r=0;for(;e<n.length&&r<t.length;){const i=n.codePointAt(e),s=t.codePointAt(r);if(i!==s)return i<s?-1:1;e+=i>65535?2:1,r+=s>65535?2:1}return e<n.length?1:r<t.length?-1:0}l(c,"utf8Compare");class f{static{l(this,"StorageArea")}#t=new Map;#r=0;#e=null;constructor(t){if(t&&typeof t=="object")for(const e of Object.keys(t))typeof t[e]=="string"&&this.set(e,t[e])}get(t){const e=this.#t.get(t);return e===void 0?null:e}set(t,e){const r=this.#t.get(t),i=r===void 0?0:o(t)+o(r),s=this.#r-i+o(t)+o(e);return s>5242880?!1:(r===void 0&&(this.#e=null),this.#t.set(t,e),this.#r=s,!0)}remove(t){const e=this.#t.get(t);return e===void 0?!1:(this.#t.delete(t),this.#r-=o(t)+o(e),this.#e=null,!0)}clear(){return this.#t.size===0?!1:(this.#t.clear(),this.#r=0,this.#e=null,!0)}key(t){if(t<0)return null;this.#e||(this.#e=[...this.#t.keys()].sort(c));const e=this.#e[t];return e===void 0?null:e}get length(){return this.#t.size}get bytes(){return this.#r}toObject(){return Object.fromEntries(this.#t)}}class g{static{l(this,"StorageMirror")}#t;#r;#e;constructor(t,e){this.#t=new f(t&&t.local),this.#r=new f(t&&t.session),this.#e=e}#n(t){return t?this.#r:this.#t}get(t,e){return this.#n(t).get(String(e))}set(t,e,r){const i=String(e),s=String(r);return this.#n(t).set(i,s)?(this.#e(t?"session":"local","set",i,s),!0):!1}remove(t,e){const r=String(e);this.#n(t).remove(r)&&this.#e(t?"session":"local","remove",r)}clear(t){this.#n(t).clear()&&this.#e(t?"session":"local","clear")}key(t,e){return this.#n(t).key(e)}length(t){return this.#n(t).length}}export{a as MAX_STORAGE_BYTES,f as StorageArea,g as StorageMirror,c as utf8Compare,o as utf8Length};
@@ -0,0 +1,9 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var R=Object.defineProperty;var c=(s,e)=>R(s,"name",{value:e,configurable:!0});import{StorageArea as m}from"./plugin-storage.js";import{MAX_FIELD_COMPONENTS as P,MAX_FIELDS as g,ParamStore as S}from"./param-store.js";import{keyEdge as j}from"./keys.js";import{cursorShape as b}from"./cursor.js";const A=250,D=2e3,u=50,E=25,F=100,H=5e3,W=1e3,U=1e3,w=8*1024,h=256,X=1024,K=32,G=256,V=new Set(["checkbox","combo","color","slider","drag"]),J=new Set(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","PageUp","PageDown","Home","End"]),Y=new Set(["trace","debug","info","log","warn","error"]),q={trace:"[T]",debug:"[D]",warn:"[W]",error:"[E]"},Q=new Set(["boot","evaluating","initializing","running","failed"]),$=new Set(["keys","import-meta","network","shader"]),Z=2048,ee=256,o=c((s,e)=>{const t=String(s);return t.length>e?t.slice(0,e)+" [... "+(t.length-e)+" more]":t},"text"),d=c(s=>typeof s=="number"&&isFinite(s)?s:0,"num"),te=new TextEncoder,se=new TextDecoder,ie=c((s,e)=>{const t=String(s);if(t.length*3<=e)return t;const i=te.encode(t);if(i.length<=e)return t;let r=e;for(;(i[r]&192)===128;)r--;return se.decode(i.subarray(0,r))+"... ["+(i.length-r)+" more bytes truncated]"},"clipMessage");let y={folder:null,area:null};function M(s){try{const e=localStorage.getItem(s);return e?JSON.parse(e):null}catch{return null}}c(M,"readJson");function re(s){const e={local:"overglaze.storage."+s,params:"overglaze.params."+s};return{read:c(()=>({local:M(e.local),params:M(e.params)}),"read"),write(t){try{for(const i of["local","params"])t[i]!==void 0&&(t[i]===null?localStorage.removeItem(e[i]):localStorage.setItem(e[i],JSON.stringify(t[i])))}catch{}}}}c(re,"localKeep");const k=c(s=>typeof s=="number"&&isFinite(s),"finite");function v(s,e){return!Array.isArray(s)||s.length!==e?null:s.map(t=>typeof t=="number"?t:NaN)}c(v,"numbers");function ae(s){if(!s||typeof s!="object"||typeof s.key!="string")return null;const e=s.comps;if(!Number.isInteger(e)||e<1||e>P)return null;const t=v(s.value,e),i=v(s.def,e);if(!t||!i)return null;const r={key:o(s.key,h),label:o(s.label,h),comps:e,int:s.int===!0,unsigned:s.unsigned===!0,bool:s.bool===!0,widget:V.has(s.widget)?s.widget:"drag",step:k(s.step)&&s.step>0?s.step:s.int===!0?1:.01,min:k(s.min)?s.min:void 0,max:k(s.max)?s.max:void 0,choices:Array.isArray(s.choices)?s.choices.slice(0,G).map(a=>o(a,h)):void 0,tooltip:s.tooltip===void 0?void 0:o(s.tooltip,X),hint:Array.isArray(s.hint)?s.hint.slice(0,K).map(a=>o(a,h)):void 0,group:s.group===void 0?void 0:o(s.group,h),def:i,value:t},n=r.widget;return(n==="combo"&&(e!==1||!r.choices||!r.choices.length)||n==="color"&&e<3||n==="checkbox"&&e!==1||n==="slider"&&(r.min===void 0||r.max===void 0))&&(r.widget="drag"),r}c(ae,"paramRow");function ne(s){const e=Array.isArray(s.rows)?s.rows.slice(0,g).map(ae).filter(Boolean):[];return{resettable:s.resettable===!0,rows:e}}c(ne,"paramModel");function oe(s){if(!Array.isArray(s))return[];const e=[];for(const t of s.slice(0,g)){if(!Array.isArray(t)||typeof t[0]!="string"||!Array.isArray(t[1]))continue;const i=Math.min(t[1].length,P);i<1||e.push([o(t[0],h),v(t[1].slice(0,i),i)])}return e}c(oe,"paramValues");const he=.02;function ce(){const s=new URL("worker.js",import.meta.url);return s.origin===self.origin?new Worker(s,{type:"module"}):new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(le(s.href)))}c(ce,"startWorker");function le(s){return['"use strict";',"const on = addEventListener.bind(self), off = removeEventListener.bind(self);","const fire = dispatchEvent.bind(self), Message = MessageEvent, later = setTimeout;","const held = [];","const hold = (e) => { held.push(e); e.stopImmediatePropagation(); };",'on("message", hold);',"import("+JSON.stringify(s)+").then(() => {",' off("message", hold);',' for (const e of held) fire(new Message("message", { data: e.data, ports: e.ports }));',"}, (err) => {",' off("message", hold);'," later(() => { throw err; });","});",""].join(`
7
+ `)}c(le,"importer");async function f(s,e){const t={colorSpaceConversion:"none",premultiplyAlpha:"none"},i=await createImageBitmap(s,t);return i.width===e[0]&&i.height===e[1]?i:(i.close(),createImageBitmap(s,{...t,resizeWidth:e[0],resizeHeight:e[1],resizeQuality:"high"}))}c(f,"sceneBitmap");class me{static{c(this,"Session")}constructor({box:e,plugin:t,modules:i,files:r=null,descriptor:n=null,folder:a,keep:l=null,picture:x,scene:_,params:C,persistParams:T=!1,watchdog:I=!0,clock:L="wall",refreshHz:z=60,pointer:N=null,hold:B=!1,on:O}){this.box=e,this.pointerAt=N,this.hold=B,this.mode="opaque",this.resizer=null,this.cursorScale=0,this.watchdog=I,this.clock=L==="stepped"?"stepped":"wall",this.refreshHz=z,this.steps=new Map,this.stepId=0,this.plugin=t,this.modules=i,this.files=r instanceof Map?r:null,this.descriptor=n,this.folder=a,this.keep=l||re(a),this.picture=x,this.scene=_,this.persistParams=T===!0,this.local=new m(null),this.paramStore=new S(this.persistParams?null:C);const p=this.keep.read();p&&typeof p.then=="function"?this.saved=p:this.#o(p),this.on=O||{},this.package="",this.displayName="",this.gpuFeatures=[],this.worker=null,this.canvas=null,this.phase="boot",this.paused=!1,this.splitAt=null,this.stoppedWith=null,this.beating=!1,this.lastBeat=0,this.lastCheck=0,this.inPlugin=!1,this.pluginSince=0,this.armed=!1,this.timer=0,this.flushTimer=0,this.probes=new Map,this.probeId=0,this.pictureSent=0,this.pictureTaken=0,this.pictureWaiters=[],this.claim=[],y.folder!==a&&(y={folder:a,area:new m(null)}),this.session=y.area,this.onVisibility=()=>this.#c(),this.onPageHide=()=>this.#r()}#o(e){const t=e&&typeof e=="object"?e:{};this.local=new m(t.local&&typeof t.local=="object"?t.local:null),this.persistParams&&(this.paramStore=new S(t.params&&typeof t.params=="object"?t.params:null))}async start(){if(this.saved){let a=null;try{a=await this.saved}catch{}this.saved=null,this.#o(a)}let e=this.descriptor;if(!this.files){const a=await fetch(this.plugin+"overglaze-web.json");if(!a.ok){this.displayName=this.folder,this.#i(),this.#a("missing","there is no plugin '"+this.folder+"' here");return}e=await a.json()}if(this.package=o(e.package||"",h),this.displayName=o(e.displayName||this.package,h),this.gpuFeatures=Array.isArray(e.gpuFeatures)?e.gpuFeatures.slice(0,16).map(a=>o(a,h)):[],!("gpu"in navigator)){this.#i(),this.#a("unsupported","this browser has no WebGPU");return}this.canvas=this.#u(),this.#v(this.canvas);const t=await f(this.picture,this.scene);this.cursorScale=this.#n(this.scene);const i=await b(this.cursorScale),r=this.#b();this.resizer=new ResizeObserver(a=>this.#w(a[a.length-1]));try{this.resizer.observe(this.canvas,{box:"device-pixel-content-box"})}catch{this.resizer.observe(this.canvas)}const n=this.canvas.transferControlToOffscreen();this.worker=ce(),this.worker.onmessage=a=>this.#d(a.data),this.worker.onerror=a=>{a.preventDefault(),this.#s("error","the engine failed to start: "+o(a.message,h))},this.worker.postMessage({type:"start",canvas:n,picture:t,plugin:this.plugin,modules:this.modules,files:this.files?[...this.files]:void 0,descriptor:this.files?e:void 0,scene:this.scene,output:r,cursor:i.bitmap,hot:i.hot,pointer:this.pointerAt,hold:this.hold,beat:u,clock:this.clock,refreshHz:this.refreshHz,params:this.paramStore.toObject(),watchParams:typeof this.on.params=="function",storage:{local:this.local.toObject(),session:this.session.toObject()}},[n,t,i.bitmap]),document.addEventListener("visibilitychange",this.onVisibility),addEventListener("pagehide",this.onPageHide),this.timer=setInterval(()=>this.#m(),E),this.splitAt!==null&&this.#e({type:"split",at:this.splitAt}),this.paused?this.#e({type:"pause"}):document.hidden&&this.#c()}pause(){this.paused=!0,this.#e({type:"pause"}),this.armed=!1}resume(){this.paused=!1,document.hidden||this.#l()}async resize(e,t){if(this.scene=e,t&&(this.picture=t),!this.worker){this.stoppedWith&&this.#i();return}const i=await f(this.picture,e);this.cursorScale=this.#n(e);const r=await b(this.cursorScale);this.#e({type:"resize",scene:e,picture:i,cursor:r.bitmap,hot:r.hot},[i,r.bitmap])}split(e){this.splitAt=e===null?null:Number(e),this.#e({type:"split",at:this.splitAt})}async setPicture(e){if(this.picture=e,!this.worker){this.stoppedWith&&this.#i();return}const t=await f(e,this.scene);if(!this.worker){t.close();return}this.#e({type:"desktop",picture:t,id:++this.pictureSent},[t])}pictureIn(){if(!this.worker||this.pictureTaken>=this.pictureSent)return Promise.resolve();const e=this.pictureSent;return new Promise(t=>this.pictureWaiters.push({want:e,resolve:t}))}cancel(){this.worker&&(this.#e({type:"cancel"}),setTimeout(()=>this.#s("cancelled","the load was cancelled"),W))}stop(){this.#s("stopped","stopped")}storage(){return{local:this.local.toObject(),session:this.session.toObject()}}savedParams(){return this.paramStore.toObject()}param(e,...t){this.#e({type:"param",key:String(e),values:t.map(Number)})}resetParams(){this.#e({type:"param-reset"})}probe(){const e=++this.probeId;return new Promise(t=>{this.probes.set(e,t),this.#e({type:"probe",id:e})})}destroyDevice(){this.#e({type:"destroy-device"})}step(e,t=!1){if(this.clock!=="stepped"||!this.worker)return Promise.resolve(null);const i=++this.stepId;return new Promise(r=>{this.steps.set(i,r),this.#e({type:"step",id:i,t:Number(e),capture:!!t})})}runOn(e){this.clock!=="stepped"||!this.worker||(this.clock="wall",this.#e({type:"run",t:Number(e)}))}pointer(e,t){this.#e({type:"pointer",kind:"move",x:Number(e),y:Number(t),button:0,buttons:0,notches:0,t:0})}#d(e){if(!(!e||typeof e!="object"||!this.worker))switch(e.type){case"beat":{const t=performance.now();this.beating?this.armed&&t-this.lastBeat>2*u&&this.#t("log","[page] no heartbeat for "+Math.round(t-this.lastBeat)+" ms (at "+(t/1e3).toFixed(1)+" s)","info"):(this.beating=!0,this.armed=!this.paused&&!document.hidden),this.lastBeat=t;break}case"plugin":{const t=performance.now();e.running===!0?(this.inPlugin=!0,this.pluginSince=t):this.inPlugin&&(this.inPlugin=!1,this.armed&&t-this.pluginSince>2*u&&this.#t("log","[page] the plugin's frame took "+Math.round(t-this.pluginSince)+" ms (at "+(t/1e3).toFixed(1)+" s)","info"),this.lastBeat=t);break}case"phase":Q.has(e.phase)&&(this.phase=e.phase,this.#t("phase",e.phase));break;case"log":{const t=Y.has(e.level)?e.level:"info",i=(e.source==="engine"?"[engine ":"[js ")+this.package+"] ",r=q[t]||"[I]",n=ie(e.text,w).split(`
8
+ `).map(a=>r+" "+i+a.replace(/\r$/,""));this.#t("log",n.join(`
9
+ `),t);break}case"fault":this.#t("fault",o(e.where,h),o(e.message,w));break;case"absent-op":this.#t("absent",o(e.name,h));break;case"progress":this.#t("progress",d(e.fraction),o(e.label,h));break;case"storage":this.#f(e);break;case"params":this.#g(e);break;case"params-model":this.#t("params",ne(e));break;case"param-values":this.#t("paramValues",oe(e.values));break;case"ready":this.#t("ready",{adapter:o(e.adapter||"",h),fallback:e.fallback===!0,features:Array.isArray(e.features)?e.features.slice(0,64).map(t=>o(t,h)):[],canvasFormat:o(e.canvasFormat||"",h)});break;case"drawn":this.#t("drawn");break;case"stats":this.#t("stats",{fps:d(e.fps),frames:d(e.frames),faults:d(e.faults),mode:o(e.mode,16)});break;case"mode":{const t=e.mode==="warp"||e.mode==="transparent"?e.mode:"opaque";if(t===this.mode)break;this.mode=t,this.canvas&&(this.canvas.style.cursor=t==="warp"?"none":""),this.#t("mode",t);break}case"held":if(this.paused)break;this.paused=!0,this.armed=!1,this.#t("held");break;case"globals":this.#t("globals",{stuck:Array.isArray(e.stuck)?e.stuck.slice(0,256).map(t=>o(t,h)):[],inherited:Array.isArray(e.inherited)?e.inherited.slice(0,256).map(t=>o(t,h)):[]});break;case"gap":$.has(e.kind)&&this.#t("gap",e.kind,o(e.detail===void 0?"":e.detail,Z));break;case"unsupported":this.#s("unsupported",o(e.message,h));break;case"disabled":this.#s(e.kind==="crash"?"crash":"load",o(e.message,w));break;case"lost":this.#s("lost","the GPU device was lost ("+o(e.reason,h)+"): "+o(e.message,h));break;case"claim":this.claim=Array.isArray(e.rects)?e.rects.slice(0,ee*4).map(Number).filter(t=>Number.isFinite(t)):[],this.claim.length%4&&(this.claim.length-=this.claim.length%4);break;case"desktop-in":Number.isInteger(e.id)&&e.id>this.pictureTaken&&e.id<=this.pictureSent&&(this.pictureTaken=e.id,this.#p());break;case"probe":{const t=this.probes.get(e.id);this.probes.delete(e.id),t&&t(e.result);break}case"stepped":{const t=this.steps.get(e.id);if(this.steps.delete(e.id),!t)break;const i=this.scene[0]*this.scene[1]*4;t(e.pixels instanceof ArrayBuffer&&e.pixels.byteLength===i?e.pixels:null);break}}}#f(e){const t=e.area==="local"?this.local:e.area==="session"?this.session:null;if(t){if(e.op==="set")t.set(String(e.key),String(e.value));else if(e.op==="remove")t.remove(String(e.key));else if(e.op==="clear")t.clear();else return;t===this.local&&this.#h()}}#g(e){if(e.op==="write"&&Array.isArray(e.entries))for(const t of e.entries.slice(0,g))Array.isArray(t)&&this.paramStore.set(String(t[0]),t[1]);else if(e.op==="forget")this.paramStore.forget(String(e.key));else if(e.op==="prune"&&Array.isArray(e.live))this.paramStore.prune(e.live.slice(0,g));else return;this.persistParams&&this.#h()}#h(){this.flushTimer||(this.flushTimer=setTimeout(()=>this.#r(),U))}#r(){clearTimeout(this.flushTimer),this.flushTimer=0,this.keep.write({local:this.local.length?this.local.toObject():null,params:this.persistParams?this.paramStore.size?this.paramStore.toObject():null:void 0})}#m(){const e=performance.now(),t=e-this.lastCheck,i=this.lastCheck&&t>E+F;if(this.lastCheck=e,!this.armed||!this.worker)return;if(i){this.#t("log","[page] the page itself was busy for "+Math.round(t)+" ms (at "+(e/1e3).toFixed(1)+" s)","info"),this.lastBeat=e,this.inPlugin&&(this.pluginSince=e);return}if(!this.watchdog)return;if(this.phase==="running"&&this.inPlugin){const l=e-this.pluginSince;l>A&&this.#s("hang","the plugin's frame ran "+Math.round(l)+" ms (budget "+A+" ms) and was stopped");return}const r=this.phase!=="running",n=(r?D:H)+u,a=e-this.lastBeat;a>n&&this.#s("hang",(r?"the plugin stopped responding during its load":"the engine stopped responding outside the plugin's frame")+" ("+Math.round(a)+" ms without a heartbeat, budget "+n+" ms) and was stopped")}#c(){document.hidden?(this.#e({type:"pause"}),this.armed=!1):this.paused||this.#l()}#l(){this.#e({type:"resume"}),this.lastBeat=performance.now(),this.armed=this.beating&&this.worker!==null}#s(e,t){if(this.worker){this.worker.terminate(),this.worker=null,this.armed=!1,this.resizer&&this.resizer.disconnect(),this.resizer=null;for(const i of this.steps.values())i(null);this.steps.clear(),this.pictureTaken=this.pictureSent,this.#p(),this.claim=[],clearInterval(this.timer),document.removeEventListener("visibilitychange",this.onVisibility),removeEventListener("pagehide",this.onPageHide),this.#r(),this.#i(),this.#a(e,t)}}claims(e,t){const i=this.claim;for(let r=0;r<i.length;r+=4)if(e>=i[r]&&e<i[r]+i[r+2]&&t>=i[r+1]&&t<i[r+1]+i[r+3])return!0;return!1}#p(){const e=this.pictureWaiters;this.pictureWaiters=e.filter(t=>t.want>this.pictureTaken);for(const t of e)t.want<=this.pictureTaken&&t.resolve()}#a(e,t){this.stoppedWith={reason:e,message:t},this.#t("stopped",e,t)}async#i(){const e=this.#u();try{const t=await f(this.picture,this.scene);e.getContext("2d").drawImage(t,0,0),t.close()}catch{}}#u(){const e=document.createElement("canvas");return e.width=this.scene[0],e.height=this.scene[1],e.tabIndex=0,this.box.replaceChildren(e),e}#b(){const e=this.canvas.getBoundingClientRect(),t=devicePixelRatio||1;return[Math.max(1,Math.round(e.width*t)),Math.max(1,Math.round(e.height*t))]}#w(e){if(!this.worker||!e)return;const t=e.devicePixelContentBoxSize&&e.devicePixelContentBoxSize[0];let i;if(t)i=[t.inlineSize,t.blockSize];else{const r=devicePixelRatio||1;i=[Math.round(e.contentRect.width*r),Math.round(e.contentRect.height*r)]}i[0]<1||i[1]<1||(this.#e({type:"output",size:i}),this.#y())}#n(e){const t=this.canvas?this.canvas.getBoundingClientRect().width:0;return t>0?e[0]/t:1}async#y(){const e=this.#n(this.scene);if(Math.abs(e-this.cursorScale)<=he*e)return;this.cursorScale=e;const t=await b(e);if(e!==this.cursorScale){t.bitmap.close();return}this.#e({type:"cursor",cursor:t.bitmap,hot:t.hot},[t.bitmap])}#k(){const e=document.fullscreenElement;return document.activeElement===this.canvas||!!(e&&e.contains(this.canvas))}#e(e,t){this.worker&&this.worker.postMessage(e,t||[])}#t(e,...t){const i=this.on[e];i&&i(...t)}#v(e){const t=c((r,n)=>Math.min(n,Math.max(0,r)),"clamp"),i=c((r,n,a)=>{const l=e.getBoundingClientRect();this.#e({type:"pointer",kind:r,x:t((n.clientX-l.left)/l.width*this.scene[0],this.scene[0]),y:t((n.clientY-l.top)/l.height*this.scene[1],this.scene[1]),button:n.button,buttons:n.buttons,ctrl:n.ctrlKey,shift:n.shiftKey,alt:n.altKey,meta:n.metaKey,t:n.timeStamp,notches:0,...a})},"send");e.addEventListener("pointermove",r=>i("move",r)),e.addEventListener("pointerdown",r=>{e.focus({preventScroll:!0});try{e.setPointerCapture(r.pointerId)}catch{}i("down",r)}),e.addEventListener("pointerup",r=>i("up",r)),e.addEventListener("pointerenter",()=>this.#e({type:"hover",over:!0})),e.addEventListener("pointerleave",()=>this.#e({type:"hover",over:!1})),e.addEventListener("wheel",r=>{if(!this.#k())return;r.preventDefault();const n=r.deltaMode===1?1/3:r.deltaMode===2?1:1/100;i("wheel",r,{notches:-r.deltaY*n})},{passive:!1});for(const r of["keydown","keyup"])e.addEventListener(r,n=>{const a=j(n);a&&(J.has(n.code)&&n.preventDefault(),this.#e({type:"key",key:a}))})}}export{me as Session,re as localKeep};
@@ -0,0 +1,7 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var j=Object.defineProperty;var l=(u,t)=>j(u,"name",{value:t,configurable:!0});const c=globalThis,z=c.WebAssembly.instantiate.bind(c.WebAssembly),g=c.GPUDevice,E=c.GPUAdapter,U=c.GPUShaderModule,N=c.GPUValidationError,I=c.GPUUncapturedErrorEvent,T=c.EventTarget.prototype.addEventListener,q=c.EventTarget.prototype.dispatchEvent,O=c.crypto.getRandomValues.bind(c.crypto),V=c.Promise,v=new TextEncoder,C=new TextDecoder,R=1024;class k{static{l(this,"Naga")}#e;static async load(t){const{instance:p}=await z(t,{});return new k(p.exports)}constructor(t){this.#e=t}check(t,p){const r=this.#e;if(!r)return x("naga.wasm trapped on an earlier shader");try{const a=this.#t(v.encode(t)),i=this.#t(v.encode(p)),d=r.og_check(a.ptr,a.len,i.ptr,i.len),o=JSON.parse(C.decode(new Uint8Array(r.memory.buffer,r.og_result(),d)));return r.og_free(a.ptr,a.len),r.og_free(i.ptr,i.len),o.error===void 0?null:{error:String(o.error),message:String(o.message===void 0?o.error:o.message),lineNum:Number(o.lineNum)||0,linePos:Number(o.linePos)||0,offset:Number(o.offset)||0,length:Number(o.length)||0}}catch(a){return this.#e=null,x("naga.wasm trapped on "+(t?"the shader '"+t+"'":"a shader")+": "+(a&&a.message?a.message:String(a)))}}#t(t){const p=this.#e,r=p.og_alloc(t.length);return new Uint8Array(p.memory.buffer,r,t.length).set(t),{ptr:r,len:t.length}}}function x(u){return{error:u,message:u,lineNum:0,linePos:0,offset:0,length:0}}l(x,"trapped");function H(u,t){const r="overglaze_naga_"+Array.from(O(new Uint8Array(8)),s=>s.toString(16).padStart(2,"0")).join("")+"_",a=new RegExp(r+"(\\d+)"),i=new Map,d=new WeakMap,o={checked:0,refused:0};let G=0;const S=l(s=>{if(!s||typeof s!="object")return null;const e=a.exec(String(s.message));if(!e)return null;const n=i.get(Number(e[1]));return i.delete(Number(e[1])),n||null},"take"),m=g.prototype.createShaderModule;g.prototype.createShaderModule=l(function(e){const n=e;if(n===null||typeof n!="object"&&typeof n!="function"||n.code===void 0)return m.apply(this,arguments);const h=n.label===void 0?"":String(n.label),w=String(n.code),_=n.compilationHints;o.checked++;const f=u.check(h,w);if(!f)return m.call(this,{label:h,code:w,compilationHints:_});o.refused++;const y=++G;i.set(y,f),i.size>R&&i.delete(i.keys().next().value);const b=m.call(this,{label:r+y,code:r+y});return b.label=h,d.set(b,f),t(f),b},"createShaderModule");const A=g.prototype.popErrorScope;g.prototype.popErrorScope=l(function(){return A.apply(this,arguments).then(e=>{const n=S(e);return n?new N(n.error):e})},"popErrorScope");const M=U.prototype.getCompilationInfo;U.prototype.getCompilationInfo=l(function(){const e=d.get(this);if(!e)return M.apply(this,arguments);const n=Object.freeze({message:e.message,type:"error",lineNum:e.lineNum,linePos:e.linePos,offset:e.offset,length:e.length});return V.resolve(Object.freeze({messages:Object.freeze([n])}))},"getCompilationInfo");const P=l(s=>{T.call(s,"uncapturederror",e=>{const n=S(e.error);n&&(e.stopImmediatePropagation(),e.preventDefault(),q.call(s,new I("uncapturederror",{error:new N(n.error)})))})},"watch"),D=E.prototype.requestDevice;return E.prototype.requestDevice=l(function(){return D.apply(this,arguments).then(e=>(P(e),e))},"requestDevice"),{watch:P,counts:o}}l(H,"checkShaders");function J(u){for(const t of String(u.message).split(`
7
+ `))if(t.trim())return t.trim();return String(u.error)}l(J,"headline");export{k as Naga,H as checkShaders,J as headline};
package/engine/tex.js ADDED
@@ -0,0 +1,6 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var P=Object.defineProperty;var l=(s,e)=>P(s,"name",{value:e,configurable:!0});import{natives as m}from"./core.js";import{pluginSubpath as S}from"./files.js";const p=32,M={1:["rgba8unorm-srgb",1,4],2:["rgba8unorm",1,4],3:["r8unorm",1,1],4:["rgba16float",1,8],5:["bc7-rgba-unorm-srgb",4,16],6:["bc7-rgba-unorm",4,16],7:["bc6h-rgb-ufloat",4,16],8:["bc4-r-unorm",4,8]},v={0:"2d",1:"cube",2:"2d-array"},R={0:"nearest"},k={1:"clamp-to-edge",2:"mirror-repeat"},E=l((s,e)=>Math.max(1,s>>>e),"mipDim"),F=l((s,e)=>32-Math.clz32(Math.max(s,e,1)),"maxMipLevels");function I(s,e,t,o,r,n){const a=[];let h=0;for(let i=0;i<o;i++){const c=Math.ceil(E(s,i)/r),u=Math.ceil(E(e,i)/r),f=c*n,d=f*u*t;a.push({level:i,copyWidth:c*r,copyHeight:u*r,offset:h,bytesPerRow:f,blockRows:u,bytes:d}),h+=d}return a}l(I,"mipRanges");function D(s){const e=new Uint8Array(s);if(e.length<p)throw new Error("file too small for header ("+e.length+" bytes)");const t=new DataView(s,0,p);if(e[0]!==84||e[1]!==69||e[2]!==88||e[3]!==49)throw new Error("bad magic (not a .tex file)");const o=t.getUint32(4,!0);if(o!==1)throw new Error("unsupported version "+o+" (want 1)");const r=M[t.getUint32(8,!0)];if(!r)throw new Error("unknown format "+t.getUint32(8,!0));const[n,a,h]=r,i=t.getUint32(12,!0),c=t.getUint32(16,!0),u=t.getUint16(20,!0),f=t.getUint16(22,!0),d=v[e[27]];if(!d)throw new Error("unknown dimension "+e[27]);const w=t.getUint32(28,!0);if(i===0||c===0)throw new Error("degenerate dimensions "+i+"x"+c);if(f===0)throw new Error("depthOrArrayLayers is 0 (stale .cooked/ -- delete and recook)");if(d==="cube"&&f!==6)throw new Error("cube texture with "+f+" layers (want 6)");if(a>1&&(i%a!==0||c%a!==0))throw new Error("BC texture "+i+"x"+c+" not a multiple of "+a+" (recook)");const x=F(i,c);if(u===0||u>x)throw new Error("mip_level_count "+u+" out of range 1..="+x+" for "+i+"x"+c);const b=I(i,c,f,u,a,h),y=b.reduce((U,T)=>U+T.bytes,0);if(w!==y)throw new Error("payload size "+w+" != expected "+y);if(e.length<p+w)throw new Error("file truncated ("+e.length+" bytes, want "+(p+w)+")");const g=R[e[24]]||"linear";return{format:n,width:i,height:c,layers:f,mips:u,dimension:d,ranges:b,payload:e.subarray(p,p+w),samplerDesc:{magFilter:g,minFilter:g,mipmapFilter:g,addressModeU:k[e[25]]||"repeat",addressModeV:k[e[26]]||"repeat"}}}l(D,"parseTex");function N(s,e){return!e.startsWith("bc")||s.features.has("texture-compression-bc")}l(N,"deviceSupports");function _(s,e,t){const o=s.createTexture({label:t,size:[e.width,e.height,e.layers],format:e.format,mipLevelCount:e.mips,usage:m.GPUTextureUsage.TEXTURE_BINDING|m.GPUTextureUsage.COPY_DST});for(const r of e.ranges)s.queue.writeTexture({texture:o,mipLevel:r.level},e.payload.subarray(r.offset,r.offset+r.bytes),{offset:0,bytesPerRow:r.bytesPerRow,rowsPerImage:r.blockRows},[r.copyWidth,r.copyHeight,e.layers]);return o}l(_,"uploadTex");function B(s){const e=s.createTexture({label:"asset.fallback.color",size:[2,2,1],format:"rgba8unorm-srgb",usage:m.GPUTextureUsage.TEXTURE_BINDING|m.GPUTextureUsage.COPY_DST}),t=new Uint8Array([255,0,255,255,0,0,0,255,0,0,0,255,255,0,255,255]);return s.queue.writeTexture({texture:e},t,{bytesPerRow:8,rowsPerImage:2},[2,2,1]),{texture:e,width:2,height:2,layers:1,dimension:"2d",isFallback:!0,samplerDesc:{magFilter:"linear",minFilter:"linear",mipmapFilter:"linear",addressModeU:"repeat",addressModeV:"repeat"}}}l(B,"fallbackTex");const A=1469598103934665603n,G=1099511628211n,C=(1n<<64n)-1n,L=new m.TextEncoder;function O(s){let e=A;for(const t of L.encode(s))e=(e^BigInt(t))*G&C;return e.toString(16).padStart(16,"0")}l(O,"cookedName");class H{static{l(this,"CookedTextures")}#t;#s;#e;#r=new Map;#o=null;constructor(e,t,o){this.#t=e,this.#s=t,this.#e=o}fallback(){return this.#o||(this.#o=B(this.#t)),this.#o}load(e){const t=S(e);if(t===null)return this.#e("warn","[assets] invalid asset path '"+e+"' -> fallback"),Promise.resolve(this.fallback());const o=O(t),r=this.#r.get(o);if(r)return r;const n=this.#n(e,o).then(a=>a||(this.#r.delete(o),this.fallback()));return this.#r.set(o,n),n}async#n(e,t){const o=await this.#s.raw(".cooked/"+t+".tex"),r=o&&o.buffer;if(!r)return this.#e("warn","[assets] read failed for '"+e+"' (.cooked/"+t+".tex missing? recook) -> fallback"),null;let n;try{n=D(r)}catch(h){return this.#e("warn","[assets] bad cooked texture for '"+e+"': "+h.message+" -> fallback"),null}const a=await this.#a(n,e);return a?(this.#e("info","[assets] loaded '"+e+"' "+n.width+"x"+n.height+"x"+n.layers+" "+n.format+" ("+n.payload.length+" bytes)"),{texture:a,width:n.width,height:n.height,layers:n.layers,dimension:n.dimension,isFallback:!1,samplerDesc:n.samplerDesc}):(this.#e("warn","[assets] GPU upload failed for '"+e+"' -> fallback"),null)}async#a(e,t){const o=this.#t;if(!N(o,e.format))return null;o.pushErrorScope("validation");const r=_(o,e,"asset:"+t);return await o.popErrorScope()?(r.destroy(),null):r}}export{H as CookedTextures,O as cookedName,N as deviceSupports,B as fallbackTex,D as parseTex,_ as uploadTex};
@@ -0,0 +1,6 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var n=Object.defineProperty;var h=(s,t)=>n(s,"name",{value:t,configurable:!0});const o=[{name:"display",fields:[{name:"hdr_enabled",type:"u32"},{name:"sdr_white",type:"f32"},{name:"hdr_max",type:"f32"},{name:"refresh_rate",type:"f32"}],fill:h(s=>[0,80,80,s.refreshHz],"fill")},{name:"input",fields:[{name:"mouse",type:"vec4f"},{name:"drag",type:"vec2f"},{name:"scroll",type:"f32"}],fill:h(s=>{const t=s.input;return[t.mouseX,t.mouseY,t.clickX,t.clickY,t.dragX,t.dragY,t.scroll]},"fill")}];function r(){return JSON.stringify({contributors:o.map(s=>({name:s.name,fields:s.fields}))})}h(r,"uniformManifestJson");function m(s){const t=[];for(const i of o)for(const e of i.fill(s))t.push(e);return t}h(m,"uniformValues");class c{static{h(this,"PointerTracker")}#i=0;#e=0;#h=0;#t=[0,0];#n=!1;#l=0;#r={ctrl:!1,shift:!1,alt:!1,meta:!1};#s=null;#o=[];push(t){this.#i=t.x,this.#e=t.y,this.#h=t.buttons|0,this.#r={ctrl:!!t.ctrl,shift:!!t.shift,alt:!!t.alt,meta:!!t.meta},t.kind==="down"&&t.button===0&&(this.#t=[t.x,t.y],this.#n=!0),t.kind==="wheel"&&(this.#l+=t.notches),t.kind!=="move"&&this.#o.push(t)}place(t,i){this.#i=t,this.#e=i}rescale(t,i){this.#i*=t,this.#e*=i,this.#t=[this.#t[0]*t,this.#t[1]*i],this.#s&&(this.#s=[this.#s[0]*t,this.#s[1]*i])}position(){return[this.#i,this.#e]}sample(){const t=(this.#h&1)!==0,i={mouseX:this.#i,mouseY:this.#e,clickX:0,clickY:0,dragX:0,dragY:0,scroll:this.#l,movementX:this.#s?this.#i-this.#s[0]:0,movementY:this.#s?this.#e-this.#s[1]:0,buttons:this.#h,...this.#r};return t?(i.clickX=this.#t[0],i.clickY=this.#t[1],i.dragX=this.#i-this.#t[0],i.dragY=this.#e-this.#t[1]):this.#n&&(i.clickX=-this.#t[0],i.clickY=-this.#t[1]),this.#s=[this.#i,this.#e],i}drain(){const t=this.#o;return this.#o=[],t}}function a(s,t,i){return{snapshot:{mouseX:s.mouseX,mouseY:s.mouseY,movementX:s.movementX,movementY:s.movementY,buttons:s.buttons,ctrl:s.ctrl,shift:s.shift,alt:s.alt,meta:s.meta},mouse:t.map(e=>({type:e.kind==="down"?"mousedown":e.kind==="up"?"mouseup":"wheel",button:e.button|0,x:e.x,y:e.y,wheel:e.kind==="wheel"?e.notches:0,ctrl:!!e.ctrl,shift:!!e.shift,alt:!!e.alt,meta:!!e.meta,timeStamp:e.t||0})),keys:i}}h(a,"domInputFrame");export{c as PointerTracker,a as domInputFrame,r as uniformManifestJson,m as uniformValues};
@@ -0,0 +1,74 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var Qe=Object.defineProperty;var i=(e,t)=>Qe(e,"name",{value:t,configurable:!0});import{attachOps as Ke,natives as s}from"./core.js";import{ABSENT as Ze,createOps as $e}from"./ops.js";import{domInputFrame as et,PointerTracker as tt,uniformValues as rt}from"./uniforms.js";import{CookedTextures as nt}from"./tex.js";import{PluginFiles as it}from"./files.js";import{dataUrl as at,moduleGraph as ot,PluginJs as st}from"./modules.js";import{checkShaders as lt,headline as ut,Naga as ct}from"./shaders.js";import{StorageMirror as ft}from"./plugin-storage.js";import{ParamStore as Ee}from"./param-store.js";import{contractWarning as pt}from"./descriptor.js";import{denyReadback as dt,pruneGlobals as gt,removeShadowed as mt}from"./globals.js";import{GOLDEN_GLOBALS as ht}from"./golden-globals.js";const u=s.postMessage,A=s.console,b=s.GPUTextureUsage,S=s.performanceNow,we=3e4,bt=1e3,n={capabilities:new Set,sceneSize:[1920,1080],sceneTex:null,desktopTex:null,published:!1,inputFrame:null,uniformValues:[],mode:"opaque",interactiveRects:[],inFrame:!1,params:new Ee(null),auto:[],storage:null,files:null,textures:null,log(e,t){(A[e]||A.log).call(A,t),u({type:"log",level:e,text:t,source:"js"})},fault(e,t){_.report(e,t)},progress(e,t){m==="initializing"&&(Q=S(),u({type:"progress",fraction:e,label:t}))},paramsChanged(e){u({type:"params",...e})}};function d(e,t){(A[e]||A.log).call(A,t),u({type:"log",level:e,text:t,source:"engine"})}i(d,"engineLog");function T(e){return String(e)+(e&&e.stack?`
7
+ `+e.stack:"")}i(T,"errorText");const _={logged:!1,short:"",errorThisFrame:!1,streakStart:null,latched:null,count:0,report(e,t){this.count++,this.logged||(this.logged=!0,this.short=t.split(`
8
+ `)[0],d("error","[script] plugin fault ("+e+"): "+t),u({type:"fault",where:e,message:t})),this.errorThisFrame=!0},loadFailure(e,t){this.count++,this.short||(this.short=t.split(`
9
+ `)[0]),d("error","[script] plugin load failed ("+e+"): "+t),u({type:"fault",where:e,message:t}),this.latched||(this.latched={kind:"load",message:this.short})},boundary(e){this.errorThisFrame?this.streakStart===null?this.streakStart=e:!this.latched&&e-this.streakStart>=bt&&(this.latched={kind:"crash",message:this.short}):this.streakStart=null,this.errorThisFrame=!1}};Ke($e(n),e=>{A.warn("[web] unimplemented op touched: "+e),u({type:"absent-op",name:e})});function Re(e){m==="evaluating"?w("plugin evaluation",e):m==="initializing"?w("plugin init",e):_.report("event loop",e)}i(Re,"eventLoopError");s.addEventListener("error",e=>{e.preventDefault(),Re(e.error!==void 0?T(e.error):String(e.message))});s.addEventListener("unhandledrejection",e=>{e.preventDefault(),Re(T(e.reason))});const xe=new Set;function J(e,t){const r=e+`
10
+ `+t;xe.has(r)||(xe.add(r),u({type:"gap",kind:e,detail:t}))}i(J,"gap");const vt=new s.URL("../",import.meta.url).href;function yt(){if(typeof s.PerformanceObserver=="function")try{new s.PerformanceObserver(e=>{for(const t of e.getEntries()){const r=String(t.name);(r.startsWith("https:")||r.startsWith("http:"))&&!r.startsWith(vt)&&J("network",r)}}).observe({type:"resource",buffered:!0})}catch{}}i(yt,"watchNetwork");function wt(){const e=Object.getOwnPropertyDescriptor(globalThis,"addEventListener");if(!e||typeof e.value!="function")return;const t=e.value;Object.defineProperty(globalThis,"addEventListener",{...e,value:i(function(a,c,g){return(a==="keydown"||a==="keyup")&&J("keys",""),t.apply(this,arguments)},"addEventListener")})}i(wt,"watchKeyListeners");function xt(){for(const e of["navigator","self"])Object.defineProperty(globalThis,e,{value:globalThis[e],writable:!0,configurable:!0,enumerable:!0})}i(xt,"prepareGlobal");async function Tt(){const e=await s.gpu.requestAdapter();if(!e)return null;const t=[];e.features.has("texture-compression-bc")&&t.push("texture-compression-bc");const r=await e.requestDevice({requiredFeatures:t});return globalThis.__device=r,{adapter:e,device:r}}i(Tt,"createDevice");const Oe=`@vertex fn vs(@builtin(vertex_index) vi : u32) -> @builtin(position) vec4<f32> {
11
+ var p = array<vec2<f32>, 3>(vec2<f32>(-1.,-1.), vec2<f32>(3.,-1.), vec2<f32>(-1.,3.));
12
+ return vec4<f32>(p[vi], 0., 1.);
13
+ }
14
+ `,kt=Oe+`@group(0) @binding(0) var src : texture_2d<f32>;
15
+ fn srgb_to_linear(c : vec3<f32>) -> vec3<f32> {
16
+ let lo = c / 12.92;
17
+ let hi = pow((c + 0.055) / 1.055, vec3<f32>(2.4));
18
+ return select(hi, lo, c <= vec3<f32>(0.04045));
19
+ }
20
+ @fragment fn fs(@builtin(position) frag : vec4<f32>) -> @location(0) vec4<f32> {
21
+ let c = textureLoad(src, vec2<i32>(frag.xy), 0);
22
+ return vec4<f32>(srgb_to_linear(c.rgb), 1.0);
23
+ }
24
+ `,_t=32,Ne=Oe+`struct Box { scale : vec2<f32>, split : f32, pad : f32 };
25
+ @group(0) @binding(0) var scene : texture_2d<f32>;
26
+ @group(0) @binding(1) var desk : texture_2d<f32>;
27
+ @group(0) @binding(2) var<uniform> box : Box;
28
+ fn shown(p : vec2<i32>, before : bool) -> vec3<f32> {
29
+ let d = clamp(textureLoad(desk, p, 0).rgb, vec3<f32>(0.0), vec3<f32>(1.0));
30
+ if (before) { return d; }
31
+ let c = textureLoad(scene, p, 0);
32
+ let rgb = clamp(c.rgb, vec3<f32>(0.0), vec3<f32>(1.0));
33
+ return rgb * c.a + d * (1.0 - c.a);
34
+ }
35
+ @fragment fn fs(@builtin(position) frag : vec4<f32>) -> @location(0) vec4<f32> {
36
+ let size = vec2<i32>(textureDimensions(scene));
37
+ let before = frag.x < box.split;
38
+ let w = clamp(box.scale, vec2<f32>(1.0), vec2<f32>(`+_t+`.0));
39
+ let c = frag.xy * box.scale;
40
+ let lo = c - 0.5 * w;
41
+ let hi = c + 0.5 * w;
42
+ let first = vec2<i32>(floor(lo));
43
+ let last = vec2<i32>(ceil(hi)) - vec2<i32>(1);
44
+ var sum = vec3<f32>(0.0);
45
+ var weight = 0.0;
46
+ for (var y = first.y; y <= last.y; y++) {
47
+ let wy = min(hi.y, f32(y + 1)) - max(lo.y, f32(y));
48
+ for (var x = first.x; x <= last.x; x++) {
49
+ let wx = min(hi.x, f32(x + 1)) - max(lo.x, f32(x));
50
+ let p = clamp(vec2<i32>(x, y), vec2<i32>(0), size - vec2<i32>(1));
51
+ sum += shown(p, before) * (wx * wy);
52
+ weight += wx * wy;
53
+ }
54
+ }
55
+ return vec4<f32>(sum / weight, 1.0);
56
+ }
57
+ `,St=`struct Quad { rect : vec4<f32> };
58
+ @group(0) @binding(0) var tex : texture_2d<f32>;
59
+ @group(0) @binding(1) var samp : sampler;
60
+ @group(0) @binding(2) var<uniform> q : Quad;
61
+ struct VsOut { @builtin(position) pos : vec4<f32>, @location(0) uv : vec2<f32> };
62
+ @vertex fn vs(@builtin(vertex_index) vi : u32) -> VsOut {
63
+ var corners = array<vec2<f32>, 6>(vec2<f32>(0., 0.), vec2<f32>(1., 0.), vec2<f32>(0., 1.),
64
+ vec2<f32>(0., 1.), vec2<f32>(1., 0.), vec2<f32>(1., 1.));
65
+ let c = corners[vi];
66
+ var o : VsOut;
67
+ o.pos = vec4<f32>(mix(q.rect.x, q.rect.z, c.x), mix(q.rect.w, q.rect.y, c.y), 0., 1.);
68
+ o.uv = c;
69
+ return o;
70
+ }
71
+ @fragment fn fs(@location(0) uv : vec2<f32>) -> @location(0) vec4<f32> {
72
+ return textureSample(tex, samp, uv);
73
+ }
74
+ `;function ne(e,t,r,a){const c=s.createShaderModule.call(e,{code:t,label:a});return e.createRenderPipeline({label:a,layout:"auto",vertex:{module:c,entryPoint:"vs"},fragment:{module:c,entryPoint:"fs",targets:[{format:r}]},primitive:{topology:"triangle-list"}})}i(ne,"fullscreenPipeline");let o=null,ie=null,z=null,G="",ae=null,F=null,Ae=null,M=0,ue=null,Y=null,ce=null;const Pt=8192;let V=null;function Fe(e){const[t,r]=n.sceneSize,a=o.createTexture({label:"overglaze.picture",size:[t,r],format:"rgba8unorm",usage:b.TEXTURE_BINDING|b.COPY_DST|b.RENDER_ATTACHMENT});s.copyExternalImageToTexture.call(o.queue,{source:e},{texture:a},[t,r]),V&&V.destroy(),V=a,Be()}i(Fe,"setPicture");function Be(){const e=o.createCommandEncoder(),t=e.beginRenderPass({colorAttachments:[{view:n.desktopTex.createView(),loadOp:"clear",storeOp:"store"}]});t.setPipeline(ae),t.setBindGroup(0,o.createBindGroup({layout:ae.getBindGroupLayout(0),entries:[{binding:0,resource:V.createView()}]})),t.draw(3),t.end(),o.queue.submit([e.finish()]),l.baked=!1}i(Be,"linearize");function Ge(e,t){const r=[n.sceneTex,n.desktopTex],a=n.sceneSize;n.sceneSize=e,r[0]&&C.rescale(e[0]/a[0],e[1]/a[1]),n.desktopTex=o.createTexture({label:"overglaze.desktop",size:e,format:"rgba16float",usage:b.TEXTURE_BINDING|b.RENDER_ATTACHMENT|b.COPY_SRC}),Fe(t),n.sceneTex=o.createTexture({label:"overglaze.scene",size:e,format:"rgba16float",usage:b.RENDER_ATTACHMENT|b.TEXTURE_BINDING|b.COPY_DST|b.COPY_SRC}),M++,F&&Ue();for(const c of r)c&&c.destroy()}i(Ge,"buildScene");function Ue(){Ae=o.createBindGroup({layout:F.getBindGroupLayout(0),entries:[{binding:0,resource:n.sceneTex.createView()},{binding:1,resource:n.desktopTex.createView()},{binding:2,resource:{buffer:ce}}]}),Ce()}i(Ue,"bindOutput");function Ce(){const[e,t]=n.sceneSize,[r,a]=ue||n.sceneSize;z.width!==r&&(z.width=r),z.height!==a&&(z.height=a);const c=Y===null?-1:Y*r;o.queue.writeBuffer(ce,0,new Float32Array([e/r,t/a,c,0]))}i(Ce,"fitOutput");function fe(e){return s.createBuffer.call(o,{label:e,size:16,usage:s.GPUBufferUsage.UNIFORM|s.GPUBufferUsage.COPY_DST})}i(fe,"uniformBuffer");const l={pipeline:null,sampler:null,quad:null,texture:null,bindGroup:null,size:[0,0],hot:[0,0],over:!1,baked:!1};function oe(e,t){if(!l.pipeline){const r=s.createShaderModule.call(o,{code:St,label:"overglaze.cursor"});l.pipeline=o.createRenderPipeline({label:"overglaze.cursor",layout:"auto",vertex:{module:r,entryPoint:"vs"},fragment:{module:r,entryPoint:"fs",targets:[{format:"rgba16float",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),l.sampler=o.createSampler({magFilter:"linear",minFilter:"linear"}),l.quad=fe("overglaze.cursor.quad")}l.texture&&l.texture.destroy(),l.size=[e.width,e.height],l.hot=[Number(t[0])||0,Number(t[1])||0],l.texture=o.createTexture({label:"overglaze.cursor",size:l.size,format:"rgba8unorm-srgb",usage:b.TEXTURE_BINDING|b.COPY_DST|b.RENDER_ATTACHMENT}),s.copyExternalImageToTexture.call(o.queue,{source:e},{texture:l.texture},l.size),l.bindGroup=o.createBindGroup({layout:l.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:l.texture.createView()},{binding:1,resource:l.sampler},{binding:2,resource:{buffer:l.quad}}]})}i(oe,"setCursor");function zt(){const e=n.mode==="warp"&&l.over&&l.texture!==null;if(!e&&!l.baked||(Be(),!e))return;const[t,r]=n.sceneSize,[a,c]=C.position(),g=Math.round(a-l.hot[0]),v=Math.round(c-l.hot[1]),f=[g/t*2-1,1-(v+l.size[1])/r*2,(g+l.size[0])/t*2-1,1-v/r*2];o.queue.writeBuffer(l.quad,0,new Float32Array(f));const h=o.createCommandEncoder(),x=h.beginRenderPass({colorAttachments:[{view:n.desktopTex.createView(),loadOp:"load",storeOp:"store"}]});x.setPipeline(l.pipeline),x.setBindGroup(0,l.bindGroup),x.draw(6),x.end(),o.queue.submit([h.finish()]),l.baked=!0}i(zt,"desktopLayer");let m="boot",Q=0,Te=0;function U(e){m=e,u({type:"phase",phase:e}),e==="running"&&qe()}i(U,"setPhase");function w(e,t){_.loadFailure(e,t),Le()}i(w,"failLoad");function Le(){m!=="failed"&&(U("failed"),u({type:"disabled",kind:_.latched.kind,message:_.latched.message}))}i(Le,"disable");function Et(e){return"/plugin/"+e}i(Et,"entryPath");async function Rt(e){const t=String(e.entry),r=t.lastIndexOf("."),a=r<0?"":t.slice(r+1).toLowerCase();if(a==="wgsl"||a==="wasm"){d("info","[script] loading "+a.toUpperCase()+"-only plugin: "+t);let f;try{f=await n.files.read(Et(t))}catch(h){w("plugin load",h.message);return}try{a==="wgsl"?globalThis.__ogRunWgsl(new s.TextDecoder().decode(f)):globalThis.__ogRunWasm(f)}catch(h){w("plugin load",T(h));return}d("info","[script] "+a.toUpperCase()+"-only plugin loaded"),U("running");return}const c="unsupported entry '"+t+"': not a module the engine runs";let g;if(e.modules){if(typeof e.module!="string"){w("plugin load",c);return}g=e.modules+e.module}else{let f;try{f=await Ot(e)}catch(h){w("plugin load",T(h));return}if(f.kind!=="javascript"&&f.kind!=="typescript"){w("plugin load",c);return}d("info","[script] made "+f.modules+" module(s) from the plugin's files");for(const h of f.meta)for(const x of h.reads)J("import-meta",h.path+": import.meta"+(x?"."+x:""));g=f.url}d("info","[script] loading plugin module: "+t),U("evaluating");let v;try{v=await import(g)}catch(f){m==="evaluating"&&w("plugin evaluation",T(f));return}m==="evaluating"&&At(v)}i(Rt,"beginSelection");let $=null,X=null;async function Ot(e){if(!$){const a=await s.fetch(new s.URL("plugin-js.wasm",import.meta.url).href);if(!a.ok)throw new Error("plugin-js.wasm: HTTP "+a.status);$=await st.load(await a.arrayBuffer())}const t={};if(e.plugin)for(const[a,c]of Object.entries(e.packageImports||{}))t[a]=new s.URL(c,e.plugin).href;const r=n.files;return ot({entry:String(e.entry),js:$,has:i(a=>r.has(a),"has"),read:i(a=>r.source(a),"read"),packages:t,lock:r.has("deno.lock"),url:at})}i(Ot,"sourceModules");async function Nt(){const e=await s.fetch(new s.URL("naga.wasm",import.meta.url).href);if(!e.ok)throw new Error("naga.wasm: HTTP "+e.status);return ct.load(await e.arrayBuffer())}i(Nt,"loadNaga");function At(e){const t=e.init;if(typeof t!="function"){d("info","[script] plugin loaded"),ke(),U("running");return}U("initializing"),Te=Q=S();let r;try{r=globalThis.__ogRunInit(t,n.sceneSize[0],n.sceneSize[1])}catch(a){w("plugin init",T(a));return}Promise.resolve(r).then(()=>{m==="initializing"&&(d("info","[script] plugin init(ctx) resolved after "+((S()-Te)/1e3).toFixed(2)+"s"),ke(),U("running"))},a=>{m==="initializing"&&w("plugin init",T(a))})}i(At,"startInit");function ke(){try{globalThis.__ogPruneParams&&globalThis.__ogPruneParams()}catch(e){d("warn","[script] parameter prune failed: "+String(e))}}i(ke,"pruneParams");function Ft(e){m!=="initializing"||e-Q<we||w("plugin init","stalled for "+we/1e3+"s with no progress reported (call ctx.progress() during long setup to keep the host informed)")}i(Ft,"pollLoad");function Bt(){if(m==="initializing")try{globalThis.__ogAbortInit&&globalThis.__ogAbortInit()}catch(e){d("warn","[script] init abort failed: "+String(e))}}i(Bt,"cancel");const C=new tt;let se=[],pe=0,N=!1,j=0,D=60,R=0,W=0,H=0,_e=!1;function Me(e){!e||_e||(_e=!0,u({type:"drawn"}))}i(Me,"tellDrawn");let Se="",ee=n.interactiveRects,le=!1;function Gt(e){if(n.mode==="transparent"){e.beginRenderPass({colorAttachments:[{view:n.sceneTex.createView(),clearValue:[0,0,0,0],loadOp:"clear",storeOp:"store"}]}).end();return}e.copyTextureToTexture({texture:n.desktopTex},{texture:n.sceneTex},n.sceneSize)}i(Gt,"prepaint");function Ut(){if(m!=="running"){n.mode="opaque",n.interactiveRects.length&&(n.interactiveRects=[]);return}try{globalThis.__ogPollCompositor&&globalThis.__ogPollCompositor()}catch(e){d("error","[script] compositor poll failed: "+String(e))}}i(Ut,"pollCompositor");function Ct(){const e=C.sample(),t=C.drain(),r=se;if(se=[],m==="boot"||m==="failed"||!t.length&&!r.length&&e.movementX===0&&e.movementY===0)return e;n.inputFrame=et(e,t,r);try{globalThis.__ogDispatchInput&&globalThis.__ogDispatchInput()}catch(a){d("error","[script] input dispatch failed: "+String(a))}return e}i(Ct,"dispatchInput");function De(e){if(!N)return;if(pe=ge(De),j){const r=e-j;r>0&&r<250&&(D+=(1e3/r-D)*.05)}j=e;const t=de();Me(t),R++,W++,e-H>=1e3&&(u({type:"stats",fps:W*1e3/(e-H),frames:R,faults:_.count,mode:n.mode}),W=0,H=e),le&&t&&(le=!1,He(),u({type:"held"}))}i(De,"tick");function de(){const e=globalThis,[t,r]=n.sceneSize;Ft(S()),Ut(),n.mode!==Se&&(Se=n.mode,u({type:"mode",mode:n.mode})),n.interactiveRects!==ee&&(ee=n.interactiveRects,u({type:"claim",rects:Array.from(ee,Number)})),zt();const a=o.createCommandEncoder();Gt(a),o.queue.submit([a.finish()]);const c=m==="running";c&&u({type:"plugin",running:!0});const g=Ct(),v=m==="running";if(v){n.published=!0,n.uniformValues=rt({refreshHz:Math.round(D),input:g}),n.inFrame=!0;try{e.__ogFrame?e.__ogFrame(t,r,M):e.frame&&(e.__w=t,e.__h=r,e.frame())}catch(f){_.report("frame callback",T(f))}finally{n.inFrame=!1}_.boundary(S()),_.latched&&Le()}return c&&u({type:"plugin",running:!1}),qe(),je(),v}i(de,"renderFrame");let E=null,Ie=!1,Pe=-1,te=new Map,re=!1;function Lt(e,t){if(!e||e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(!Object.is(e[r],t[r]))return!1;return!0}i(Lt,"sameValues");function qe(){if(!Ie||E===null)return;if(E.presentationRevision()!==Pe){const t=E.presentation();Pe=t.revision,te=new Map(t.rows.map(r=>[r.key,r.value])),u({type:"params-model",resettable:t.resettable,rows:t.rows});return}const e=[];for(const[t,r]of E.presentationValues())Lt(te.get(t),r)||(te.set(t,r),e.push([t,r]));e.length&&u({type:"param-values",values:e})}i(qe,"reportParams");function Ve(){N||k!==null||R===0||re||(re=!0,ge(()=>{re=!1,We()}))}i(Ve,"afterEdit");function Mt(e,t){E===null||!Array.isArray(t)||E.presentationWrite(e,t.map(Number))&&Ve()}i(Mt,"writeParam");function Dt(){E!==null&&(E.resetAll(),Ve())}i(Dt,"resetParams");function je(){const e=o.createCommandEncoder(),t=e.beginRenderPass({colorAttachments:[{view:ie.getCurrentTexture().createView({format:G+"-srgb"}),loadOp:"clear",storeOp:"store"}]});t.setPipeline(F),t.setBindGroup(0,Ae),t.draw(3),t.end(),o.queue.submit([e.finish()])}i(je,"present");function ze(){Ce(),!N&&R>0&&je()}i(ze,"refit");function We(){N||k!==null||R===0||!F||(K-=1e3/Math.max(1,D),de(),R++)}i(We,"redraw");let k=null,B=null,K=0;function It(){return k!==null?k:(B===null?S():B)-K}i(It,"pluginNow");function qt(e){if(k===null||!Number.isFinite(e))return;k=null;const t=S();K=t-e,L&&(B=t),me()}i(qt,"runOn");let y=null;function Vt(){const[e,t]=n.sceneSize;if(y&&y.epoch===M)return y;if(y&&y.texture.destroy(),!y){const r=fe("overglaze.golden.box");o.queue.writeBuffer(r,0,new Float32Array([1,1,-1,0])),y={pipeline:ne(o,Ne,"rgba8unorm-srgb","overglaze.golden"),box:r}}return y.epoch=M,y.texture=o.createTexture({label:"overglaze.golden",size:[e,t],format:"rgba8unorm-srgb",usage:b.RENDER_ATTACHMENT|b.COPY_SRC}),y.bindGroup=o.createBindGroup({layout:y.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:n.sceneTex.createView()},{binding:1,resource:n.desktopTex.createView()},{binding:2,resource:{buffer:y.box}}]}),y}i(Vt,"goldenTarget");async function jt(){const[e,t]=n.sceneSize,r=Vt(),a=e*4,c=Math.ceil(a/256)*256,g=s.createBuffer.call(o,{label:"overglaze.golden.readback",size:c*t,usage:s.GPUBufferUsage.MAP_READ|s.GPUBufferUsage.COPY_DST}),v=o.createCommandEncoder(),f=v.beginRenderPass({colorAttachments:[{view:r.texture.createView(),loadOp:"clear",storeOp:"store"}]});f.setPipeline(r.pipeline),f.setBindGroup(0,r.bindGroup),f.draw(3),f.end(),v.copyTextureToBuffer({texture:r.texture},{buffer:g,bytesPerRow:c,rowsPerImage:t},[e,t]),o.queue.submit([v.finish()]),await g.mapAsync(s.GPUMapMode.READ);const h=new Uint8Array(g.getMappedRange()),x=new Uint8Array(a*t);for(let P=0;P<t;P++)x.set(h.subarray(P*c,P*c+a),P*a);return g.unmap(),g.destroy(),x.buffer}i(jt,"readOutput");async function Wt(e){if(k===null||!o)return;k=Number(e.t),Me(de()),R++;const t=e.capture?await jt():null;u({type:"stepped",id:e.id,frame:R,pixels:t},t?[t]:[])}i(Wt,"step");const ge=s.requestAnimationFrame||(e=>s.setTimeout(()=>e(S()),16)),Ht=s.cancelAnimationFrame||s.clearTimeout;let L=!1;function me(){N||L||k!==null||(N=!0,j=0,W=0,H=S(),pe=ge(De))}i(me,"play");function He(){L=!0,B===null&&(B=S()),N&&(N=!1,Ht(pe))}i(He,"pause");function Yt(){if(!L)return;L=!1;const e=S()-B;B=null,K+=e,Q+=e,_.streakStart=null,me()}i(Yt,"resume");async function Xt(e){const{canvas:t,picture:r,plugin:a,modules:c,scene:g,storage:v,params:f,beat:h,clock:x,refreshHz:P}=e,he=c?null:Nt().then(p=>({naga:p}),p=>({e:p}));yt(),u({type:"beat"}),s.setInterval(()=>u({type:"beat"}),h),z=t,ue=Ye(e.output),le=e.hold===!0,Array.isArray(e.pointer)&&C.place(Number(e.pointer[0])||0,Number(e.pointer[1])||0),xt(),mt(),x==="stepped"&&(k=0,Number.isFinite(P)&&P>0&&(D=P)),Object.defineProperty(s.performance,"now",{value:i(function(){return It()},"now"),writable:!0,configurable:!0}),await import("../host/bootstrap.js");const be=Array.isArray(e.files),O=be?e.descriptor:await(await s.fetch(a+"overglaze-web.json")).json(),ve=pt(O);ve&&d("warn",ve),n.capabilities=new Set(O.capabilities||[]),n.capabilities.size?d("info","[script] plugin capabilities granted: "+[...n.capabilities].join(", ")):d("info","[script] plugin capabilities: none declared"),n.capabilities.has("desktopCapture")&&dt(s.GPUDevice,s.GPUBufferUsage),n.storage=new ft(v,(p,Z,Xe,Je)=>{u({type:"storage",area:p,op:Z,key:Xe,value:Je})}),n.params=new Ee(f),E=await import("../host/params.js"),Ie=e.watchParams===!0;const I=await Tt();if(!I){u({type:"unsupported",message:"no WebGPU adapter"});return}if(o=I.device,o.lost.then(p=>u({type:"lost",reason:String(p.reason),message:String(p.message)})),he){const p=await he;if(p.e){w("plugin load",T(p.e));return}X=lt(p.naga,Z=>J("shader",ut(Z))),X.watch(o)}ae=ne(o,kt,"rgba16float","overglaze.linearize"),ce=fe("overglaze.box"),Ge(g,r),r.close(),e.cursor&&(oe(e.cursor,e.hot||[0,0]),e.cursor.close()),n.files=new it(be?new Map(e.files):a,O.files||[],o),n.textures=new nt(o,n.files,d),n.auto=[];for(const p of O.autoBindings||[])n.auto.push({name:p.name,entry:await n.textures.load(p.path)});n.auto.length&&d("info","[assets] auto-bindable in assets/: "+n.auto.map(p=>p.name).join(", "));try{globalThis.__ogInit(o)}catch(p){d("error","[script] @overglaze/api init failed: "+T(p))}(O.mode==="transparent"||O.mode==="warp")&&(globalThis.overglaze.mode=O.mode),k!==null&&await import("../host/seeded_random.js"),wt();const ye=gt(ht);u({type:"globals",stuck:ye.stuck,inherited:ye.inherited}),ie=z.getContext("webgpu"),G=s.gpu.getPreferredCanvasFormat(),ie.configure({device:o,format:G,viewFormats:[G+"-srgb"],alphaMode:"opaque"}),F=ne(o,Ne,G+"-srgb","overglaze.output"),Ue();const q=I.adapter.info||{};u({type:"ready",adapter:[q.vendor,q.architecture,q.description].filter(Boolean).join(" "),fallback:!!(q.isFallbackAdapter||I.adapter.isFallbackAdapter),features:[...o.features],canvasFormat:G,absentDeclared:Ze}),k===null&&me(),await Rt({...O,plugin:a,modules:c})}i(Xt,"start");function Ye(e){if(!Array.isArray(e))return null;const t=i(r=>Math.min(Pt,Math.max(1,Math.round(Number(r))||1)),"side");return[t(e[0]),t(e[1])]}i(Ye,"outputDims");function Jt(){const e=globalThis.gpu&&globalThis.gpu.builtinUniforms||{};return{frames:R,faults:_.count,phase:m,mode:n.mode,epoch:M,paused:L,scene:n.sceneSize.slice(),output:z?[z.width,z.height]:null,split:Y,cursor:{over:l.over,baked:l.baked,size:l.size.slice()},input:e.input?JSON.parse(JSON.stringify(e.input)):null,display:e.display?{...e.display}:null,resolution:e.resolution?JSON.parse(JSON.stringify(e.resolution)):null,time:e.time?{...e.time}:null,params:n.params.toObject(),shaders:X?{...X.counts}:null}}i(Jt,"probe");s.addEventListener("message",e=>{const t=e.data;switch(t.type){case"start":Xt(t).catch(r=>w("start",T(r)));break;case"pause":He();break;case"resume":Yt();break;case"resize":o&&Ge(t.scene,t.picture),t.picture.close(),o&&t.cursor&&oe(t.cursor,t.hot||[0,0]),t.cursor&&t.cursor.close();break;case"desktop":o&&(Fe(t.picture),We()),t.picture.close(),Number.isInteger(t.id)&&u({type:"desktop-in",id:t.id});break;case"output":ue=Ye(t.size),F&&ze();break;case"split":Y=t.at===null?null:Math.min(1,Math.max(0,Number(t.at)||0)),F&&ze();break;case"cursor":o&&oe(t.cursor,t.hot||[0,0]),t.cursor.close();break;case"hover":l.over=t.over===!0;break;case"pointer":C.push(t);break;case"key":se.push(t.key);break;case"cancel":Bt();break;case"step":Wt(t).catch(r=>d("error","[web] step failed: "+T(r)));break;case"run":qt(Number(t.t));break;case"param":Mt(String(t.key),t.values);break;case"param-reset":Dt();break;case"probe":u({type:"probe",id:t.id,result:Jt()});break;case"destroy-device":o&&o.destroy();break}});
package/host/api.js ADDED
@@ -0,0 +1,30 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var te=Object.defineProperty;var f=(e,n)=>te(e,"name",{value:n,configurable:!0});import{core as g}from"../engine/core.js";import{listCount as ne,listSlots as re,sealProjection as W,setProjectionListener as oe}from"./params.js";import{autoBoundTextures as ie,mintTextureView as se,textureRevision as q}from"./assets.js";const ae={f32:{size:4,align:4,comps:1,kind:"f"},u32:{size:4,align:4,comps:1,kind:"u"},i32:{size:4,align:4,comps:1,kind:"i"},vec2f:{size:8,align:8,comps:2,kind:"f"},vec3f:{size:12,align:16,comps:3,kind:"f"},vec4f:{size:16,align:16,comps:4,kind:"f"}},G=f((e,n)=>e+(n-1)&~(n-1),"alignUp");function k(e){let n=0;const s=[];for(const o of e){if(o.array){const i=o.array.elemSize,t=G(n,16),p=i*o.array.capacity;s.push({name:o.name,array:o.array,stride:i,byteSize:p,offset:t,src:o.src}),n=t+p;continue}const a=ae[o.type];if(!a)throw new Error("unsupported uniform type: "+o.type);const r=G(n,a.align);s.push({name:o.name,wgslType:o.type,kind:a.kind,comps:a.comps,byteSize:a.size,offset:r,src:o.src,countOf:o.countOf}),n=r+a.size}return{size:G(n,16),recs:s}}f(k,"layoutFields");function j(e,n,s){let o="struct "+e+` {
7
+ `,a=0,r=0;const i=f(t=>{for(;a+4<=t;)o+=" _pad"+r+++` : u32,
8
+ `,a+=4},"padTo");for(const t of n)i(t.offset),o+=t.array?" "+t.name+" : array<"+t.array.struct+", "+t.array.capacity+`>,
9
+ `:" "+t.name+" : "+t.wgslType+`,
10
+ `,a+=t.byteSize;return i(s),o+`};
11
+ `}f(j,"wgslStruct");function le(e,n,s){let o=0;for(const a of n)for(let r=0;r<a.comps;r++){const i=a.offset+r*4,t=s[o++];a.kind==="u"?e.setUint32(i,t,!0):a.kind==="i"?e.setInt32(i,t,!0):e.setFloat32(i,t,!0)}}f(le,"packStd140");const T=f(e=>e.charAt(0).toUpperCase()+e.slice(1),"structNameOf"),U="params",ue=[{name:"resolution",fields:[{name:"size",type:"vec2f"}],read:f(e=>[e.w,e.h],"read")},{name:"time",fields:[{name:"value",type:"f32"},{name:"delta",type:"f32"},{name:"frame",type:"u32"}],read:f(e=>[e.time,e.delta,e.frame],"read")},{name:"date",fields:[{name:"year",type:"f32"},{name:"month",type:"f32"},{name:"day",type:"f32"},{name:"seconds",type:"f32"}],read:f(()=>{const e=new Date;return[e.getFullYear(),e.getMonth()+1,e.getDate(),e.getHours()*3600+e.getMinutes()*60+e.getSeconds()]},"read")}],ce=`fn srgb_to_linear(c : vec3<f32>) -> vec3<f32> {
12
+ let lo = c / 12.92;
13
+ let hi = pow((c + vec3<f32>(0.055)) / 1.055, vec3<f32>(2.4));
14
+ return select(lo, hi, c > vec3<f32>(0.04045));
15
+ }
16
+ fn linear_to_srgb(c : vec3<f32>) -> vec3<f32> {
17
+ let lo = c * 12.92;
18
+ let hi = 1.055 * pow(c, vec3<f32>(1.0 / 2.4)) - vec3<f32>(0.055);
19
+ return select(lo, hi, c > vec3<f32>(0.0031308));
20
+ }
21
+ `,fe=`@vertex fn vs(@builtin(vertex_index) vi : u32) -> @builtin(position) vec4<f32> {
22
+ var p = array<vec2<f32>, 3>(vec2<f32>(-1.,-1.), vec2<f32>(3.,-1.), vec2<f32>(-1.,3.));
23
+ return vec4<f32>(p[vi], 0., 1.);
24
+ }
25
+ `,u={device:null,format:"rgba16float",builtinBindGroup:null,sceneView:null,desktopView:null,builtinUniforms:{},paramsEpoch:0,__ready:!1};globalThis.gpu=u;let y=[],_=null,P=0,Y=null;const x=new Map;let S=!1,H="",C=null,J=!1,F=!1,v=null,pe=[];function me(e){return e==="cube"?"texture_cube<f32>":e==="2d-array"?"texture_2d_array<f32>":"texture_2d<f32>"}f(me,"autoTextureType");function N(){if(!S)return;const e=u.desktopView??Y,n=[{binding:P,resource:e}];for(const o of y)n.push({binding:o.binding,resource:{buffer:o.buffer}});const s=[];for(const o of v??[]){const a=se(o.texture);if(!a)return;s.push(a),n.push({binding:o.binding,resource:a}),n.push({binding:o.binding+1,resource:o.texture.sampler})}for(const o of v??[])o.builtRev=q(o.texture);pe=s,u.builtinBindGroup=u.device.createBindGroup({layout:C,entries:n})}f(N,"rebuildBindGroup");function de(){for(const e of v??[])if(q(e.texture)!==e.builtRev)return!0;return!1}f(de,"autoBoundReloaded");function X(e){if(_!==null){y=y.filter(r=>r!==_);try{_.buffer.destroy()}catch{}_=null}const n=e.scalars;if(n.length||e.lists.length){const r=new Set,i=new Set([T(U)]);for(const l of y)i.add(T(l.name));let t=n.map(l=>(r.add(l.key),{name:l.key,type:l.t.wgsl,src:l})),p="";const c=[];for(const l of e.lists){const w=l.name+"Count",d=T(l.name)+"Item",z=r.has(l.name)?l.name:r.has(w)?w:i.has(d)?d:"";if(z!==""){g.ops.op_overglaze_log("error","@overglaze/api: capacity list '"+l.name+"' needs the name '"+z+"', which @group(0) already uses; not projected (rename the list)");continue}r.add(l.name),r.add(w),i.add(d);const B=k(l.shape.map(V=>({name:V.field,type:V.t.wgsl})));p+=j(d,B.recs,B.size),c.push({list:l,countName:w,structName:d,elem:B})}for(const l of c)t.push({name:l.countName,type:"u32",countOf:l.list});for(const l of c)t.push({name:l.list.name,array:{list:l.list,struct:l.structName,capacity:l.list.capacity,elemSize:l.elem.size,elemRecs:l.elem.recs}});let{size:m,recs:b}=k(t);const h=u.device.limits?.maxUniformBufferBindingSize??65536;if(m>h&&c.length&&(g.ops.op_overglaze_log("error","@overglaze/api: struct Params would be "+m+" bytes, past this device's "+h+"-byte uniform limit; the capacity list(s) "+c.map(l=>l.list.name+"["+l.list.capacity+"]").join(", ")+" are not projected -- reduce a capacity"),p="",c.length=0,t=t.filter(l=>!l.array&&l.countOf===void 0),{size:m,recs:b}=k(t)),b.length){const l=new ArrayBuffer(m);_={name:U,binding:y.length+1,kind:"params",recs:b,size:m,cpu:l,view:new DataView(l),preWgsl:p,structNames:c.map(d=>d.structName),buffer:u.device.createBuffer({size:m,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,label:"overglaze.uniform."+U})},y.push(_);const w=c.length?"; "+c.length+" capacity list(s): "+c.map(d=>d.list.name+"["+d.list.capacity+"] { "+d.list.shape.map(z=>z.field+": "+z.t.wgsl).join(", ")+" }").join(", "):"";g.ops.op_overglaze_log("info","@overglaze/api: projected "+n.length+" parameter(s) into struct Params"+(n.length?": "+n.map(d=>d.key+": "+d.t.wgsl).join(", "):"")+w+" ("+m+" bytes)")}}let s="@group(0) @binding("+P+`) var src : texture_2d<f32>;
26
+ `;for(const r of y){const i=T(r.name);r.preWgsl&&(s+=r.preWgsl),s+=j(i,r.recs,r.size),s+="@group(0) @binding("+r.binding+") var<uniform> "+r.name+" : "+i+`;
27
+ `}if(v===null){const r=new Set(["src","vs","srgb_to_linear","linear_to_srgb",U]);for(const i of y){r.add(i.name),r.add(T(i.name));for(const t of i.structNames??[])r.add(t)}v=[];for(const i of ie()){if(r.has(i.name)||r.has(i.name+"Sampler")){g.ops.op_overglaze_log("error","@overglaze/api: asset '"+i.name+"' collides with a name @group(0) already uses; not bound (rename the file)");continue}r.add(i.name),r.add(i.name+"Sampler"),v.push({...i,binding:0,builtRev:-1})}v.length&&g.ops.op_overglaze_log("info","@overglaze/api: bound "+v.length+" asset(s) into @group(0): "+v.map(i=>i.name+" ("+i.texture.dimension+")").join(", "))}let o=y.length+1;for(const r of v)r.binding=o,o+=2,s+="@group(0) @binding("+r.binding+") var "+r.name+" : "+me(r.texture.dimension)+`;
28
+ `,s+="@group(0) @binding("+(r.binding+1)+") var "+r.name+`Sampler : sampler;
29
+ `;H=s+ce;const a=[{binding:P,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float",viewDimension:"2d",multisampled:!1}}];for(const r of y)a.push({binding:r.binding,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}});for(const r of v)a.push({binding:r.binding,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:r.texture.dimension,multisampled:!1}}),a.push({binding:r.binding+1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}});C=u.device.createBindGroupLayout({entries:a}),J&&N()}f(X,"composeGroup0");function K(){S||!u.__ready||(S=!0,X(W()))}f(K,"seal");oe(()=>{S&&(F=!0)});function I(){!F||!S||(F=!1,X(W()),x.clear(),u.paramsEpoch++)}f(I,"recomposeProjection");Object.defineProperty(u,"builtinWgsl",{get:f(()=>(K(),I(),H),"get"),enumerable:!0});Object.defineProperty(u,"builtinBindGroupLayout",{get:f(()=>(K(),I(),C),"get"),enumerable:!0});let L=-1,E=0,R=0,A=0,O=0,M=0;function Q(e,n,s){const o=u.device.createShaderModule({code:u.builtinWgsl+fe+e});return u.device.createRenderPipeline({layout:u.device.createPipelineLayout({bindGroupLayouts:[u.builtinBindGroupLayout,...n]}),vertex:{module:o,entryPoint:"vs"},fragment:{module:o,entryPoint:"fs",targets:[s?{format:u.format,blend:s}:{format:u.format}]},primitive:{topology:"triangle-list"}})}f(Q,"buildPipeline");function ge(e,n=[]){return Q(e,n,void 0)}f(ge,"createFullscreenPipeline");function Z(e,n,s,o,a){for(let r=0;r<o;r++){const i=Number(a[r]),t=isFinite(i)?i:0,p=n+r*4;s==="u"?e.setUint32(p,t,!0):s==="i"?e.setInt32(p,t,!0):e.setFloat32(p,t,!0)}}f(Z,"packHolder");function D(e,n,s){for(let o=0;o+4<=s;o+=4)e.setUint32(n+o,0,!0)}f(D,"zeroRange");function be(e,n){const s=re(n.array.list);for(let a=0;a<s.length;a++){const r=s[a],i=n.offset+a*n.stride;for(const t of n.array.elemRecs){const p=r.get(t.name);p===void 0||!p.projected?D(e,i+t.offset,t.byteSize):Z(e,i+t.offset,t.kind,t.comps,p.holder)}}const o=n.offset+s.length*n.stride;D(e,o,n.offset+n.byteSize-o)}f(be,"packArray");function $(){if(!_)return;const e=_.view;for(const n of _.recs)n.array?be(e,n):n.countOf?e.setUint32(n.offset,ne(n.countOf),!0):Z(e,n.offset,n.kind,n.comps,n.src.holder);u.device.queue.writeBuffer(_.buffer,0,_.cpu)}f($,"writeParams");function ee(e,n=[]){$();const s=u.device.createCommandEncoder(),o=s.beginRenderPass({colorAttachments:[{view:u.sceneView,loadOp:"load",storeOp:"store"}]});o.setPipeline(e),o.setBindGroup(0,u.builtinBindGroup);for(let a=0;a<n.length;a++)o.setBindGroup(1+a,n[a]);o.draw(3),o.end(),u.device.queue.submit([s.finish()])}f(ee,"drawFullscreen");function ye(e){const n=f(t=>t===null?"null":typeof t,"kind");if(e===null||typeof e!="object")throw new TypeError("gpu.runFullscreenEffect takes an options object, { code, blend?, groups? }, not "+n(e));const{code:s,blend:o,groups:a=[]}=e;if(typeof s!="string")throw new TypeError("gpu.runFullscreenEffect needs code, the WGSL source, as a string, not "+n(s));const r=s+"\0"+(o?JSON.stringify(o):"");let i=x.get(r);i||(i=Q(s,a.map(t=>t.layout),o),x.set(r,i)),ee(i,a.map(t=>t.bindGroup))}f(ye,"runFullscreenEffect");u.createFullscreenPipeline=ge;u.drawFullscreen=ee;u.runFullscreenEffect=ye;u.writeParams=$;globalThis.__ogRunInit=(e,n,s)=>{const o=new AbortController;globalThis.__ogAbortInit=()=>o.abort();const a={progress(r,i){const t=typeof r=="number"&&isFinite(r)?r:-1;g.ops.op_overglaze_init_progress(t,i===void 0?"":String(i))},signal:o.signal,width:n,height:s};return(async()=>await e(a))()};globalThis.__ogRunWgsl=e=>{globalThis.__ogWgslModule(e),globalThis.frame=()=>{u.__ready&&u.runFullscreenEffect({code:e})}};globalThis.__ogRunWasm=e=>{const n=f(c=>({ptr:Number(c&0xffffffffn),len:Number(c>>32n&0xffffffffn)}),"unpack"),s=f(()=>new Uint8Array(o.exports.memory.buffer),"memBytes");let o,a;try{o=new WebAssembly.Instance(new WebAssembly.Module(e),{});const c=o.exports.og_abi_version();if(c!==1)throw new Error("plugin declares WASM ABI v"+c+"; host speaks v1");const m=n(o.exports.og_init());a=new TextDecoder().decode(s().subarray(m.ptr,m.ptr+m.len))}catch(c){g.ops.op_overglaze_report_fault("wasm plugin init",String(c)+(c&&c.stack?`
30
+ `+c.stack:""));return}let r=null,i=null,t=null,p=0;globalThis.frame=()=>{if(!u.__ready)return;const c=u.builtinUniforms.time,m=u.builtinUniforms.resolution;let b;try{b=o.exports.og_frame(c.value,c.delta,m.size[0],m.size[1])}catch(z){g.ops.op_overglaze_report_fault("wasm plugin og_frame",String(z));return}const{ptr:h,len:l}=n(b),w=s().subarray(h,h+l),d=l+15&-16;(!r||d>p)&&(p=d,t=u.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),r=u.device.createBuffer({size:d,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,label:"overglaze.wasm-plugin.params"}),i=u.device.createBindGroup({layout:t,entries:[{binding:0,resource:{buffer:r}}]})),u.device.queue.writeBuffer(r,0,w),u.runFullscreenEffect({code:a,groups:[{layout:t,bindGroup:i}]})}};globalThis.__ogInit=e=>{try{u.device=e;try{e.addEventListener("uncapturederror",t=>{g.ops.op_overglaze_log("error","[gpu] uncaptured error: "+(t.error&&t.error.message))}),e.lost.then(t=>{g.ops.op_overglaze_log("error","[gpu] device lost ("+t.reason+"): "+t.message)}).catch(()=>{})}catch(t){g.ops.op_overglaze_log("warn","@overglaze/api: GPU diagnostics wiring failed: "+t)}const s=(JSON.parse(g.ops.op_overglaze_uniform_manifest()||"{}").contributors||[]).map(t=>({name:t.name,fields:t.fields.map(p=>({name:p.name,type:p.type})),kind:"rust"})),a=[...ue.map(t=>({...t,kind:"native"})),...s];P=0;let r=1;y=a.map(t=>{const{size:p,recs:c}=k(t.fields),m=new ArrayBuffer(p),b={name:t.name,binding:r++,kind:t.kind,recs:c,size:p,cpu:m,view:new DataView(m),read:t.read,slots:c.reduce((l,w)=>l+w.comps,0),buffer:e.createBuffer({size:p,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,label:"overglaze.uniform."+t.name})},h={};for(const l of c)h[l.name]=l.comps===1?0:new Array(l.comps).fill(0);return u.builtinUniforms[t.name]=h,b}),Y=e.createTexture({size:[1,1],format:u.format,usage:GPUTextureUsage.TEXTURE_BINDING,label:"overglaze.src.dummy"}).createView(),E=performance.now()/1e3,R=E,A=0,O=0,M=0,u.__ready=!0,g.ops.op_overglaze_log("info","@overglaze/api: builtin uniforms ready")}catch(n){g.ops.op_overglaze_log("error","@overglaze/api init failed: "+n),globalThis.__ogFrame=void 0}};globalThis.__ogFrame=(e,n,s)=>{globalThis.__w=e,globalThis.__h=n;const o=performance.now()/1e3;O=o-R,R=o,A=o-E,M++;const a={w:e,h:n,time:A,delta:O,frame:M},r=g.ops.op_overglaze_uniform_values();let i=0;for(const t of y){if(t.kind==="params")continue;const p=t.kind==="native"?t.read(a):r.slice(i,i+=t.slots);le(t.view,t.recs,p),u.device.queue.writeBuffer(t.buffer,0,t.cpu);const c=u.builtinUniforms[t.name];let m=0;for(const b of t.recs)if(b.comps===1)c[b.name]=p[m++];else{const h=c[b.name];for(let l=0;l<b.comps;l++)h[l]=p[m++]}}!Number.isFinite(s)||s!==L?(L=s,u.sceneView=g.ops.op_overglaze_scene_view(),u.desktopView=g.ops.op_overglaze_desktop_view(),J=!0,N()):de()&&N(),I(),globalThis.frame&&globalThis.frame(),globalThis.__ogAutoPanel&&globalThis.__ogAutoPanel()};
package/host/assets.js ADDED
@@ -0,0 +1,6 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var l=Object.defineProperty;var u=(r,e)=>l(r,"name",{value:e,configurable:!0});import{core as i}from"../engine/core.js";const a=new WeakMap;class p{static{u(this,"Texture")}#e;constructor(e){this.#e=e,a.set(this,e);const s=i.ops.op_assets_texture_info(e);this.width=s.width,this.height=s.height,this.depthOrArrayLayers=s.depthOrArrayLayers,this.dimension=s.dimension,this.isFallback=s.isFallback,this.view=i.ops.op_assets_texture_view(e,null);const t=globalThis.__device;this.sampler=t?t.createSampler(s.samplerDesc):null}createView(e){return i.ops.op_assets_texture_view(this.#e,e??null)}}class c{static{u(this,"AssetBindGroup")}#e;#s;#t=null;#r=null;constructor(e,s){if(!e)throw new TypeError("makeBindGroup: layout is required");if(!Array.isArray(s))throw new TypeError("makeBindGroup: entries must be an array");this.#e=e,this.#s=s.map((t,n)=>{if(t===null||typeof t!="object"||typeof t.binding!="number")throw new TypeError("makeBindGroup: entry "+n+" needs a numeric 'binding'");if(t.asset!==void 0){const o=a.get(t.asset);if(!o)throw new TypeError("makeBindGroup: entry "+n+".asset is not an assets Texture");return{binding:t.binding,asset:t.asset,token:o,viewDesc:t.view??null,builtRev:0}}if(t.sampler!==void 0)return{binding:t.binding,resource:t.sampler};if(t.resource!==void 0)return{binding:t.binding,resource:t.resource};throw new TypeError("makeBindGroup: entry "+n+" needs 'asset', 'sampler', or 'resource'")})}get gpuBindGroup(){return(this.#t===null||this.#n())&&this.#i(),this.#t}#n(){for(const e of this.#s)if(e.token&&i.ops.op_assets_texture_revision(e.token)!==e.builtRev)return!0;return!1}#i(){this.#t=null;const e=globalThis.__device;if(!e)return;const s=[],t=[];for(const n of this.#s)if(n.token){const o=i.ops.op_assets_texture_view(n.token,n.viewDesc);if(!o)return;n.builtRev=i.ops.op_assets_texture_revision(n.token),s.push(o),t.push({binding:n.binding,resource:o})}else t.push({binding:n.binding,resource:n.resource});this.#r=s,this.#t=e.createBindGroup({layout:this.#e,entries:t})}}globalThis.assets={async loadTexture(r){const e=await i.ops.op_assets_load_texture(String(r));return new p(e)},makeBindGroup(r,e){return new c(r,e)}};function _(){const r=i.ops.op_assets_auto_binding_names(),e=[];for(let s=0;s<r.length;s++)e.push({name:r[s],texture:new p(i.ops.op_assets_auto_binding_texture(s))});return e}u(_,"autoBoundTextures");function w(r){const e=a.get(r);return e?i.ops.op_assets_texture_view(e,null):null}u(w,"mintTextureView");function f(r){const e=a.get(r);return e?i.ops.op_assets_texture_revision(e):0}u(f,"textureRevision");export{_ as autoBoundTextures,w as mintTextureView,f as textureRevision};
@@ -0,0 +1,7 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var f=Object.defineProperty;var s=(e,o)=>f(e,"name",{value:o,configurable:!0});import{core as t}from"../engine/core.js";import"./storage.js";import"./webshim.js";import"./params.js";import"./api.js";import"./imgui.js";import"./assets.js";import"./webio.js";const i=t.createLazyLoader("ext:deno_webgpu/01_webgpu.js")();i.initGPU();globalThis.navigator={gpu:i.gpu};globalThis.GPUBufferUsage=i.GPUBufferUsage;globalThis.GPUColorWrite=i.GPUColorWrite;globalThis.GPUMapMode=i.GPUMapMode;globalThis.GPUShaderStage=i.GPUShaderStage;globalThis.GPUTextureUsage=i.GPUTextureUsage;globalThis.self=globalThis;const b=t.loadExtScript("ext:deno_web/02_timers.js");globalThis.setTimeout=b.setTimeout;globalThis.clearTimeout=b.clearTimeout;globalThis.setInterval=b.setInterval;globalThis.clearInterval=b.clearInterval;const m=t.loadExtScript("ext:deno_web/15_performance.js");m.setTimeOrigin();globalThis.Performance=m.Performance;globalThis.performance=m.performance;const d=t.loadExtScript("ext:deno_web/01_dom_exception.js");globalThis.DOMException=d.DOMException;const _=t.loadExtScript("ext:deno_web/03_abort_signal.js");globalThis.AbortController=_.AbortController;globalThis.AbortSignal=_.AbortSignal;const h=t.loadExtScript("ext:deno_web/00_url.js");globalThis.URL=h.URL;globalThis.URLSearchParams=h.URLSearchParams;const T=t.loadExtScript("ext:deno_web/08_text_encoding.js");globalThis.TextEncoder=T.TextEncoder;globalThis.TextDecoder=T.TextDecoder;WebAssembly.compileStreaming=e=>Promise.resolve(e).then(o=>o.arrayBuffer()).then(o=>WebAssembly.compile(o));WebAssembly.instantiateStreaming=(e,o)=>Promise.resolve(e).then(r=>r.arrayBuffer()).then(r=>WebAssembly.instantiate(r,o));let c=new Map,u=0;globalThis.requestAnimationFrame=e=>{const o=++u;return c.set(o,e),o};globalThis.cancelAnimationFrame=e=>{c.delete(e)};globalThis.__ogFlushAnimationFrames=e=>{const o=c;c=new Map;for(const r of o.values())try{r(e)}catch(l){t.ops.op_overglaze_report_fault("requestAnimationFrame callback",String(l)+(l&&l.stack?`
7
+ `+l.stack:""))}};const n=s(e=>e.map(o=>typeof o=="string"?o:String(o)).join(" "),"fmt");globalThis.console={log:s((...e)=>t.ops.op_overglaze_log("info",n(e)),"log"),info:s((...e)=>t.ops.op_overglaze_log("info",n(e)),"info"),warn:s((...e)=>t.ops.op_overglaze_log("warn",n(e)),"warn"),error:s((...e)=>t.ops.op_overglaze_log("error",n(e)),"error"),debug:s((...e)=>t.ops.op_overglaze_log("debug",n(e)),"debug"),trace:s((...e)=>t.ops.op_overglaze_log("trace",n(e)),"trace")};globalThis.overglaze={mode:"opaque",interactiveRects:[]};let p=[];globalThis.__ogPollCompositor=()=>{const e=globalThis.overglaze||{};t.ops.op_overglaze_set_compositor(String(e.mode||"opaque"));const o=[],r=e.interactiveRects;if(Array.isArray(r))for(let a=0;a<r.length;a++){const g=r[a];g&&o.push(+g.x,+g.y,+g.width,+g.height)}let l=o.length===p.length;for(let a=0;l&&a<o.length;a++)l=o[a]===p[a];l||(p=o,t.ops.op_overglaze_set_interactive_rects(o)),globalThis.__ogSyncParams&&globalThis.__ogSyncParams()};
package/host/imgui.js ADDED
@@ -0,0 +1,6 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var m=Object.defineProperty;var n=(i,e)=>m(i,"name",{value:e,configurable:!0});import{core as S}from"../engine/core.js";const o=S.ops,d=n((i,e)=>i!=null&&i[e]!=null?+i[e]:0,"_n");globalThis.ImGui={BeginChild:n((i,e,t,r)=>o.op_overglaze_imgui_beginchild(String(i),d(e,0),d(e,1),t===void 0?0:t,r===void 0?0:r),"BeginChild"),EndChild:n(()=>o.op_overglaze_imgui_endchild(),"EndChild"),GetWindowWidth:n(()=>o.op_overglaze_imgui_getwindowwidth(),"GetWindowWidth"),GetWindowHeight:n(()=>o.op_overglaze_imgui_getwindowheight(),"GetWindowHeight"),BeginPopup:n((i,e)=>o.op_overglaze_imgui_beginpopup(String(i),e===void 0?0:e),"BeginPopup"),EndPopup:n(()=>o.op_overglaze_imgui_endpopup(),"EndPopup"),OpenPopup:n((i,e)=>o.op_overglaze_imgui_openpopup(String(i),e===void 0?0:e),"OpenPopup"),CloseCurrentPopup:n(()=>o.op_overglaze_imgui_closecurrentpopup(),"CloseCurrentPopup"),IsPopupOpen:n((i,e)=>o.op_overglaze_imgui_ispopupopen(String(i),e===void 0?0:e),"IsPopupOpen"),BeginPopupContextItem:n((i,e)=>o.op_overglaze_imgui_beginpopupcontextitem(i===void 0?null:String(i),e===void 0?0:e),"BeginPopupContextItem"),Separator:n(()=>o.op_overglaze_imgui_separator(),"Separator"),SeparatorText:n(i=>o.op_overglaze_imgui_separatortext(String(i)),"SeparatorText"),SameLine:n((i,e)=>o.op_overglaze_imgui_sameline(i===void 0?0:i,e===void 0?-1:e),"SameLine"),NewLine:n(()=>o.op_overglaze_imgui_newline(),"NewLine"),Spacing:n(()=>o.op_overglaze_imgui_spacing(),"Spacing"),Dummy:n(i=>o.op_overglaze_imgui_dummy(d(i,0),d(i,1)),"Dummy"),Indent:n(i=>o.op_overglaze_imgui_indent(i===void 0?0:i),"Indent"),Unindent:n(i=>o.op_overglaze_imgui_unindent(i===void 0?0:i),"Unindent"),BeginGroup:n(()=>o.op_overglaze_imgui_begingroup(),"BeginGroup"),EndGroup:n(()=>o.op_overglaze_imgui_endgroup(),"EndGroup"),SetNextItemWidth:n(i=>o.op_overglaze_imgui_setnextitemwidth(i),"SetNextItemWidth"),PushItemWidth:n(i=>o.op_overglaze_imgui_pushitemwidth(i),"PushItemWidth"),PopItemWidth:n(()=>o.op_overglaze_imgui_popitemwidth(),"PopItemWidth"),GetFrameHeight:n(()=>o.op_overglaze_imgui_getframeheight(),"GetFrameHeight"),GetFrameHeightWithSpacing:n(()=>o.op_overglaze_imgui_getframeheightwithspacing(),"GetFrameHeightWithSpacing"),PushID:n(i=>o.op_overglaze_imgui_pushid(String(i)),"PushID"),PopID:n(()=>o.op_overglaze_imgui_popid(),"PopID"),BeginTable:n((i,e,t,r,l)=>o.op_overglaze_imgui_begintable(String(i),e,t===void 0?0:t,d(r,0),d(r,1),l===void 0?0:l),"BeginTable"),EndTable:n(()=>o.op_overglaze_imgui_endtable(),"EndTable"),TableNextRow:n((i,e)=>o.op_overglaze_imgui_tablenextrow(i===void 0?0:i,e===void 0?0:e),"TableNextRow"),TableNextColumn:n(()=>o.op_overglaze_imgui_tablenextcolumn(),"TableNextColumn"),TableSetColumnIndex:n(i=>o.op_overglaze_imgui_tablesetcolumnindex(i),"TableSetColumnIndex"),TableSetupColumn:n((i,e,t,r)=>o.op_overglaze_imgui_tablesetupcolumn(String(i),e===void 0?0:e,t===void 0?0:t,r===void 0?0:r),"TableSetupColumn"),TableSetupScrollFreeze:n((i,e)=>o.op_overglaze_imgui_tablesetupscrollfreeze(i,e),"TableSetupScrollFreeze"),TableHeadersRow:n(()=>o.op_overglaze_imgui_tableheadersrow(),"TableHeadersRow"),BeginDisabled:n(i=>o.op_overglaze_imgui_begindisabled(!!i),"BeginDisabled"),EndDisabled:n(()=>o.op_overglaze_imgui_enddisabled(),"EndDisabled"),TextUnformatted:n((i,e)=>o.op_overglaze_imgui_textunformatted(String(i)),"TextUnformatted"),Bullet:n(()=>o.op_overglaze_imgui_bullet(),"Bullet"),Button:n((i,e)=>o.op_overglaze_imgui_button(String(i),d(e,0),d(e,1)),"Button"),SmallButton:n(i=>o.op_overglaze_imgui_smallbutton(String(i)),"SmallButton"),InvisibleButton:n((i,e,t)=>o.op_overglaze_imgui_invisiblebutton(String(i),d(e,0),d(e,1),t===void 0?0:t),"InvisibleButton"),Checkbox:n((i,e)=>{const t=o.op_overglaze_imgui_checkbox(String(i),!!(e&&e[0]));return e[0]=!!t[1],!!t[0]},"Checkbox"),RadioButton:n((i,e)=>o.op_overglaze_imgui_radiobutton(String(i),!!e),"RadioButton"),ProgressBar:n((i,e,t)=>o.op_overglaze_imgui_progressbar(i,d(e,0),d(e,1),t===void 0?null:String(t)),"ProgressBar"),Selectable:n((i,e,t,r)=>o.op_overglaze_imgui_selectable(String(i),!!e,t===void 0?0:t,d(r,0),d(r,1)),"Selectable"),BeginListBox:n((i,e)=>o.op_overglaze_imgui_beginlistbox(String(i),d(e,0),d(e,1)),"BeginListBox"),EndListBox:n(()=>o.op_overglaze_imgui_endlistbox(),"EndListBox"),SliderFloat:n((i,e,t,r,l,g)=>{const u=o.op_overglaze_imgui_sliderfloat(String(i),d(e,0),t,r,l===void 0?"%.3f":String(l),g===void 0?0:g);return e[0]=u[1],!!u[0]},"SliderFloat"),SliderFloat2:n((i,e,t,r,l,g)=>{const u=o.op_overglaze_imgui_sliderfloat2(String(i),[d(e,0),d(e,1)],t,r,l===void 0?"%.3f":String(l),g===void 0?0:g);return e[0]=u[1],e[1]=u[2],!!u[0]},"SliderFloat2"),SliderFloat3:n((i,e,t,r,l,g)=>{const u=o.op_overglaze_imgui_sliderfloat3(String(i),[d(e,0),d(e,1),d(e,2)],t,r,l===void 0?"%.3f":String(l),g===void 0?0:g);return e[0]=u[1],e[1]=u[2],e[2]=u[3],!!u[0]},"SliderFloat3"),SliderFloat4:n((i,e,t,r,l,g)=>{const u=o.op_overglaze_imgui_sliderfloat4(String(i),[d(e,0),d(e,1),d(e,2),d(e,3)],t,r,l===void 0?"%.3f":String(l),g===void 0?0:g);return e[0]=u[1],e[1]=u[2],e[2]=u[3],e[3]=u[4],!!u[0]},"SliderFloat4"),SliderInt:n((i,e,t,r,l,g)=>{const u=o.op_overglaze_imgui_sliderint(String(i),d(e,0),t,r,l===void 0?"%d":String(l),g===void 0?0:g);return e[0]=u[1],!!u[0]},"SliderInt"),SliderInt2:n((i,e,t,r,l,g)=>{const u=o.op_overglaze_imgui_sliderint2(String(i),[d(e,0),d(e,1)],t,r,l===void 0?"%d":String(l),g===void 0?0:g);return e[0]=u[1],e[1]=u[2],!!u[0]},"SliderInt2"),SliderInt3:n((i,e,t,r,l,g)=>{const u=o.op_overglaze_imgui_sliderint3(String(i),[d(e,0),d(e,1),d(e,2)],t,r,l===void 0?"%d":String(l),g===void 0?0:g);return e[0]=u[1],e[1]=u[2],e[2]=u[3],!!u[0]},"SliderInt3"),SliderInt4:n((i,e,t,r,l,g)=>{const u=o.op_overglaze_imgui_sliderint4(String(i),[d(e,0),d(e,1),d(e,2),d(e,3)],t,r,l===void 0?"%d":String(l),g===void 0?0:g);return e[0]=u[1],e[1]=u[2],e[2]=u[3],e[3]=u[4],!!u[0]},"SliderInt4"),SliderAngle:n((i,e,t,r,l,g)=>{const u=o.op_overglaze_imgui_sliderangle(String(i),d(e,0),t===void 0?-360:t,r===void 0?360:r,l===void 0?"%.0f deg":String(l),g===void 0?0:g);return e[0]=u[1],!!u[0]},"SliderAngle"),DragFloat:n((i,e,t,r,l,g,u)=>{const a=o.op_overglaze_imgui_dragfloat(String(i),d(e,0),t===void 0?1:t,r===void 0?0:r,l===void 0?0:l,g===void 0?"%.3f":String(g),u===void 0?0:u);return e[0]=a[1],!!a[0]},"DragFloat"),DragFloat2:n((i,e,t,r,l,g,u)=>{const a=o.op_overglaze_imgui_dragfloat2(String(i),[d(e,0),d(e,1)],t===void 0?1:t,r===void 0?0:r,l===void 0?0:l,g===void 0?"%.3f":String(g),u===void 0?0:u);return e[0]=a[1],e[1]=a[2],!!a[0]},"DragFloat2"),DragFloat3:n((i,e,t,r,l,g,u)=>{const a=o.op_overglaze_imgui_dragfloat3(String(i),[d(e,0),d(e,1),d(e,2)],t===void 0?1:t,r===void 0?0:r,l===void 0?0:l,g===void 0?"%.3f":String(g),u===void 0?0:u);return e[0]=a[1],e[1]=a[2],e[2]=a[3],!!a[0]},"DragFloat3"),DragFloat4:n((i,e,t,r,l,g,u)=>{const a=o.op_overglaze_imgui_dragfloat4(String(i),[d(e,0),d(e,1),d(e,2),d(e,3)],t===void 0?1:t,r===void 0?0:r,l===void 0?0:l,g===void 0?"%.3f":String(g),u===void 0?0:u);return e[0]=a[1],e[1]=a[2],e[2]=a[3],e[3]=a[4],!!a[0]},"DragFloat4"),DragInt:n((i,e,t,r,l,g,u)=>{const a=o.op_overglaze_imgui_dragint(String(i),d(e,0),t===void 0?1:t,r===void 0?0:r,l===void 0?0:l,g===void 0?"%d":String(g),u===void 0?0:u);return e[0]=a[1],!!a[0]},"DragInt"),DragInt2:n((i,e,t,r,l,g,u)=>{const a=o.op_overglaze_imgui_dragint2(String(i),[d(e,0),d(e,1)],t===void 0?1:t,r===void 0?0:r,l===void 0?0:l,g===void 0?"%d":String(g),u===void 0?0:u);return e[0]=a[1],e[1]=a[2],!!a[0]},"DragInt2"),DragInt3:n((i,e,t,r,l,g,u)=>{const a=o.op_overglaze_imgui_dragint3(String(i),[d(e,0),d(e,1),d(e,2)],t===void 0?1:t,r===void 0?0:r,l===void 0?0:l,g===void 0?"%d":String(g),u===void 0?0:u);return e[0]=a[1],e[1]=a[2],e[2]=a[3],!!a[0]},"DragInt3"),DragInt4:n((i,e,t,r,l,g,u)=>{const a=o.op_overglaze_imgui_dragint4(String(i),[d(e,0),d(e,1),d(e,2),d(e,3)],t===void 0?1:t,r===void 0?0:r,l===void 0?0:l,g===void 0?"%d":String(g),u===void 0?0:u);return e[0]=a[1],e[1]=a[2],e[2]=a[3],e[3]=a[4],!!a[0]},"DragInt4"),ColorEdit3:n((i,e,t)=>{const r=o.op_overglaze_imgui_coloredit3(String(i),[d(e,0),d(e,1),d(e,2)],t===void 0?0:t);return e[0]=r[1],e[1]=r[2],e[2]=r[3],!!r[0]},"ColorEdit3"),ColorEdit4:n((i,e,t)=>{const r=o.op_overglaze_imgui_coloredit4(String(i),[d(e,0),d(e,1),d(e,2),d(e,3)],t===void 0?0:t);return e[0]=r[1],e[1]=r[2],e[2]=r[3],e[3]=r[4],!!r[0]},"ColorEdit4"),ColorPicker3:n((i,e,t)=>{const r=o.op_overglaze_imgui_colorpicker3(String(i),[d(e,0),d(e,1),d(e,2)],t===void 0?0:t);return e[0]=r[1],e[1]=r[2],e[2]=r[3],!!r[0]},"ColorPicker3"),ColorPicker4:n((i,e,t)=>{const r=o.op_overglaze_imgui_colorpicker4(String(i),[d(e,0),d(e,1),d(e,2),d(e,3)],t===void 0?0:t);return e[0]=r[1],e[1]=r[2],e[2]=r[3],e[3]=r[4],!!r[0]},"ColorPicker4"),TreeNode:n(i=>o.op_overglaze_imgui_treenode(String(i)),"TreeNode"),TreeNodeEx:n((i,e)=>o.op_overglaze_imgui_treenodeex(String(i),e===void 0?0:e),"TreeNodeEx"),TreePop:n(()=>o.op_overglaze_imgui_treepop(),"TreePop"),CollapsingHeader:n((i,e)=>o.op_overglaze_imgui_collapsingheader(String(i),e===void 0?0:e),"CollapsingHeader"),SetNextItemOpen:n((i,e)=>o.op_overglaze_imgui_setnextitemopen(!!i,e===void 0?0:e),"SetNextItemOpen"),BeginTooltip:n(()=>o.op_overglaze_imgui_begintooltip(),"BeginTooltip"),EndTooltip:n(()=>o.op_overglaze_imgui_endtooltip(),"EndTooltip"),BeginTabBar:n((i,e)=>o.op_overglaze_imgui_begintabbar(String(i),e===void 0?0:e),"BeginTabBar"),EndTabBar:n(()=>o.op_overglaze_imgui_endtabbar(),"EndTabBar"),BeginTabItem:n((i,e,t)=>{const r=o.op_overglaze_imgui_begintabitem(String(i),Array.isArray(e)?!!e[0]:!1,Array.isArray(e),t===void 0?0:t);return Array.isArray(e)&&(e[0]=!!r[1]),!!r[0]},"BeginTabItem"),EndTabItem:n(()=>o.op_overglaze_imgui_endtabitem(),"EndTabItem"),IsItemHovered:n(i=>o.op_overglaze_imgui_isitemhovered(i===void 0?0:i),"IsItemHovered"),IsItemActive:n(()=>o.op_overglaze_imgui_isitemactive(),"IsItemActive"),IsItemClicked:n(i=>o.op_overglaze_imgui_isitemclicked(i===void 0?0:i),"IsItemClicked"),GetTime:n(()=>o.op_overglaze_imgui_gettime(),"GetTime"),Text:n(i=>o.op_overglaze_imgui_text(String(i)),"Text"),Combo:n((i,e,t,r)=>{const l=o.op_overglaze_imgui_combo(String(i),d(e,0),(t||[]).map(String),r===void 0?0:r);return l[0]&&(e[0]=l[1]),!!l[0]},"Combo")};ImGui.WindowFlags={None:0,NoTitleBar:1,NoResize:2,NoMove:4,NoScrollbar:8,NoScrollWithMouse:16,NoCollapse:32,AlwaysAutoResize:64,NoBackground:128,NoSavedSettings:256,NoMouseInputs:512,MenuBar:1024,HorizontalScrollbar:2048,NoFocusOnAppearing:4096,NoBringToFrontOnFocus:8192,AlwaysVerticalScrollbar:16384,AlwaysHorizontalScrollbar:32768,NoNavInputs:65536,NoNavFocus:131072,UnsavedDocument:262144,NoNav:196608,NoDecoration:43,NoInputs:197120};ImGui.ChildFlags={None:0,Borders:1,AlwaysUseWindowPadding:2,ResizeX:4,ResizeY:8,AutoResizeX:16,AutoResizeY:32,AlwaysAutoResize:64,FrameStyle:128,NavFlattened:256};ImGui.Cond={None:0,Always:1,Once:2,FirstUseEver:4,Appearing:8};ImGui.ColorEditFlags={None:0,NoAlpha:2,NoPicker:4,NoOptions:8,NoSmallPreview:16,NoInputs:32,NoTooltip:64,NoLabel:128,NoSidePreview:256,NoDragDrop:512,NoBorder:1024,NoColorMarkers:2048,AlphaOpaque:4096,AlphaNoBg:8192,AlphaPreviewHalf:16384,AlphaBar:262144,HDR:524288,DisplayRGB:1048576,DisplayHSV:2097152,DisplayHex:4194304,Uint8:8388608,Float:16777216,PickerHueBar:33554432,PickerHueWheel:67108864,InputRGB:134217728,InputHSV:268435456,AlphaPreview:0};ImGui.SliderFlags={None:0,Logarithmic:32,NoRoundToFormat:64,NoInput:128,WrapAround:256,ClampOnInput:512,ClampZeroRange:1024,NoSpeedTweaks:2048,ColorMarkers:4096,AlwaysClamp:1536};ImGui.TreeNodeFlags={None:0,Selected:1,Framed:2,AllowOverlap:4,NoTreePushOnOpen:8,NoAutoOpenOnLog:16,DefaultOpen:32,OpenOnDoubleClick:64,OpenOnArrow:128,Leaf:256,Bullet:512,FramePadding:1024,SpanAvailWidth:2048,SpanFullWidth:4096,SpanLabelWidth:8192,SpanAllColumns:16384,LabelSpanAllColumns:32768,NavLeftJumpsToParent:131072,CollapsingHeader:26,DrawLinesNone:262144,DrawLinesFull:524288,DrawLinesToNodes:1048576,NavLeftJumpsBackHere:131072,SpanTextWidth:8192};ImGui.TabBarFlags={None:0,Reorderable:1,AutoSelectNewTabs:2,TabListPopupButton:4,NoCloseWithMiddleMouseButton:8,NoTabListScrollingButtons:16,NoTooltip:32,DrawSelectedOverline:64,FittingPolicyMixed:128,FittingPolicyShrink:256,FittingPolicyScroll:512,FittingPolicyResizeDown:256};ImGui.TabItemFlags={None:0,UnsavedDocument:1,SetSelected:2,NoCloseWithMiddleMouseButton:4,NoPushId:8,NoTooltip:16,NoReorder:32,Leading:64,Trailing:128,NoAssumedClosure:256};ImGui.ComboFlags={None:0,PopupAlignLeft:1,HeightSmall:2,HeightRegular:4,HeightLarge:8,HeightLargest:16,NoArrowButton:32,NoPreview:64,WidthFitPreview:128};ImGui.TableFlags={None:0,Resizable:1,Reorderable:2,Hideable:4,Sortable:8,NoSavedSettings:16,ContextMenuInBody:32,RowBg:64,BordersInnerH:128,BordersOuterH:256,BordersInnerV:512,BordersOuterV:1024,BordersH:384,BordersV:1536,BordersInner:640,BordersOuter:1280,Borders:1920,NoBordersInBody:2048,NoBordersInBodyUntilResize:4096,SizingFixedFit:8192,SizingFixedSame:16384,SizingStretchProp:24576,SizingStretchSame:32768,NoHostExtendX:65536,NoHostExtendY:131072,NoKeepColumnsVisible:262144,PreciseWidths:524288,NoClip:1048576,PadOuterX:2097152,NoPadOuterX:4194304,NoPadInnerX:8388608,ScrollX:16777216,ScrollY:33554432,SortMulti:67108864,SortTristate:134217728,HighlightHoveredColumn:268435456};ImGui.TableColumnFlags={None:0,Disabled:1,DefaultHide:2,DefaultSort:4,WidthStretch:8,WidthFixed:16,NoResize:32,NoReorder:64,NoHide:128,NoClip:256,NoSort:512,NoSortAscending:1024,NoSortDescending:2048,NoHeaderLabel:4096,NoHeaderWidth:8192,PreferSortAscending:16384,PreferSortDescending:32768,IndentEnable:65536,IndentDisable:131072,AngledHeader:262144,IsEnabled:16777216,IsVisible:33554432,IsSorted:67108864,IsHovered:134217728};ImGui.TableRowFlags={None:0,Headers:1};ImGui.SelectableFlags={None:0,NoAutoClosePopups:1,SpanAllColumns:2,AllowDoubleClick:4,Disabled:8,AllowOverlap:16,Highlight:32,SelectOnNav:64,DontClosePopups:1};ImGui.PopupFlags={None:0,MouseButtonLeft:4,MouseButtonRight:8,MouseButtonMiddle:12,NoReopen:32,NoOpenOverExistingPopup:128,NoOpenOverItems:256,AnyPopupId:1024,AnyPopupLevel:2048,AnyPopup:3072};ImGui.HoveredFlags={None:0,ChildWindows:1,RootWindow:2,AnyWindow:4,NoPopupHierarchy:8,AllowWhenBlockedByPopup:32,AllowWhenBlockedByActiveItem:128,AllowWhenOverlappedByItem:256,AllowWhenOverlappedByWindow:512,AllowWhenDisabled:1024,NoNavOverride:2048,AllowWhenOverlapped:768,RectOnly:928,RootAndChildWindows:3,ForTooltip:4096,Stationary:8192,DelayNone:16384,DelayShort:32768,DelayNormal:65536,NoSharedDelay:131072};ImGui.FocusedFlags={None:0,ChildWindows:1,RootWindow:2,AnyWindow:4,NoPopupHierarchy:8,RootAndChildWindows:3};ImGui.MouseButton={Left:0,Right:1,Middle:2};ImGui.DataType={S8:0,U8:1,S16:2,U16:3,S32:4,U32:5,S64:6,U64:7,Float:8,Double:9,Bool:10,String:11};const p=[];globalThis.__ogImGuiStack=p;const _=n(()=>o.op_overglaze_imgui_depth(),"_depth"),s={};for(const i of["EndChild","EndGroup","EndDisabled","PopItemWidth","PopID","TreePop","EndTooltip","EndTabBar","EndTabItem","EndTable","EndListBox","EndPopup"])s[i]=ImGui[i];for(const i of Object.keys(s)){const e=s[i];ImGui[i]=(...t)=>{const r=_(),l=e(...t);return _()<r&&p[p.length-1]===e&&p.pop(),l}}for(const[i,e]of[["BeginChild","EndChild"],["BeginGroup","EndGroup"],["BeginDisabled","EndDisabled"],["PushItemWidth","PopItemWidth"],["PushID","PopID"],["TreeNode","TreePop"],["TreeNodeEx","TreePop"],["BeginTooltip","EndTooltip"],["BeginTabBar","EndTabBar"],["BeginTabItem","EndTabItem"],["BeginTable","EndTable"],["BeginListBox","EndListBox"],["BeginPopup","EndPopup"],["BeginPopupContextItem","EndPopup"]]){const t=ImGui[i],r=s[e];ImGui[i]=(...l)=>{const g=_(),u=t(...l);return _()>g&&p.push(r),u}}
package/host/params.js ADDED
@@ -0,0 +1,6 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var we=Object.defineProperty;var s=(e,t)=>we(e,"name",{value:t,configurable:!0});import{core as m}from"../engine/core.js";const w={f32:{comps:1,wgsl:"f32"},u32:{comps:1,int:!0,unsigned:!0,wgsl:"u32"},i32:{comps:1,int:!0,wgsl:"i32"},bool:{comps:1,bool:!0,wgsl:"u32"},vec2:{comps:2,wgsl:"vec2f"},vec3:{comps:3,wgsl:"vec3f"},vec4:{comps:4,wgsl:"vec4f"}},ve={vec2f:"vec2",vec3f:"vec3",vec4f:"vec4"},W=/^[A-Za-z][A-Za-z0-9_]*$/,Ie=["slider","drag","checkbox","color","combo"],V=256,xe=128,z=256,d=new Map,P=new Map;let _=null,ee=!1,k=null;function Xe(e){k=e}s(Xe,"setProjectionListener");function j(){ee&&k!==null&&k()}s(j,"projectionChanged");let I=0;const Z=new Set;let F=null;function ye(e){return F===null&&(F=new TextEncoder),F.encode(e).length}s(ye,"keyBytes");function f(e,t,n){Z.has(t)||(Z.add(t),m.ops.op_overglaze_log(e,"@overglaze/params: "+n))}s(f,"logOnce");function J(){if(_===null)try{_=m.ops.op_overglaze_params_saved()||{}}catch{_={}}return _}s(J,"savedDoc");function b(e,t){const n=Number(e);return isFinite(n)?n:t}s(b,"num");function S(e,t){if(!e.int)return Math.fround(t);const n=Math.round(t);return e.unsigned?Math.max(0,n):n}s(S,"coerce");function G(e,t,n){const i=new Array(t.comps).fill(0);if(t.comps===1){const o=t.bool?n?1:0:b(n,NaN);return isFinite(o)?(i[0]=S(t,o),i):(n!==void 0&&f("warn","def:"+e,e+": default is not a number; starting at 0"),i)}if(!Array.isArray(n)||n.length!==t.comps)return n!==void 0&&f("warn","def:"+e,e+": default must be "+t.comps+" numbers; starting at zero"),i;for(let o=0;o<t.comps;o++)i[o]=S(t,b(n[o],0));return i}s(G,"defaultValues");function ne(e,t,n){const i={};if(n===null||typeof n!="object")return i;for(const u in n)ie.indexOf(u)<0&&_e.indexOf(u)<0&&f("warn","opt:"+e+":"+u,e+": unknown option "+JSON.stringify(u)+"; ignoring it");n.label!==void 0&&(i.label=String(n.label)),n.tooltip!==void 0&&(i.tooltip=String(n.tooltip)),n.hint!==void 0&&(i.hint=Array.isArray(n.hint)?n.hint.map(String):[String(n.hint)]),n.group!==void 0&&(i.group=String(n.group)),n.wgsl===!0&&(W.test(e)?i.wgsl=!0:f("warn","wgsl:"+e,e+": not a WGSL identifier, so it cannot be projected; staying JS-only"));const o=n.min===void 0?void 0:b(n.min,NaN),r=n.max===void 0?void 0:b(n.max,NaN),a=o!==void 0&&r!==void 0;if(o!==void 0&&!isFinite(o)||r!==void 0&&!isFinite(r)?f("warn","bound:"+e,e+": min/max must be numbers; ignoring both"):a&&o>r?f("warn","bound:"+e,e+": min > max; ignoring both"):(o!==void 0&&(i.min=o),r!==void 0&&(i.max=r)),n.step!==void 0){const u=b(n.step,NaN);isFinite(u)&&u>0?i.step=u:f("warn","step:"+e,e+": step must be a positive number; ignoring it")}if(n.widget!==void 0){const u=String(n.widget);if(Ie.indexOf(u)<0)f("warn","widget:"+e,e+": unknown widget "+JSON.stringify(u));else if(u==="color"&&t.comps<3)f("warn","widget:"+e,e+": widget 'color' needs a vec3 or vec4");else if(u==="combo"){const l=Array.isArray(n.choices)?n.choices.map(String):[];t.comps!==1||t.bool?f("warn","widget:"+e,e+": widget 'combo' needs a scalar int"):l.length===0?f("warn","widget:"+e,e+": widget 'combo' needs a non-empty choices[]"):(i.widget=u,i.choices=l)}else i.widget=u}return i}s(ne,"sanitizeOpts");function te(e,t,n,i){const r=J()[e];if(r===void 0)return i;if(!Array.isArray(r)||r.length!==t.comps)return f("warn","saved:"+e,e+": saved value no longer matches the declaration; using the default"),m.ops.op_overglaze_params_forget(e),i;const a=new Array(t.comps);for(let u=0;u<t.comps;u++){let l=b(r[u],NaN);if(!isFinite(l))return f("warn","saved:"+e,e+": saved value is not a number; using the default"),m.ops.op_overglaze_params_forget(e),i;n.min!==void 0&&l<n.min&&(l=n.min),n.max!==void 0&&l>n.max&&(l=n.max),a[u]=S(t,l)}return a}s(te,"restore");function N(e,t){return e.bool?[t[0]!==0]:t.slice()}s(N,"holderFor");const ie=["label","tooltip","hint","group","min","max","step","widget","choices"],_e=["persist","wgsl"];function L(e){if(e===null||typeof e!="object")return!1;for(const t in e)if(ie.indexOf(t)>=0)return!0;return!1}s(L,"hasMeta");function Se(e,t){if(t!==null&&typeof t=="object"&&t.persist===!1)return!1;if(ye(e)>xe)return f("warn","key:"+e,e+": key is too long to persist; live for this session only"),!1;let n=0;return d.forEach(i=>{i.persist&&n++}),n>=V?(f("warn","quota:"+e,e+": over the "+V+"-parameter limit; live for this session only"),!1):!0}s(Se,"persistable");function Ge(e,t,n){const i=e.t,o=ne(e.key,i,n);for(const a in o)e.opts[a]=o[a];if(e.opts.wgsl=!0,e.meta=e.meta||L(n),n!==null&&typeof n=="object"&&n.persist===!1&&(e.persist=!1),t!==void 0){const a=G(e.key,i,t);let u=!0;for(let l=0;l<i.comps;l++)a[l]!==e.def[l]&&(u=!1);u||(f("warn","twodefaults:"+e.key,e.key+": the shader and the JS declaration state different defaults; using the JS one"),e.def=a)}const r=te(e.key,i,e.opts,e.def);for(let a=0;a<i.comps;a++)e.holder[a]=i.bool?r[a]!==0:r[a];e.lastSent=r.slice(),I++}s(Ge,"mergeJs");function h(e,t,n,i,o,r){const a=w[e],u=typeof t=="string"?t:"";if(u==="")return f("warn","nokey:"+String(t),"a parameter key must be a non-empty string"),N(a,G("",a,n));const l=d.get(u);if(l)return l.type!==e?(f("warn","retype:"+u,l.fromWgsl&&o==="js"?u+": the shader declares this as "+l.type+"; the shader wins":u+": already declared as "+l.type+"; keeping the first declaration"),l.holder):(o==="js"&&l.fromWgsl&&Ge(l,n,i),l.holder);let c=i;r&&L(i)&&i.group===void 0&&(c={...i,group:R(r.list.name)+" "+r.index});const g=ne(u,a,c),x=G(u,a,n),v=te(u,a,g,x),X=N(a,v),K={key:u,holder:X,type:e,comps:a.comps,t:a,opts:g,def:x,fromWgsl:o==="wgsl",meta:L(i),persist:Se(u,i),lastSent:v.slice(),slot:null,projected:!1};return d.set(u,K),I++,r?Me(K,r,e,i):g.wgsl&&j(),X}s(h,"declare");function Ae(e){const t=J();t[e]!==void 0&&delete t[e],m.ops.op_overglaze_params_forget(e)}s(Ae,"forgetSaved");function oe(e){const t=d.get(e);t!==void 0&&(d.delete(e),I++,t.slot?je(t):t.opts.wgsl&&j()),Ae(e)}s(oe,"dropKey");function D(e){const t=[];d.forEach(i=>{i.key.indexOf(e)===0&&t.push(i.key)});const n=J();for(const i in n)i.indexOf(e)===0&&t.indexOf(i)<0&&t.push(i);for(const i of t)oe(i);return t.length}s(D,"dropUnder");function se(e){let t;try{t=m.ops.op_overglaze_params_saved()||{}}catch{return[]}_=t;const n=[];for(const i in t)i.indexOf(e)===0&&n.push(i);return n.sort(),n}s(se,"savedKeysUnder");function B(e){if(e.live===null){const t=[];e.items.forEach((n,i)=>{n.size>0&&t.push(i)}),t.sort((n,i)=>n-i),e.live=t}return e.live}s(B,"liveIndices");function Te(e){if(e.slots===null){const t=B(e),n=Math.min(t.length,e.capacity),i=[];for(let o=0;o<n;o++)i.push(e.items.get(t[o]));e.slots=i}return e.slots}s(Te,"listSlots");function Ne(e){return Te(e).length}s(Ne,"listCount");function Y(e){e.live=null,e.slots=null}s(Y,"listChanged");function Oe(e,t,n){const i=e.shapeAt.get(t);return i!==void 0?i.type!==n?(f("warn","listtype:"+e.name+"."+t,e.name+"."+t+": this list already carries "+t+" as "+i.type+", not "+n+"; the field stays out of the array"),!1):!0:e.projectable?W.test(t)?(e.shape.push({field:t,type:n,t:w[n]}),e.shapeAt.set(t,{field:t,type:n,t:w[n]}),j(),!0):(f("warn","listfield:"+e.name+"."+t,e.name+"."+t+": not a WGSL identifier, so it cannot be a struct member; the field stays out of the array"),!1):!1}s(Oe,"shapeSlot");function Me(e,t,n,i){const o=t.list;let r=o.items.get(t.index);r===void 0&&(r=new Map,o.items.set(t.index,r)),r.set(t.field,e),Y(o),e.slot=t;const a=i!==null&&typeof i=="object"&&i.wgsl===!1;e.projected=!a&&Oe(o,t.field,n),e.projected&&B(o).length>o.capacity&&f("warn","listcap:"+o.name,o.name+": more items than the declared capacity of "+o.capacity+"; the extra ones keep their parameters but get no array slot")}s(Me,"attachSlot");function je(e){const{list:t,index:n,field:i}=e.slot,o=t.items.get(n);o!==void 0&&(o.delete(i),o.size===0&&t.items.delete(n)),Y(t)}s(je,"detachSlot");const O={f32:"f32",u32:"u32",int:"u32",i32:"i32",bool:"bool",vec2:"vec2",vec3:"vec3",vec4:"vec4"};function Ee(e,t){const n={index:t};for(const i in O){const o=O[i];n[i]=(r,a,u)=>typeof r!="string"||r===""?(f("warn","listnofield:"+e.name,e.name+": an item field needs a non-empty name"),N(w[o],G("",w[o],a))):h(o,e.name+"."+t+"."+r,a,u,"js",{list:e,index:t,field:r})}return n}s(Ee,"itemHandle");function ze(){const e={index:-1};for(const t in O){const n=O[t];e[t]=(i,o)=>N(w[n],G("",w[n],o))}return e}s(ze,"detachedItem");function Fe(e,t){const n=Math.floor(b(t,NaN));if(!isFinite(n)||n<0)return f("warn","listindex:"+e.name,e.name+": an item index must be a non-negative integer"),ze();let i=e.handles.get(n);return i===void 0&&(i=Ee(e,n),e.handles.set(n,i)),i}s(Fe,"itemAt");function Pe(e){const t=e+".",n=[];for(const i of se(t)){const o=i.slice(t.length),r=o.indexOf(".");if(r<=0)continue;const a=Number(o.slice(0,r));!isFinite(a)||Math.floor(a)!==a||a<0||n.indexOf(a)>=0||n.push(a)}return n.sort((i,o)=>i-o),n}s(Pe,"savedIndicesOf");function q(e){return{name:e.name,get capacity(){return e.capacity},get count(){return Ne(e)},get indices(){return B(e).slice()},at:s(t=>Fe(e,t),"at"),remove:s(t=>{const n=Math.floor(b(t,NaN));if(!isFinite(n)||n<0){f("warn","listremove:"+e.name,e.name+": remove(index) needs a non-negative integer");return}D(e.name+"."+n+".")},"remove"),clear:s(()=>D(e.name+"."),"clear"),savedIndices:s(()=>Pe(e.name),"savedIndices")}}s(q,"listHandle");function ke(e,t){const n=typeof e=="string"?e:"";if(n===""||n.indexOf(".")>=0)return f("warn","listname:"+n,"params.list(name, capacity) needs a non-empty name with no dots in it"),q({name:"list",capacity:1,projectable:!1,shape:[],shapeAt:new Map,items:new Map,handles:new Map,live:null,slots:null});let i=Math.floor(b(t,NaN));!isFinite(i)||i<1?(f("warn","listcapnum:"+n,n+": a list capacity must be a positive integer; using 1"),i=1):i>z&&(f("warn","listcapmax:"+n,n+": capacity "+i+" is over the "+z+" limit; clamping"),i=z);const o=P.get(n);if(o!==void 0)return o.capacity!==i&&(o.capacity=i,Y(o),j()),o.handle;const r={name:n,capacity:i,projectable:W.test(n),shape:[],shapeAt:new Map,items:new Map,handles:new Map,live:null,slots:null};return r.projectable||f("warn","listident:"+n,n+": not a WGSL identifier, so this list cannot be projected; its items are ordinary parameters"),r.handle=q(r),P.set(n,r),r.handle}s(ke,"declareList");function re(e,t){const n=e.holder[t];if(e.t.bool)return n?1:0;const i=Number(n);return isFinite(i)?S(e.t,i):NaN}s(re,"slotValue");function Le(e){const t=new Array(e.comps);let n=!1;for(let i=0;i<e.comps;i++){const o=re(e,i);if(!isFinite(o))return f("debug","nan:"+e.key,e.key+": holder is not a number; keeping the last value"),null;t[i]=o,o!==e.lastSent[i]&&(n=!0)}return n?t:null}s(Le,"movedValues");globalThis.__ogSyncParams=()=>{if(d.size===0)return;let e=null;if(d.forEach(n=>{if(!n.persist)return;const i=Le(n);i!==null&&(n.lastSent=i,e===null&&(e=[]),e.push([n.key,i]))}),e===null)return;const t=m.ops.op_overglaze_params_write(e);for(const n of t){const i=d.get(n);i&&(i.persist=!1,I++),f("warn","refused:"+n,n+": the store refused this value; not persisting it")}};function Ke(){ee=!0;const e=[];d.forEach(n=>{n.opts.wgsl&&n.slot===null&&e.push(n)});const t=[];return P.forEach(n=>{n.projectable&&n.shape.length>0&&t.push(n)}),{scalars:e,lists:t}}s(Ke,"sealProjection");const De=/^[ \t]*\/\/[ \t]*@param[ \t]+(.*)$/,$=s(e=>e===" "||e===" ","isSpace");function Ce(e){const t=[];let n=0;for(;n<e.length;){for(;n<e.length&&$(e[n]);)n++;if(n>=e.length)break;let i="";for(;n<e.length&&!$(e[n]);)if(e[n]==='"'){for(n++;n<e.length&&e[n]!=='"';)i+=e[n++];n++}else i+=e[n++];t.push(i)}return t}s(Ce,"tokenize");function We(e,t){return e.bool?t==="true"||t==="1":e.comps===1?Number(t):t.split(",").map(Number)}s(We,"parseDefault");function Je(e,t,n,i){switch(t){case"min":case"max":case"step":e[t]=Number(n);break;case"label":case"tooltip":case"hint":case"group":case"widget":e[t]=n;break;case"choices":e.choices=n.split(",");break;case"persist":e.persist=n!=="false";break;default:f("warn","atopt:"+t,"@param: unknown option "+JSON.stringify(t)+" in: "+i)}}s(Je,"applyOpt");function Be(e){const t=String(e).split(/\r?\n/);for(let n=0;n<t.length;n++){const i=De.exec(t[n]);if(i===null)continue;const o=i[1],r=Ce(o);if(r.length<2){f("warn","atline:"+o,"@param needs a name and a type: "+o);continue}const a=r[0],u=ve[r[1]]||r[1];if(w[u]===void 0){f("warn","attype:"+o,"@param: unknown type "+JSON.stringify(r[1])+" in: "+o);continue}const l=w[u],c={wgsl:!0};let g=2,x;for(r.length>2&&r[2].indexOf("=")<0&&(x=We(l,r[2]),g=3);g<r.length;g++){const v=r[g].indexOf("=");if(v<=0){f("warn","atopt:"+o,"@param: expected key=value, got "+JSON.stringify(r[g])+" in: "+o);continue}Je(c,r[g].slice(0,v),r[g].slice(v+1),o)}h(u,a,x,c,"wgsl")}}s(Be,"parseWgslParams");globalThis.__ogWgslModule=e=>{try{Be(e)}catch(t){f("warn","atcrash","@param scan failed: "+t)}return e};globalThis.__ogPruneParams=()=>{if(d.size===0)return;const e=[];d.forEach(t=>{t.persist&&e.push(t.key)}),e.length!==0&&m.ops.op_overglaze_params_prune(e)};function R(e){const t=s(i=>i>="A"&&i<="Z","upper");let n="";for(let i=0;i<e.length;i++){const o=e[i];t(o)&&i>0&&!t(e[i-1])&&(n+=" "),n+=i===0?o.toUpperCase():o}return n}s(R,"humanize");function E(e){return e.opts.widget!==void 0?e.opts.widget:e.t.bool?"checkbox":e.opts.min!==void 0&&e.opts.max!==void 0?"slider":"drag"}s(E,"widgetOf");function ae(e){return e.opts.step!==void 0?e.opts.step:e.opts.min!==void 0&&e.opts.max!==void 0?(e.opts.max-e.opts.min)/200:e.t.int?1:.01}s(ae,"stepOf");const M=34028234663852886e22,le=-2147483648,ue=2147483647,p=512;function fe(e){const t=e.opts;if(t.min===void 0&&t.max===void 0)return[0,0];const n=E(e)==="slider"?[0,0]:e.t.int?[e.t.unsigned?0:le,ue]:[-M,M];return[t.min===void 0?n[0]:t.min,t.max===void 0?n[1]:t.max]}s(fe,"boundsOf");function ce(e){const t=e.opts,n=E(e);if(n!=="drag"&&n!=="slider")return[t.min,t.max];const[i,o]=fe(e);if(n==="slider")return i===0&&o===0?[void 0,void 0]:[Math.min(i,o),Math.max(i,o)];if(!(i<o||i===o&&i!==0))return[void 0,void 0];const r=s(a=>a===-M||a===M||a===le||a===ue?void 0:a,"free");return[r(i),r(o)]}s(ce,"heldOf");function C(e){const t=e.opts,n=(t.label!==void 0?t.label:R(e.key))+"##og."+e.key,i=e.comps,o=e.t.int?"%d":"%.3f",[r,a]=fe(e),u=e.holder.slice();let l;switch(E(e)){case"checkbox":l=ImGui.Checkbox(n,e.holder);break;case"combo":l=ImGui.Combo(n,e.holder,t.choices);break;case"color":l=i>=4?ImGui.ColorEdit4(n,e.holder):ImGui.ColorEdit3(n,e.holder);break;case"slider":e.t.int?i===1?l=ImGui.SliderInt(n,e.holder,r,a,o,p):i===2?l=ImGui.SliderInt2(n,e.holder,r,a,o,p):i===3?l=ImGui.SliderInt3(n,e.holder,r,a,o,p):l=ImGui.SliderInt4(n,e.holder,r,a,o,p):i===1?l=ImGui.SliderFloat(n,e.holder,r,a,o,p):i===2?l=ImGui.SliderFloat2(n,e.holder,r,a,o,p):i===3?l=ImGui.SliderFloat3(n,e.holder,r,a,o,p):l=ImGui.SliderFloat4(n,e.holder,r,a,o,p);break;default:{const c=ae(e);e.t.int?i===1?l=ImGui.DragInt(n,e.holder,c,r,a,o,p):i===2?l=ImGui.DragInt2(n,e.holder,c,r,a,o,p):i===3?l=ImGui.DragInt3(n,e.holder,c,r,a,o,p):l=ImGui.DragInt4(n,e.holder,c,r,a,o,p):i===1?l=ImGui.DragFloat(n,e.holder,c,r,a,o,p):i===2?l=ImGui.DragFloat2(n,e.holder,c,r,a,o,p):i===3?l=ImGui.DragFloat3(n,e.holder,c,r,a,o,p):l=ImGui.DragFloat4(n,e.holder,c,r,a,o,p)}}if(!l)for(let c=0;c<u.length;c++)e.holder[c]=u[c];if(t.tooltip!==void 0&&ImGui.IsItemHovered(0)&&ImGui.BeginTooltip()&&(ImGui.Text(t.tooltip),ImGui.EndTooltip()),t.hint!==void 0){ImGui.Indent(0);for(const c of t.hint)ImGui.Bullet(),ImGui.Text(c);ImGui.Unindent(0)}}s(C,"drawRow");function U(){const e=[];return d.forEach(t=>{t.meta&&e.push(t)}),e}s(U,"drawable");function H(){let e=0;return d.forEach(t=>{t.persist&&e++}),e}s(H,"persistCount");function de(){let e=0;d.forEach(t=>{if(t.persist){for(let n=0;n<t.comps;n++)t.holder[n]=t.t.bool?t.def[n]!==0:t.def[n];t.lastSent=t.def.slice(),m.ops.op_overglaze_params_forget(t.key),e++}}),m.ops.op_overglaze_log("info","@overglaze/params: reset "+e+" parameter(s)")}s(de,"resetAll");function Ye(){H()!==0&&(ImGui.Spacing(),ImGui.Separator(),ImGui.SmallButton("Reset all##og.resetall")&&de(),ImGui.IsItemHovered(0)&&ImGui.BeginTooltip()&&(ImGui.Text("Put every parameter back to the value this plugin declares,"),ImGui.Text("and forget what was saved."),ImGui.EndTooltip()))}s(Ye,"drawResetFooter");const A=10;let pe=!1,y=0,T="";function Q(e){const t=globalThis.__ogImGuiStack;if(!(!t||t.length<=e))for(f("warn","unbalanced","panel left the ImGui stack unbalanced; unwinding it");t.length>e;){const n=t.pop();try{n()}catch{}}}s(Q,"unwind");function me(e){const t=m.ops.op_overglaze_panel_begin();if(t===-2){f("warn","nested","params.panel is already open; a plugin gets one window");return}if(t<0){f("warn","notinframe","params.panel only draws from the frame callback -- there is no ImGui frame open during module evaluation or init(ctx)");return}if(t===0)return;const n=globalThis.__ogImGuiStack;n&&(n.length=0);const i=0;try{if(t!==2)return;if(y>=A){ImGui.Text("Panel disabled after "+A+" errors."),ImGui.Text(T);return}try{e(),y=0}catch(o){Q(i),y++,T=String(o&&o.message||o),y===1?m.ops.op_overglaze_log("error","@overglaze/params: panel threw: "+(o&&o.stack||T)):y===A&&m.ops.op_overglaze_log("error","@overglaze/params: panel threw "+A+" times in a row; not calling it again. The effect keeps rendering."),ImGui.Text("Panel error:"),ImGui.Text(T)}}finally{Q(i),t===2&&Ye(),m.ops.op_overglaze_panel_end()}}s(me,"openPanel");function ge(){const e=U(),t=e.filter(i=>i.opts.group===void 0),n=[];for(const i of e){const o=i.opts.group;if(!(o===void 0||n.indexOf(o)>=0)){n.push(o);for(const r of e)r.opts.group===o&&t.push(r)}}return t}s(ge,"panelOrder");function he(){let e;for(const t of ge()){const n=t.opts.group;n!==void 0&&n!==e&&ImGui.SeparatorText(n),e=n,C(t)}}s(he,"emitAll");globalThis.__ogAutoPanel=()=>{pe||d.size===0||U().length===0&&H()===0||me(he)};function be(e){const t=new Array(e.comps);for(let n=0;n<e.comps;n++)t[n]=re(e,n);return t}s(be,"valuesOf");function Ve(){return I}s(Ve,"presentationRevision");function Ze(){return{revision:I,resettable:H()>0,rows:ge().map(e=>{const t=e.opts,[n,i]=ce(e);return{key:e.key,type:e.type,comps:e.comps,int:e.t.int===!0,unsigned:e.t.unsigned===!0,bool:e.t.bool===!0,widget:E(e),label:t.label!==void 0?t.label:R(e.key),step:ae(e),min:n,max:i,choices:t.choices,tooltip:t.tooltip,hint:t.hint,group:t.group,def:e.def.slice(),value:be(e)}})}}s(Ze,"presentation");function qe(){const e=[];return d.forEach(t=>{t.meta&&e.push([t.key,be(t)])}),e}s(qe,"presentationValues");function $e(e,t){const n=d.get(e);if(n===void 0||!Array.isArray(t)||t.length!==n.comps)return!1;const i=n.opts,[o,r]=ce(n),a=new Array(n.comps);for(let u=0;u<n.comps;u++){let l=b(t[u],NaN);if(!isFinite(l))return!1;o!==void 0&&l<o&&(l=o),r!==void 0&&l>r&&(l=r),i.choices!==void 0&&(l=Math.min(Math.max(l,0),i.choices.length-1)),a[u]=S(n.t,l)}for(let u=0;u<n.comps;u++)n.holder[u]=n.t.bool?a[u]!==0:a[u];return!0}s($e,"presentationWrite");const Re={f32:s((e,t,n)=>h("f32",e,t,n,"js"),"f32"),u32:s((e,t,n)=>h("u32",e,t,n,"js"),"u32"),int:s((e,t,n)=>h("u32",e,t,n,"js"),"int"),i32:s((e,t,n)=>h("i32",e,t,n,"js"),"i32"),bool:s((e,t,n)=>h("bool",e,t,n,"js"),"bool"),vec2:s((e,t,n)=>h("vec2",e,t,n,"js"),"vec2"),vec3:s((e,t,n)=>h("vec3",e,t,n,"js"),"vec3"),vec4:s((e,t,n)=>h("vec4",e,t,n,"js"),"vec4"),drop:s(e=>{if(typeof e!="string"||e===""){f("warn","dropkey","params.drop(key) needs a non-empty string");return}oe(e)},"drop"),dropPrefix:s(e=>{if(typeof e!="string"||e===""){f("warn","dropprefix","params.dropPrefix(prefix) needs a non-empty string");return}D(e)},"dropPrefix"),savedKeys:s(e=>se(typeof e=="string"?e:""),"savedKeys"),list:s((e,t)=>ke(e,t),"list"),panel:s(e=>{if(pe=!0,typeof e!="function"){f("warn","panelarg","params.panel(fn) needs a function");return}me(e)},"panel"),draw:s(e=>{const t=d.get(e);if(!t||!t.meta){f("warn","draw:"+e,e+": nothing to draw (unknown, or declared with no options)");return}C(t)},"draw"),drawGroup:s(e=>{for(const t of U())t.opts.group===e&&C(t)},"drawGroup"),drawAll:s(()=>he(),"drawAll"),resetAll:s(()=>de(),"resetAll")};globalThis.params=Re;export{Ne as listCount,Te as listSlots,Ze as presentation,Ve as presentationRevision,qe as presentationValues,$e as presentationWrite,de as resetAll,Ke as sealProjection,Xe as setProjectionListener};
@@ -0,0 +1,6 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var u=Object.defineProperty;var a=(r,t)=>u(r,"name",{value:t,configurable:!0});(function(){"use strict";const r=Math.imul;let t=1869048954;function n(){t=t+1831565813|0;let e=r(t^t>>>15,1|t);return e=e+r(e^e>>>7,61|e)^e,((e^e>>>14)>>>0)/4294967296}a(n,"random"),Object.defineProperty(Math,"random",{value:n,writable:!0,enumerable:!1,configurable:!0})})();
@@ -0,0 +1,6 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var n=Object.defineProperty;var g=(o,e)=>n(o,"name",{value:e,configurable:!0});import{core as t}from"../engine/core.js";function l(o){return{getItem(e){const r=t.ops.op_overglaze_storage_get(o,String(e));return r??null},setItem(e,r){if(!t.ops.op_overglaze_storage_set(o,String(e),String(r))){const a=new Error("Failed to execute 'setItem' on 'Storage': the quota has been exceeded.");throw a.name="QuotaExceededError",a}},removeItem(e){t.ops.op_overglaze_storage_remove(o,String(e))},clear(){t.ops.op_overglaze_storage_clear(o)},key(e){const r=t.ops.op_overglaze_storage_key(o,e);return r??null},get length(){return t.ops.op_overglaze_storage_length(o)}}}g(l,"makeStorage");globalThis.localStorage=l(!1);globalThis.sessionStorage=l(!0);
package/host/webio.js ADDED
@@ -0,0 +1,6 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var _=Object.defineProperty;var h=(n,e)=>_(n,"name",{value:e,configurable:!0});import{core as g}from"../engine/core.js";const w=g.ops,f=Symbol("ogWebioInternal"),v={json:"application/json",txt:"text/plain",html:"text/html",css:"text/css",js:"text/javascript",mjs:"text/javascript",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",gltf:"model/gltf+json",glb:"model/gltf-binary",wgsl:"text/wgsl"};function R(n){const e=n.lastIndexOf(".");return e<0?"application/octet-stream":v[n.slice(e+1).toLowerCase()]||"application/octet-stream"}h(R,"guessContentType");function B(n){return n instanceof Uint8Array?n:n instanceof ArrayBuffer?new Uint8Array(n):ArrayBuffer.isView(n)?new Uint8Array(n.buffer,n.byteOffset,n.byteLength):null}h(B,"bytesOf");function E(){const n=new Error("The operation was aborted");return n.name="AbortError",n}h(E,"abortError");class m{static{h(this,"Blob")}#e;#r;constructor(e=[],t={}){const r=[];let s=0;const l=e&&typeof e.length=="number"?e.length:0;for(let u=0;u<l;u++){const a=e[u];let o;if(typeof a=="string"?o=g.encode(a):a instanceof m?o=a.#e:o=B(a),!o)throw new TypeError("Blob: unsupported part type");r.push(o),s+=o.byteLength}const c=new Uint8Array(s);let i=0;for(const u of r)c.set(u,i),i+=u.byteLength;this.#e=c,this.#r=t&&t.type?String(t.type):""}get size(){return this.#e.byteLength}get type(){return this.#r}arrayBuffer(){return Promise.resolve(this.#e.slice().buffer)}text(){return Promise.resolve(g.decode(this.#e))}}class A{static{h(this,"Headers")}#e=[];constructor(e){if(e&&typeof e=="object"&&!Array.isArray(e))for(const t of Object.keys(e))this.append(t,e[t])}get(e){const t=String(e).toLowerCase(),r=[];for(const[s,l]of this.#e)s===t&&r.push(l);return r.length?r.join(", "):null}has(e){const t=String(e).toLowerCase();return this.#e.some(([r])=>r===t)}set(e,t){const r=String(e).toLowerCase();this.#e=this.#e.filter(([s])=>s!==r),this.#e.push([r,String(t)])}append(e,t){this.#e.push([String(e).toLowerCase(),String(t)])}delete(e){const t=String(e).toLowerCase();this.#e=this.#e.filter(([r])=>r!==t)}forEach(e,t){for(const[r,s]of this.#e.slice())e.call(t,s,r,this)}}class y{static{h(this,"Request")}constructor(e,t={}){if(e===void 0)throw new TypeError("Request: url required");this.url=e instanceof y?e.url:String(e),this.method=t&&t.method?String(t.method):"GET"}}class b{static{h(this,"Response")}#e;#r;#s;#t;#n;#i=!1;constructor(e,t,r,s,l,c){if(e!==f)throw new TypeError("Response: cannot be constructed directly");this.#e=t,this.#r=r,this.#s=s,this.#t=l,this.#n=c}get ok(){return this.#t>=200&&this.#t<300}get status(){return this.#t}get statusText(){return this.#n}get url(){return this.#r}get bodyUsed(){return this.#i}get headers(){const e=new A;return this.#s&&e.set("content-type",this.#s),e.set("content-length",String(this.#e.byteLength)),e}#o(){return this.#i?Promise.reject(new TypeError("Response body already consumed")):(this.#i=!0,Promise.resolve(this.#e))}arrayBuffer(){return this.#o().then(e=>e.slice().buffer)}text(){return this.#o().then(e=>g.decode(e))}json(){return this.#o().then(e=>JSON.parse(g.decode(e)))}blob(){const e=this.#s;return this.#o().then(t=>new m([t],{type:e}))}clone(){if(this.#i)throw new TypeError("Response: cannot clone a used body");return new b(f,this.#e,this.#r,this.#s,this.#t,this.#n)}}const S="/plugin/";function k(n){let e=n;if(e.startsWith("plugin://")){const t=e.indexOf("/",9);e=t>=0?e.slice(t):"/"}return!e.startsWith("/")||!e.startsWith(S)?null:e}h(k,"pluginVfsPath");globalThis.fetch=h(function(e,t){if(e===void 0)return Promise.reject(new TypeError("fetch: url required"));const r=e instanceof y?e.url:String(e);if(!r)return Promise.reject(new TypeError("fetch: empty url"));const s=t&&t.signal;if(s&&s.aborted)return Promise.reject(E());const l=k(r);if(l===null)return Promise.reject(new TypeError("fetch: network permission not granted (only /plugin/... is supported)"));const c=R(l);return w.op_webio_read(l).then(i=>{if(s&&s.aborted)throw E();return new b(f,i,r,c,200,"OK")},i=>{throw s&&s.aborted?E():new TypeError("fetch: "+(i&&i.message?i.message:String(i)))})},"fetch");let I;const O=globalThis.EventTarget;class T extends O{static{h(this,"Image")}#e="";#r=null;#s=0;#t=0;#n=!1;#i=!1;#o=0;onload=null;onerror=null;crossOrigin=null;decoding="auto";get src(){return this.#e}set src(e){this.#e=String(e);const t=++this.#o;this.#n=!1,this.#i=!1,this.#r=null,this.#s=0,this.#t=0,w.op_webio_read(this.#e).then(r=>w.op_webio_decode(r)).then(r=>{t===this.#o&&(this.#r=r.rgba,this.#s=r.width,this.#t=r.height,this.#n=!0,this.#a("load",this.onload))},r=>{t===this.#o&&(this.#i=!0,g.ops.op_overglaze_log("warn","Image '"+this.#e+"': "+(r&&r.message?r.message:String(r))),this.#a("error",this.onerror))})}get width(){return this.#s}get height(){return this.#t}get naturalWidth(){return this.#s}get naturalHeight(){return this.#t}get complete(){return this.#n||this.#i}#a(e,t){if(this.dispatchEvent(new globalThis.Event(e)),typeof t=="function")try{t.call(this)}catch(r){g.ops.op_overglaze_log("error","Image on"+e+": "+r)}}static{I=h(e=>e.#n&&e.#r?{rgba:e.#r,width:e.#s,height:e.#t}:null,"imageData")}}let x;class d{static{h(this,"ImageBitmap")}#e;#r;#s;#t=!1;constructor(e,t,r,s){if(e!==f)throw new TypeError("ImageBitmap: cannot be constructed directly");this.#e=t,this.#r=r,this.#s=s}get width(){return this.#t?0:this.#r}get height(){return this.#t?0:this.#s}close(){this.#t=!0,this.#e=null}static{x=h(e=>e.#t||!e.#e?null:{rgba:e.#e,width:e.#r,height:e.#s},"bitmapData")}}globalThis.createImageBitmap=h(function(e,t){if(e instanceof d){const s=x(e);return s?Promise.resolve(new d(f,s.rgba.slice(),s.width,s.height)):Promise.reject(new Error("createImageBitmap: source ImageBitmap is closed"))}if(e instanceof T){const s=I(e);return s?Promise.resolve(new d(f,s.rgba.slice(),s.width,s.height)):Promise.reject(new Error("createImageBitmap: image is not loaded"))}const r=B(e);return r?w.op_webio_decode(r).then(s=>new d(f,s.rgba,s.width,s.height)):Promise.reject(new TypeError("createImageBitmap: unsupported source (expected ArrayBuffer / TypedArray / ImageBitmap / Image)"))},"createImageBitmap");const U=g.createLazyLoader("ext:deno_webgpu/01_webgpu.js")();U.GPUQueue.prototype.copyExternalImageToTexture=function(n,e,t){const r=n&&n.source;let s=null;if(r instanceof d?s=x(r):r instanceof T&&(s=I(r)),!s)throw new TypeError("copyExternalImageToTexture: unsupported source (expected ImageBitmap or loaded Image)");let l=0,c=0;const i=n.origin;Array.isArray(i)?(l=i[0]|0,c=(i.length>1?i[1]:0)|0):i&&typeof i=="object"&&(l=i.x|0,c=i.y|0);const u=!!n.flipY;let a,o;if(Array.isArray(t)?(a=t[0]>>>0,o=(t.length>1?t[1]:1)>>>0):(a=t.width>>>0,o=(t.height!==void 0?t.height:1)>>>0),a===0||o===0)return;if(l+a>s.width||c+o>s.height)throw new RangeError("copyExternalImageToTexture: copy rect exceeds source bounds");const j=new Uint8Array(a*o*4),L=s.width*4;for(let p=0;p<o;p++){const P=(u?c+o-1-p:c+p)*L+l*4;j.set(s.rgba.subarray(P,P+a*4),p*a*4)}this.writeTexture(e,j,{offset:0,bytesPerRow:a*4,rowsPerImage:o},[a,o,1])};globalThis.Blob=m;globalThis.Headers=A;globalThis.Request=y;globalThis.Response=b;globalThis.Image=T;globalThis.HTMLImageElement=T;g.ops.op_overglaze_log("info","webio: fetch/Image/createImageBitmap ready");
@@ -0,0 +1,6 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var _=Object.defineProperty;var r=(s,t)=>_(s,"name",{value:t,configurable:!0});import{core as d}from"../engine/core.js";globalThis.window=globalThis;function u(){const[s,t,e]=d.ops.op_overglaze_viewport();return{w:s,h:t,dpr:e>0?e:1}}r(u,"viewport");const g=r((s,t)=>Object.defineProperty(globalThis,s,{get:t,configurable:!0}),"defineGetter");g("innerWidth",()=>{const s=u();return Math.round(s.w/s.dpr)});g("innerHeight",()=>{const s=u();return Math.round(s.h/s.dpr)});g("devicePixelRatio",()=>u().dpr);if(globalThis.navigator&&!globalThis.navigator.userAgent)try{globalThis.navigator.userAgent="Overglaze/1.0"}catch{}const l=Symbol("ogListeners");class T{static{r(this,"Event")}constructor(t,e={}){this.type=String(t),this.bubbles=!!e.bubbles,this.cancelable=!!e.cancelable,this.defaultPrevented=!1,this.cancelBubble=!1,this.target=null,this.currentTarget=null,this.timeStamp=0,this._stopImmediate=!1}preventDefault(){this.cancelable&&(this.defaultPrevented=!0)}stopPropagation(){this.cancelBubble=!0}stopImmediatePropagation(){this.cancelBubble=!0,this._stopImmediate=!0}}class M extends T{static{r(this,"CustomEvent")}constructor(t,e={}){super(t,e),this.detail=e&&e.detail!==void 0?e.detail:null}}class f{static{r(this,"EventTarget")}addEventListener(t,e,a){if(!e)return;const i=this[l]||(this[l]=new Map);let n=i.get(t);n||i.set(t,n=[]);const o=!!(a&&a.once),h=a&&a.signal;if(h&&h.aborted)return;const v={cb:e,once:o};n.push(v),h&&typeof h.addEventListener=="function"&&h.addEventListener("abort",()=>{const p=n.indexOf(v);p>=0&&n.splice(p,1)},{once:!0})}removeEventListener(t,e){const a=this[l]&&this[l].get(t);if(!a)return;const i=a.findIndex(n=>n.cb===e);i>=0&&a.splice(i,1)}dispatchEvent(t){t.target=this,t.currentTarget=this;const e=this[l]&&this[l].get(t.type);if(e)for(const a of e.slice()){try{a.cb.call(this,t)}catch(i){d.ops.op_overglaze_log("error","event listener: "+i)}if(a.once&&this.removeEventListener(t.type,a.cb),t._stopImmediate)break}return!t.defaultPrevented}}globalThis.Event=T;globalThis.CustomEvent=M;globalThis.EventTarget=f;const m=f.prototype;function x(s,t,e){return m.addEventListener.call(this??globalThis,s,t,e)}r(x,"addEventListener");function Y(s,t){return m.removeEventListener.call(this??globalThis,s,t)}r(Y,"removeEventListener");function L(s){return m.dispatchEvent.call(this??globalThis,s)}r(L,"dispatchEvent");Object.defineProperties(globalThis,{addEventListener:{value:x,writable:!0,configurable:!0},removeEventListener:{value:Y,writable:!0,configurable:!0},dispatchEvent:{value:L,writable:!0,configurable:!0}});globalThis[l]=new Map;class E{static{r(this,"GPUCanvasContext")}configure(){}unconfigure(){}getCurrentTexture(){throw new Error("GPUCanvasContext.getCurrentTexture: overlay canvas has no surface (render into a RenderTarget or the host scene buffer)")}}let b=null;class K extends f{static{r(this,"HTMLCanvasElement")}constructor(){super(),this.width=globalThis.innerWidth,this.height=globalThis.innerHeight,this.style={},this._ctx=null,b||(b=this)}get clientWidth(){return Math.round(this.width/u().dpr)}get clientHeight(){return Math.round(this.height/u().dpr)}getContext(t){return t!=="webgpu"?null:(this._ctx||(this._ctx=new E),this._ctx)}getBoundingClientRect(){return{x:0,y:0,left:0,top:0,width:this.clientWidth,height:this.clientHeight,right:this.clientWidth,bottom:this.clientHeight}}setPointerCapture(){}releasePointerCapture(){}hasPointerCapture(){return!1}}globalThis.HTMLCanvasElement=K;globalThis.GPUCanvasContext=globalThis.GPUCanvasContext||E;function y(s){const t=String(s||"").toLowerCase();return t==="canvas"?new K:t==="img"&&typeof globalThis.Image=="function"?new globalThis.Image:{style:{}}}r(y,"createElementByTag");globalThis.document=globalThis.document||{createElement:r(s=>y(s),"createElement"),createElementNS:r((s,t)=>y(t),"createElementNS"),body:{appendChild(){}}};typeof globalThis.VideoFrame>"u"&&(globalThis.VideoFrame=class{static{r(this,"VideoFrame")}});const w=globalThis.Event;function S(s,t){return t==="mousemove"?0:s+1}r(S,"mouseWhich");function C(s,t){if(t)try{Object.defineProperty(s,"timeStamp",{value:t,writable:!0,configurable:!0})}catch{}}r(C,"setTimeStamp");globalThis.MouseEvent=class extends w{static{r(this,"MouseEvent")}constructor(t,e={}){super(t,e);const a=e.clientX||0,i=e.clientY||0;this.clientX=a,this.clientY=i,this.screenX=e.screenX!==void 0?e.screenX:a,this.screenY=e.screenY!==void 0?e.screenY:i,this.offsetX=a,this.offsetY=i,this.pageX=a,this.pageY=i,this.x=a,this.y=i,this.movementX=e.movementX||0,this.movementY=e.movementY||0,this.button=e.button||0,this.buttons=e.buttons||0,this.ctrlKey=!!e.ctrlKey,this.shiftKey=!!e.shiftKey,this.altKey=!!e.altKey,this.metaKey=!!e.metaKey,this.which=S(this.button,t),this.detail=e.detail||0,this.relatedTarget=null,C(this,e.timeStamp)}getModifierState(t){switch(t){case"Control":return this.ctrlKey;case"Shift":return this.shiftKey;case"Alt":return this.altKey;case"Meta":return this.metaKey;default:return!1}}};globalThis.WheelEvent=class extends globalThis.MouseEvent{static{r(this,"WheelEvent")}constructor(t,e={}){super(t,e),this.deltaX=e.deltaX||0,this.deltaY=e.deltaY||0,this.deltaZ=e.deltaZ||0,this.deltaMode=e.deltaMode||0}};globalThis.KeyboardEvent=class extends w{static{r(this,"KeyboardEvent")}constructor(t,e={}){super(t,e),this.key=e.key||"",this.code=e.code||"",this.keyCode=e.keyCode||0,this.which=e.which!==void 0?e.which:this.keyCode,this.location=e.location||0,this.repeat=!!e.repeat,this.isComposing=!1,this.ctrlKey=!!e.ctrlKey,this.shiftKey=!!e.shiftKey,this.altKey=!!e.altKey,this.metaKey=!!e.metaKey,C(this,e.timeStamp)}getModifierState(t){switch(t){case"Control":return this.ctrlKey;case"Shift":return this.shiftKey;case"Alt":return this.altKey;case"Meta":return this.metaKey;case"CapsLock":return!1;default:return!1}}};globalThis.KeyboardEvent.DOM_KEY_LOCATION_STANDARD=0;globalThis.KeyboardEvent.DOM_KEY_LOCATION_LEFT=1;globalThis.KeyboardEvent.DOM_KEY_LOCATION_RIGHT=2;globalThis.KeyboardEvent.DOM_KEY_LOCATION_NUMPAD=3;const X=100;function c(s){const t=b,e=s();t?(t.dispatchEvent(e),e.bubbles&&!e.cancelBubble&&globalThis.dispatchEvent(s())):globalThis.dispatchEvent(e)}r(c,"fire");globalThis.__ogDispatchInput=()=>{const s=d.ops.op_overglaze_input_events();if(!s)return;const e=1/(globalThis.devicePixelRatio||1),a=s.snapshot,i=r(n=>Object.assign({clientX:a.mouseX*e,clientY:a.mouseY*e,screenX:a.mouseX*e,screenY:a.mouseY*e,buttons:a.buttons,ctrlKey:a.ctrl,shiftKey:a.shift,altKey:a.alt,metaKey:a.meta,bubbles:!0,cancelable:!0},n),"baseMouse");if(a.movementX!==0||a.movementY!==0){const n=i({movementX:a.movementX*e,movementY:a.movementY*e,button:0});c(()=>new globalThis.MouseEvent("mousemove",n))}for(const n of s.mouse){const o=i({clientX:n.x*e,clientY:n.y*e,screenX:n.x*e,screenY:n.y*e,ctrlKey:n.ctrl,shiftKey:n.shift,altKey:n.alt,metaKey:n.meta,timeStamp:n.timeStamp});n.type==="wheel"?(o.button=0,o.deltaY=-n.wheel*X,c(()=>new globalThis.WheelEvent("wheel",o))):(o.button=n.button,c(()=>new globalThis.MouseEvent(n.type,o)),n.type==="mouseup"&&n.button===0&&c(()=>new globalThis.MouseEvent("click",o)))}for(const n of s.keys){const o={key:n.key,code:n.code,keyCode:n.keyCode,which:n.keyCode,location:n.location,repeat:n.repeat,ctrlKey:n.ctrl,shiftKey:n.shift,altKey:n.alt,metaKey:n.meta,bubbles:!0,cancelable:!0,timeStamp:n.timeStamp};c(()=>new globalThis.KeyboardEvent(n.type,o))}};d.ops.op_overglaze_log("info","webshim: Event/EventTarget + input dispatch ready");
package/package.json CHANGED
@@ -1,6 +1,21 @@
1
1
  {
2
2
  "name": "@overglaze/web",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.9.1",
4
+ "description": "The Overglaze web engine: an Overglaze plugin, run from its own files, live in a player's box on any page.",
5
+ "type": "module",
6
+ "main": "embed.js",
7
+ "keywords": [
8
+ "overglaze",
9
+ "overglaze-plugin",
10
+ "webgpu",
11
+ "wgsl",
12
+ "shader",
13
+ "player",
14
+ "embed"
15
+ ],
16
+ "author": "Overglaze",
17
+ "license": "SEE LICENSE IN LICENSE",
18
+ "overglaze": {
19
+ "contract": "0.2.0"
20
+ }
21
+ }
package/player/fill.js ADDED
@@ -0,0 +1,6 @@
1
+ /*! Overglaze web engine. Licensed under the PolyForm Noncommercial License 1.0.0
2
+ * <https://polyformproject.org/licenses/noncommercial/1.0.0>
3
+ * Required Notice: Copyright (c) 2026 Svetlozar Kostadinov
4
+ * With an added permission to run it to develop and preview Overglaze plugins: see LICENSE in @overglaze/web
5
+ */
6
+ var X=Object.defineProperty;var k=(o,r)=>X(o,"name",{value:r,configurable:!0});const z={light:{base:["#b9cfea","#dce6f1","#f4d2bb"],pools:["#d4c3f2","#a8d6cd","#f4d2bb"],mottle:9,grain:3},dark:{base:["#10294a","#0a1120","#3a1a48"],pools:["#0d3d47","#2a1f5c","#3a1a48"],mottle:6,grain:2}},I=[1920,1080],Y=[{x:1560,y:160,rx:420,ry:250,a:.85},{x:240,y:960,rx:480,ry:270,a:.9},{x:980,y:640,rx:360,ry:220,a:.55}],Z=[{period:112,share:.5,seed:2654435769},{period:28,share:.32,seed:2246822507},{period:7,share:.18,seed:3266489909}],C=1024;function B(o){return[parseInt(o.slice(1,3),16),parseInt(o.slice(3,5),16),parseInt(o.slice(5,7),16)]}k(B,"rgb");function D(o){return o=Math.imul(o^o>>>16,2146121005),o=Math.imul(o^o>>>15,2221713035),(o^o>>>16)>>>0}k(D,"hash");function G(o,r){const y=new Int32Array(o),c=new Float32Array(o);for(let s=0;s<o;s++){const i=s/r,e=Math.floor(i),M=i-e;y[s]=e,c[s]=M*M*(3-2*M)}return{cell:y,ease:c}}k(G,"lattice");function tt(o,r,y){const c=Math.max(1,Math.floor(r)),s=Math.max(1,Math.floor(y)),i=z[o]||z.light,e=Math.max(c/I[0],s/I[1]),M=(c-I[0]*e)/2,_=(s-I[1]*e)/2,O=i.base.map(B),P=new Float32Array(C*3);for(let t=0;t<C;t++){const p=t/(C-1),[f,d,h]=p<.5?[O[0],O[1],p*2]:[O[1],O[2],p*2-1];for(let x=0;x<3;x++)P[t*3+x]=f[x]+(d[x]-f[x])*h}const j=new Float32Array(c),q=new Float32Array(s);for(let t=0;t<c;t++)j[t]=Math.min(1,Math.max(0,(t-M)/(I[0]*e)))/2;for(let t=0;t<s;t++)q[t]=Math.min(1,Math.max(0,(t-_)/(I[1]*e)))/2;const H=Y.map((t,p)=>{const f=new Float32Array(c),d=new Float32Array(s),h=M+t.x*e,x=_+t.y*e;for(let n=0;n<c;n++){const w=(n-h)/(t.rx*e);f[n]=Math.exp(-.5*w*w)*t.a}for(let n=0;n<s;n++){const w=(n-x)/(t.ry*e);d[n]=Math.exp(-.5*w*w)}return{px:f,py:d,c:B(i.pools[p])}}),J=Z.map(t=>{const p=Math.ceil(c/t.period)+2,f=Math.ceil(s/t.period)+2,d=new Float32Array(p*f);for(let h=0;h<d.length;h++)d[h]=D(h^t.seed)/2147483648-1;return{gw:p,grid:d,cols:G(c,t.period),rows:G(s,t.period),amp:t.share*i.mottle}}),[E,S,L]=H,[u,A,F]=J,K=i.grain/127.5,T=new Uint8ClampedArray(c*s*4);let v=0;for(let t=0;t<s;t++){const p=q[t],f=E.py[t],d=S.py[t],h=L.py[t],x=u.rows.cell[t]*u.gw,n=A.rows.cell[t]*A.gw,w=F.rows.cell[t]*F.gw,N=u.rows.ease[t],Q=A.rows.ease[t],R=F.rows.ease[t];for(let a=0;a<c;a++){const V=Math.round((j[a]+p)*(C-1))*3;let b=P[V],g=P[V+1],m=P[V+2],l=E.px[a]*f;b+=(E.c[0]-b)*l,g+=(E.c[1]-g)*l,m+=(E.c[2]-m)*l,l=S.px[a]*d,b+=(S.c[0]-b)*l,g+=(S.c[1]-g)*l,m+=(S.c[2]-m)*l,l=L.px[a]*h,b+=(L.c[0]-b)*l,g+=(L.c[1]-g)*l,m+=(L.c[2]-m)*l;const U=W(u,x+u.cols.cell[a],u.cols.ease[a],N)+W(A,n+A.cols.cell[a],A.cols.ease[a],Q)+W(F,w+F.cols.cell[a],F.cols.ease[a],R)+((D(v)&255)-127.5)*K;T[v++]=b+U,T[v++]=g+U,T[v++]=m+U,T[v++]=255}}return{width:c,height:s,data:T}}k(tt,"fill");function W(o,r,y,c){const s=o.grid,i=s[r]+(s[r+1]-s[r])*y,e=s[r+o.gw]+(s[r+o.gw+1]-s[r+o.gw])*y;return(i+(e-i)*c)*o.amp}k(W,"noise");export{z as FILL_PALETTES,tt as fill};