@jucie.io/engine-painter 1.0.45 → 1.0.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +1 -1
- package/dist/main.js.map +3 -3
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var l={"2D":"2d",WEBGL:"webgl",WEBGL2:"webgl2",BITMAPRENDERER:"bitmaprenderer"};var d=class{#t=new Map;register(e,t){if(!e)throw new Error("Hit area must have an id");return this.#t.set(e,{id:e,...t}),()=>this.unregister(e)}unregister(e){this.#t.delete(e)}get(e){return this.#t.get(e)}has(e){return this.#t.has(e)}get areas(){return Array.from(this.#t.values())}clear(){this.#t.clear()}};import{ServiceProvider as S}from"@jucie.io/engine";var f=class extends S{#t=null;#o=null;#i=null;#y=null;#u=new Set;#h=new Set;#v=null;#c=null;#s=!1;#e={isPressed:!1,button:null,dragStartX:null,dragStartY:null,isDragging:!1,dragThreshold:5,prevX:null,prevY:null};static manifest={name:"CanvasEvents",namespace:"canvasEvents",version:"1.0.0"};actions(){return{setCanvas:e=>this.setCanvas(e),subscribe:e=>this.subscribe(e),onResize:e=>this.onResize(e),transferControlToOffscreen:()=>this.transferControlToOffscreen()}}setCanvas(e){this.#t&&this.#n(),this.#t=e,this.#g(),this.#w()}subscribe(e){return this.#u.add(e),()=>this.#u.delete(e)}onResize(e){return this.#h.add(e),()=>this.#h.delete(e)}transferControlToOffscreen(){if(!this.#t)throw new Error("Canvas must be set before transferring control to offscreen");if(this.#s)throw new Error("Control has already been transferred to offscreen");return this.#o=this.#t.transferControlToOffscreen(),this.#s=!0,this.#o.width=this.#i.width,this.#o.height=this.#i.height,this.#S({width:this.#t.width,height:this.#t.height}),this.#o}#g(){this.#t&&(this.#i=this.#t.getBoundingClientRect())}#w(){this.#t&&(this.#g(),this.#y=new ResizeObserver(e=>{for(let t of e){if(t.target!==this.#t)continue;let{width:s,height:i}=t.contentRect;this.#S({width:s,height:i})}this.#g()}),this.#y.observe(this.#t),document.addEventListener("wheel",this.#l,{passive:!1}),document.addEventListener("pointermove",this.#m),document.addEventListener("pointerdown",this.#d),document.addEventListener("pointerup",this.#a),document.addEventListener("pointercancel",this.#a),document.addEventListener("dblclick",this.#R))}#n(){this.#y&&(this.#y.disconnect(),this.#y=null),document.removeEventListener("wheel",this.#l),document.removeEventListener("pointermove",this.#m),document.removeEventListener("pointerdown",this.#d),document.removeEventListener("pointerup",this.#a),document.removeEventListener("pointercancel",this.#a),document.removeEventListener("dblclick",this.#R)}#l=e=>{if(e.target===this.#t)if(e.preventDefault(),e.stopPropagation(),e.ctrlKey){let t=this.#b(e,"zoom");this.#f(t)}else{let t=this.#b(e,"scroll");this.#f(t)}};#m=e=>{this.#v=e,!this.#c&&(this.#c=requestAnimationFrame(()=>{if(this.#v){let t=this.#v;this.#v=null;let s="move",i=this.#x(t);if(this.#e.isPressed&&!this.#e.isDragging){let a=i.x-this.#e.dragStartX,n=i.y-this.#e.dragStartY;Math.sqrt(a*a+n*n)>this.#e.dragThreshold&&(this.#e.isDragging=!0,s="dragstart")}else this.#e.isDragging&&(s="drag");let r=this.#b(t,s);this.#f(r)}this.#c=null}))};#d=e=>{if(e.target===this.#t){let t=this.#x(e);this.#e.isPressed=!0,this.#e.button=e.button??null,this.#e.dragStartX=t.x,this.#e.dragStartY=t.y,this.#e.isDragging=!1;let s=this.#b(e,"down");this.#f(s)}};#a=e=>{if(this.#e.isDragging){let s=this.#b(e,"dragend");this.#f(s)}let t=this.#b(e,"up");this.#f(t),this.#e.isPressed=!1,this.#e.isDragging=!1,this.#e.dragStartX=null,this.#e.dragStartY=null};#R=e=>{let t=this.#b(e,"dblclick");this.#f(t)};#f(e){for(let t of this.#u)t(e)}#S(e){for(let t of this.#h)t(e)}#x(e){let t=e.target===this.#t,s,i;return t?(s=e.offsetX,i=e.offsetY):this.#i?(s=e.clientX-this.#i.left,i=e.clientY-this.#i.top):(s=e.clientX,i=e.clientY),{x:s,y:i,isOverCanvas:t}}#b(e,t){let{x:s,y:i,isOverCanvas:r}=this.#x(e),a=r||this.#i&&s>=0&&s<=this.#i.width&&i>=0&&i<=this.#i.height,n=0,o=0,h=0,p=0;t==="scroll"?(n=e.deltaX,o=e.deltaY,h=e.deltaZ,p=e.deltaMode):t==="zoom"?(n=0,o=e.deltaY,h=0):(t==="move"||t==="drag"||t==="dragstart")&&this.#e.prevX!==null&&this.#e.prevY!==null&&(n=s-this.#e.prevX,o=i-this.#e.prevY);let y=0;if(this.#e.isDragging&&this.#e.dragStartX!==null&&this.#e.dragStartY!==null){let v=s-this.#e.dragStartX,w=i-this.#e.dragStartY;y=Math.sqrt(v*v+w*w)}let x={x:s,y:i,clientX:e.clientX,clientY:e.clientY,prevX:this.#e.prevX,prevY:this.#e.prevY,type:t,timestamp:Date.now(),isOverCanvas:r,isWithinBounds:a,deltaX:n,deltaY:o,deltaZ:h,deltaMode:p,button:e.button??this.#e.button,buttons:e.buttons??0,isPressed:this.#e.isPressed,isDragging:this.#e.isDragging,dragStartX:this.#e.dragStartX,dragStartY:this.#e.dragStartY,dragDistance:y,shiftKey:e.shiftKey||!1,ctrlKey:e.ctrlKey||!1,altKey:e.altKey||!1,metaKey:e.metaKey||!1};return this.#e.prevX=s,this.#e.prevY=i,x}destroy(){this.#c&&(cancelAnimationFrame(this.#c),this.#c=null),this.#n(),this.#t=null,this.#o=null,this.#i=null,this.#u.clear(),this.#h.clear(),this.#s=!1,this.#e.isPressed=!1,this.#e.button=null,this.#e.dragStartX=null,this.#e.dragStartY=null,this.#e.isDragging=!1,this.#e.prevX=null,this.#e.prevY=null}};import{defineSurface as E}from"@jucie.io/reactive";var u=E(c=>{let e=c.signal(null),t=c.signal(null),s=c.signal(null),i=c.action((o,h)=>{e(h)}),r=c.action((o,h)=>{t(h)}),a=c.action((o,h)=>{s(h)}),n=c.action(()=>{e(null),t(null),s(null)});return{event:e,hoveredArea:t,activeArea:s,handleEvent:i,setHoveredArea:r,setActiveArea:a,reset:n}});import{ServiceProvider as T}from"@jucie.io/engine";import{createComputed as C,destroyComputed as g,addEffect as P}from"@jucie.io/reactive";import{createDefinition as R,definitionType as m}from"@jucie.io/engine";var A=R("BRUSH",[Object]),L=R("LAYER",[Object]),b=class extends T{#t=new Map;#o=null;#i=new Map;#y=new Map;#u=!1;#h=null;#v=!1;#c=!1;#s={targetFPS:60,fixedTimeStep:1e3/60,timeScale:1,debug:{enabled:!1,showFPS:!0,showBounds:!0,showLayerTiming:!0}};#e={lastFrameTime:0,deltaTime:0,elapsedTime:0,frameCount:0};#g={fps:0,frameTime:0,layerTimes:new Map,brushTimes:new Map,skippedFrames:0};#w=new d;#n=u();#l=null;#m=null;#d=null;#a=new Map;#R=!1;static manifest={name:"Painter",namespace:"painter",version:"1.0.0",defaults:{targetFPS:60,fixedTimeStep:1e3/60,timeScale:1,debug:{enabled:!1,showFPS:!0,showBounds:!0,showLayerTiming:!0}}};getters(){return{pointer:()=>this.#n}}actions(){return this.config&&Object.assign(this.#s,this.config),{addLayer:e=>this.addLayer(e),addLayers:(...e)=>{for(let t of e)this.addLayer(t)},updateCanvas:e=>this.updateCanvas(e),setCanvas:e=>this.setCanvas(e),setOffscreenCanvas:e=>this.setOffscreenCanvas(e),setAssets:e=>this.setAssets(e),removeLayer:e=>this.removeLayer(e),start:()=>this.start(),stop:()=>this.stop(),render:()=>this.render(),setTargetFPS:e=>this.setTargetFPS(e),setTimeScale:e=>this.setTimeScale(e),setFixedTimeStep:e=>this.setFixedTimeStep(e),setDebug:e=>this.setDebug(e),getMetrics:()=>this.getMetrics(),handleResize:(e,t)=>this.handleResize(e,t),subscribe:(e,t)=>this.subscribe(e,t),handlePointerEvent:e=>this.handlePointerEvent(e),subscribeToPointer:e=>this.#n.$subscribe(e),bindPointer:e=>this.#n.$bind(e),_testEmitPointerEvent:e=>this._testEmitPointerEvent(e)}}setCanvas(e){let t=e,s=e.transferControlToOffscreen();s.width=t.width,s.height=t.height,this.#o=s,Object.values(l).forEach(i=>{try{let r=s.getContext(i);r&&this.#i.set(i,r)}catch{console.warn(`Context type ${i} not supported`)}}),this.#l||(this.#l=new f),this.#l.setCanvas(t),this.#d&&this.#d.disconnect(),this.#d=new ResizeObserver(i=>{let r=i[0];r&&r.target===t&&(s.width=t.width,s.height=t.height,this.handleResize(t.width,t.height))}),this.#d.observe(t),this.#m&&this.#m(),this.#m=this.#l.subscribe(i=>{this.handlePointerEvent(i)})}setOffscreenCanvas(e){this.#o=e,Object.values(l).forEach(t=>{try{let s=e.getContext(t);s&&this.#i.set(t,s)}catch{console.warn(`Context type ${t} not supported`)}})}updateCanvas(e){let t=e(this.#o);t&&(this.#o=t)}setAssets(e){this.#y=e}start(){this.#u||(this.#u=!0,this.#f())}stop(){this.#u&&(this.#u=!1,this.#h&&(cancelAnimationFrame(this.#h),this.#h=null))}addLayer(e){if(m(e)!=="LAYER")throw new Error("Invalid layer definition");let t=e._name,s=e(this.useContext,this.#w),i={...s,name:t,context:this.#i.get(s.context||"2d")};if(s.data&&(i.dataReactor=this.#E(s.data,()=>this.#n)),s.when&&(i.whenReactor=this.#E(s.when,()=>i?.dataReactor?.computed()||void 0)),i.brushes=s.children.map(r=>{if(m(r)==="BRUSH"){let a=r._name,n=r(this.useContext,this.#w),o={name:a,...n};if(n.data&&(o.dataReactor=this.#E(n.data,()=>this.#n)),n.when&&(o.whenReactor=this.#E(n.when,()=>o?.dataReactor?.computed()||void 0)),o.lifecycle?.onMount)try{o.lifecycle.onMount(this.#i.get(o.context||s.context))}catch(h){console.error(`Error in brush "${o.name}" onMount:`,h)}return o}return m(r)==="LAYER"?this.addLayer(r):r}),this.#t.set(t,i),i.lifecycle?.onMount)try{i.lifecycle.onMount(i.context)}catch(r){console.error(`Error in layer "${t}" onMount:`,r)}return i}removeLayer(e){let t=this.#t.get(e);if(t){if(t.lifecycle?.onUnmount)try{t.lifecycle.onUnmount(t.context)}catch(s){console.error(`Error in layer "${e}" onUnmount:`,s)}t.brushes.forEach(s=>{if(s.lifecycle?.onUnmount)try{s.lifecycle.onUnmount(this.#i.get(s.context||t.context))}catch(i){console.error(`Error in brush "${s.name}" onUnmount:`,i)}s.whenReactor&&g(s.whenReactor),s.dataReactor&&(s.dataReactor?.unsubscribe(),s.dataReactor?.computed&&g(s.dataReactor.computed))}),t.whenReactor&&(t.whenReactor?.unsubscribe(),t.whenReactor?.computed&&g(t.whenReactor.computed)),this.#t.delete(e)}}#f(){this.#c||this.#v||(this.#c=!0,this.#h=requestAnimationFrame(()=>{this.#c=!1,this.#h=null,this.#S()}))}async#S(){if(this.#o){this.#v=!0;try{this.#w.clear();let e=this.#s.debug?.enabled?performance.now():0;this.#i.forEach(t=>{t.clearRect(0,0,this.#o.width,this.#o.height)});for(let t of this.#t.values()){let s=this.#s.debug?.enabled?performance.now():0;if(t.whenReactor&&!t.whenReactor.computed())continue;let i=t.context;if(i){if(t.lifecycle?.beforeRender)try{t.lifecycle.beforeRender(i,this.#e)}catch(r){console.error(`Error in layer "${t.name}" beforeRender:`,r),t.lifecycle?.onError&&t.lifecycle.onError(r)}i.save(),t.settings&&Object.entries(t.settings).forEach(([r,a])=>{typeof i[r]=="function"?i[r](...Array.isArray(a)?a:[a]):i[r]=a});for(let r of t.brushes){let a=this.#s.debug?.enabled?performance.now():0;if(r.whenReactor&&!r.whenReactor.computed())continue;let n=r.context?this.#i.get(r.context):i;if(n){if(r.lifecycle?.beforeRender)try{r.lifecycle.beforeRender(n,this.#e)}catch(o){console.error(`Error in brush "${r.name}" beforeRender:`,o),r.lifecycle?.onError&&r.lifecycle.onError(o);continue}n.save(),r.settings&&Object.entries(r.settings).forEach(([o,h])=>{typeof n[o]=="function"?n[o](...Array.isArray(h)?h:[h]):n[o]=h});try{let o={};if(r.assets)for(let h of r.assets)o[h]=this.#y.get(h);if(r.render(n,r.dataReactor?r.dataReactor.computed():void 0,o,this.#e),r.lifecycle?.afterRender&&r.lifecycle.afterRender(n,this.#e),this.#s.debug?.enabled){let h=performance.now()-a;this.#g.brushTimes.set(r.name,h),this.#s.debug?.showBounds&&this.#x(n,r)}}catch(o){console.error(`Error in brush "${r.name}":`,o),r.lifecycle?.onError&&r.lifecycle.onError(o)}finally{n.restore()}}}if(i.restore(),t.lifecycle?.afterRender)try{t.lifecycle.afterRender(i,this.#e)}catch(r){console.error(`Error in layer "${t.name}" afterRender:`,r),t.lifecycle?.onError&&t.lifecycle.onError(r)}if(this.#s.debug?.enabled){let r=performance.now()-s;this.#g.layerTimes.set(t.name,r),this.#s.debug?.showBounds&&this.#b(i,t)}}}this.#s.debug?.enabled&&this.#P()}finally{this.#v=!1}}}#x(e,t){e.save(),e.strokeStyle="rgba(0, 255, 0, 0.5)",e.lineWidth=1,e.strokeRect(0,0,e.canvas.width,e.canvas.height),e.restore()}#b(e,t){e.save(),e.strokeStyle="rgba(255, 0, 0, 0.5)",e.lineWidth=2,e.strokeRect(0,0,e.canvas.width,e.canvas.height),e.restore()}#P(){let e=this.#i.get(l["2D"]);if(!e)return;e.save(),e.resetTransform(),e.font="12px monospace",e.fillStyle="white",e.strokeStyle="black",e.lineWidth=3;let t=20,s=15;if(this.#s.debug?.showFPS){let i=`FPS: ${Math.round(this.#g.fps)} (${this.#e.deltaTime.toFixed(2)}ms)`;e.strokeText(i,10,t),e.fillText(i,10,t),t+=s}if(this.#s.debug?.showLayerTiming){e.fillText("Layer Times:",10,t),t+=s;for(let[i,r]of this.#g.layerTimes){let a=` ${i}: ${r.toFixed(2)}ms`;e.strokeText(a,10,t),e.fillText(a,10,t),t+=s}e.fillText(this.state.get(["_transitions","pointer","currentState"]),10,t)}e.restore()}handleResize(e,t){for(let s of this.#t.values())if(s.lifecycle?.onResize)try{s.lifecycle.onResize(e,t,s.context)}catch(i){console.error(`Error in layer "${s.name}" onResize:`,i),s.lifecycle?.onError&&s.lifecycle.onError(i)}}#E(e,t=()=>{}){if(!e)return null;let s=C(e,{immediate:!0,context:t}),i=P(s,()=>this.#f());return{computed:s,unsubscribe:i}}destroy(){this.stop(),this.#m&&(this.#m(),this.#m=null),this.#l&&(this.#l.destroy(),this.#l=null),this.#d&&(this.#d.disconnect(),this.#d=null),this.#n&&this.#n.$destroy();for(let e of this.#t.keys())this.removeLayer(e)}setTargetFPS(e){this.#s.targetFPS=e,this.#s.fixedTimeStep=1e3/e}setTimeScale(e){this.#s.timeScale=Math.max(0,e)}setFixedTimeStep(e){this.#s.fixedTimeStep=e}setDebug(e={}){this.#s.debug||(this.#s.debug={}),Object.assign(this.#s.debug,e)}getMetrics(){return{...this.#g,deltaTime:this.#e.deltaTime,elapsedTime:this.#e.elapsedTime,frameCount:this.#e.frameCount}}handlePointerEvent(e){this.#n.handleEvent(e),this.#C(e),this.#A(e)}#A(e){let{type:t}=e,s=this.#n,i=s.event;switch(t){case"down":this.#r("pointer:down",s);break;case"up":this.#r("pointer:up",s),i&&!i.isDragging&&this.#r("pointer:click",s);break;case"move":this.#r("pointer:move",s);break;case"dragstart":this.#r("pointer:drag:start",s);break;case"drag":this.#r("pointer:drag:move",s);break;case"dragend":this.#r("pointer:drag:end",s);break;case"scroll":this.#r("pointer:scroll",s);break;case"zoom":this.#r("pointer:zoom",s);break;case"dblclick":this.#r("pointer:dblclick",s);break}let r=this.#R,a=i?.isOverCanvas||!1;a&&!r?this.#r("pointer:enter",s):!a&&r&&this.#r("pointer:leave",s),this.#R=a}#C(e){let{type:t,x:s,y:i}=e,r=this.#n;switch(t){case"down":{let n=this.#T(s,i);if(r.setActiveArea(n),n?.onPointerDown?.handler){let o=this.#p(n);n.onPointerDown.handler({event:e,ctx:o,emit:this.#r.bind(this)})}break}case"up":{let n=r.activeArea;if(n?.onPointerUp?.handler){let o=this.#p(n);n.onPointerUp.handler({event:e,ctx:o,emit:this.#r.bind(this)})}break}case"move":{let n=this.#T(s,i),o=r.hoveredArea;if(n?.onPointerMove?.handler&&!e.isDragging){let h=this.#p(n);n.onPointerMove.handler({event:e,ctx:h,emit:this.#r.bind(this)})}if(n?.id!==o?.id){if(o?.onPointerLeave?.handler){let h=this.#p(o);o.onPointerLeave.handler({event:e,ctx:h,emit:this.#r.bind(this)})}if(n?.onPointerEnter?.handler){let h=this.#p(n);n.onPointerEnter.handler({event:e,ctx:h,emit:this.#r.bind(this)})}r.setHoveredArea(n)}break}case"dragstart":{let n=r.activeArea;if(n?.onDragStart?.handler){let o=this.#p(n);n.onDragStart.handler({event:e,ctx:o,emit:this.#r.bind(this)})}break}case"drag":{let n=r.activeArea;if(n?.onDragMove?.handler){let o=this.#p(n);n.onDragMove.handler({event:e,ctx:o,emit:this.#r.bind(this)})}break}case"dragend":{let n=r.activeArea;if(n?.onDragEnd?.handler){let o=this.#p(n);n.onDragEnd.handler({event:e,ctx:o,emit:this.#r.bind(this)})}break}case"dblclick":let a=this.#T(s,i);if(r.setActiveArea(a),a?.onPointerDblClick?.handler){let n=this.#p(a);a.onPointerDblClick.handler({event:e,ctx:n,emit:this.#r.bind(this)})}break}}#p(e){return e?e.context?this.#i.get(e.context):this.#i.get(l["2D"]):null}subscribe(e,t){return this.#a.has(e)||this.#a.set(e,new Set),this.#a.get(e).add(t),()=>{let s=this.#a.get(e);s&&(s.delete(t),s.size===0&&this.#a.delete(e))}}#T(e,t){let s=this.#w.areas.sort((i,r)=>(r.priority||0)-(i.priority||0));for(let i of s)if(this.#L(e,t,i.bounds))return i;return null}#L(e,t,s){return e>=s.x&&e<=s.x+s.width&&t>=s.y&&t<=s.y+s.height}#r(e,t){let s=this.#a.get(e);if(s)for(let i of s)i(t)}_testEmitPointerEvent(e){this.#n.handleEvent(e),this.#C(e)}};export{f as CanvasEvents,d as HitRegistry,b as Painter,A as defineBrush,L as defineLayer,u as usePointerSurface};
|
|
1
|
+
var f={"2D":"2d",WEBGL:"webgl",WEBGL2:"webgl2",BITMAPRENDERER:"bitmaprenderer"};var u=class{#t=new Map;register(e,t){if(!e)throw new Error("Hit area must have an id");return this.#t.set(e,{id:e,...t}),()=>this.unregister(e)}unregister(e){this.#t.delete(e)}get(e){return this.#t.get(e)}has(e){return this.#t.has(e)}get areas(){return Array.from(this.#t.values())}clear(){this.#t.clear()}};import{ServiceProvider as T}from"@jucie.io/engine";var g=class extends T{#t=null;#a=null;#i=null;#r=null;#y=new Set;#g=new Set;#l=null;#d=null;#S=!1;#e={isPressed:!1,button:null,dragStartX:null,dragStartY:null,isDragging:!1,dragThreshold:5,prevX:null,prevY:null};static manifest={name:"CanvasEvents",namespace:"canvasEvents",version:"1.0.0"};actions(){return{setCanvas:e=>this.setCanvas(e),subscribe:e=>this.subscribe(e),onResize:e=>this.onResize(e),transferControlToOffscreen:()=>this.transferControlToOffscreen()}}setCanvas(e){this.#t&&this.#R(),this.#t=e,this.#o(),this.#w()}subscribe(e){return this.#y.add(e),()=>this.#y.delete(e)}onResize(e){return this.#g.add(e),()=>this.#g.delete(e)}transferControlToOffscreen(){if(!this.#t)throw new Error("Canvas must be set before transferring control to offscreen");if(this.#S)throw new Error("Control has already been transferred to offscreen");return this.#a=this.#t.transferControlToOffscreen(),this.#S=!0,this.#a.width=this.#i.width,this.#a.height=this.#i.height,this.#v({width:this.#t.width,height:this.#t.height}),this.#a}#o(){this.#t&&(this.#i=this.#t.getBoundingClientRect())}#w(){this.#t&&(this.#o(),this.#r=new ResizeObserver(e=>{for(let t of e){if(t.target!==this.#t)continue;let{width:s,height:i}=t.contentRect;this.#v({width:s,height:i})}this.#o()}),this.#r.observe(this.#t),document.addEventListener("wheel",this.#n,{passive:!1}),document.addEventListener("pointermove",this.#f),document.addEventListener("pointerdown",this.#m),document.addEventListener("pointerup",this.#h),document.addEventListener("pointercancel",this.#h),document.addEventListener("dblclick",this.#b))}#R(){this.#r&&(this.#r.disconnect(),this.#r=null),document.removeEventListener("wheel",this.#n),document.removeEventListener("pointermove",this.#f),document.removeEventListener("pointerdown",this.#m),document.removeEventListener("pointerup",this.#h),document.removeEventListener("pointercancel",this.#h),document.removeEventListener("dblclick",this.#b)}#n=e=>{if(e.target===this.#t)if(e.preventDefault(),e.stopPropagation(),e.ctrlKey){let t=this.#p(e,"zoom");this.#u(t)}else{let t=this.#p(e,"scroll");this.#u(t)}};#f=e=>{this.#l=e,!this.#d&&(this.#d=requestAnimationFrame(()=>{if(this.#l){let t=this.#l;this.#l=null;let s="move",i=this.#x(t);if(this.#e.isPressed&&!this.#e.isDragging){let r=i.x-this.#e.dragStartX,o=i.y-this.#e.dragStartY;Math.sqrt(r*r+o*o)>this.#e.dragThreshold&&(this.#e.isDragging=!0,s="dragstart")}else this.#e.isDragging&&(s="drag");let n=this.#p(t,s);this.#u(n)}this.#d=null}))};#m=e=>{if(e.target===this.#t){let t=this.#x(e);this.#e.isPressed=!0,this.#e.button=e.button??null,this.#e.dragStartX=t.x,this.#e.dragStartY=t.y,this.#e.isDragging=!1;let s=this.#p(e,"down");this.#u(s)}};#h=e=>{if(this.#e.isDragging){let s=this.#p(e,"dragend");this.#u(s)}let t=this.#p(e,"up");this.#u(t),this.#e.isPressed=!1,this.#e.isDragging=!1,this.#e.dragStartX=null,this.#e.dragStartY=null};#b=e=>{let t=this.#p(e,"dblclick");this.#u(t)};#u(e){for(let t of this.#y)t(e)}#v(e){for(let t of this.#g)t(e)}#x(e){let t=e.target===this.#t,s,i;return t?(s=e.offsetX,i=e.offsetY):this.#i?(s=e.clientX-this.#i.left,i=e.clientY-this.#i.top):(s=e.clientX,i=e.clientY),{x:s,y:i,isOverCanvas:t}}#p(e,t){let{x:s,y:i,isOverCanvas:n}=this.#x(e),r=n||this.#i&&s>=0&&s<=this.#i.width&&i>=0&&i<=this.#i.height,o=0,a=0,h=0,c=0;t==="scroll"?(o=e.deltaX,a=e.deltaY,h=e.deltaZ,c=e.deltaMode):t==="zoom"?(o=0,a=e.deltaY,h=0):(t==="move"||t==="drag"||t==="dragstart")&&this.#e.prevX!==null&&this.#e.prevY!==null&&(o=s-this.#e.prevX,a=i-this.#e.prevY);let S=0;if(this.#e.isDragging&&this.#e.dragStartX!==null&&this.#e.dragStartY!==null){let w=s-this.#e.dragStartX,R=i-this.#e.dragStartY;S=Math.sqrt(w*w+R*R)}let C={x:s,y:i,clientX:e.clientX,clientY:e.clientY,prevX:this.#e.prevX,prevY:this.#e.prevY,type:t,timestamp:Date.now(),isOverCanvas:n,isWithinBounds:r,deltaX:o,deltaY:a,deltaZ:h,deltaMode:c,button:e.button??this.#e.button,buttons:e.buttons??0,isPressed:this.#e.isPressed,isDragging:this.#e.isDragging,dragStartX:this.#e.dragStartX,dragStartY:this.#e.dragStartY,dragDistance:S,shiftKey:e.shiftKey||!1,ctrlKey:e.ctrlKey||!1,altKey:e.altKey||!1,metaKey:e.metaKey||!1};return this.#e.prevX=s,this.#e.prevY=i,C}destroy(){this.#d&&(cancelAnimationFrame(this.#d),this.#d=null),this.#R(),this.#t=null,this.#a=null,this.#i=null,this.#y.clear(),this.#g.clear(),this.#S=!1,this.#e.isPressed=!1,this.#e.button=null,this.#e.dragStartX=null,this.#e.dragStartY=null,this.#e.isDragging=!1,this.#e.prevX=null,this.#e.prevY=null}};import{defineSurface as P}from"@jucie.io/reactive";var p=P(l=>{let e=l.signal(null),t=l.signal(null),s=l.signal(null),i=l.action((a,h)=>{e(h)}),n=l.action((a,h)=>{t(h)}),r=l.action((a,h)=>{s(h)}),o=l.action(()=>{e(null),t(null),s(null)});return{event:e,hoveredArea:t,activeArea:s,handleEvent:i,setHoveredArea:n,setActiveArea:r,reset:o}});import{ServiceProvider as A}from"@jucie.io/engine";import{createComputed as L,destroyComputed as v,addEffect as k}from"@jucie.io/reactive";import{createDefinition as m,definitionType as b}from"@jucie.io/engine";var d={BRUSH:"BRUSH",LAYER:"LAYER",SUBSCRIPTION:"SUBSCRIPTION",SUBSCRIPTIONS:"SUBSCRIPTIONS"},x="GLOBAL_LAYER",O=m(d.BRUSH,[Object]),E=m(d.LAYER,[Object]),D=m(d.SUBSCRIPTION,[Function]),Y=m(d.SUBSCRIPTIONS,[Array]),y=class extends A{#t=new Map;#a=new Map;#i=null;#r=new Map;#y=new Map;#g=!1;#l=null;#d=!1;#S=!1;#e={targetFPS:60,fixedTimeStep:1e3/60,timeScale:1,debug:{enabled:!1,showFPS:!0,showBounds:!0,showLayerTiming:!0}};#o={lastFrameTime:0,deltaTime:0,elapsedTime:0,frameCount:0};#w={fps:0,frameTime:0,layerTimes:new Map,brushTimes:new Map,skippedFrames:0};#R=new u;#n=p();#f=null;#m=null;#h=null;#b=new Map;#u=!1;static manifest={name:"Painter",namespace:"painter",version:"1.0.0",defaults:{targetFPS:60,fixedTimeStep:1e3/60,timeScale:1,debug:{enabled:!1,showFPS:!0,showBounds:!0,showLayerTiming:!0}}};getters(){return{pointer:()=>this.#n}}initialize(){this.#v(E(x,()=>({context:f["2D"]})))}actions(){return this.config&&Object.assign(this.#e,this.config),{addLayer:e=>this.#v(e),addLayers:(...e)=>{for(let t of e)this.#v(t)},use:(...e)=>this.use(e),updateCanvas:e=>this.updateCanvas(e),setCanvas:e=>this.setCanvas(e),setOffscreenCanvas:e=>this.setOffscreenCanvas(e),setAssets:e=>this.setAssets(e),removeLayer:e=>this.#T(e),start:()=>this.start(),stop:()=>this.stop(),render:()=>this.render(),setTargetFPS:e=>this.setTargetFPS(e),setTimeScale:e=>this.setTimeScale(e),setFixedTimeStep:e=>this.setFixedTimeStep(e),setDebug:e=>this.setDebug(e),getMetrics:()=>this.getMetrics(),handleResize:(e,t)=>this.handleResize(e,t),subscribe:(e,t)=>this.subscribe(e,t),handlePointerEvent:e=>this.handlePointerEvent(e),subscribeToPointer:e=>this.#n.$subscribe(e),bindPointer:e=>this.#n.$bind(e),_testEmitPointerEvent:e=>this._testEmitPointerEvent(e)}}use(e){for(let t of e){let s=b(t);switch(s){case d.BRUSH:this.#x(x,t);break;case d.LAYER:this.#v(t);break;case d.SUBSCRIPTION:this.#p(t);break;case d.SUBSCRIPTIONS:this.#L(t);break;default:throw new Error(`Invalid factory type: ${s}`)}}return this}setCanvas(e){let t=e,s=e.transferControlToOffscreen();s.width=t.width,s.height=t.height,this.#i=s,Object.values(f).forEach(i=>{try{let n=s.getContext(i);n&&this.#r.set(i,n)}catch{console.warn(`Context type ${i} not supported`)}}),this.#f||(this.#f=new g),this.#f.setCanvas(t),this.#h&&this.#h.disconnect(),this.#h=new ResizeObserver(i=>{let n=i[0];n&&n.target===t&&(s.width=t.width,s.height=t.height,this.handleResize(t.width,t.height))}),this.#h.observe(t),this.#m&&this.#m(),this.#m=this.#f.subscribe(i=>{this.handlePointerEvent(i)})}setOffscreenCanvas(e){this.#i=e,Object.values(f).forEach(t=>{try{let s=e.getContext(t);s&&this.#r.set(t,s)}catch{console.warn(`Context type ${t} not supported`)}})}updateCanvas(e){let t=e(this.#i);t&&(this.#i=t)}setAssets(e){this.#y=e}start(){this.#g||(this.#g=!0,this.#P())}stop(){this.#g&&(this.#g=!1,this.#l&&(cancelAnimationFrame(this.#l),this.#l=null))}#v(e){if(b(e)!=="LAYER")throw new Error("Invalid layer definition");let t=e._name,s=e(this.useContext,this.#R),i={...s,name:t,context:this.#r.get(s.context||"2d")};if(s.data&&(i.dataReactor=this.#E(s.data,()=>this.#n)),s.when&&(i.whenReactor=this.#E(s.when,()=>i?.dataReactor?.computed()||void 0)),s.children&&s.children.length>0)for(let n of s.children)b(n)==="BRUSH"&&this.#x(t,n),b(n)==="LAYER"&&this.#v(n);if(this.#t.set(t,i),i.lifecycle?.onMount)try{i.lifecycle.onMount(i.context)}catch(n){console.error(`Error in layer "${t}" onMount:`,n)}return i}#x(e,t){let s=t._name,i=t(this.useContext,this.#R),n={name:s,...i};if(i.data&&(n.dataReactor=this.#E(i.data,()=>this.#n)),i.when&&(n.whenReactor=this.#E(i.when,()=>n?.dataReactor?.computed()||void 0)),n.lifecycle?.onMount)try{n.lifecycle.onMount(this.#r.get(n.context||this.#t.get(e)?.context))}catch(r){console.error(`Error in brush "${n.name}" onMount:`,r)}return this.#a.has(e)||this.#a.set(e,[]),this.#a.get(e).push(n),n}#p(e){let t=e._name,s=e(this.useContext);this.subscribe(t,s)}#L(e){let t=e._name,s=e(this.useContext);for(let{event:i,handler:n}of s){let r=t?`${t}:${i}`:i;this.subscribe(r,n)}}#T(e){let t=this.#t.get(e);if(!t)return;if(t.lifecycle?.onUnmount)try{t.lifecycle.onUnmount(t.context)}catch(i){console.error(`Error in layer "${e}" onUnmount:`,i)}let s=this.#a.get(e)||[];this.#a.delete(e);for(let i of s){if(i.lifecycle?.onUnmount)try{i.lifecycle.onUnmount(this.#r.get(i.context||t.context))}catch(n){console.error(`Error in brush "${i.name}" onUnmount:`,n)}i.whenReactor&&v(i.whenReactor),i.dataReactor&&(i.dataReactor?.unsubscribe(),i.dataReactor?.computed&&v(i.dataReactor.computed))}t.whenReactor&&(t.whenReactor?.unsubscribe(),t.whenReactor?.computed&&v(t.whenReactor.computed)),this.#t.delete(e)}#P(){this.#S||this.#d||(this.#S=!0,this.#l=requestAnimationFrame(()=>{this.#S=!1,this.#l=null,this.#k()}))}async#k(){if(this.#i){this.#d=!0;try{this.#R.clear();let e=this.#e.debug?.enabled?performance.now():0;this.#r.forEach(t=>{t.clearRect(0,0,this.#i.width,this.#i.height)});for(let t of this.#t.values()){let s=this.#e.debug?.enabled?performance.now():0;if(t.whenReactor&&!t.whenReactor.computed())continue;let i=t.context;if(!i)continue;if(t.lifecycle?.beforeRender)try{t.lifecycle.beforeRender(i,this.#o)}catch(r){console.error(`Error in layer "${t.name}" beforeRender:`,r),t.lifecycle?.onError&&t.lifecycle.onError(r)}i.save(),t.settings&&Object.entries(t.settings).forEach(([r,o])=>{typeof i[r]=="function"?i[r](...Array.isArray(o)?o:[o]):i[r]=o});let n=this.#a.get(t.name)||[];for(let r of n){let o=this.#e.debug?.enabled?performance.now():0;if(r.whenReactor&&!r.whenReactor.computed())continue;let a=r.context?this.#r.get(r.context):i;if(a){if(r.lifecycle?.beforeRender)try{r.lifecycle.beforeRender(a,this.#o)}catch(h){console.error(`Error in brush "${r.name}" beforeRender:`,h),r.lifecycle?.onError&&r.lifecycle.onError(h);continue}a.save(),r.settings&&Object.entries(r.settings).forEach(([h,c])=>{typeof a[h]=="function"?a[h](...Array.isArray(c)?c:[c]):a[h]=c});try{let h={};if(r.assets)for(let c of r.assets)h[c]=this.#y.get(c);if(r.render(a,r.dataReactor?r.dataReactor.computed():void 0,h,this.#o),r.lifecycle?.afterRender&&r.lifecycle.afterRender(a,this.#o),this.#e.debug?.enabled){let c=performance.now()-o;this.#w.brushTimes.set(r.name,c),this.#e.debug?.showBounds&&this.#O(a,r)}}catch(h){console.error(`Error in brush "${r.name}":`,h),r.lifecycle?.onError&&r.lifecycle.onError(h)}finally{a.restore()}}}if(i.restore(),t.lifecycle?.afterRender)try{t.lifecycle.afterRender(i,this.#o)}catch(r){console.error(`Error in layer "${t.name}" afterRender:`,r),t.lifecycle?.onError&&t.lifecycle.onError(r)}if(this.#e.debug?.enabled){let r=performance.now()-s;this.#w.layerTimes.set(t.name,r),this.#e.debug?.showBounds&&this.#D(i,t)}}this.#e.debug?.enabled&&this.#Y()}finally{this.#d=!1}}}#O(e,t){e.save(),e.strokeStyle="rgba(0, 255, 0, 0.5)",e.lineWidth=1,e.strokeRect(0,0,e.canvas.width,e.canvas.height),e.restore()}#D(e,t){e.save(),e.strokeStyle="rgba(255, 0, 0, 0.5)",e.lineWidth=2,e.strokeRect(0,0,e.canvas.width,e.canvas.height),e.restore()}#Y(){let e=this.#r.get(f["2D"]);if(!e)return;e.save(),e.resetTransform(),e.font="12px monospace",e.fillStyle="white",e.strokeStyle="black",e.lineWidth=3;let t=20,s=15;if(this.#e.debug?.showFPS){let i=`FPS: ${Math.round(this.#w.fps)} (${this.#o.deltaTime.toFixed(2)}ms)`;e.strokeText(i,10,t),e.fillText(i,10,t),t+=s}if(this.#e.debug?.showLayerTiming){e.fillText("Layer Times:",10,t),t+=s;for(let[i,n]of this.#w.layerTimes){let r=` ${i}: ${n.toFixed(2)}ms`;e.strokeText(r,10,t),e.fillText(r,10,t),t+=s}e.fillText(this.state.get(["_transitions","pointer","currentState"]),10,t)}e.restore()}handleResize(e,t){for(let s of this.#t.values())if(s.lifecycle?.onResize)try{s.lifecycle.onResize(e,t,s.context)}catch(i){console.error(`Error in layer "${s.name}" onResize:`,i),s.lifecycle?.onError&&s.lifecycle.onError(i)}}#E(e,t=()=>{}){if(!e)return null;let s=L(e,{immediate:!0,context:t}),i=k(s,()=>this.#P());return{computed:s,unsubscribe:i}}destroy(){this.stop(),this.#m&&(this.#m(),this.#m=null),this.#f&&(this.#f.destroy(),this.#f=null),this.#h&&(this.#h.disconnect(),this.#h=null),this.#n&&this.#n.$destroy();for(let e of this.#t.keys())this.#T(e)}setTargetFPS(e){this.#e.targetFPS=e,this.#e.fixedTimeStep=1e3/e}setTimeScale(e){this.#e.timeScale=Math.max(0,e)}setFixedTimeStep(e){this.#e.fixedTimeStep=e}setDebug(e={}){this.#e.debug||(this.#e.debug={}),Object.assign(this.#e.debug,e)}getMetrics(){return{...this.#w,deltaTime:this.#o.deltaTime,elapsedTime:this.#o.elapsedTime,frameCount:this.#o.frameCount}}handlePointerEvent(e){this.#n.handleEvent(e),this.#A(e),this.#B(e)}#B(e){let{type:t}=e,s=this.#n,i=s.event;switch(t){case"down":this.#s("pointer:down",s);break;case"up":this.#s("pointer:up",s),i&&!i.isDragging&&this.#s("pointer:click",s);break;case"move":this.#s("pointer:move",s);break;case"dragstart":this.#s("pointer:drag:start",s);break;case"drag":this.#s("pointer:drag:move",s);break;case"dragend":this.#s("pointer:drag:end",s);break;case"scroll":this.#s("pointer:scroll",s);break;case"zoom":this.#s("pointer:zoom",s);break;case"dblclick":this.#s("pointer:dblclick",s);break}let n=this.#u,r=i?.isOverCanvas||!1;r&&!n?this.#s("pointer:enter",s):!r&&n&&this.#s("pointer:leave",s),this.#u=r}#A(e){let{type:t,x:s,y:i}=e,n=this.#n;switch(t){case"down":{let o=this.#C(s,i);if(n.setActiveArea(o),o?.onPointerDown?.handler){let a=this.#c(o);o.onPointerDown.handler({event:e,ctx:a,emit:this.#s.bind(this)})}break}case"up":{let o=n.activeArea;if(o?.onPointerUp?.handler){let a=this.#c(o);o.onPointerUp.handler({event:e,ctx:a,emit:this.#s.bind(this)})}break}case"move":{let o=this.#C(s,i),a=n.hoveredArea;if(o?.onPointerMove?.handler&&!e.isDragging){let h=this.#c(o);o.onPointerMove.handler({event:e,ctx:h,emit:this.#s.bind(this)})}if(o?.id!==a?.id){if(a?.onPointerLeave?.handler){let h=this.#c(a);a.onPointerLeave.handler({event:e,ctx:h,emit:this.#s.bind(this)})}if(o?.onPointerEnter?.handler){let h=this.#c(o);o.onPointerEnter.handler({event:e,ctx:h,emit:this.#s.bind(this)})}n.setHoveredArea(o)}break}case"dragstart":{let o=n.activeArea;if(o?.onDragStart?.handler){let a=this.#c(o);o.onDragStart.handler({event:e,ctx:a,emit:this.#s.bind(this)})}break}case"drag":{let o=this.#C(s,i),a=n.hoveredArea;if(o?.id!==a?.id){if(a?.onPointerLeave?.handler){let c=this.#c(a);a.onPointerLeave.handler({event:e,ctx:c,emit:this.#s.bind(this)})}if(o?.onPointerEnter?.handler){let c=this.#c(o);o.onPointerEnter.handler({event:e,ctx:c,emit:this.#s.bind(this)})}n.setHoveredArea(o)}let h=n.activeArea;if(h?.onDragMove?.handler){let c=this.#c(h);h.onDragMove.handler({event:e,ctx:c,emit:this.#s.bind(this)})}break}case"dragend":{let o=n.activeArea;if(o?.onDragEnd?.handler){let a=this.#c(o);o.onDragEnd.handler({event:e,ctx:a,emit:this.#s.bind(this)})}break}case"dblclick":let r=this.#C(s,i);if(n.setActiveArea(r),r?.onPointerDblClick?.handler){let o=this.#c(r);r.onPointerDblClick.handler({event:e,ctx:o,emit:this.#s.bind(this)})}break}}#c(e){return e?e.context?this.#r.get(e.context):this.#r.get(f["2D"]):null}subscribe(e,t){return this.#b.has(e)||this.#b.set(e,new Set),this.#b.get(e).add(t),()=>{let s=this.#b.get(e);s&&(s.delete(t),s.size===0&&this.#b.delete(e))}}#C(e,t){let s=this.#R.areas.sort((i,n)=>(n.priority||0)-(i.priority||0));for(let i of s)if(this.#M(e,t,i.bounds))return i;return null}#M(e,t,s){return e>=s.x&&e<=s.x+s.width&&t>=s.y&&t<=s.y+s.height}#s(e,t){let s=this.#b.get(e);if(s)for(let i of s)i(t)}_testEmitPointerEvent(e){this.#n.handleEvent(e),this.#A(e)}};export{g as CanvasEvents,u as HitRegistry,y as Painter,O as defineBrush,E as defineLayer,D as defineSubscription,Y as defineSubscriptions,p as usePointerSurface};
|
|
2
2
|
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/ContextTypes.js", "../src/HitRegistry.js", "../src/CanvasEvents.js", "../src/usePointerSurface.js", "../src/Painter.js"],
|
|
4
|
-
"sourcesContent": ["export const ContextTypes = {\n '2D': '2d',\n 'WEBGL': 'webgl',\n 'WEBGL2': 'webgl2',\n 'BITMAPRENDERER': 'bitmaprenderer'\n};", "export class HitRegistry {\n #areas = new Map();\n\n register(id, area) {\n if (!id) {\n throw new Error('Hit area must have an id');\n }\n this.#areas.set(id, { id, ...area });\n return () => this.unregister(id);\n }\n\n unregister(id) {\n this.#areas.delete(id);\n }\n\n get(id) {\n return this.#areas.get(id);\n }\n\n has(id) {\n return this.#areas.has(id);\n }\n\n get areas() {\n return Array.from(this.#areas.values());\n }\n\n clear() {\n this.#areas.clear();\n }\n}", "import { ServiceProvider } from '@jucie.io/engine';\n\nexport class CanvasEvents extends ServiceProvider {\n #canvas = null;\n #offscreenCanvas = null;\n #cachedRect = null;\n #resizeObserver = null;\n #subscribers = new Set();\n #resizeSubscribers = new Set();\n #pendingMove = null;\n #rafId = null;\n #hasTransferredControl = false;\n\n // Internal state for semantic event interpretation\n #state = {\n isPressed: false,\n button: null,\n dragStartX: null,\n dragStartY: null,\n isDragging: false,\n dragThreshold: 5,\n prevX: null,\n prevY: null\n };\n\n static manifest = {\n name: 'CanvasEvents',\n namespace: 'canvasEvents',\n version: '1.0.0'\n };\n\n actions() {\n return {\n setCanvas: (canvas) => this.setCanvas(canvas),\n subscribe: (listener) => this.subscribe(listener),\n onResize: (listener) => this.onResize(listener),\n transferControlToOffscreen: () => this.transferControlToOffscreen()\n };\n }\n\n setCanvas(canvas) {\n if (this.#canvas) {\n this.#removeListeners();\n }\n \n this.#canvas = canvas;\n this.#updateCachedRect();\n this.#initializeListeners();\n }\n\n subscribe(subscriber) {\n this.#subscribers.add(subscriber);\n return () => this.#subscribers.delete(subscriber);\n }\n\n onResize(subscriber) {\n this.#resizeSubscribers.add(subscriber);\n return () => this.#resizeSubscribers.delete(subscriber);\n }\n\n transferControlToOffscreen() {\n if (!this.#canvas) {\n throw new Error('Canvas must be set before transferring control to offscreen');\n }\n\n if (this.#hasTransferredControl) {\n throw new Error('Control has already been transferred to offscreen');\n }\n\n // Transfer control\n this.#offscreenCanvas = this.#canvas.transferControlToOffscreen();\n this.#hasTransferredControl = true;\n\n\n\n // Set initial dimensions on offscreen canvas\n this.#offscreenCanvas.width = this.#cachedRect.width;\n this.#offscreenCanvas.height = this.#cachedRect.height;\n\n // Emit initial resize event with actual canvas dimensions\n this.#emitResize({\n width: this.#canvas.width,\n height: this.#canvas.height\n });\n\n return this.#offscreenCanvas;\n }\n\n #updateCachedRect() {\n if (this.#canvas) {\n this.#cachedRect = this.#canvas.getBoundingClientRect();\n }\n }\n\n #initializeListeners() {\n if (!this.#canvas) return;\n\n this.#updateCachedRect();\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target !== this.#canvas) {\n continue;\n }\n const { width, height } = entry.contentRect;\n this.#emitResize({\n width: width,\n height: height\n });\n }\n this.#updateCachedRect();\n });\n this.#resizeObserver.observe(this.#canvas);\n\n document.addEventListener('wheel', this.#handleScroll, { passive: false });\n document.addEventListener('pointermove', this.#handleMove);\n document.addEventListener('pointerdown', this.#handleDown);\n document.addEventListener('pointerup', this.#handleUp);\n document.addEventListener('pointercancel', this.#handleUp);\n document.addEventListener('dblclick', this.#handleDblClick);\n }\n\n #removeListeners() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n\n document.removeEventListener('wheel', this.#handleScroll);\n document.removeEventListener('pointermove', this.#handleMove);\n document.removeEventListener('pointerdown', this.#handleDown);\n document.removeEventListener('pointerup', this.#handleUp);\n document.removeEventListener('pointercancel', this.#handleUp);\n document.removeEventListener('dblclick', this.#handleDblClick);\n }\n\n #handleScroll = (event) => {\n if (event.target !== this.#canvas) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n \n if (event.ctrlKey) {\n const normalized = this.#normalizeEvent(event, 'zoom');\n this.#emit(normalized);\n } else {\n const normalized = this.#normalizeEvent(event, 'scroll');\n this.#emit(normalized);\n }\n }\n\n #handleMove = (event) => {\n // Store latest raw event and throttle with RAF\n this.#pendingMove = event;\n if (this.#rafId) return;\n \n this.#rafId = requestAnimationFrame(() => {\n if (this.#pendingMove) {\n const rawEvent = this.#pendingMove;\n this.#pendingMove = null;\n \n // Determine event type based on state\n let type = 'move';\n const position = this.#getPosition(rawEvent);\n \n // Check for drag start\n if (this.#state.isPressed && !this.#state.isDragging) {\n const dx = position.x - this.#state.dragStartX;\n const dy = position.y - this.#state.dragStartY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n if (distance > this.#state.dragThreshold) {\n this.#state.isDragging = true;\n type = 'dragstart';\n }\n } else if (this.#state.isDragging) {\n type = 'drag';\n }\n \n const normalized = this.#normalizeEvent(rawEvent, type);\n this.#emit(normalized);\n }\n this.#rafId = null;\n });\n }\n\n #handleDown = (event) => {\n // Only capture if starting on canvas\n if (event.target === this.#canvas) {\n const position = this.#getPosition(event);\n \n // Update state\n this.#state.isPressed = true;\n this.#state.button = event.button ?? null;\n this.#state.dragStartX = position.x;\n this.#state.dragStartY = position.y;\n this.#state.isDragging = false;\n \n const normalized = this.#normalizeEvent(event, 'down');\n this.#emit(normalized); // Immediate\n }\n }\n\n #handleUp = (event) => {\n // Emit dragend if we were dragging\n if (this.#state.isDragging) {\n const dragend = this.#normalizeEvent(event, 'dragend');\n this.#emit(dragend);\n }\n \n // Always emit up event\n const normalized = this.#normalizeEvent(event, 'up');\n this.#emit(normalized); // Immediate\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.isDragging = false;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n }\n\n #handleDblClick = (event) => {\n const normalized = this.#normalizeEvent(event, 'dblclick');\n this.#emit(normalized);\n }\n\n #emit(event) {\n for (const subscriber of this.#subscribers) {\n subscriber(event);\n }\n }\n\n #emitResize(resizeData) {\n for (const subscriber of this.#resizeSubscribers) {\n subscriber(resizeData);\n }\n }\n\n #getPosition(event) {\n const isOverCanvas = event.target === this.#canvas;\n \n let x, y;\n if (isOverCanvas) {\n x = event.offsetX;\n y = event.offsetY;\n } else if (this.#cachedRect) {\n x = event.clientX - this.#cachedRect.left;\n y = event.clientY - this.#cachedRect.top;\n } else {\n x = event.clientX;\n y = event.clientY;\n }\n \n return { x, y, isOverCanvas };\n }\n\n #normalizeEvent(event, type) {\n const { x, y, isOverCanvas } = this.#getPosition(event);\n\n const isWithinBounds = isOverCanvas || (\n this.#cachedRect &&\n x >= 0 && \n x <= this.#cachedRect.width && \n y >= 0 && \n y <= this.#cachedRect.height\n );\n \n // Calculate deltas based on event type\n let deltaX = 0;\n let deltaY = 0;\n let deltaZ = 0;\n let deltaMode = 0;\n \n if (type === 'scroll') {\n // Scroll events use wheel deltas\n deltaX = event.deltaX;\n deltaY = event.deltaY;\n deltaZ = event.deltaZ;\n deltaMode = event.deltaMode;\n } else if (type === 'zoom') {\n // Zoom uses simplified delta\n deltaX = 0;\n deltaY = event.deltaY;\n deltaZ = 0;\n } else if (type === 'move' || type === 'drag' || type === 'dragstart') {\n // Position-based events calculate deltas from previous position\n if (this.#state.prevX !== null && this.#state.prevY !== null) {\n deltaX = x - this.#state.prevX;\n deltaY = y - this.#state.prevY;\n }\n }\n \n // Calculate drag distance if dragging\n let dragDistance = 0;\n if (this.#state.isDragging && this.#state.dragStartX !== null && this.#state.dragStartY !== null) {\n const dx = x - this.#state.dragStartX;\n const dy = y - this.#state.dragStartY;\n dragDistance = Math.sqrt(dx * dx + dy * dy);\n }\n\n const normalized = {\n // Position\n x,\n y,\n clientX: event.clientX,\n clientY: event.clientY,\n prevX: this.#state.prevX,\n prevY: this.#state.prevY,\n \n // Event metadata\n type,\n timestamp: Date.now(),\n isOverCanvas,\n isWithinBounds,\n \n // Deltas (appropriate to event type)\n deltaX,\n deltaY,\n deltaZ,\n deltaMode,\n \n // Button state\n button: event.button ?? this.#state.button,\n buttons: event.buttons ?? 0,\n isPressed: this.#state.isPressed,\n \n // Drag state\n isDragging: this.#state.isDragging,\n dragStartX: this.#state.dragStartX,\n dragStartY: this.#state.dragStartY,\n dragDistance,\n \n // Modifiers\n shiftKey: event.shiftKey || false,\n ctrlKey: event.ctrlKey || false,\n altKey: event.altKey || false,\n metaKey: event.metaKey || false\n };\n \n // Update previous position for next delta calculation\n this.#state.prevX = x;\n this.#state.prevY = y;\n\n return normalized;\n }\n\n destroy() {\n if (this.#rafId) {\n cancelAnimationFrame(this.#rafId);\n this.#rafId = null;\n }\n this.#removeListeners();\n this.#canvas = null;\n this.#offscreenCanvas = null;\n this.#cachedRect = null;\n this.#subscribers.clear();\n this.#resizeSubscribers.clear();\n this.#hasTransferredControl = false;\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.button = null;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n this.#state.isDragging = false;\n this.#state.prevX = null;\n this.#state.prevY = null;\n }\n}\n", "import { defineSurface } from '@jucie.io/reactive';\n\nexport const usePointerSurface = defineSurface((setup) => {\n // Current normalized event from CanvasEvents\n const event = setup.signal(null);\n \n // Hit registry integration (still managed here)\n const hoveredArea = setup.signal(null);\n const activeArea = setup.signal(null);\n \n // Main handler - just stores the event\n const handleEvent = setup.action((_, normalizedEvent) => {\n event(normalizedEvent);\n });\n \n const setHoveredArea = setup.action((_, area) => {\n hoveredArea(area);\n });\n \n const setActiveArea = setup.action((_, area) => {\n activeArea(area);\n });\n \n const reset = setup.action(() => {\n event(null);\n hoveredArea(null);\n activeArea(null);\n });\n \n return {\n // Signals\n event,\n hoveredArea,\n activeArea,\n\n // Actions\n handleEvent,\n setHoveredArea,\n setActiveArea,\n reset\n };\n});\n", "import { ServiceProvider } from '@jucie.io/engine';\nimport { ContextTypes } from './ContextTypes.js';\nimport { createComputed, destroyComputed, addEffect } from '@jucie.io/reactive';\nimport { createDefinition, definitionType } from '@jucie.io/engine';\nimport { HitRegistry } from './HitRegistry.js';\nimport { CanvasEvents } from './CanvasEvents.js';\nimport { usePointerSurface } from './usePointerSurface.js';\n\nexport const defineBrush = createDefinition('BRUSH', [Object]);\nexport const defineLayer = createDefinition('LAYER', [Object]);\n\nexport class Painter extends ServiceProvider {\n #layers = new Map();\n #canvas = null; // Always OffscreenCanvas\n #contexts = new Map();\n #assets = new Map();\n #isRunning = false;\n #frameId = null;\n #isRendering = false;\n #renderScheduled = false;\n\n // Mutable runtime config (separate from frozen config)\n #runtimeConfig = {\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n };\n\n // Timing state\n #timing = {\n lastFrameTime: 0,\n deltaTime: 0,\n elapsedTime: 0,\n frameCount: 0\n };\n\n // Debug metrics\n #metrics = {\n fps: 0,\n frameTime: 0,\n layerTimes: new Map(),\n brushTimes: new Map(),\n skippedFrames: 0\n };\n\n // Hit detection state\n #hitRegistry = new HitRegistry();\n #pointerSurface = usePointerSurface();\n #canvasEvents = null; // Only created in main thread mode\n #pointerUnsubscribe = null;\n #resizeObserver = null; // For main thread canvas resize watching\n #subscribers = new Map(); // Map<event, Set<callback>>\n \n // Track state for event emission\n #wasOverCanvas = false;\n\n static manifest = {\n name: 'Painter',\n namespace: 'painter',\n version: '1.0.0',\n defaults: {\n // Timing configuration\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n // Debug configuration\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n }\n };\n\n getters () {\n return {\n pointer: () => this.#pointerSurface,\n };\n }\n\n actions() {\n // Initialize runtime config from frozen config\n if (this.config) {\n Object.assign(this.#runtimeConfig, this.config);\n }\n \n return {\n addLayer: (layerDef) => this.addLayer(layerDef),\n addLayers: (...layers) => {\n for (const layer of layers) {\n this.addLayer(layer);\n }\n },\n updateCanvas: (fn) => this.updateCanvas(fn),\n setCanvas: (canvas) => this.setCanvas(canvas),\n setOffscreenCanvas: (offscreenCanvas) => this.setOffscreenCanvas(offscreenCanvas),\n setAssets: (assets) => this.setAssets(assets),\n removeLayer: (name) => this.removeLayer(name),\n start: () => this.start(),\n stop: () => this.stop(),\n render: () => this.render(),\n setTargetFPS: (fps) => this.setTargetFPS(fps),\n setTimeScale: (scale) => this.setTimeScale(scale),\n setFixedTimeStep: (step) => this.setFixedTimeStep(step),\n setDebug: (options) => this.setDebug(options),\n getMetrics: () => this.getMetrics(),\n handleResize: (width, height) => this.handleResize(width, height),\n subscribe: (event, callback) => this.subscribe(event, callback),\n // Pointer API - receives normalized events from main thread\n handlePointerEvent: (normalizedEvent) => this.handlePointerEvent(normalizedEvent),\n subscribeToPointer: (callback) => this.#pointerSurface.$subscribe(callback),\n bindPointer: (path) => this.#pointerSurface.$bind(path),\n // Test helper - only for testing\n _testEmitPointerEvent: (normalizedEvent) => this._testEmitPointerEvent(normalizedEvent)\n };\n }\n\n // Main thread mode: Pass regular canvas, we create OffscreenCanvas + CanvasEvents\n setCanvas(canvas) {\n // Store reference to DOM canvas for resize observation\n const domCanvas = canvas;\n \n // Transfer control to offscreen\n const offscreenCanvas = canvas.transferControlToOffscreen();\n \n // Set initial dimensions\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Create and set up canvas events (main thread only)\n if (!this.#canvasEvents) {\n this.#canvasEvents = new CanvasEvents();\n }\n \n this.#canvasEvents.setCanvas(domCanvas);\n\n // Watch for canvas resizes and sync to offscreen canvas\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n \n this.#resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry && entry.target === domCanvas) {\n // Sync dimensions to offscreen canvas\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n // Notify layers of resize\n this.handleResize(domCanvas.width, domCanvas.height);\n }\n });\n \n this.#resizeObserver.observe(domCanvas);\n\n // Connect canvas events to surface\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n }\n\n this.#pointerUnsubscribe = this.#canvasEvents.subscribe((normalizedEvent) => {\n this.handlePointerEvent(normalizedEvent);\n });\n }\n\n // Worker thread mode: Accept pre-created OffscreenCanvas, expect external events\n setOffscreenCanvas(offscreenCanvas) {\n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Don't create CanvasEvents - events will come from external source\n // via handlePointerEvent()\n }\n\n updateCanvas(fn) {\n const result = fn(this.#canvas);\n if (result) {\n this.#canvas = result;\n }\n }\n\n setAssets(assets) {\n this.#assets = assets;\n }\n\n start() {\n if (!this.#isRunning) {\n this.#isRunning = true;\n this.#scheduleRender();\n }\n }\n\n stop() {\n if (this.#isRunning) {\n this.#isRunning = false;\n if (this.#frameId) {\n cancelAnimationFrame(this.#frameId);\n this.#frameId = null;\n }\n }\n }\n\n addLayer(layerDef) {\n if (definitionType(layerDef) !== 'LAYER') {\n throw new Error('Invalid layer definition');\n }\n\n const name = layerDef._name;\n const config = layerDef(this.useContext, this.#hitRegistry);\n\n const layer = {...config, name, context: this.#contexts.get(config.context || '2d') };\n \n // Set up layer computed if it has data paths\n if (config.data) {\n layer.dataReactor = this.#createReactor(config.data, () => this.#pointerSurface);\n }\n\n // Set up when reactor if layer has condition\n if (config.when) {\n layer.whenReactor = this.#createReactor(config.when, () => (layer?.dataReactor?.computed() || undefined));\n }\n\n // Set up brush reactors and structure\n layer.brushes = config.children.map(child => {\n if (definitionType(child) === 'BRUSH') {\n const name = child._name;\n const brushConfig = child(this.useContext, this.#hitRegistry);\n const brush = {\n name,\n ...brushConfig\n };\n\n if (brushConfig.data) {\n brush.dataReactor = this.#createReactor(brushConfig.data, () => this.#pointerSurface);\n }\n\n if (brushConfig.when) {\n brush.whenReactor = this.#createReactor(brushConfig.when, () => (brush?.dataReactor?.computed() || undefined));\n }\n\n // Call brush mount hook\n if (brush.lifecycle?.onMount) {\n try {\n brush.lifecycle.onMount(this.#contexts.get(brush.context || config.context));\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onMount:`, error);\n }\n }\n\n return brush;\n }\n \n // Handle nested layers recursively\n if (definitionType(child) === 'LAYER') { \n return this.addLayer(child);\n }\n\n return child;\n });\n\n \n\n this.#layers.set(name, layer);\n\n // Call layer mount hook\n if (layer.lifecycle?.onMount) {\n try {\n layer.lifecycle.onMount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onMount:`, error);\n }\n }\n\n return layer;\n }\n\n removeLayer(name) {\n const layer = this.#layers.get(name);\n if (!layer) return;\n\n // Call layer unmount hook\n if (layer.lifecycle?.onUnmount) {\n try {\n layer.lifecycle.onUnmount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onUnmount:`, error);\n }\n }\n\n // Call brush unmount hooks and clean up reactors\n layer.brushes.forEach(brush => {\n if (brush.lifecycle?.onUnmount) {\n try {\n brush.lifecycle.onUnmount(\n this.#contexts.get(brush.context || layer.context)\n );\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onUnmount:`, error);\n }\n }\n // Clean up brush when reactor\n if (brush.whenReactor) {\n destroyComputed(brush.whenReactor);\n }\n // Clean up brush computed and subscription\n if (brush.dataReactor) {\n brush.dataReactor?.unsubscribe();\n if (brush.dataReactor?.computed) {\n destroyComputed(brush.dataReactor.computed);\n }\n }\n });\n\n // Clean up layer when reactor\n if (layer.whenReactor) {\n layer.whenReactor?.unsubscribe();\n if (layer.whenReactor?.computed) {\n destroyComputed(layer.whenReactor.computed);\n }\n }\n\n this.#layers.delete(name);\n }\n\n #scheduleRender() {\n if (this.#renderScheduled || this.#isRendering) return;\n \n this.#renderScheduled = true;\n \n this.#frameId = requestAnimationFrame(() => {\n this.#renderScheduled = false;\n this.#frameId = null;\n this.#render();\n });\n }\n\n async #render() {\n if (!this.#canvas) return;\n this.#isRendering = true;\n \n try {\n // Clear hit registry at start of render\n this.#hitRegistry.clear();\n \n const renderStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Clear all contexts\n this.#contexts.forEach(ctx => {\n ctx.clearRect(0, 0, this.#canvas.width, this.#canvas.height);\n });\n\n // Render layers in order\n for (const layer of this.#layers.values()) {\n const layerStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Check layer condition\n if (layer.whenReactor && !layer.whenReactor.computed()) continue;\n\n const ctx = layer.context;\n\n if (!ctx) continue;\n\n // Layer beforeRender hook\n if (layer.lifecycle?.beforeRender) {\n try {\n layer.lifecycle.beforeRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" beforeRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n // Apply layer settings\n ctx.save();\n if (layer.settings) {\n Object.entries(layer.settings).forEach(([key, value]) => {\n if (typeof ctx[key] === 'function') {\n ctx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n ctx[key] = value;\n }\n });\n }\n\n // Render brushes\n for (const brush of layer.brushes) {\n const brushStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n if (brush.whenReactor && !brush.whenReactor.computed()) continue;\n\n\n const brushCtx = brush.context ? \n this.#contexts.get(brush.context) : \n ctx;\n\n if (!brushCtx) continue;\n\n // Brush beforeRender hook\n if (brush.lifecycle?.beforeRender) {\n try {\n brush.lifecycle.beforeRender(brushCtx, this.#timing);\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" beforeRender:`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n continue;\n }\n }\n\n brushCtx.save();\n \n if (brush.settings) {\n Object.entries(brush.settings).forEach(([key, value]) => {\n if (typeof brushCtx[key] === 'function') {\n brushCtx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n brushCtx[key] = value;\n }\n });\n }\n \n try {\n const requiredAssets = {};\n if (brush.assets) {\n for (const key of brush.assets) {\n requiredAssets[key] = this.#assets.get(key);\n }\n }\n brush.render(brushCtx, (brush.dataReactor ? brush.dataReactor.computed() : undefined), requiredAssets, this.#timing);\n\n // Brush afterRender hook\n if (brush.lifecycle?.afterRender) {\n brush.lifecycle.afterRender(brushCtx, this.#timing);\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const brushTime = performance.now() - brushStart;\n this.#metrics.brushTimes.set(brush.name, brushTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderBrushBounds(brushCtx, brush);\n }\n }\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\":`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n } finally {\n brushCtx.restore();\n }\n }\n\n ctx.restore();\n\n // Layer afterRender hook\n if (layer.lifecycle?.afterRender) {\n try {\n layer.lifecycle.afterRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" afterRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const layerTime = performance.now() - layerStart;\n this.#metrics.layerTimes.set(layer.name, layerTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderLayerBounds(ctx, layer);\n }\n }\n }\n\n // Render debug overlay if enabled\n if (this.#runtimeConfig.debug?.enabled) {\n this.#renderDebugOverlay();\n }\n \n } finally {\n this.#isRendering = false;\n }\n }\n\n #renderBrushBounds(ctx, brush) {\n ctx.save();\n ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';\n ctx.lineWidth = 1;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderLayerBounds(ctx, layer) {\n ctx.save();\n ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';\n ctx.lineWidth = 2;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderDebugOverlay() {\n const ctx = this.#contexts.get(ContextTypes['2D']);\n if (!ctx) return;\n\n ctx.save();\n ctx.resetTransform();\n ctx.font = '12px monospace';\n ctx.fillStyle = 'white';\n ctx.strokeStyle = 'black';\n ctx.lineWidth = 3;\n\n let y = 20;\n const lineHeight = 15;\n\n if (this.#runtimeConfig.debug?.showFPS) {\n const text = `FPS: ${Math.round(this.#metrics.fps)} (${this.#timing.deltaTime.toFixed(2)}ms)`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n if (this.#runtimeConfig.debug?.showLayerTiming) {\n ctx.fillText('Layer Times:', 10, y);\n y += lineHeight;\n\n for (const [name, time] of this.#metrics.layerTimes) {\n const text = ` ${name}: ${time.toFixed(2)}ms`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n ctx.fillText(this.state.get(['_transitions', 'pointer', 'currentState']), 10, y);\n }\n\n ctx.restore();\n }\n\n handleResize(width, height) {\n // Call onResize hooks for all layers\n for (const layer of this.#layers.values()) {\n if (layer.lifecycle?.onResize) {\n try {\n layer.lifecycle.onResize(width, height, layer.context);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" onResize:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n }\n }\n\n #createReactor(fn, context = () => undefined) {\n if (!fn) return null;\n \n const computed = createComputed(fn, {\n immediate: true,\n context\n });\n \n const unsubscribe = addEffect(computed, () => this.#scheduleRender());\n \n return {computed, unsubscribe};\n }\n\n destroy() {\n this.stop();\n\n // Clean up pointer system\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n this.#pointerUnsubscribe = null;\n }\n if (this.#canvasEvents) {\n this.#canvasEvents.destroy();\n this.#canvasEvents = null;\n }\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n if (this.#pointerSurface) {\n this.#pointerSurface.$destroy();\n }\n\n // Clean up all layers and reactors\n for (const name of this.#layers.keys()) {\n this.removeLayer(name);\n }\n }\n\n setTargetFPS(fps) {\n this.#runtimeConfig.targetFPS = fps;\n this.#runtimeConfig.fixedTimeStep = 1000 / fps;\n }\n\n setTimeScale(scale) {\n this.#runtimeConfig.timeScale = Math.max(0, scale);\n }\n\n setFixedTimeStep(step) {\n this.#runtimeConfig.fixedTimeStep = step;\n }\n\n setDebug(options = {}) {\n if (!this.#runtimeConfig.debug) {\n this.#runtimeConfig.debug = {};\n }\n Object.assign(this.#runtimeConfig.debug, options);\n }\n\n getMetrics() {\n return {\n ...this.#metrics,\n deltaTime: this.#timing.deltaTime,\n elapsedTime: this.#timing.elapsedTime,\n frameCount: this.#timing.frameCount\n };\n }\n\n // Public method to receive pointer events from main thread\n handlePointerEvent(normalizedEvent) {\n // Feed normalized events into surface\n this.#pointerSurface.handleEvent(normalizedEvent);\n\n // Handle hit testing and interactions\n this.#handlePointerInteraction(normalizedEvent);\n \n // Emit generic pointer events for external subscribers\n this.#emitPointerEvents(normalizedEvent);\n }\n\n #emitPointerEvents(normalizedEvent) {\n const { type } = normalizedEvent;\n const pointer = this.#pointerSurface;\n const event = pointer.event;\n \n // Emit basic pointer events\n switch (type) {\n case 'down':\n this.#emit('pointer:down', pointer);\n break;\n \n case 'up':\n this.#emit('pointer:up', pointer);\n \n // Emit click if it wasn't a drag\n if (event && !event.isDragging) {\n this.#emit('pointer:click', pointer);\n }\n break;\n \n case 'move':\n this.#emit('pointer:move', pointer);\n break;\n \n case 'dragstart':\n this.#emit('pointer:drag:start', pointer);\n break;\n \n case 'drag':\n this.#emit('pointer:drag:move', pointer);\n break;\n \n case 'dragend':\n this.#emit('pointer:drag:end', pointer);\n break;\n \n case 'scroll':\n this.#emit('pointer:scroll', pointer);\n break;\n \n case 'zoom':\n this.#emit('pointer:zoom', pointer);\n break;\n \n case 'dblclick':\n this.#emit('pointer:dblclick', pointer);\n break;\n }\n \n // Check for canvas enter/leave\n const wasOverCanvas = this.#wasOverCanvas;\n const isOverCanvas = event?.isOverCanvas || false;\n \n if (isOverCanvas && !wasOverCanvas) {\n this.#emit('pointer:enter', pointer);\n } else if (!isOverCanvas && wasOverCanvas) {\n this.#emit('pointer:leave', pointer);\n }\n \n this.#wasOverCanvas = isOverCanvas;\n }\n\n #handlePointerInteraction(normalizedEvent) {\n const { type, x, y } = normalizedEvent;\n const pointer = this.#pointerSurface;\n\n switch (type) {\n case 'down': {\n const hitArea = this.#hitTest(x, y);\n pointer.setActiveArea(hitArea);\n\n if (hitArea?.onPointerDown?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerDown.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'up': {\n const activeArea = pointer.activeArea;\n if (activeArea?.onPointerUp?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onPointerUp.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'move': {\n const hitArea = this.#hitTest(x, y);\n const prevHovered = pointer.hoveredArea;\n\n // Handle pointer move on hovered area (only when NOT dragging)\n if (hitArea?.onPointerMove?.handler && !normalizedEvent.isDragging) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerMove.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n // Handle hover changes\n if (hitArea?.id !== prevHovered?.id) {\n if (prevHovered?.onPointerLeave?.handler) {\n const ctx = this.#getContextForArea(prevHovered);\n prevHovered.onPointerLeave.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n if (hitArea?.onPointerEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerEnter.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n pointer.setHoveredArea(hitArea);\n }\n break;\n }\n\n case 'dragstart': {\n const activeArea = pointer.activeArea;\n if (activeArea?.onDragStart?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onDragStart.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'drag': {\n const activeArea = pointer.activeArea;\n if (activeArea?.onDragMove?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onDragMove.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'dragend': {\n const activeArea = pointer.activeArea;\n if (activeArea?.onDragEnd?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onDragEnd.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'dblclick':\n const hitArea = this.#hitTest(x, y);\n pointer.setActiveArea(hitArea);\n\n if (hitArea?.onPointerDblClick?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerDblClick.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n }\n\n #getContextForArea(area) {\n if (!area) return null;\n return area.context \n ? this.#contexts.get(area.context) \n : this.#contexts.get(ContextTypes['2D']);\n }\n\n subscribe(event, callback) {\n if (!this.#subscribers.has(event)) {\n this.#subscribers.set(event, new Set());\n }\n this.#subscribers.get(event).add(callback);\n \n return () => {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) {\n this.#subscribers.delete(event);\n }\n }\n };\n }\n\n #hitTest(x, y) {\n // Sort by priority (highest first) and test\n const sorted = this.#hitRegistry.areas.sort((a, b) => \n (b.priority || 0) - (a.priority || 0)\n );\n \n for (const area of sorted) {\n if (this.#isPointInBounds(x, y, area.bounds)) {\n return area;\n }\n }\n return null;\n }\n\n #isPointInBounds(x, y, bounds) {\n return x >= bounds.x && \n x <= bounds.x + bounds.width &&\n y >= bounds.y && \n y <= bounds.y + bounds.height;\n }\n\n #emit(event, data) {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n for (const callback of callbacks) {\n callback(data);\n }\n }\n }\n\n // Test helper - only for testing, simulates normalized pointer events\n _testEmitPointerEvent(normalizedEvent) {\n this.#pointerSurface.handleEvent(normalizedEvent);\n this.#handlePointerInteraction(normalizedEvent);\n }\n}"],
|
|
5
|
-
"mappings": "AAAO,IAAMA,EAAe,CAC1B,KAAM,KACN,MAAS,QACT,OAAU,SACV,eAAkB,gBACpB,ECLO,IAAMC,EAAN,KAAkB,CACvBC,GAAS,IAAI,IAEb,SAASC,EAAIC,EAAM,CACjB,GAAI,CAACD,EACH,MAAM,IAAI,MAAM,0BAA0B,EAE5C,YAAKD,GAAO,IAAIC,EAAI,CAAE,GAAAA,EAAI,GAAGC,CAAK,CAAC,EAC5B,IAAM,KAAK,WAAWD,CAAE,CACjC,CAEA,WAAWA,EAAI,CACb,KAAKD,GAAO,OAAOC,CAAE,CACvB,CAEA,IAAIA,EAAI,CACN,OAAO,KAAKD,GAAO,IAAIC,CAAE,CAC3B,CAEA,IAAIA,EAAI,CACN,OAAO,KAAKD,GAAO,IAAIC,CAAE,CAC3B,CAEA,IAAI,OAAQ,CACV,OAAO,MAAM,KAAK,KAAKD,GAAO,OAAO,CAAC,CACxC,CAEA,OAAQ,CACN,KAAKA,GAAO,MAAM,CACpB,CACF,EC9BA,OAAS,mBAAAG,MAAuB,mBAEzB,IAAMC,EAAN,cAA2BD,CAAgB,CAChDE,GAAU,KACVC,GAAmB,KACnBC,GAAc,KACdC,GAAkB,KAClBC,GAAe,IAAI,IACnBC,GAAqB,IAAI,IACzBC,GAAe,KACfC,GAAS,KACTC,GAAyB,GAGzBC,GAAS,CACP,UAAW,GACX,OAAQ,KACR,WAAY,KACZ,WAAY,KACZ,WAAY,GACZ,cAAe,EACf,MAAO,KACP,MAAO,IACT,EAEA,OAAO,SAAW,CAChB,KAAM,eACN,UAAW,eACX,QAAS,OACX,EAEA,SAAU,CACR,MAAO,CACL,UAAYC,GAAW,KAAK,UAAUA,CAAM,EAC5C,UAAYC,GAAa,KAAK,UAAUA,CAAQ,EAChD,SAAWA,GAAa,KAAK,SAASA,CAAQ,EAC9C,2BAA4B,IAAM,KAAK,2BAA2B,CACpE,CACF,CAEA,UAAUD,EAAQ,CACZ,KAAKV,IACP,KAAKY,GAAiB,EAGxB,KAAKZ,GAAUU,EACf,KAAKG,GAAkB,EACvB,KAAKC,GAAqB,CAC5B,CAEA,UAAUC,EAAY,CACpB,YAAKX,GAAa,IAAIW,CAAU,EACzB,IAAM,KAAKX,GAAa,OAAOW,CAAU,CAClD,CAEA,SAASA,EAAY,CACnB,YAAKV,GAAmB,IAAIU,CAAU,EAC/B,IAAM,KAAKV,GAAmB,OAAOU,CAAU,CACxD,CAEA,4BAA6B,CAC3B,GAAI,CAAC,KAAKf,GACR,MAAM,IAAI,MAAM,6DAA6D,EAG/E,GAAI,KAAKQ,GACP,MAAM,IAAI,MAAM,mDAAmD,EAIrE,YAAKP,GAAmB,KAAKD,GAAQ,2BAA2B,EAChE,KAAKQ,GAAyB,GAK9B,KAAKP,GAAiB,MAAQ,KAAKC,GAAY,MAC/C,KAAKD,GAAiB,OAAS,KAAKC,GAAY,OAGhD,KAAKc,GAAY,CACf,MAAO,KAAKhB,GAAQ,MACpB,OAAQ,KAAKA,GAAQ,MACvB,CAAC,EAEM,KAAKC,EACd,CAEAY,IAAoB,CACd,KAAKb,KACP,KAAKE,GAAc,KAAKF,GAAQ,sBAAsB,EAE1D,CAEAc,IAAuB,CAChB,KAAKd,KAEV,KAAKa,GAAkB,EAEvB,KAAKV,GAAkB,IAAI,eAAgBc,GAAY,CACrD,QAAWC,KAASD,EAAS,CAC3B,GAAIC,EAAM,SAAW,KAAKlB,GACxB,SAEF,GAAM,CAAE,MAAAmB,EAAO,OAAAC,CAAO,EAAIF,EAAM,YAChC,KAAKF,GAAY,CACf,MAAOG,EACP,OAAQC,CACV,CAAC,CACH,CACA,KAAKP,GAAkB,CACzB,CAAC,EACD,KAAKV,GAAgB,QAAQ,KAAKH,EAAO,EAEzC,SAAS,iBAAiB,QAAS,KAAKqB,GAAe,CAAE,QAAS,EAAM,CAAC,EACzE,SAAS,iBAAiB,cAAe,KAAKC,EAAW,EACzD,SAAS,iBAAiB,cAAe,KAAKC,EAAW,EACzD,SAAS,iBAAiB,YAAa,KAAKC,EAAS,EACrD,SAAS,iBAAiB,gBAAiB,KAAKA,EAAS,EACzD,SAAS,iBAAiB,WAAY,KAAKC,EAAe,EAC5D,CAEAb,IAAmB,CACb,KAAKT,KACP,KAAKA,GAAgB,WAAW,EAChC,KAAKA,GAAkB,MAGzB,SAAS,oBAAoB,QAAS,KAAKkB,EAAa,EACxD,SAAS,oBAAoB,cAAe,KAAKC,EAAW,EAC5D,SAAS,oBAAoB,cAAe,KAAKC,EAAW,EAC5D,SAAS,oBAAoB,YAAa,KAAKC,EAAS,EACxD,SAAS,oBAAoB,gBAAiB,KAAKA,EAAS,EAC5D,SAAS,oBAAoB,WAAY,KAAKC,EAAe,CAC/D,CAEAJ,GAAiBK,GAAU,CACzB,GAAIA,EAAM,SAAW,KAAK1B,GAO1B,GAHA0B,EAAM,eAAe,EACrBA,EAAM,gBAAgB,EAElBA,EAAM,QAAS,CACjB,IAAMC,EAAa,KAAKC,GAAgBF,EAAO,MAAM,EACrD,KAAKG,GAAMF,CAAU,CACvB,KAAO,CACL,IAAMA,EAAa,KAAKC,GAAgBF,EAAO,QAAQ,EACvD,KAAKG,GAAMF,CAAU,CACvB,CACF,EAEAL,GAAeI,GAAU,CAEvB,KAAKpB,GAAeoB,EAChB,MAAKnB,KAET,KAAKA,GAAS,sBAAsB,IAAM,CACxC,GAAI,KAAKD,GAAc,CACrB,IAAMwB,EAAW,KAAKxB,GACtB,KAAKA,GAAe,KAGpB,IAAIyB,EAAO,OACLC,EAAW,KAAKC,GAAaH,CAAQ,EAG3C,GAAI,KAAKrB,GAAO,WAAa,CAAC,KAAKA,GAAO,WAAY,CACpD,IAAMyB,EAAKF,EAAS,EAAI,KAAKvB,GAAO,WAC9B0B,EAAKH,EAAS,EAAI,KAAKvB,GAAO,WACnB,KAAK,KAAKyB,EAAKA,EAAKC,EAAKA,CAAE,EAE7B,KAAK1B,GAAO,gBACzB,KAAKA,GAAO,WAAa,GACzBsB,EAAO,YAEX,MAAW,KAAKtB,GAAO,aACrBsB,EAAO,QAGT,IAAMJ,EAAa,KAAKC,GAAgBE,EAAUC,CAAI,EACtD,KAAKF,GAAMF,CAAU,CACvB,CACA,KAAKpB,GAAS,IAChB,CAAC,EACH,EAEAgB,GAAeG,GAAU,CAEvB,GAAIA,EAAM,SAAW,KAAK1B,GAAS,CACjC,IAAMgC,EAAW,KAAKC,GAAaP,CAAK,EAGxC,KAAKjB,GAAO,UAAY,GACxB,KAAKA,GAAO,OAASiB,EAAM,QAAU,KACrC,KAAKjB,GAAO,WAAauB,EAAS,EAClC,KAAKvB,GAAO,WAAauB,EAAS,EAClC,KAAKvB,GAAO,WAAa,GAEzB,IAAMkB,EAAa,KAAKC,GAAgBF,EAAO,MAAM,EACrD,KAAKG,GAAMF,CAAU,CACvB,CACF,EAEAH,GAAaE,GAAU,CAErB,GAAI,KAAKjB,GAAO,WAAY,CAC1B,IAAM2B,EAAU,KAAKR,GAAgBF,EAAO,SAAS,EACrD,KAAKG,GAAMO,CAAO,CACpB,CAGA,IAAMT,EAAa,KAAKC,GAAgBF,EAAO,IAAI,EACnD,KAAKG,GAAMF,CAAU,EAGrB,KAAKlB,GAAO,UAAY,GACxB,KAAKA,GAAO,WAAa,GACzB,KAAKA,GAAO,WAAa,KACzB,KAAKA,GAAO,WAAa,IAC3B,EAEAgB,GAAmBC,GAAU,CAC3B,IAAMC,EAAa,KAAKC,GAAgBF,EAAO,UAAU,EACzD,KAAKG,GAAMF,CAAU,CACvB,EAEAE,GAAMH,EAAO,CACX,QAAWX,KAAc,KAAKX,GAC5BW,EAAWW,CAAK,CAEpB,CAEAV,GAAYqB,EAAY,CACtB,QAAWtB,KAAc,KAAKV,GAC5BU,EAAWsB,CAAU,CAEzB,CAEAJ,GAAaP,EAAO,CAClB,IAAMY,EAAeZ,EAAM,SAAW,KAAK1B,GAEvCuC,EAAGC,EACP,OAAIF,GACFC,EAAIb,EAAM,QACVc,EAAId,EAAM,SACD,KAAKxB,IACdqC,EAAIb,EAAM,QAAU,KAAKxB,GAAY,KACrCsC,EAAId,EAAM,QAAU,KAAKxB,GAAY,MAErCqC,EAAIb,EAAM,QACVc,EAAId,EAAM,SAGL,CAAE,EAAAa,EAAG,EAAAC,EAAG,aAAAF,CAAa,CAC9B,CAEAV,GAAgBF,EAAOK,EAAM,CAC3B,GAAM,CAAE,EAAAQ,EAAG,EAAAC,EAAG,aAAAF,CAAa,EAAI,KAAKL,GAAaP,CAAK,EAEhDe,EAAiBH,GACrB,KAAKpC,IACLqC,GAAK,GACLA,GAAK,KAAKrC,GAAY,OACtBsC,GAAK,GACLA,GAAK,KAAKtC,GAAY,OAIpBwC,EAAS,EACTC,EAAS,EACTC,EAAS,EACTC,EAAY,EAEZd,IAAS,UAEXW,EAAShB,EAAM,OACfiB,EAASjB,EAAM,OACfkB,EAASlB,EAAM,OACfmB,EAAYnB,EAAM,WACTK,IAAS,QAElBW,EAAS,EACTC,EAASjB,EAAM,OACfkB,EAAS,IACAb,IAAS,QAAUA,IAAS,QAAUA,IAAS,cAEpD,KAAKtB,GAAO,QAAU,MAAQ,KAAKA,GAAO,QAAU,OACtDiC,EAASH,EAAI,KAAK9B,GAAO,MACzBkC,EAASH,EAAI,KAAK/B,GAAO,OAK7B,IAAIqC,EAAe,EACnB,GAAI,KAAKrC,GAAO,YAAc,KAAKA,GAAO,aAAe,MAAQ,KAAKA,GAAO,aAAe,KAAM,CAChG,IAAMyB,EAAKK,EAAI,KAAK9B,GAAO,WACrB0B,EAAKK,EAAI,KAAK/B,GAAO,WAC3BqC,EAAe,KAAK,KAAKZ,EAAKA,EAAKC,EAAKA,CAAE,CAC5C,CAEA,IAAMR,EAAa,CAEjB,EAAAY,EACA,EAAAC,EACA,QAASd,EAAM,QACf,QAASA,EAAM,QACf,MAAO,KAAKjB,GAAO,MACnB,MAAO,KAAKA,GAAO,MAGnB,KAAAsB,EACA,UAAW,KAAK,IAAI,EACpB,aAAAO,EACA,eAAAG,EAGA,OAAAC,EACA,OAAAC,EACA,OAAAC,EACA,UAAAC,EAGA,OAAQnB,EAAM,QAAU,KAAKjB,GAAO,OACpC,QAASiB,EAAM,SAAW,EAC1B,UAAW,KAAKjB,GAAO,UAGvB,WAAY,KAAKA,GAAO,WACxB,WAAY,KAAKA,GAAO,WACxB,WAAY,KAAKA,GAAO,WACxB,aAAAqC,EAGA,SAAUpB,EAAM,UAAY,GAC5B,QAASA,EAAM,SAAW,GAC1B,OAAQA,EAAM,QAAU,GACxB,QAASA,EAAM,SAAW,EAC5B,EAGA,YAAKjB,GAAO,MAAQ8B,EACpB,KAAK9B,GAAO,MAAQ+B,EAEbb,CACT,CAEA,SAAU,CACJ,KAAKpB,KACP,qBAAqB,KAAKA,EAAM,EAChC,KAAKA,GAAS,MAEhB,KAAKK,GAAiB,EACtB,KAAKZ,GAAU,KACf,KAAKC,GAAmB,KACxB,KAAKC,GAAc,KACnB,KAAKE,GAAa,MAAM,EACxB,KAAKC,GAAmB,MAAM,EAC9B,KAAKG,GAAyB,GAG9B,KAAKC,GAAO,UAAY,GACxB,KAAKA,GAAO,OAAS,KACrB,KAAKA,GAAO,WAAa,KACzB,KAAKA,GAAO,WAAa,KACzB,KAAKA,GAAO,WAAa,GACzB,KAAKA,GAAO,MAAQ,KACpB,KAAKA,GAAO,MAAQ,IACtB,CACF,EClXA,OAAS,iBAAAsC,MAAqB,qBAEvB,IAAMC,EAAoBD,EAAeE,GAAU,CAExD,IAAMC,EAAQD,EAAM,OAAO,IAAI,EAGzBE,EAAcF,EAAM,OAAO,IAAI,EAC/BG,EAAaH,EAAM,OAAO,IAAI,EAG9BI,EAAcJ,EAAM,OAAO,CAACK,EAAGC,IAAoB,CACvDL,EAAMK,CAAe,CACvB,CAAC,EAEKC,EAAiBP,EAAM,OAAO,CAACK,EAAGG,IAAS,CAC/CN,EAAYM,CAAI,CAClB,CAAC,EAEKC,EAAgBT,EAAM,OAAO,CAACK,EAAGG,IAAS,CAC9CL,EAAWK,CAAI,CACjB,CAAC,EAEKE,EAAQV,EAAM,OAAO,IAAM,CAC/BC,EAAM,IAAI,EACVC,EAAY,IAAI,EAChBC,EAAW,IAAI,CACjB,CAAC,EAED,MAAO,CAEL,MAAAF,EACA,YAAAC,EACA,WAAAC,EAGA,YAAAC,EACA,eAAAG,EACA,cAAAE,EACA,MAAAC,CACF,CACF,CAAC,ECzCD,OAAS,mBAAAC,MAAuB,mBAEhC,OAAS,kBAAAC,EAAgB,mBAAAC,EAAiB,aAAAC,MAAiB,qBAC3D,OAAS,oBAAAC,EAAkB,kBAAAC,MAAsB,mBAK1C,IAAMC,EAAcF,EAAiB,QAAS,CAAC,MAAM,CAAC,EAChDG,EAAcH,EAAiB,QAAS,CAAC,MAAM,CAAC,EAEhDI,EAAN,cAAsBR,CAAgB,CAC3CS,GAAU,IAAI,IACdC,GAAU,KACVC,GAAY,IAAI,IAChBC,GAAU,IAAI,IACdC,GAAa,GACbC,GAAW,KACXC,GAAe,GACfC,GAAmB,GAGnBC,GAAiB,CACf,UAAW,GACX,cAAe,IAAO,GACtB,UAAW,EACX,MAAO,CACL,QAAS,GACT,QAAS,GACT,WAAY,GACZ,gBAAiB,EACnB,CACF,EAGAC,GAAU,CACR,cAAe,EACf,UAAW,EACX,YAAa,EACb,WAAY,CACd,EAGAC,GAAW,CACT,IAAK,EACL,UAAW,EACX,WAAY,IAAI,IAChB,WAAY,IAAI,IAChB,cAAe,CACjB,EAGAC,GAAe,IAAIC,EACnBC,GAAkBC,EAAkB,EACpCC,GAAgB,KAChBC,GAAsB,KACtBC,GAAkB,KAClBC,GAAe,IAAI,IAGnBC,GAAiB,GAEjB,OAAO,SAAW,CAChB,KAAM,UACN,UAAW,UACX,QAAS,QACT,SAAU,CAER,UAAW,GACX,cAAe,IAAO,GACtB,UAAW,EAEX,MAAO,CACL,QAAS,GACT,QAAS,GACT,WAAY,GACZ,gBAAiB,EACnB,CACF,CACF,EAEA,SAAW,CACT,MAAO,CACL,QAAS,IAAM,KAAKN,EACtB,CACF,CAEA,SAAU,CAER,OAAI,KAAK,QACP,OAAO,OAAO,KAAKL,GAAgB,KAAK,MAAM,EAGzC,CACL,SAAWY,GAAa,KAAK,SAASA,CAAQ,EAC9C,UAAW,IAAIC,IAAW,CACxB,QAAWC,KAASD,EAClB,KAAK,SAASC,CAAK,CAEvB,EACA,aAAeC,GAAO,KAAK,aAAaA,CAAE,EAC1C,UAAYC,GAAW,KAAK,UAAUA,CAAM,EAC5C,mBAAqBC,GAAoB,KAAK,mBAAmBA,CAAe,EAChF,UAAYC,GAAW,KAAK,UAAUA,CAAM,EAC5C,YAAcC,GAAS,KAAK,YAAYA,CAAI,EAC5C,MAAO,IAAM,KAAK,MAAM,EACxB,KAAM,IAAM,KAAK,KAAK,EACtB,OAAQ,IAAM,KAAK,OAAO,EAC1B,aAAeC,GAAQ,KAAK,aAAaA,CAAG,EAC5C,aAAeC,GAAU,KAAK,aAAaA,CAAK,EAChD,iBAAmBC,GAAS,KAAK,iBAAiBA,CAAI,EACtD,SAAWC,GAAY,KAAK,SAASA,CAAO,EAC5C,WAAY,IAAM,KAAK,WAAW,EAClC,aAAc,CAACC,EAAOC,IAAW,KAAK,aAAaD,EAAOC,CAAM,EAChE,UAAW,CAACC,EAAOC,IAAa,KAAK,UAAUD,EAAOC,CAAQ,EAE9D,mBAAqBC,GAAoB,KAAK,mBAAmBA,CAAe,EAChF,mBAAqBD,GAAa,KAAKtB,GAAgB,WAAWsB,CAAQ,EAC1E,YAAcE,GAAS,KAAKxB,GAAgB,MAAMwB,CAAI,EAEtD,sBAAwBD,GAAoB,KAAK,sBAAsBA,CAAe,CACxF,CACF,CAGA,UAAUZ,EAAQ,CAEhB,IAAMc,EAAYd,EAGZC,EAAkBD,EAAO,2BAA2B,EAG1DC,EAAgB,MAAQa,EAAU,MAClCb,EAAgB,OAASa,EAAU,OAEnC,KAAKrC,GAAUwB,EAGf,OAAO,OAAOc,CAAY,EAAE,QAAQC,GAAQ,CAC1C,GAAI,CACF,IAAMC,EAAMhB,EAAgB,WAAWe,CAAI,EACvCC,GAAK,KAAKvC,GAAU,IAAIsC,EAAMC,CAAG,CACvC,MAAY,CACV,QAAQ,KAAK,gBAAgBD,CAAI,gBAAgB,CACnD,CACF,CAAC,EAGI,KAAKzB,KACR,KAAKA,GAAgB,IAAI2B,GAG3B,KAAK3B,GAAc,UAAUuB,CAAS,EAGlC,KAAKrB,IACP,KAAKA,GAAgB,WAAW,EAGlC,KAAKA,GAAkB,IAAI,eAAgB0B,GAAY,CACrD,IAAMC,EAAQD,EAAQ,CAAC,EACnBC,GAASA,EAAM,SAAWN,IAE5Bb,EAAgB,MAAQa,EAAU,MAClCb,EAAgB,OAASa,EAAU,OAGnC,KAAK,aAAaA,EAAU,MAAOA,EAAU,MAAM,EAEvD,CAAC,EAED,KAAKrB,GAAgB,QAAQqB,CAAS,EAGlC,KAAKtB,IACP,KAAKA,GAAoB,EAG3B,KAAKA,GAAsB,KAAKD,GAAc,UAAWqB,GAAoB,CAC3E,KAAK,mBAAmBA,CAAe,CACzC,CAAC,CACH,CAGA,mBAAmBX,EAAiB,CAClC,KAAKxB,GAAUwB,EAGf,OAAO,OAAOc,CAAY,EAAE,QAAQC,GAAQ,CAC1C,GAAI,CACF,IAAMC,EAAMhB,EAAgB,WAAWe,CAAI,EACvCC,GAAK,KAAKvC,GAAU,IAAIsC,EAAMC,CAAG,CACvC,MAAY,CACV,QAAQ,KAAK,gBAAgBD,CAAI,gBAAgB,CACnD,CACF,CAAC,CAIH,CAEA,aAAajB,EAAI,CACf,IAAMsB,EAAStB,EAAG,KAAKtB,EAAO,EAC1B4C,IACF,KAAK5C,GAAU4C,EAEnB,CAEA,UAAUnB,EAAQ,CAChB,KAAKvB,GAAUuB,CACjB,CAEA,OAAQ,CACD,KAAKtB,KACR,KAAKA,GAAa,GAClB,KAAK0C,GAAgB,EAEzB,CAEA,MAAO,CACD,KAAK1C,KACP,KAAKA,GAAa,GACd,KAAKC,KACP,qBAAqB,KAAKA,EAAQ,EAClC,KAAKA,GAAW,MAGtB,CAEA,SAASe,EAAU,CACjB,GAAIxB,EAAewB,CAAQ,IAAM,QAC/B,MAAM,IAAI,MAAM,0BAA0B,EAG5C,IAAMO,EAAOP,EAAS,MAChB2B,EAAS3B,EAAS,KAAK,WAAY,KAAKT,EAAY,EAEpDW,EAAQ,CAAC,GAAGyB,EAAQ,KAAApB,EAAM,QAAS,KAAKzB,GAAU,IAAI6C,EAAO,SAAW,IAAI,CAAE,EAuDpF,GApDIA,EAAO,OACTzB,EAAM,YAAc,KAAK0B,GAAeD,EAAO,KAAM,IAAM,KAAKlC,EAAe,GAI7EkC,EAAO,OACTzB,EAAM,YAAc,KAAK0B,GAAeD,EAAO,KAAM,IAAOzB,GAAO,aAAa,SAAS,GAAK,MAAU,GAI1GA,EAAM,QAAUyB,EAAO,SAAS,IAAIE,GAAS,CAC3C,GAAIrD,EAAeqD,CAAK,IAAM,QAAS,CACrC,IAAMtB,EAAOsB,EAAM,MACbC,EAAcD,EAAM,KAAK,WAAY,KAAKtC,EAAY,EACtDwC,EAAQ,CACZ,KAAAxB,EACA,GAAGuB,CACL,EAWA,GATIA,EAAY,OACdC,EAAM,YAAc,KAAKH,GAAeE,EAAY,KAAM,IAAM,KAAKrC,EAAe,GAGlFqC,EAAY,OACdC,EAAM,YAAc,KAAKH,GAAeE,EAAY,KAAM,IAAOC,GAAO,aAAa,SAAS,GAAK,MAAU,GAI3GA,EAAM,WAAW,QACnB,GAAI,CACFA,EAAM,UAAU,QAAQ,KAAKjD,GAAU,IAAIiD,EAAM,SAAWJ,EAAO,OAAO,CAAC,CAC7E,OAASK,EAAO,CACd,QAAQ,MAAM,mBAAmBD,EAAM,IAAI,aAAcC,CAAK,CAChE,CAGF,OAAOD,CACT,CAGA,OAAIvD,EAAeqD,CAAK,IAAM,QACrB,KAAK,SAASA,CAAK,EAGrBA,CACT,CAAC,EAID,KAAKjD,GAAQ,IAAI2B,EAAML,CAAK,EAGxBA,EAAM,WAAW,QACnB,GAAI,CACFA,EAAM,UAAU,QAAQA,EAAM,OAAO,CACvC,OAAS8B,EAAO,CACd,QAAQ,MAAM,mBAAmBzB,CAAI,aAAcyB,CAAK,CAC1D,CAGF,OAAO9B,CACT,CAEA,YAAYK,EAAM,CAChB,IAAML,EAAQ,KAAKtB,GAAQ,IAAI2B,CAAI,EACnC,GAAKL,EAGL,IAAIA,EAAM,WAAW,UACnB,GAAI,CACFA,EAAM,UAAU,UAAUA,EAAM,OAAO,CACzC,OAAS8B,EAAO,CACd,QAAQ,MAAM,mBAAmBzB,CAAI,eAAgByB,CAAK,CAC5D,CAIF9B,EAAM,QAAQ,QAAQ6B,GAAS,CAC7B,GAAIA,EAAM,WAAW,UACnB,GAAI,CACFA,EAAM,UAAU,UACd,KAAKjD,GAAU,IAAIiD,EAAM,SAAW7B,EAAM,OAAO,CACnD,CACF,OAAS8B,EAAO,CACd,QAAQ,MAAM,mBAAmBD,EAAM,IAAI,eAAgBC,CAAK,CAClE,CAGED,EAAM,aACR1D,EAAgB0D,EAAM,WAAW,EAG/BA,EAAM,cACRA,EAAM,aAAa,YAAY,EAC3BA,EAAM,aAAa,UACrB1D,EAAgB0D,EAAM,YAAY,QAAQ,EAGhD,CAAC,EAGG7B,EAAM,cACRA,EAAM,aAAa,YAAY,EAC3BA,EAAM,aAAa,UACrB7B,EAAgB6B,EAAM,YAAY,QAAQ,GAI9C,KAAKtB,GAAQ,OAAO2B,CAAI,EAC1B,CAEAmB,IAAkB,CACZ,KAAKvC,IAAoB,KAAKD,KAElC,KAAKC,GAAmB,GAExB,KAAKF,GAAW,sBAAsB,IAAM,CAC1C,KAAKE,GAAmB,GACxB,KAAKF,GAAW,KAChB,KAAKgD,GAAQ,CACf,CAAC,EACH,CAEA,KAAMA,IAAU,CACd,GAAK,KAAKpD,GACV,MAAKK,GAAe,GAEpB,GAAI,CAEF,KAAKK,GAAa,MAAM,EAExB,IAAM2C,EAAc,KAAK9C,GAAe,OAAO,QAAU,YAAY,IAAI,EAAI,EAG7E,KAAKN,GAAU,QAAQuC,GAAO,CAC5BA,EAAI,UAAU,EAAG,EAAG,KAAKxC,GAAQ,MAAO,KAAKA,GAAQ,MAAM,CAC7D,CAAC,EAGD,QAAWqB,KAAS,KAAKtB,GAAQ,OAAO,EAAG,CACzC,IAAMuD,EAAa,KAAK/C,GAAe,OAAO,QAAU,YAAY,IAAI,EAAI,EAG5E,GAAIc,EAAM,aAAe,CAACA,EAAM,YAAY,SAAS,EAAG,SAExD,IAAMmB,EAAMnB,EAAM,QAElB,GAAKmB,EAGL,IAAInB,EAAM,WAAW,aACnB,GAAI,CACFA,EAAM,UAAU,aAAamB,EAAK,KAAKhC,EAAO,CAChD,OAAS2C,EAAO,CACd,QAAQ,MAAM,mBAAmB9B,EAAM,IAAI,kBAAmB8B,CAAK,EAC/D9B,EAAM,WAAW,SAASA,EAAM,UAAU,QAAQ8B,CAAK,CAC7D,CAIFX,EAAI,KAAK,EACLnB,EAAM,UACR,OAAO,QAAQA,EAAM,QAAQ,EAAE,QAAQ,CAAC,CAACkC,EAAKC,CAAK,IAAM,CACnD,OAAOhB,EAAIe,CAAG,GAAM,WACtBf,EAAIe,CAAG,EAAE,GAAI,MAAM,QAAQC,CAAK,EAAIA,EAAQ,CAACA,CAAK,CAAE,EAEpDhB,EAAIe,CAAG,EAAIC,CAEf,CAAC,EAIH,QAAWN,KAAS7B,EAAM,QAAS,CACjC,IAAMoC,EAAa,KAAKlD,GAAe,OAAO,QAAU,YAAY,IAAI,EAAI,EAE5E,GAAI2C,EAAM,aAAe,CAACA,EAAM,YAAY,SAAS,EAAG,SAGxD,IAAMQ,EAAWR,EAAM,QACrB,KAAKjD,GAAU,IAAIiD,EAAM,OAAO,EAChCV,EAEF,GAAKkB,EAGL,IAAIR,EAAM,WAAW,aACnB,GAAI,CACFA,EAAM,UAAU,aAAaQ,EAAU,KAAKlD,EAAO,CACrD,OAAS2C,EAAO,CACd,QAAQ,MAAM,mBAAmBD,EAAM,IAAI,kBAAmBC,CAAK,EAC/DD,EAAM,WAAW,SAASA,EAAM,UAAU,QAAQC,CAAK,EAC3D,QACF,CAGFO,EAAS,KAAK,EAEVR,EAAM,UACR,OAAO,QAAQA,EAAM,QAAQ,EAAE,QAAQ,CAAC,CAACK,EAAKC,CAAK,IAAM,CACnD,OAAOE,EAASH,CAAG,GAAM,WAC3BG,EAASH,CAAG,EAAE,GAAI,MAAM,QAAQC,CAAK,EAAIA,EAAQ,CAACA,CAAK,CAAE,EAEzDE,EAASH,CAAG,EAAIC,CAElB,CAAC,EAGL,GAAI,CACF,IAAMG,EAAiB,CAAC,EACxB,GAAIT,EAAM,OACR,QAAWK,KAAOL,EAAM,OACtBS,EAAeJ,CAAG,EAAI,KAAKrD,GAAQ,IAAIqD,CAAG,EAU9C,GAPAL,EAAM,OAAOQ,EAAWR,EAAM,YAAcA,EAAM,YAAY,SAAS,EAAI,OAAYS,EAAgB,KAAKnD,EAAO,EAG/G0C,EAAM,WAAW,aACnBA,EAAM,UAAU,YAAYQ,EAAU,KAAKlD,EAAO,EAGhD,KAAKD,GAAe,OAAO,QAAS,CACtC,IAAMqD,EAAY,YAAY,IAAI,EAAIH,EACtC,KAAKhD,GAAS,WAAW,IAAIyC,EAAM,KAAMU,CAAS,EAE9C,KAAKrD,GAAe,OAAO,YAC7B,KAAKsD,GAAmBH,EAAUR,CAAK,CAE3C,CACF,OAASC,EAAO,CACd,QAAQ,MAAM,mBAAmBD,EAAM,IAAI,KAAMC,CAAK,EAClDD,EAAM,WAAW,SAASA,EAAM,UAAU,QAAQC,CAAK,CAC7D,QAAE,CACAO,EAAS,QAAQ,CACnB,EACF,CAKA,GAHAlB,EAAI,QAAQ,EAGRnB,EAAM,WAAW,YACnB,GAAI,CACFA,EAAM,UAAU,YAAYmB,EAAK,KAAKhC,EAAO,CAC/C,OAAS2C,EAAO,CACd,QAAQ,MAAM,mBAAmB9B,EAAM,IAAI,iBAAkB8B,CAAK,EAC9D9B,EAAM,WAAW,SAASA,EAAM,UAAU,QAAQ8B,CAAK,CAC7D,CAGF,GAAI,KAAK5C,GAAe,OAAO,QAAS,CACtC,IAAMuD,EAAY,YAAY,IAAI,EAAIR,EACtC,KAAK7C,GAAS,WAAW,IAAIY,EAAM,KAAMyC,CAAS,EAE9C,KAAKvD,GAAe,OAAO,YAC7B,KAAKwD,GAAmBvB,EAAKnB,CAAK,CAEtC,EACF,CAGI,KAAKd,GAAe,OAAO,SAC7B,KAAKyD,GAAoB,CAG7B,QAAE,CACA,KAAK3D,GAAe,EACtB,EACF,CAEAwD,GAAmBrB,EAAKU,EAAO,CAC7BV,EAAI,KAAK,EACTA,EAAI,YAAc,uBAClBA,EAAI,UAAY,EAChBA,EAAI,WAAW,EAAG,EAAGA,EAAI,OAAO,MAAOA,EAAI,OAAO,MAAM,EACxDA,EAAI,QAAQ,CACd,CAEAuB,GAAmBvB,EAAKnB,EAAO,CAC7BmB,EAAI,KAAK,EACTA,EAAI,YAAc,uBAClBA,EAAI,UAAY,EAChBA,EAAI,WAAW,EAAG,EAAGA,EAAI,OAAO,MAAOA,EAAI,OAAO,MAAM,EACxDA,EAAI,QAAQ,CACd,CAEAwB,IAAsB,CACpB,IAAMxB,EAAM,KAAKvC,GAAU,IAAIqC,EAAa,IAAI,CAAC,EACjD,GAAI,CAACE,EAAK,OAEVA,EAAI,KAAK,EACTA,EAAI,eAAe,EACnBA,EAAI,KAAO,iBACXA,EAAI,UAAY,QAChBA,EAAI,YAAc,QAClBA,EAAI,UAAY,EAEhB,IAAIyB,EAAI,GACFC,EAAa,GAEnB,GAAI,KAAK3D,GAAe,OAAO,QAAS,CACtC,IAAM4D,EAAO,QAAQ,KAAK,MAAM,KAAK1D,GAAS,GAAG,CAAC,KAAK,KAAKD,GAAQ,UAAU,QAAQ,CAAC,CAAC,MACxFgC,EAAI,WAAW2B,EAAM,GAAIF,CAAC,EAC1BzB,EAAI,SAAS2B,EAAM,GAAIF,CAAC,EACxBA,GAAKC,CACP,CAEA,GAAI,KAAK3D,GAAe,OAAO,gBAAiB,CAC9CiC,EAAI,SAAS,eAAgB,GAAIyB,CAAC,EAClCA,GAAKC,EAEL,OAAW,CAACxC,EAAM0C,CAAI,IAAK,KAAK3D,GAAS,WAAY,CACnD,IAAM0D,EAAO,KAAKzC,CAAI,KAAK0C,EAAK,QAAQ,CAAC,CAAC,KAC1C5B,EAAI,WAAW2B,EAAM,GAAIF,CAAC,EAC1BzB,EAAI,SAAS2B,EAAM,GAAIF,CAAC,EACxBA,GAAKC,CACP,CAEA1B,EAAI,SAAS,KAAK,MAAM,IAAI,CAAC,eAAgB,UAAW,cAAc,CAAC,EAAG,GAAIyB,CAAC,CACjF,CAEAzB,EAAI,QAAQ,CACd,CAEA,aAAaT,EAAOC,EAAQ,CAE1B,QAAWX,KAAS,KAAKtB,GAAQ,OAAO,EACtC,GAAIsB,EAAM,WAAW,SACnB,GAAI,CACFA,EAAM,UAAU,SAASU,EAAOC,EAAQX,EAAM,OAAO,CACvD,OAAS8B,EAAO,CACd,QAAQ,MAAM,mBAAmB9B,EAAM,IAAI,cAAe8B,CAAK,EAC3D9B,EAAM,WAAW,SAASA,EAAM,UAAU,QAAQ8B,CAAK,CAC7D,CAGN,CAEAJ,GAAezB,EAAI+C,EAAU,IAAG,GAAc,CAC5C,GAAI,CAAC/C,EAAI,OAAO,KAEhB,IAAMgD,EAAW/E,EAAe+B,EAAI,CAClC,UAAW,GACX,QAAA+C,CACF,CAAC,EAEKE,EAAc9E,EAAU6E,EAAU,IAAM,KAAKzB,GAAgB,CAAC,EAEpE,MAAO,CAAC,SAAAyB,EAAU,YAAAC,CAAW,CAC/B,CAEA,SAAU,CACR,KAAK,KAAK,EAGN,KAAKxD,KACP,KAAKA,GAAoB,EACzB,KAAKA,GAAsB,MAEzB,KAAKD,KACP,KAAKA,GAAc,QAAQ,EAC3B,KAAKA,GAAgB,MAEnB,KAAKE,KACP,KAAKA,GAAgB,WAAW,EAChC,KAAKA,GAAkB,MAErB,KAAKJ,IACP,KAAKA,GAAgB,SAAS,EAIhC,QAAWc,KAAQ,KAAK3B,GAAQ,KAAK,EACnC,KAAK,YAAY2B,CAAI,CAEzB,CAEA,aAAaC,EAAK,CAChB,KAAKpB,GAAe,UAAYoB,EAChC,KAAKpB,GAAe,cAAgB,IAAOoB,CAC7C,CAEA,aAAaC,EAAO,CAClB,KAAKrB,GAAe,UAAY,KAAK,IAAI,EAAGqB,CAAK,CACnD,CAEA,iBAAiBC,EAAM,CACrB,KAAKtB,GAAe,cAAgBsB,CACtC,CAEA,SAASC,EAAU,CAAC,EAAG,CAChB,KAAKvB,GAAe,QACvB,KAAKA,GAAe,MAAQ,CAAC,GAE/B,OAAO,OAAO,KAAKA,GAAe,MAAOuB,CAAO,CAClD,CAEA,YAAa,CACX,MAAO,CACL,GAAG,KAAKrB,GACR,UAAW,KAAKD,GAAQ,UACxB,YAAa,KAAKA,GAAQ,YAC1B,WAAY,KAAKA,GAAQ,UAC3B,CACF,CAGA,mBAAmB2B,EAAiB,CAElC,KAAKvB,GAAgB,YAAYuB,CAAe,EAGhD,KAAKqC,GAA0BrC,CAAe,EAG9C,KAAKsC,GAAmBtC,CAAe,CACzC,CAEAsC,GAAmBtC,EAAiB,CAClC,GAAM,CAAE,KAAAI,CAAK,EAAIJ,EACXuC,EAAU,KAAK9D,GACfqB,EAAQyC,EAAQ,MAGtB,OAAQnC,EAAM,CACZ,IAAK,OACH,KAAKoC,GAAM,eAAgBD,CAAO,EAClC,MAEF,IAAK,KACH,KAAKC,GAAM,aAAcD,CAAO,EAG5BzC,GAAS,CAACA,EAAM,YAClB,KAAK0C,GAAM,gBAAiBD,CAAO,EAErC,MAEF,IAAK,OACH,KAAKC,GAAM,eAAgBD,CAAO,EAClC,MAEF,IAAK,YACH,KAAKC,GAAM,qBAAsBD,CAAO,EACxC,MAEF,IAAK,OACH,KAAKC,GAAM,oBAAqBD,CAAO,EACvC,MAEF,IAAK,UACH,KAAKC,GAAM,mBAAoBD,CAAO,EACtC,MAEF,IAAK,SACH,KAAKC,GAAM,iBAAkBD,CAAO,EACpC,MAEF,IAAK,OACH,KAAKC,GAAM,eAAgBD,CAAO,EAClC,MAEF,IAAK,WACH,KAAKC,GAAM,mBAAoBD,CAAO,EACtC,KACJ,CAGA,IAAME,EAAgB,KAAK1D,GACrB2D,EAAe5C,GAAO,cAAgB,GAExC4C,GAAgB,CAACD,EACnB,KAAKD,GAAM,gBAAiBD,CAAO,EAC1B,CAACG,GAAgBD,GAC1B,KAAKD,GAAM,gBAAiBD,CAAO,EAGrC,KAAKxD,GAAiB2D,CACxB,CAEAL,GAA0BrC,EAAiB,CACzC,GAAM,CAAE,KAAAI,EAAM,EAAAuC,EAAG,EAAAb,CAAE,EAAI9B,EACjBuC,EAAU,KAAK9D,GAErB,OAAQ2B,EAAM,CACZ,IAAK,OAAQ,CACX,IAAMwC,EAAU,KAAKC,GAASF,EAAGb,CAAC,EAGlC,GAFAS,EAAQ,cAAcK,CAAO,EAEzBA,GAAS,eAAe,QAAS,CACnC,IAAMvC,EAAM,KAAKyC,GAAmBF,CAAO,EAC3CA,EAAQ,cAAc,QAAQ,CAC5B,MAAO5C,EACP,IAAAK,EACA,KAAM,KAAKmC,GAAM,KAAK,IAAI,CAC5B,CAAC,CACH,CACA,KACF,CAEA,IAAK,KAAM,CACT,IAAMO,EAAaR,EAAQ,WAC3B,GAAIQ,GAAY,aAAa,QAAS,CACpC,IAAM1C,EAAM,KAAKyC,GAAmBC,CAAU,EAC9CA,EAAW,YAAY,QAAQ,CAC7B,MAAO/C,EACP,IAAAK,EACA,KAAM,KAAKmC,GAAM,KAAK,IAAI,CAC5B,CAAC,CACH,CACA,KACF,CAEA,IAAK,OAAQ,CACX,IAAMI,EAAU,KAAKC,GAASF,EAAGb,CAAC,EAC5BkB,EAAcT,EAAQ,YAG5B,GAAIK,GAAS,eAAe,SAAW,CAAC5C,EAAgB,WAAY,CAClE,IAAMK,EAAM,KAAKyC,GAAmBF,CAAO,EAC3CA,EAAQ,cAAc,QAAQ,CAC5B,MAAO5C,EACP,IAAAK,EACA,KAAM,KAAKmC,GAAM,KAAK,IAAI,CAC5B,CAAC,CACH,CAGA,GAAII,GAAS,KAAOI,GAAa,GAAI,CACnC,GAAIA,GAAa,gBAAgB,QAAS,CACxC,IAAM3C,EAAM,KAAKyC,GAAmBE,CAAW,EAC/CA,EAAY,eAAe,QAAQ,CACjC,MAAOhD,EACP,IAAAK,EACA,KAAM,KAAKmC,GAAM,KAAK,IAAI,CAC5B,CAAC,CACH,CAEA,GAAII,GAAS,gBAAgB,QAAS,CACpC,IAAMvC,EAAM,KAAKyC,GAAmBF,CAAO,EAC3CA,EAAQ,eAAe,QAAQ,CAC7B,MAAO5C,EACP,IAAAK,EACA,KAAM,KAAKmC,GAAM,KAAK,IAAI,CAC5B,CAAC,CACH,CAEAD,EAAQ,eAAeK,CAAO,CAChC,CACA,KACF,CAEA,IAAK,YAAa,CAChB,IAAMG,EAAaR,EAAQ,WAC3B,GAAIQ,GAAY,aAAa,QAAS,CACpC,IAAM1C,EAAM,KAAKyC,GAAmBC,CAAU,EAC9CA,EAAW,YAAY,QAAQ,CAC7B,MAAO/C,EACP,IAAAK,EACA,KAAM,KAAKmC,GAAM,KAAK,IAAI,CAC5B,CAAC,CACH,CACA,KACF,CAEA,IAAK,OAAQ,CACX,IAAMO,EAAaR,EAAQ,WAC3B,GAAIQ,GAAY,YAAY,QAAS,CACnC,IAAM1C,EAAM,KAAKyC,GAAmBC,CAAU,EAC9CA,EAAW,WAAW,QAAQ,CAC5B,MAAO/C,EACP,IAAAK,EACA,KAAM,KAAKmC,GAAM,KAAK,IAAI,CAC5B,CAAC,CACH,CACA,KACF,CAEA,IAAK,UAAW,CACd,IAAMO,EAAaR,EAAQ,WAC3B,GAAIQ,GAAY,WAAW,QAAS,CAClC,IAAM1C,EAAM,KAAKyC,GAAmBC,CAAU,EAC9CA,EAAW,UAAU,QAAQ,CAC3B,MAAO/C,EACP,IAAAK,EACA,KAAM,KAAKmC,GAAM,KAAK,IAAI,CAC5B,CAAC,CACH,CACA,KACF,CAEA,IAAK,WACH,IAAMI,EAAU,KAAKC,GAASF,EAAGb,CAAC,EAGlC,GAFAS,EAAQ,cAAcK,CAAO,EAEzBA,GAAS,mBAAmB,QAAS,CACvC,IAAMvC,EAAM,KAAKyC,GAAmBF,CAAO,EAC3CA,EAAQ,kBAAkB,QAAQ,CAChC,MAAO5C,EACP,IAAAK,EACA,KAAM,KAAKmC,GAAM,KAAK,IAAI,CAC5B,CAAC,CACH,CACA,KACJ,CACF,CAEAM,GAAmBG,EAAM,CACvB,OAAKA,EACEA,EAAK,QACR,KAAKnF,GAAU,IAAImF,EAAK,OAAO,EAC/B,KAAKnF,GAAU,IAAIqC,EAAa,IAAI,CAAC,EAHvB,IAIpB,CAEA,UAAUL,EAAOC,EAAU,CACzB,OAAK,KAAKjB,GAAa,IAAIgB,CAAK,GAC9B,KAAKhB,GAAa,IAAIgB,EAAO,IAAI,GAAK,EAExC,KAAKhB,GAAa,IAAIgB,CAAK,EAAE,IAAIC,CAAQ,EAElC,IAAM,CACX,IAAMmD,EAAY,KAAKpE,GAAa,IAAIgB,CAAK,EACzCoD,IACFA,EAAU,OAAOnD,CAAQ,EACrBmD,EAAU,OAAS,GACrB,KAAKpE,GAAa,OAAOgB,CAAK,EAGpC,CACF,CAEA+C,GAASF,EAAGb,EAAG,CAEb,IAAMqB,EAAS,KAAK5E,GAAa,MAAM,KAAK,CAAC6E,EAAGC,KAC7CA,EAAE,UAAY,IAAMD,EAAE,UAAY,EACrC,EAEA,QAAWH,KAAQE,EACjB,GAAI,KAAKG,GAAiBX,EAAGb,EAAGmB,EAAK,MAAM,EACzC,OAAOA,EAGX,OAAO,IACT,CAEAK,GAAiBX,EAAGb,EAAGyB,EAAQ,CAC7B,OAAOZ,GAAKY,EAAO,GACZZ,GAAKY,EAAO,EAAIA,EAAO,OACvBzB,GAAKyB,EAAO,GACZzB,GAAKyB,EAAO,EAAIA,EAAO,MAChC,CAEAf,GAAM1C,EAAO0D,EAAM,CACjB,IAAMN,EAAY,KAAKpE,GAAa,IAAIgB,CAAK,EAC7C,GAAIoD,EACF,QAAWnD,KAAYmD,EACrBnD,EAASyD,CAAI,CAGnB,CAGA,sBAAsBxD,EAAiB,CACrC,KAAKvB,GAAgB,YAAYuB,CAAe,EAChD,KAAKqC,GAA0BrC,CAAe,CAChD,CACF",
|
|
6
|
-
"names": ["ContextTypes", "HitRegistry", "#areas", "id", "area", "ServiceProvider", "CanvasEvents", "#canvas", "#offscreenCanvas", "#cachedRect", "#resizeObserver", "#subscribers", "#resizeSubscribers", "#pendingMove", "#rafId", "#hasTransferredControl", "#state", "canvas", "listener", "#removeListeners", "#updateCachedRect", "#initializeListeners", "subscriber", "#emitResize", "entries", "entry", "width", "height", "#handleScroll", "#handleMove", "#handleDown", "#handleUp", "#handleDblClick", "event", "normalized", "#normalizeEvent", "#emit", "rawEvent", "type", "position", "#getPosition", "dx", "dy", "dragend", "resizeData", "isOverCanvas", "x", "y", "isWithinBounds", "deltaX", "deltaY", "deltaZ", "deltaMode", "dragDistance", "defineSurface", "usePointerSurface", "setup", "event", "hoveredArea", "activeArea", "handleEvent", "_", "normalizedEvent", "setHoveredArea", "area", "setActiveArea", "reset", "ServiceProvider", "createComputed", "destroyComputed", "addEffect", "createDefinition", "definitionType", "defineBrush", "defineLayer", "Painter", "#layers", "#canvas", "#contexts", "#assets", "#isRunning", "#frameId", "#isRendering", "#renderScheduled", "#runtimeConfig", "#timing", "#metrics", "#hitRegistry", "HitRegistry", "#pointerSurface", "usePointerSurface", "#canvasEvents", "#pointerUnsubscribe", "#resizeObserver", "#subscribers", "#wasOverCanvas", "layerDef", "layers", "layer", "fn", "canvas", "offscreenCanvas", "assets", "name", "fps", "scale", "step", "options", "width", "height", "event", "callback", "normalizedEvent", "path", "
|
|
4
|
+
"sourcesContent": ["export const ContextTypes = {\n '2D': '2d',\n 'WEBGL': 'webgl',\n 'WEBGL2': 'webgl2',\n 'BITMAPRENDERER': 'bitmaprenderer'\n};", "export class HitRegistry {\n #areas = new Map();\n\n register(id, area) {\n if (!id) {\n throw new Error('Hit area must have an id');\n }\n this.#areas.set(id, { id, ...area });\n return () => this.unregister(id);\n }\n\n unregister(id) {\n this.#areas.delete(id);\n }\n\n get(id) {\n return this.#areas.get(id);\n }\n\n has(id) {\n return this.#areas.has(id);\n }\n\n get areas() {\n return Array.from(this.#areas.values());\n }\n\n clear() {\n this.#areas.clear();\n }\n}", "import { ServiceProvider } from '@jucie.io/engine';\n\nexport class CanvasEvents extends ServiceProvider {\n #canvas = null;\n #offscreenCanvas = null;\n #cachedRect = null;\n #resizeObserver = null;\n #subscribers = new Set();\n #resizeSubscribers = new Set();\n #pendingMove = null;\n #rafId = null;\n #hasTransferredControl = false;\n\n // Internal state for semantic event interpretation\n #state = {\n isPressed: false,\n button: null,\n dragStartX: null,\n dragStartY: null,\n isDragging: false,\n dragThreshold: 5,\n prevX: null,\n prevY: null\n };\n\n static manifest = {\n name: 'CanvasEvents',\n namespace: 'canvasEvents',\n version: '1.0.0'\n };\n\n actions() {\n return {\n setCanvas: (canvas) => this.setCanvas(canvas),\n subscribe: (listener) => this.subscribe(listener),\n onResize: (listener) => this.onResize(listener),\n transferControlToOffscreen: () => this.transferControlToOffscreen()\n };\n }\n\n setCanvas(canvas) {\n if (this.#canvas) {\n this.#removeListeners();\n }\n \n this.#canvas = canvas;\n this.#updateCachedRect();\n this.#initializeListeners();\n }\n\n subscribe(subscriber) {\n this.#subscribers.add(subscriber);\n return () => this.#subscribers.delete(subscriber);\n }\n\n onResize(subscriber) {\n this.#resizeSubscribers.add(subscriber);\n return () => this.#resizeSubscribers.delete(subscriber);\n }\n\n transferControlToOffscreen() {\n if (!this.#canvas) {\n throw new Error('Canvas must be set before transferring control to offscreen');\n }\n\n if (this.#hasTransferredControl) {\n throw new Error('Control has already been transferred to offscreen');\n }\n\n // Transfer control\n this.#offscreenCanvas = this.#canvas.transferControlToOffscreen();\n this.#hasTransferredControl = true;\n\n\n\n // Set initial dimensions on offscreen canvas\n this.#offscreenCanvas.width = this.#cachedRect.width;\n this.#offscreenCanvas.height = this.#cachedRect.height;\n\n // Emit initial resize event with actual canvas dimensions\n this.#emitResize({\n width: this.#canvas.width,\n height: this.#canvas.height\n });\n\n return this.#offscreenCanvas;\n }\n\n #updateCachedRect() {\n if (this.#canvas) {\n this.#cachedRect = this.#canvas.getBoundingClientRect();\n }\n }\n\n #initializeListeners() {\n if (!this.#canvas) return;\n\n this.#updateCachedRect();\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target !== this.#canvas) {\n continue;\n }\n const { width, height } = entry.contentRect;\n this.#emitResize({\n width: width,\n height: height\n });\n }\n this.#updateCachedRect();\n });\n this.#resizeObserver.observe(this.#canvas);\n\n document.addEventListener('wheel', this.#handleScroll, { passive: false });\n document.addEventListener('pointermove', this.#handleMove);\n document.addEventListener('pointerdown', this.#handleDown);\n document.addEventListener('pointerup', this.#handleUp);\n document.addEventListener('pointercancel', this.#handleUp);\n document.addEventListener('dblclick', this.#handleDblClick);\n }\n\n #removeListeners() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n\n document.removeEventListener('wheel', this.#handleScroll);\n document.removeEventListener('pointermove', this.#handleMove);\n document.removeEventListener('pointerdown', this.#handleDown);\n document.removeEventListener('pointerup', this.#handleUp);\n document.removeEventListener('pointercancel', this.#handleUp);\n document.removeEventListener('dblclick', this.#handleDblClick);\n }\n\n #handleScroll = (event) => {\n if (event.target !== this.#canvas) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n \n if (event.ctrlKey) {\n const normalized = this.#normalizeEvent(event, 'zoom');\n this.#emit(normalized);\n } else {\n const normalized = this.#normalizeEvent(event, 'scroll');\n this.#emit(normalized);\n }\n }\n\n #handleMove = (event) => {\n // Store latest raw event and throttle with RAF\n this.#pendingMove = event;\n if (this.#rafId) return;\n \n this.#rafId = requestAnimationFrame(() => {\n if (this.#pendingMove) {\n const rawEvent = this.#pendingMove;\n this.#pendingMove = null;\n \n // Determine event type based on state\n let type = 'move';\n const position = this.#getPosition(rawEvent);\n \n // Check for drag start\n if (this.#state.isPressed && !this.#state.isDragging) {\n const dx = position.x - this.#state.dragStartX;\n const dy = position.y - this.#state.dragStartY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n if (distance > this.#state.dragThreshold) {\n this.#state.isDragging = true;\n type = 'dragstart';\n }\n } else if (this.#state.isDragging) {\n type = 'drag';\n }\n \n const normalized = this.#normalizeEvent(rawEvent, type);\n this.#emit(normalized);\n }\n this.#rafId = null;\n });\n }\n\n #handleDown = (event) => {\n // Only capture if starting on canvas\n if (event.target === this.#canvas) {\n const position = this.#getPosition(event);\n \n // Update state\n this.#state.isPressed = true;\n this.#state.button = event.button ?? null;\n this.#state.dragStartX = position.x;\n this.#state.dragStartY = position.y;\n this.#state.isDragging = false;\n \n const normalized = this.#normalizeEvent(event, 'down');\n this.#emit(normalized); // Immediate\n }\n }\n\n #handleUp = (event) => {\n // Emit dragend if we were dragging\n if (this.#state.isDragging) {\n const dragend = this.#normalizeEvent(event, 'dragend');\n this.#emit(dragend);\n }\n \n // Always emit up event\n const normalized = this.#normalizeEvent(event, 'up');\n this.#emit(normalized); // Immediate\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.isDragging = false;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n }\n\n #handleDblClick = (event) => {\n const normalized = this.#normalizeEvent(event, 'dblclick');\n this.#emit(normalized);\n }\n\n #emit(event) {\n for (const subscriber of this.#subscribers) {\n subscriber(event);\n }\n }\n\n #emitResize(resizeData) {\n for (const subscriber of this.#resizeSubscribers) {\n subscriber(resizeData);\n }\n }\n\n #getPosition(event) {\n const isOverCanvas = event.target === this.#canvas;\n \n let x, y;\n if (isOverCanvas) {\n x = event.offsetX;\n y = event.offsetY;\n } else if (this.#cachedRect) {\n x = event.clientX - this.#cachedRect.left;\n y = event.clientY - this.#cachedRect.top;\n } else {\n x = event.clientX;\n y = event.clientY;\n }\n \n return { x, y, isOverCanvas };\n }\n\n #normalizeEvent(event, type) {\n const { x, y, isOverCanvas } = this.#getPosition(event);\n\n const isWithinBounds = isOverCanvas || (\n this.#cachedRect &&\n x >= 0 && \n x <= this.#cachedRect.width && \n y >= 0 && \n y <= this.#cachedRect.height\n );\n \n // Calculate deltas based on event type\n let deltaX = 0;\n let deltaY = 0;\n let deltaZ = 0;\n let deltaMode = 0;\n \n if (type === 'scroll') {\n // Scroll events use wheel deltas\n deltaX = event.deltaX;\n deltaY = event.deltaY;\n deltaZ = event.deltaZ;\n deltaMode = event.deltaMode;\n } else if (type === 'zoom') {\n // Zoom uses simplified delta\n deltaX = 0;\n deltaY = event.deltaY;\n deltaZ = 0;\n } else if (type === 'move' || type === 'drag' || type === 'dragstart') {\n // Position-based events calculate deltas from previous position\n if (this.#state.prevX !== null && this.#state.prevY !== null) {\n deltaX = x - this.#state.prevX;\n deltaY = y - this.#state.prevY;\n }\n }\n \n // Calculate drag distance if dragging\n let dragDistance = 0;\n if (this.#state.isDragging && this.#state.dragStartX !== null && this.#state.dragStartY !== null) {\n const dx = x - this.#state.dragStartX;\n const dy = y - this.#state.dragStartY;\n dragDistance = Math.sqrt(dx * dx + dy * dy);\n }\n\n const normalized = {\n // Position\n x,\n y,\n clientX: event.clientX,\n clientY: event.clientY,\n prevX: this.#state.prevX,\n prevY: this.#state.prevY,\n \n // Event metadata\n type,\n timestamp: Date.now(),\n isOverCanvas,\n isWithinBounds,\n \n // Deltas (appropriate to event type)\n deltaX,\n deltaY,\n deltaZ,\n deltaMode,\n \n // Button state\n button: event.button ?? this.#state.button,\n buttons: event.buttons ?? 0,\n isPressed: this.#state.isPressed,\n \n // Drag state\n isDragging: this.#state.isDragging,\n dragStartX: this.#state.dragStartX,\n dragStartY: this.#state.dragStartY,\n dragDistance,\n \n // Modifiers\n shiftKey: event.shiftKey || false,\n ctrlKey: event.ctrlKey || false,\n altKey: event.altKey || false,\n metaKey: event.metaKey || false\n };\n \n // Update previous position for next delta calculation\n this.#state.prevX = x;\n this.#state.prevY = y;\n\n return normalized;\n }\n\n destroy() {\n if (this.#rafId) {\n cancelAnimationFrame(this.#rafId);\n this.#rafId = null;\n }\n this.#removeListeners();\n this.#canvas = null;\n this.#offscreenCanvas = null;\n this.#cachedRect = null;\n this.#subscribers.clear();\n this.#resizeSubscribers.clear();\n this.#hasTransferredControl = false;\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.button = null;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n this.#state.isDragging = false;\n this.#state.prevX = null;\n this.#state.prevY = null;\n }\n}\n", "import { defineSurface } from '@jucie.io/reactive';\n\nexport const usePointerSurface = defineSurface((setup) => {\n // Current normalized event from CanvasEvents\n const event = setup.signal(null);\n \n // Hit registry integration (still managed here)\n const hoveredArea = setup.signal(null);\n const activeArea = setup.signal(null);\n \n // Main handler - just stores the event\n const handleEvent = setup.action((_, normalizedEvent) => {\n event(normalizedEvent);\n });\n \n const setHoveredArea = setup.action((_, area) => {\n hoveredArea(area);\n });\n \n const setActiveArea = setup.action((_, area) => {\n activeArea(area);\n });\n \n const reset = setup.action(() => {\n event(null);\n hoveredArea(null);\n activeArea(null);\n });\n \n return {\n // Signals\n event,\n hoveredArea,\n activeArea,\n\n // Actions\n handleEvent,\n setHoveredArea,\n setActiveArea,\n reset\n };\n});\n", "import { ServiceProvider } from '@jucie.io/engine';\nimport { ContextTypes } from './ContextTypes.js';\nimport { createComputed, destroyComputed, addEffect } from '@jucie.io/reactive';\nimport { createDefinition, definitionType } from '@jucie.io/engine';\nimport { HitRegistry } from './HitRegistry.js';\nimport { CanvasEvents } from './CanvasEvents.js';\nimport { usePointerSurface } from './usePointerSurface.js';\n\nconst DEFINITIONS_TYPES = {\n BRUSH: 'BRUSH',\n LAYER: 'LAYER',\n SUBSCRIPTION: 'SUBSCRIPTION',\n SUBSCRIPTIONS: 'SUBSCRIPTIONS'\n};\n\nconst GLOBAL_LAYER_NAME = 'GLOBAL_LAYER';\n\nexport const defineBrush = createDefinition(DEFINITIONS_TYPES.BRUSH, [Object]);\nexport const defineLayer = createDefinition(DEFINITIONS_TYPES.LAYER, [Object]);\nexport const defineSubscription = createDefinition(DEFINITIONS_TYPES.SUBSCRIPTION, [Function]);\nexport const defineSubscriptions = createDefinition(DEFINITIONS_TYPES.SUBSCRIPTIONS, [Array]);\n\nexport class Painter extends ServiceProvider {\n #layers = new Map();\n #brushes = new Map();\n #canvas = null; // Always OffscreenCanvas\n #contexts = new Map();\n #assets = new Map();\n #isRunning = false;\n #frameId = null;\n #isRendering = false;\n #renderScheduled = false;\n\n // Mutable runtime config (separate from frozen config)\n #runtimeConfig = {\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n };\n\n // Timing state\n #timing = {\n lastFrameTime: 0,\n deltaTime: 0,\n elapsedTime: 0,\n frameCount: 0\n };\n\n // Debug metrics\n #metrics = {\n fps: 0,\n frameTime: 0,\n layerTimes: new Map(),\n brushTimes: new Map(),\n skippedFrames: 0\n };\n\n // Hit detection state\n #hitRegistry = new HitRegistry();\n #pointerSurface = usePointerSurface();\n #canvasEvents = null; // Only created in main thread mode\n #pointerUnsubscribe = null;\n #resizeObserver = null; // For main thread canvas resize watching\n #subscribers = new Map(); // Map<event, Set<callback>>\n \n // Track state for event emission\n #wasOverCanvas = false;\n\n static manifest = {\n name: 'Painter',\n namespace: 'painter',\n version: '1.0.0',\n defaults: {\n // Timing configuration\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n // Debug configuration\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n }\n };\n\n getters () {\n return {\n pointer: () => this.#pointerSurface,\n };\n }\n \n initialize () {\n this.#addLayer(defineLayer(GLOBAL_LAYER_NAME, () => ({\n context: ContextTypes['2D']\n })));\n }\n\n actions() {\n // Initialize runtime config from frozen config\n if (this.config) {\n Object.assign(this.#runtimeConfig, this.config);\n }\n \n return {\n addLayer: (layerDef) => this.#addLayer(layerDef),\n addLayers: (...layers) => {\n for (const layer of layers) {\n this.#addLayer(layer);\n }\n },\n use: (...factories) => this.use(factories),\n updateCanvas: (fn) => this.updateCanvas(fn),\n setCanvas: (canvas) => this.setCanvas(canvas),\n setOffscreenCanvas: (offscreenCanvas) => this.setOffscreenCanvas(offscreenCanvas),\n setAssets: (assets) => this.setAssets(assets),\n removeLayer: (name) => this.#removeLayer(name),\n start: () => this.start(),\n stop: () => this.stop(),\n render: () => this.render(),\n setTargetFPS: (fps) => this.setTargetFPS(fps),\n setTimeScale: (scale) => this.setTimeScale(scale),\n setFixedTimeStep: (step) => this.setFixedTimeStep(step),\n setDebug: (options) => this.setDebug(options),\n getMetrics: () => this.getMetrics(),\n handleResize: (width, height) => this.handleResize(width, height),\n subscribe: (event, callback) => this.subscribe(event, callback),\n // Pointer API - receives normalized events from main thread\n handlePointerEvent: (normalizedEvent) => this.handlePointerEvent(normalizedEvent),\n subscribeToPointer: (callback) => this.#pointerSurface.$subscribe(callback),\n bindPointer: (path) => this.#pointerSurface.$bind(path),\n // Test helper - only for testing\n _testEmitPointerEvent: (normalizedEvent) => this._testEmitPointerEvent(normalizedEvent)\n };\n }\n\n use(factories) {\n for (const factory of factories) {\n const type = definitionType(factory);\n switch (type) {\n case DEFINITIONS_TYPES.BRUSH:\n this.#addBrush(GLOBAL_LAYER_NAME, factory);\n break;\n case DEFINITIONS_TYPES.LAYER:\n this.#addLayer(factory);\n break;\n case DEFINITIONS_TYPES.SUBSCRIPTION:\n this.#addSubscription(factory);\n break;\n\n case DEFINITIONS_TYPES.SUBSCRIPTIONS:\n this.#addSubscriptions(factory);\n break;\n\n default:\n throw new Error(`Invalid factory type: ${type}`);\n }\n }\n return this;\n }\n\n // Main thread mode: Pass regular canvas, we create OffscreenCanvas + CanvasEvents\n setCanvas(canvas) {\n // Store reference to DOM canvas for resize observation\n const domCanvas = canvas;\n \n // Transfer control to offscreen\n const offscreenCanvas = canvas.transferControlToOffscreen();\n \n // Set initial dimensions\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Create and set up canvas events (main thread only)\n if (!this.#canvasEvents) {\n this.#canvasEvents = new CanvasEvents();\n }\n \n this.#canvasEvents.setCanvas(domCanvas);\n\n // Watch for canvas resizes and sync to offscreen canvas\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n \n this.#resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry && entry.target === domCanvas) {\n // Sync dimensions to offscreen canvas\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n // Notify layers of resize\n this.handleResize(domCanvas.width, domCanvas.height);\n }\n });\n \n this.#resizeObserver.observe(domCanvas);\n\n // Connect canvas events to surface\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n }\n\n this.#pointerUnsubscribe = this.#canvasEvents.subscribe((normalizedEvent) => {\n this.handlePointerEvent(normalizedEvent);\n });\n }\n\n // Worker thread mode: Accept pre-created OffscreenCanvas, expect external events\n setOffscreenCanvas(offscreenCanvas) {\n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Don't create CanvasEvents - events will come from external source\n // via handlePointerEvent()\n }\n\n updateCanvas(fn) {\n const result = fn(this.#canvas);\n if (result) {\n this.#canvas = result;\n }\n }\n\n setAssets(assets) {\n this.#assets = assets;\n }\n\n start() {\n if (!this.#isRunning) {\n this.#isRunning = true;\n this.#scheduleRender();\n }\n }\n\n stop() {\n if (this.#isRunning) {\n this.#isRunning = false;\n if (this.#frameId) {\n cancelAnimationFrame(this.#frameId);\n this.#frameId = null;\n }\n }\n }\n\n #addLayer(layerDef) {\n if (definitionType(layerDef) !== 'LAYER') {\n throw new Error('Invalid layer definition');\n }\n\n const name = layerDef._name;\n const config = layerDef(this.useContext, this.#hitRegistry);\n\n const layer = {...config, name, context: this.#contexts.get(config.context || '2d') };\n \n // Set up layer computed if it has data paths\n if (config.data) {\n layer.dataReactor = this.#createReactor(config.data, () => this.#pointerSurface);\n }\n\n // Set up when reactor if layer has condition\n if (config.when) {\n layer.whenReactor = this.#createReactor(config.when, () => (layer?.dataReactor?.computed() || undefined));\n }\n\n // Set up brush reactors and structure\n if (config.children && config.children.length > 0) {\n for (const child of config.children) {\n if (definitionType(child) === 'BRUSH') {\n this.#addBrush(name, child);\n }\n if (definitionType(child) === 'LAYER') {\n this.#addLayer(child);\n }\n }\n }\n\n this.#layers.set(name, layer);\n\n // Call layer mount hook\n if (layer.lifecycle?.onMount) {\n try {\n layer.lifecycle.onMount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onMount:`, error);\n }\n }\n\n return layer;\n }\n\n #addBrush(layerName, brushFactory) {\n const name = brushFactory._name;\n const brushConfig = brushFactory(this.useContext, this.#hitRegistry);\n const brush = {\n name,\n ...brushConfig\n };\n\n if (brushConfig.data) {\n brush.dataReactor = this.#createReactor(brushConfig.data, () => this.#pointerSurface);\n }\n\n if (brushConfig.when) {\n brush.whenReactor = this.#createReactor(brushConfig.when, () => (brush?.dataReactor?.computed() || undefined));\n }\n\n // Call brush mount hook\n if (brush.lifecycle?.onMount) {\n try {\n brush.lifecycle.onMount(this.#contexts.get(brush.context || this.#layers.get(layerName)?.context));\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onMount:`, error);\n }\n }\n\n if (!this.#brushes.has(layerName)) {\n this.#brushes.set(layerName, []);\n }\n\n this.#brushes.get(layerName).push(brush);\n\n return brush;\n }\n\n #addSubscription(subscriptionFactory) {\n const name = subscriptionFactory._name;\n const subscriptionConfig = subscriptionFactory(this.useContext);\n this.subscribe(name, subscriptionConfig);\n }\n\n #addSubscriptions(subscriptionsFactory) {\n const prefix = subscriptionsFactory._name;\n const subscriptions = subscriptionsFactory(this.useContext);\n for (const {event, handler} of subscriptions) {\n const finalEvent = prefix ? `${prefix}:${event}` : event;\n this.subscribe(finalEvent, handler);\n }\n }\n\n #removeLayer(name) {\n const layer = this.#layers.get(name);\n if (!layer) return;\n\n // Call layer unmount hook\n if (layer.lifecycle?.onUnmount) {\n try {\n layer.lifecycle.onUnmount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onUnmount:`, error);\n }\n }\n\n const brushes = this.#brushes.get(name) || [];\n this.#brushes.delete(name);\n\n // Call brush unmount hooks and clean up reactors\n\n for (const brush of brushes) {\n if (brush.lifecycle?.onUnmount) {\n try {\n brush.lifecycle.onUnmount(\n this.#contexts.get(brush.context || layer.context)\n );\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onUnmount:`, error);\n }\n }\n // Clean up brush when reactor\n if (brush.whenReactor) {\n destroyComputed(brush.whenReactor);\n }\n // Clean up brush computed and subscription\n if (brush.dataReactor) {\n brush.dataReactor?.unsubscribe();\n if (brush.dataReactor?.computed) {\n destroyComputed(brush.dataReactor.computed);\n }\n }\n }\n\n // Clean up layer when reactor\n if (layer.whenReactor) {\n layer.whenReactor?.unsubscribe();\n if (layer.whenReactor?.computed) {\n destroyComputed(layer.whenReactor.computed);\n }\n }\n\n this.#layers.delete(name);\n }\n\n #scheduleRender() {\n if (this.#renderScheduled || this.#isRendering) return;\n \n this.#renderScheduled = true;\n \n this.#frameId = requestAnimationFrame(() => {\n this.#renderScheduled = false;\n this.#frameId = null;\n this.#render();\n });\n }\n\n async #render() {\n if (!this.#canvas) return;\n this.#isRendering = true;\n \n try {\n // Clear hit registry at start of render\n this.#hitRegistry.clear();\n \n const renderStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Clear all contexts\n this.#contexts.forEach(ctx => {\n ctx.clearRect(0, 0, this.#canvas.width, this.#canvas.height);\n });\n\n // Render layers in order\n for (const layer of this.#layers.values()) {\n const layerStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Check layer condition\n if (layer.whenReactor && !layer.whenReactor.computed()) continue;\n\n const ctx = layer.context;\n\n if (!ctx) continue;\n\n // Layer beforeRender hook\n if (layer.lifecycle?.beforeRender) {\n try {\n layer.lifecycle.beforeRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" beforeRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n // Apply layer settings\n ctx.save();\n if (layer.settings) {\n Object.entries(layer.settings).forEach(([key, value]) => {\n if (typeof ctx[key] === 'function') {\n ctx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n ctx[key] = value;\n }\n });\n }\n\n const brushes = this.#brushes.get(layer.name) || [];\n\n // Render brushes\n for (const brush of brushes) {\n const brushStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n if (brush.whenReactor && !brush.whenReactor.computed()) continue;\n\n\n const brushCtx = brush.context ? \n this.#contexts.get(brush.context) : \n ctx;\n\n if (!brushCtx) continue;\n\n // Brush beforeRender hook\n if (brush.lifecycle?.beforeRender) {\n try {\n brush.lifecycle.beforeRender(brushCtx, this.#timing);\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" beforeRender:`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n continue;\n }\n }\n\n brushCtx.save();\n \n if (brush.settings) {\n Object.entries(brush.settings).forEach(([key, value]) => {\n if (typeof brushCtx[key] === 'function') {\n brushCtx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n brushCtx[key] = value;\n }\n });\n }\n \n try {\n const requiredAssets = {};\n if (brush.assets) {\n for (const key of brush.assets) {\n requiredAssets[key] = this.#assets.get(key);\n }\n }\n brush.render(brushCtx, (brush.dataReactor ? brush.dataReactor.computed() : undefined), requiredAssets, this.#timing);\n\n // Brush afterRender hook\n if (brush.lifecycle?.afterRender) {\n brush.lifecycle.afterRender(brushCtx, this.#timing);\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const brushTime = performance.now() - brushStart;\n this.#metrics.brushTimes.set(brush.name, brushTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderBrushBounds(brushCtx, brush);\n }\n }\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\":`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n } finally {\n brushCtx.restore();\n }\n }\n\n ctx.restore();\n\n // Layer afterRender hook\n if (layer.lifecycle?.afterRender) {\n try {\n layer.lifecycle.afterRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" afterRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const layerTime = performance.now() - layerStart;\n this.#metrics.layerTimes.set(layer.name, layerTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderLayerBounds(ctx, layer);\n }\n }\n }\n\n // Render debug overlay if enabled\n if (this.#runtimeConfig.debug?.enabled) {\n this.#renderDebugOverlay();\n }\n \n } finally {\n this.#isRendering = false;\n }\n }\n\n #renderBrushBounds(ctx, brush) {\n ctx.save();\n ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';\n ctx.lineWidth = 1;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderLayerBounds(ctx, layer) {\n ctx.save();\n ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';\n ctx.lineWidth = 2;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderDebugOverlay() {\n const ctx = this.#contexts.get(ContextTypes['2D']);\n if (!ctx) return;\n\n ctx.save();\n ctx.resetTransform();\n ctx.font = '12px monospace';\n ctx.fillStyle = 'white';\n ctx.strokeStyle = 'black';\n ctx.lineWidth = 3;\n\n let y = 20;\n const lineHeight = 15;\n\n if (this.#runtimeConfig.debug?.showFPS) {\n const text = `FPS: ${Math.round(this.#metrics.fps)} (${this.#timing.deltaTime.toFixed(2)}ms)`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n if (this.#runtimeConfig.debug?.showLayerTiming) {\n ctx.fillText('Layer Times:', 10, y);\n y += lineHeight;\n\n for (const [name, time] of this.#metrics.layerTimes) {\n const text = ` ${name}: ${time.toFixed(2)}ms`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n ctx.fillText(this.state.get(['_transitions', 'pointer', 'currentState']), 10, y);\n }\n\n ctx.restore();\n }\n\n handleResize(width, height) {\n // Call onResize hooks for all layers\n for (const layer of this.#layers.values()) {\n if (layer.lifecycle?.onResize) {\n try {\n layer.lifecycle.onResize(width, height, layer.context);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" onResize:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n }\n }\n\n #createReactor(fn, context = () => undefined) {\n if (!fn) return null;\n \n const computed = createComputed(fn, {\n immediate: true,\n context\n });\n \n const unsubscribe = addEffect(computed, () => this.#scheduleRender());\n \n return {computed, unsubscribe};\n }\n\n destroy() {\n this.stop();\n\n // Clean up pointer system\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n this.#pointerUnsubscribe = null;\n }\n if (this.#canvasEvents) {\n this.#canvasEvents.destroy();\n this.#canvasEvents = null;\n }\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n if (this.#pointerSurface) {\n this.#pointerSurface.$destroy();\n }\n\n // Clean up all layers and reactors\n for (const name of this.#layers.keys()) {\n this.#removeLayer(name);\n }\n }\n\n setTargetFPS(fps) {\n this.#runtimeConfig.targetFPS = fps;\n this.#runtimeConfig.fixedTimeStep = 1000 / fps;\n }\n\n setTimeScale(scale) {\n this.#runtimeConfig.timeScale = Math.max(0, scale);\n }\n\n setFixedTimeStep(step) {\n this.#runtimeConfig.fixedTimeStep = step;\n }\n\n setDebug(options = {}) {\n if (!this.#runtimeConfig.debug) {\n this.#runtimeConfig.debug = {};\n }\n Object.assign(this.#runtimeConfig.debug, options);\n }\n\n getMetrics() {\n return {\n ...this.#metrics,\n deltaTime: this.#timing.deltaTime,\n elapsedTime: this.#timing.elapsedTime,\n frameCount: this.#timing.frameCount\n };\n }\n\n // Public method to receive pointer events from main thread\n handlePointerEvent(normalizedEvent) {\n // Feed normalized events into surface\n this.#pointerSurface.handleEvent(normalizedEvent);\n\n // Handle hit testing and interactions\n this.#handlePointerInteraction(normalizedEvent);\n \n // Emit generic pointer events for external subscribers\n this.#emitPointerEvents(normalizedEvent);\n }\n\n #emitPointerEvents(normalizedEvent) {\n const { type } = normalizedEvent;\n const pointer = this.#pointerSurface;\n const event = pointer.event;\n \n // Emit basic pointer events\n switch (type) {\n case 'down':\n this.#emit('pointer:down', pointer);\n break;\n \n case 'up':\n this.#emit('pointer:up', pointer);\n \n // Emit click if it wasn't a drag\n if (event && !event.isDragging) {\n this.#emit('pointer:click', pointer);\n }\n break;\n \n case 'move':\n this.#emit('pointer:move', pointer);\n break;\n \n case 'dragstart':\n this.#emit('pointer:drag:start', pointer);\n break;\n \n case 'drag':\n this.#emit('pointer:drag:move', pointer);\n break;\n \n case 'dragend':\n this.#emit('pointer:drag:end', pointer);\n break;\n \n case 'scroll':\n this.#emit('pointer:scroll', pointer);\n break;\n \n case 'zoom':\n this.#emit('pointer:zoom', pointer);\n break;\n \n case 'dblclick':\n this.#emit('pointer:dblclick', pointer);\n break;\n }\n \n // Check for canvas enter/leave\n const wasOverCanvas = this.#wasOverCanvas;\n const isOverCanvas = event?.isOverCanvas || false;\n \n if (isOverCanvas && !wasOverCanvas) {\n this.#emit('pointer:enter', pointer);\n } else if (!isOverCanvas && wasOverCanvas) {\n this.#emit('pointer:leave', pointer);\n }\n \n this.#wasOverCanvas = isOverCanvas;\n }\n\n #handlePointerInteraction(normalizedEvent) {\n const { type, x, y } = normalizedEvent;\n const pointer = this.#pointerSurface;\n\n switch (type) {\n case 'down': {\n const hitArea = this.#hitTest(x, y);\n pointer.setActiveArea(hitArea);\n\n if (hitArea?.onPointerDown?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerDown.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'up': {\n const activeArea = pointer.activeArea;\n if (activeArea?.onPointerUp?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onPointerUp.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'move': {\n const hitArea = this.#hitTest(x, y);\n const prevHovered = pointer.hoveredArea;\n\n // Handle pointer move on hovered area (only when NOT dragging)\n if (hitArea?.onPointerMove?.handler && !normalizedEvent.isDragging) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerMove.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n // Handle hover changes\n if (hitArea?.id !== prevHovered?.id) {\n if (prevHovered?.onPointerLeave?.handler) {\n const ctx = this.#getContextForArea(prevHovered);\n prevHovered.onPointerLeave.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n if (hitArea?.onPointerEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerEnter.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n pointer.setHoveredArea(hitArea);\n }\n break;\n }\n\n case 'dragstart': {\n const activeArea = pointer.activeArea;\n if (activeArea?.onDragStart?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onDragStart.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'drag': {\n // Perform hit test to detect drop targets while dragging\n const hitArea = this.#hitTest(x, y);\n const prevHovered = pointer.hoveredArea;\n\n // Handle hover changes (for drop target detection)\n if (hitArea?.id !== prevHovered?.id) {\n if (prevHovered?.onPointerLeave?.handler) {\n const ctx = this.#getContextForArea(prevHovered);\n prevHovered.onPointerLeave.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n if (hitArea?.onPointerEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerEnter.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n pointer.setHoveredArea(hitArea);\n }\n\n // Call drag move handler on the active area (dragged element)\n const activeArea = pointer.activeArea;\n if (activeArea?.onDragMove?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onDragMove.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'dragend': {\n const activeArea = pointer.activeArea;\n if (activeArea?.onDragEnd?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onDragEnd.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'dblclick':\n const hitArea = this.#hitTest(x, y);\n pointer.setActiveArea(hitArea);\n\n if (hitArea?.onPointerDblClick?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerDblClick.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n }\n\n #getContextForArea(area) {\n if (!area) return null;\n return area.context \n ? this.#contexts.get(area.context) \n : this.#contexts.get(ContextTypes['2D']);\n }\n\n subscribe(event, callback) {\n if (!this.#subscribers.has(event)) {\n this.#subscribers.set(event, new Set());\n }\n this.#subscribers.get(event).add(callback);\n \n return () => {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) {\n this.#subscribers.delete(event);\n }\n }\n };\n }\n\n #hitTest(x, y) {\n // Sort by priority (highest first) and test\n const sorted = this.#hitRegistry.areas.sort((a, b) => \n (b.priority || 0) - (a.priority || 0)\n );\n \n for (const area of sorted) {\n if (this.#isPointInBounds(x, y, area.bounds)) {\n return area;\n }\n }\n return null;\n }\n\n #isPointInBounds(x, y, bounds) {\n return x >= bounds.x && \n x <= bounds.x + bounds.width &&\n y >= bounds.y && \n y <= bounds.y + bounds.height;\n }\n\n #emit(event, data) {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n for (const callback of callbacks) {\n callback(data);\n }\n }\n }\n\n // Test helper - only for testing, simulates normalized pointer events\n _testEmitPointerEvent(normalizedEvent) {\n this.#pointerSurface.handleEvent(normalizedEvent);\n this.#handlePointerInteraction(normalizedEvent);\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["ContextTypes", "HitRegistry", "#areas", "id", "area", "ServiceProvider", "CanvasEvents", "#canvas", "#offscreenCanvas", "#cachedRect", "#resizeObserver", "#subscribers", "#resizeSubscribers", "#pendingMove", "#rafId", "#hasTransferredControl", "#state", "canvas", "listener", "#removeListeners", "#updateCachedRect", "#initializeListeners", "subscriber", "#emitResize", "entries", "entry", "width", "height", "#handleScroll", "#handleMove", "#handleDown", "#handleUp", "#handleDblClick", "event", "normalized", "#normalizeEvent", "#emit", "rawEvent", "type", "position", "#getPosition", "dx", "dy", "dragend", "resizeData", "isOverCanvas", "x", "y", "isWithinBounds", "deltaX", "deltaY", "deltaZ", "deltaMode", "dragDistance", "defineSurface", "usePointerSurface", "setup", "event", "hoveredArea", "activeArea", "handleEvent", "_", "normalizedEvent", "setHoveredArea", "area", "setActiveArea", "reset", "ServiceProvider", "createComputed", "destroyComputed", "addEffect", "createDefinition", "definitionType", "DEFINITIONS_TYPES", "GLOBAL_LAYER_NAME", "defineBrush", "defineLayer", "defineSubscription", "defineSubscriptions", "Painter", "#layers", "#brushes", "#canvas", "#contexts", "#assets", "#isRunning", "#frameId", "#isRendering", "#renderScheduled", "#runtimeConfig", "#timing", "#metrics", "#hitRegistry", "HitRegistry", "#pointerSurface", "usePointerSurface", "#canvasEvents", "#pointerUnsubscribe", "#resizeObserver", "#subscribers", "#wasOverCanvas", "#addLayer", "ContextTypes", "layerDef", "layers", "layer", "factories", "fn", "canvas", "offscreenCanvas", "assets", "name", "#removeLayer", "fps", "scale", "step", "options", "width", "height", "event", "callback", "normalizedEvent", "path", "factory", "type", "#addBrush", "#addSubscription", "#addSubscriptions", "domCanvas", "ctx", "CanvasEvents", "entries", "entry", "result", "#scheduleRender", "config", "#createReactor", "child", "error", "layerName", "brushFactory", "brushConfig", "brush", "subscriptionFactory", "subscriptionConfig", "subscriptionsFactory", "prefix", "subscriptions", "handler", "finalEvent", "brushes", "#render", "renderStart", "layerStart", "key", "value", "brushStart", "brushCtx", "requiredAssets", "brushTime", "#renderBrushBounds", "layerTime", "#renderLayerBounds", "#renderDebugOverlay", "y", "lineHeight", "text", "time", "context", "computed", "unsubscribe", "#handlePointerInteraction", "#emitPointerEvents", "pointer", "#emit", "wasOverCanvas", "isOverCanvas", "x", "hitArea", "#hitTest", "#getContextForArea", "activeArea", "prevHovered", "area", "callbacks", "sorted", "a", "b", "#isPointInBounds", "bounds", "data"]
|
|
7
7
|
}
|